1 // VISU OBJECT : interactive object for VISU entities implementation
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
23 // File : VISU_MedConvertor.cxx
24 // Author : Alexey PETROV
28 #include "VISU_MedConvertor.hxx"
30 #include <vtkCellType.h>
31 #define USER_INTERLACE MED_FULL_INTERLACE
36 static int MYDEBUG = 0;
38 static int MYDEBUG = 0;
41 static med_err ret = 0;
43 typedef map<VISU::TEntity,med_entite_maillage> TVisu2MedEntity;
45 static TVisu2MedEntity aVisu2MedEntity;
48 aVisu2MedEntity[VISU::NODE_ENTITY] = MED_NOEUD,
49 aVisu2MedEntity[VISU::EDGE_ENTITY] = MED_ARETE,
50 aVisu2MedEntity[VISU::FACE_ENTITY] = MED_FACE,
51 aVisu2MedEntity[VISU::CELL_ENTITY] = MED_MAILLE,
54 static med_geometrie_element NODEGEOM[1] = {MED_POINT1};
56 static med_geometrie_element EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
60 static med_geometrie_element FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
61 MED_TRIA3, MED_QUAD4, MED_TRIA6, MED_QUAD8
64 static med_geometrie_element CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
65 MED_POINT1, MED_SEG2, MED_SEG3, MED_TRIA3,
66 MED_QUAD4, MED_TRIA6, MED_QUAD8, MED_TETRA4,
67 MED_PYRA5, MED_PENTA6, MED_HEXA8, MED_TETRA10,
68 MED_PYRA13, MED_PENTA15, MED_HEXA20
71 void GetEntity2Geom(const VISU::TEntity& theEntity, med_geometrie_element*& theVector, int* theEnd)
72 throw (std::runtime_error&)
75 case VISU::CELL_ENTITY: theVector = CELLGEOM; *theEnd = MED_NBR_GEOMETRIE_MAILLE; break;
76 case VISU::FACE_ENTITY: theVector = FACEGEOM; *theEnd = MED_NBR_GEOMETRIE_FACE; break;
77 case VISU::EDGE_ENTITY: theVector = EDGEGEOM; *theEnd = MED_NBR_GEOMETRIE_ARETE; break;
78 case VISU::NODE_ENTITY: theVector = NODEGEOM; *theEnd = 1; break;
80 throw std::runtime_error("GetEntity2Geom >> theEntity is uncorrect");
85 VISU_Convertor* CreateMedConvertor(const string& theFileName) throw(std::runtime_error&){
86 return new VISU_MedConvertor(theFileName);
93 MedFile(const MedFile&);
95 MedFile(const char* theFileName) throw(std::runtime_error&) :
96 myFileName(strdup(theFileName))
98 myFid = MEDouvrir(myFileName,MED_LECT);
101 throw std::runtime_error(string("MedFile::MedFile >> MEDouvrir(...) - ") + theFileName);
109 const med_idt& GetFid() const { return myFid;};
112 VISU_MedConvertor::VISU_MedConvertor(const string& theFileName) throw (std::runtime_error&) {
113 myFileInfo.setFile(QString(theFileName.c_str()));
114 myName = myFileInfo.baseName().latin1();
117 VISU_Convertor* VISU_MedConvertor::Build() throw (std::runtime_error&) {
118 MedFile aMedFile(myFileInfo.absFilePath());
119 med_idt fid = aMedFile.GetFid();
120 med_int iMeshEnd = MEDnMaa(fid); //Get number of meshes
121 if(MYDEBUG) MESSAGE("ImportInfo - MEDnMaa = "<<iMeshEnd<<"; myFileInfo = "<<myFileInfo.filePath());
122 for(int iMesh = 1; iMesh <= iMeshEnd; iMesh++){
124 char aMeshName[MED_TAILLE_NOM+1] = "";
125 MEDmaaInfo(fid,iMesh,aMeshName,&aMeshDim);
126 if(MYDEBUG) MESSAGE("ImportInfo - aMeshName = '"<<aMeshName<<"'; aMeshDim = "<<aMeshDim);
127 VISU::TMesh &aMesh = myMeshMap[aMeshName];
128 aMesh.myDim = aMeshDim;
129 aMesh.myName = aMeshName;
130 typedef map<med_int,VISU::TEntity> TFamily2EntityMap;
131 TFamily2EntityMap aFamily2EntityMap;
132 typedef map<med_int,med_int> TFamilyCounterMap;
133 TFamilyCounterMap aFamilyNbCellsCounterMap, aFamilyCellsSizeCounterMap;
134 TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
135 for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++) {
136 VISU::TEntity anEntity = aVisu2MedEntityIter->first;
138 med_geometrie_element* aGeomElemVector;
139 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
140 med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
141 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
142 int medId = getIdMedType(aGeomElemVector[iGeomElem]);
143 int aVtkType = med2vtk[medId].vtkType;
144 med_geometrie_element aMedType = med2vtk[medId].medType;
145 if(aMedEntity == MED_NOEUD){
146 med_geometrie_element typgeo = (med_geometrie_element)0;
147 med_connectivite typco = (med_connectivite)0;
148 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,typgeo,typco);
150 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
151 aMeshOnEntity.myEntity = anEntity;
152 aMeshOnEntity.myMeshName = aMeshName;
153 aMeshOnEntity.myNbCells = iNumElemEnd;
154 aMeshOnEntity.myCellsSize = 2*iNumElemEnd;
155 aMesh.myNbPoints = iNumElemEnd;
157 MESSAGE("ImportInfo -\t anEntity = "<<anEntity<<
158 "; medName = "<<med2vtk[medId].medName<<
159 "; myNbCells = "<<aMeshOnEntity.myNbCells<<
160 "; myCellsSize = "<<aMeshOnEntity.myCellsSize);
161 med_booleen iname_elem, inum_elem;
162 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
163 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
165 valarray<char> name_coord('\0',aMesh.myDim*MED_TAILLE_PNOM+1);
166 valarray<char> unit_coord('\0',aMesh.myDim*MED_TAILLE_PNOM+1);
167 valarray<med_float> coord(aMesh.myDim*iNumElemEnd);
168 ret = MEDnoeudsLire(fid,aMeshName,aMesh.myDim,&coord[0],MED_FULL_INTERLACE,&rep,
169 &name_coord[0],&unit_coord[0],&name_elem[0],&iname_elem,
170 &num_elem[0],&inum_elem,&num_fam_elem[0],iNumElemEnd);
171 if(ret < 0) throw std::runtime_error("ImportInfo >> MEDnoeudsLire(...)");
172 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
173 if(num_fam_elem[iNumElem] != 0){
174 aFamily2EntityMap[num_fam_elem[iNumElem]] = anEntity;
175 aFamilyNbCellsCounterMap[num_fam_elem[iNumElem]] += 1;
176 aFamilyCellsSizeCounterMap[num_fam_elem[iNumElem]] += 2;
180 //Get number of connectivities
181 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aMedType,MED_NOD);
182 if (iNumElemEnd > 0) {
183 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
184 aMeshOnEntity.myEntity = anEntity;
185 aMeshOnEntity.myMeshName = aMeshName;
186 med_booleen iname_elem, inum_elem;
187 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
188 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
189 med_int aNbConnForElem = getNbMedConnect(aMedType,anEntity,aMesh.myDim);
190 aMeshOnEntity.myNbCells += iNumElemEnd;
191 aMeshOnEntity.myCellsSize += iNumElemEnd*(med2vtk[medId].vtkNbNodes + 1);
193 MESSAGE("ImportInfo -\t anEntity = "<<anEntity<<
194 "; medName = "<<med2vtk[medId].medName<<
195 "; aNbConnForElem = "<<aNbConnForElem<<
196 "; myNbCells = "<<aMeshOnEntity.myNbCells<<
197 "; myCellsSize = "<<aMeshOnEntity.myCellsSize);
198 valarray<med_int> conn(0,aNbConnForElem*iNumElemEnd);
199 ret = MEDelementsLire(fid,aMeshName,aMesh.myDim,&conn[0],MED_FULL_INTERLACE,
200 &name_elem[0],&iname_elem,&num_elem[0],&inum_elem,
201 &num_fam_elem[0],iNumElemEnd,aMedEntity,aMedType,MED_NOD);
202 if (ret < 0) throw std::runtime_error("ImportInfo >> MEDelementsLire(...)");
203 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
204 if(num_fam_elem[iNumElem] != 0){
205 aFamily2EntityMap[num_fam_elem[iNumElem]] = anEntity;
206 aFamilyNbCellsCounterMap[num_fam_elem[iNumElem]] += 1;
207 aFamilyCellsSizeCounterMap[num_fam_elem[iNumElem]] += med2vtk[medId].vtkNbNodes + 1;
212 med_int aNbFamily = MEDnFam(fid,aMeshName,0,MED_FAMILLE);
213 if(MYDEBUG) MESSAGE("ImportInfo - aNbFamily = "<<aNbFamily);
214 for(int aFamInd = 1; aFamInd <= aNbFamily; aFamInd++){
215 med_int aNbAttrib = MEDnFam(fid,aMeshName,aFamInd,MED_ATTR);
216 valarray<med_int> anAttId(aNbAttrib), anAttVal(aNbAttrib);
217 valarray<char> anAttDesc('\0',aNbAttrib*MED_TAILLE_DESC+1);
218 med_int aNbGroup = MEDnFam(fid,aMeshName,aFamInd,MED_GROUPE);
220 MESSAGE("ImportInfo - aFamInd = "<<aFamInd<<"; aNbAttrib = "<<aNbAttrib<<"; aNbGroup = "<<aNbGroup);
221 valarray<char> aGroupNames('\0',aNbGroup*MED_TAILLE_LNOM+1);
222 char aFamilyName[MED_TAILLE_NOM+1] = "";
224 ret = MEDfamInfo(fid,aMeshName,aFamInd,aFamilyName,&aFamilyNum,
225 &anAttId[0],&anAttVal[0],&anAttDesc[0],&aNbAttrib,
226 &aGroupNames[0],&aNbGroup);
227 if(ret < 0) throw std::runtime_error("ImportInfo >> MEDfamInfo");
229 MESSAGE("ImportInfo - aFamilyNum = "<<aFamilyNum<<"; aNbGroup = "<<aNbGroup);
230 if(aFamily2EntityMap.find(aFamilyNum) == aFamily2EntityMap.end()) {
231 if(MYDEBUG) MESSAGE("ImportInfo - a Family with name '"<<aFamilyName<<"' are empty !!!");
234 VISU::TEntity anEntity = aFamily2EntityMap[aFamilyNum];
235 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
236 VISU::TFamily& aFamily = aMeshOnEntity.myFamilyMap[aFamilyName];
237 aFamily.myName = aFamilyName;
238 aFamily.myEntity = anEntity;
239 aFamily.myId = aFamilyNum;
240 aFamily.myNbCells = aFamilyNbCellsCounterMap[aFamilyNum];
241 aFamily.myCellsSize = aFamilyCellsSizeCounterMap[aFamilyNum];
243 MESSAGE("ImportInfo - aFamily.myEntity = "<<anEntity<<
244 "; myName = '"<<aFamilyName<<
245 "'; myId = "<<aFamilyNum<<
246 "; myNbCells = "<<aFamily.myNbCells<<
247 "; myCellsSize = "<<aFamily.myCellsSize);
248 VISU::TBindGroups& aBindGroups = aFamily.myGroups;
249 for(int iGroup = 0, iPos = 0; iGroup < aNbGroup; iGroup++, iPos += MED_TAILLE_LNOM){
250 char aGroupName[MED_TAILLE_LNOM+1];
251 strncpy(aGroupName,&aGroupNames[iPos],MED_TAILLE_LNOM);
252 aGroupName[MED_TAILLE_LNOM] = '\0';
253 if(MYDEBUG) MESSAGE("ImportInfo - aGroupName["<<iGroup<<"] = '"<<aGroupName<<"'");
254 aBindGroups.insert(aGroupName);
257 //Calculation of TMesh.TGroupMap
258 const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
259 if(aMeshOnEntityMap.empty()) continue;
260 VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
261 VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
262 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
263 const VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
264 const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity.myFamilyMap;
265 if(aFamilyMap.empty()) continue;
266 VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
267 for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
268 const VISU::TFamily& aFamily = aFamilyMapIter->second;
269 const VISU::TBindGroups& aBindGroups = aFamily.myGroups;
270 if(aBindGroups.empty()) continue;
271 VISU::TBindGroups::const_iterator aBindGroupsIter = aBindGroups.begin();
272 for(; aBindGroupsIter != aBindGroups.end(); aBindGroupsIter++){
273 const string& aGroupName = *aBindGroupsIter;
274 VISU::TGroup& aGroup = aGroupMap[aGroupName];
275 aGroup.myName = aGroupName;
276 aGroup.myMeshName = aMesh.myName;
277 VISU::TFamilyAndEntity aFamilyAndEntity(aFamily.myName,aFamily.myEntity);
278 aGroup.myFamilyAndEntitySet.insert(aFamilyAndEntity);
279 aGroup.myNbCells += aFamily.myNbCells;
280 aGroup.myCellsSize += aFamily.myCellsSize;
284 //Displaing information for the TMesh.TGroupMap
285 VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
286 if(MYDEBUG) MESSAGE("ImportInfo - aGroupMap.size() = "<<aGroupMap.size());
287 for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
288 const VISU::TGroup& aCGroup = aGroupMapIter->second;
289 const string& aGroupName = aGroupMapIter->first;
290 if(MYDEBUG) MESSAGE("ImportInfo - aGroupName = '"<<aGroupName<<
291 "'; myNbCells = "<<aCGroup.myNbCells<<
292 "; myCellsSize = "<<aCGroup.myCellsSize);
293 const VISU::TGroup& aGroup = aGroupMapIter->second;
294 const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup.myFamilyAndEntitySet;
295 VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
296 for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
297 const string& aFamilyName = aFamilyAndEntitySetIter->first;
298 if(MYDEBUG) MESSAGE("ImportInfo - \t aFamilyName = '"<<aFamilyName<<"'");
302 //Reading information about fields
303 med_int iFieldEnd = MEDnChamp(fid,0);
304 if (iFieldEnd < 0) throw std::runtime_error("ImportChamps >> MEDnChamp(fid,0)");
305 if(MYDEBUG) MESSAGE("ImportInfo - iFieldEnd = "<<iFieldEnd);
306 for(med_int iField = 1; iField <= iFieldEnd; iField++){
307 med_int ncomp = MEDnChamp(fid,iField);
308 if(ncomp < 0) throw std::runtime_error("ImportChamps >> MEDnChamp(fid,i)");
309 valarray<char> aCompNames('\0',ncomp*MED_TAILLE_PNOM + 1);
310 valarray<char> aUnitNames('\0',ncomp*MED_TAILLE_PNOM + 1);
311 char name_field[MED_TAILLE_NOM + 1] = "";
312 med_type_champ type_field;
313 if(MEDchampInfo(fid,iField,name_field,&type_field,&aCompNames[0],&aUnitNames[0],ncomp) < 0)
314 throw std::runtime_error(string("ImportInfo >> MEDchampInfo(...)"));
315 //if(type_field != MED_REEL64) continue; //There is some problem in reading INTXX values
316 TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
317 for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++) {
318 VISU::TEntity anEntity = aVisu2MedEntityIter->first;
320 med_geometrie_element* aGeomElemVector;
321 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
322 med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
323 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
324 med_geometrie_element& aGeom = aGeomElemVector[iGeomElem];
325 med_int iTimeStampEnd = MEDnPasdetemps(fid,name_field,aMedEntity,aGeom);
326 if(iTimeStampEnd < 0) throw std::runtime_error("ImportInfo >> MEDnPasdetemps(...)");
327 if(iTimeStampEnd > 0) {
328 for(med_int iTimeStamp = 1; iTimeStamp <= iTimeStampEnd; iTimeStamp++) {
329 char aMeshName[MED_TAILLE_NOM+1] = "";
330 med_int ngauss = 0, numdt = 0, numo = 0;
331 char dt_unit[MED_TAILLE_PNOM+1] = "";
333 ret = MEDpasdetempsInfo(fid,name_field,aMedEntity,aGeom,iTimeStamp,
334 aMeshName,&ngauss,&numdt,dt_unit,&dt,&numo);
335 if(ret < 0) throw std::runtime_error("ImportInfo >> MEDpasdetempsInfo(...) < 0");
336 if(myMeshMap.find(aMeshName) == myMeshMap.end())
337 throw std::runtime_error("ImportInfo >> MEDpasdetempsInfo(...)");
338 VISU::TMesh &aMesh = myMeshMap[aMeshName];
339 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
340 VISU::TFieldMap::iterator aFieldMapIter = aMeshOnEntity.myFieldMap.find(name_field);
341 //if(MYDEBUG && aFieldMapIter == aMeshOnEntity.myFieldMap.end()){
342 VISU::TField& aField = aMeshOnEntity.myFieldMap[name_field];
344 aField.myId = iField;
345 aField.myName = name_field;
346 aField.myEntity = anEntity;
347 aField.myMeshName = aMeshName;
348 aField.myNbComp = ncomp;
349 aField.myNbValField = iTimeStampEnd;
350 aField.myDataSize = aMeshOnEntity.myNbCells * ncomp;
351 aField.myCompNames.resize(ncomp);
352 aField.myUnitNames.resize(ncomp);
354 MESSAGE("ImportInfo - aField.myName = '"<<name_field<<
355 "'; myMeshName = '"<<aMeshName<<
356 "'; myEntity = "<<anEntity<<
357 "; myNbComp = "<<ncomp<<
358 "; myDataSize = "<<aField.myDataSize);
359 for(int iComp = 0, iPos = 0; iComp < ncomp; iComp++, iPos += MED_TAILLE_PNOM){
360 char aCompName[MED_TAILLE_PNOM+1], aUnitName[MED_TAILLE_PNOM+1];
361 strncpy(aCompName,&aCompNames[iPos],MED_TAILLE_PNOM);
362 aCompName[MED_TAILLE_PNOM] = '\0';
363 aField.myCompNames[iComp] = aCompName;
364 strncpy(aUnitName,&aUnitNames[iPos],MED_TAILLE_PNOM);
365 aUnitName[MED_TAILLE_PNOM] = '\0';
366 aField.myUnitNames[iComp] = aUnitName;
368 MESSAGE("ImportInfo - aCompName = '"<<aCompName<<"'; aUnitName = '"<<aUnitName<<"'");
372 VISU::TField::TValForTime& aValForTime = aField.myValField[iTimeStamp];
373 aValForTime.myId = iTimeStamp;
374 aValForTime.myFieldName = aField.myName;
375 aValForTime.myEntity = aField.myEntity;
376 aValForTime.myMeshName = aField.myMeshName;
377 aValForTime.myNbComp = aField.myNbComp;
378 aValForTime.myTime = VISU::TField::TTime(dt,dt_unit);
379 if(MYDEBUG && iGeomElem == 0)
380 MESSAGE("ImportInfo -\t aValForTime.myTime = "<<dt<<", "<<dt_unit);
389 int VISU_MedConvertor::LoadMeshOnEntity(VISU::TMeshOnEntity& theMeshOnEntity,
390 const string& theFamilyName)
391 throw (std::runtime_error&)
393 //Open the med file (it will be closed by call of destructor)
394 MedFile aMedFile(myFileInfo.absFilePath());
395 med_idt fid = aMedFile.GetFid();
397 const string& aMeshName = theMeshOnEntity.myMeshName;
398 const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
399 VISU::TMesh& aMesh = myMeshMap[aMeshName];
401 if(anEntity == VISU::NODE_ENTITY)
402 isPointsUpdated = LoadPoints(fid,aMesh,theFamilyName);
404 isPointsUpdated = LoadPoints(fid,aMesh);
405 int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity,theFamilyName);
407 return (isPointsUpdated || isCellsOnEntityUpdated);
410 int VISU_MedConvertor::LoadMeshOnGroup(VISU::TMesh& theMesh,
411 const VISU::TFamilyAndEntitySet& theFamilyAndEntitySet)
412 throw (std::runtime_error&)
414 //Open the med file (it will be closed by call of destructor)
415 MedFile aMedFile(myFileInfo.absFilePath());
416 med_idt fid = aMedFile.GetFid();
418 int isPointsUpdated = 0;
419 int isCellsOnEntityUpdated = 0;
420 VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = theFamilyAndEntitySet.begin();
421 for(; aFamilyAndEntitySetIter != theFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
422 const string& aFamilyName = aFamilyAndEntitySetIter->first;
423 const VISU::TEntity& anEntity = aFamilyAndEntitySetIter->second;
424 VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[anEntity];
425 if(anEntity == VISU::NODE_ENTITY){
426 isPointsUpdated += LoadPoints(fid,theMesh,aFamilyName);
427 isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity);
429 isPointsUpdated += LoadPoints(fid,theMesh);
430 isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity,aFamilyName);
434 return (isPointsUpdated || isCellsOnEntityUpdated);
437 int VISU_MedConvertor::LoadFieldOnMesh(VISU::TMesh& theMesh,
438 VISU::TMeshOnEntity& theMeshOnEntity,
439 VISU::TField& theField,
440 VISU::TField::TValForTime& theValForTime)
441 throw (std::runtime_error&)
443 //Open the med file (it will be closed by call of destructor)
444 MedFile aMedFile(myFileInfo.absFilePath());
445 med_idt fid = aMedFile.GetFid();
447 int isPointsUpdated = LoadPoints(fid,theMesh);
448 int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity);
449 int isFieldUpdated = LoadField(fid,theMeshOnEntity,theField,theValForTime);
451 return (isPointsUpdated || isCellsOnEntityUpdated || isFieldUpdated);
454 int VISU_MedConvertor::LoadPoints(const med_idt& fid, VISU::TMesh& theMesh, const string& theFamilyName)
455 throw (std::runtime_error&)
458 //Check on existing family
459 VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[VISU::NODE_ENTITY];
460 aMeshOnEntity.myEntity = VISU::NODE_ENTITY;
461 aMeshOnEntity.myMeshName = theMesh.myName;
462 VISU::TFamily* pFamily = VISU::GetFamily(aMeshOnEntity,theFamilyName);
463 bool isFamilyPresent = (pFamily != NULL);
464 VISU::TFamily& aFamily = *pFamily;
465 //Check on loading already done
466 bool isPointsLoaded = !theMesh.myPointsCoord.empty();
468 if(!isFamilyPresent) return 0;
469 else if(!aFamily.mySubMesh.empty()) return 0;
471 MESSAGE("LoadPoints - isPointsLoaded = "<<isPointsLoaded<<"; theFamilyName = '"<<theFamilyName<<"'");
473 char aMeshName[MED_TAILLE_NOM+1] = "";
474 strcpy(aMeshName,theMesh.myName.c_str());
475 med_geometrie_element typgeo = (med_geometrie_element)0; //MED_POINT1
476 med_connectivite typco = (med_connectivite)0; //MED_NOD
477 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,typgeo,typco);
478 if (iNumElemEnd <= 0) throw std::runtime_error("LoadPoints >> MEDnEntMaa(...)");
479 if(MYDEBUG) MESSAGE("LoadPoints - iNumElemEnd = "<<iNumElemEnd);
481 med_booleen iname_elem, inum_elem;
482 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
483 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
484 valarray<char> name_coord('\0',theMesh.myDim*MED_TAILLE_PNOM+1);
485 valarray<char> unit_coord('\0',theMesh.myDim*MED_TAILLE_PNOM+1);
486 valarray<med_float> coord(theMesh.myDim*iNumElemEnd);
487 ret = MEDnoeudsLire(fid,aMeshName,theMesh.myDim,&coord[0],MED_FULL_INTERLACE,&rep,
488 &name_coord[0],&unit_coord[0],&name_elem[0],&iname_elem,
489 &num_elem[0],&inum_elem,&num_fam_elem[0],iNumElemEnd);
490 if(ret < 0) throw std::runtime_error("LoadPoints >> MEDnoeudsLire(...)");
492 VISU::TMesh::TPointsCoord& aPointsCoord = theMesh.myPointsCoord;
493 aPointsCoord.resize(iNumElemEnd*theMesh.myDim);
494 if(MYDEBUG) MESSAGE("LoadPoints - Filling coordinates of the mesh - inum_elem = "<<inum_elem);
495 inum_elem = MED_FAUX; // It is workaround
496 if(inum_elem == MED_FAUX)
497 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
498 for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
499 aPointsCoord[iNumElem2Dim] = coord[iNumElem2Dim];
501 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
502 for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
503 aPointsCoord[num_elem[iNumElem2Dim]] = coord[iNumElem2Dim];
504 if(MYDEBUG) MESSAGE("LoadPoints - Filling aMeshOnEntity with type NODE_ENTITY");
505 VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = aMeshOnEntity.myCellsConn[VTK_VERTEX];
506 aConnForCellType.resize(iNumElemEnd);
507 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
508 aConnForCellType[iNumElem] = VISU::TMeshOnEntity::TConnect(1,iNumElem);
510 if(isFamilyPresent && iNumElemEnd > 0){
511 if(MYDEBUG) MESSAGE("LoadPoints - Filling aFamily SubMesh");
512 VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[VTK_VERTEX];
513 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
514 if(num_fam_elem[iNumElem] == aFamily.myId)
515 aSubMeshOnCellType.insert(iNumElem);
518 }catch(std::runtime_error& exc){
519 theMesh.myPointsCoord.clear();
520 throw std::runtime_error(exc.what());
522 theMesh.myPointsCoord.clear();
523 throw std::runtime_error("Unknown exception !!!");
528 int VISU_MedConvertor::LoadCellsOnEntity(const med_idt& fid, VISU::TMeshOnEntity& theMeshOnEntity,
529 const string& theFamilyName)
530 throw (std::runtime_error&)
533 //Check on existing family
534 VISU::TFamily* pFamily = VISU::GetFamily(theMeshOnEntity,theFamilyName);
535 bool isFamilyPresent = (pFamily != NULL);
536 VISU::TFamily& aFamily = *pFamily;
537 //Check on loading already done
538 bool isCellsLoaded = !theMeshOnEntity.myCellsConn.empty();
540 if(!isFamilyPresent) return 0;
541 else if(!aFamily.mySubMesh.empty()) return 0;
543 MESSAGE("LoadCellsOnEntity - theFamilyName = '"<<theFamilyName<<"'");
544 MESSAGE("LoadCellsOnEntity - isCellsLoaded = "<<isCellsLoaded<<"; isFamilyPresent = "<<isFamilyPresent);
548 med_geometrie_element* aGeomElemVector;
549 const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
550 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
551 const med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
552 char aMeshName[MED_TAILLE_NOM+1] = "";
553 strcpy(aMeshName,theMeshOnEntity.myMeshName.c_str());
555 MESSAGE("LoadCellsOnEntity - theMeshOnEntity.myEntity = "<<theMeshOnEntity.myEntity<<
556 "; iGeomElemEnd = "<<iGeomElemEnd<<"; theFamilyName = '"<<theFamilyName<<"'");
557 VISU::TMesh &aMesh = myMeshMap[theMeshOnEntity.myMeshName];
558 int aNbPoints = aMesh.myPointsCoord.size()/aMesh.myDim;
559 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
560 int medId = getIdMedType(aGeomElemVector[iGeomElem]);
561 int nbMedNodes = med2vtk[medId].medNbNodes;
562 int nbVtkNodes = med2vtk[medId].vtkNbNodes;
563 int aVtkType = med2vtk[medId].vtkType;
564 med_geometrie_element aMedType = med2vtk[medId].medType;
565 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aMedType,MED_NOD);
566 if (iNumElemEnd > 0) {
567 med_booleen iname_elem, inum_elem;
568 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
569 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
570 med_int aNbConnForElem = getNbMedConnect(aMedType,anEntity,aMesh.myDim);
571 if(MYDEBUG) MESSAGE("LoadCellsOnEntity - medName = "<<med2vtk[medId].medName<<
572 "; iNumElemEnd = "<<iNumElemEnd<<"; aNbConnForElem = "<<aNbConnForElem);
573 valarray<med_int> conn(aNbConnForElem*iNumElemEnd);
574 ret = MEDelementsLire(fid,aMeshName,aMesh.myDim,&conn[0],MED_FULL_INTERLACE,
575 &name_elem[0],&iname_elem,&num_elem[0],&inum_elem,
576 &num_fam_elem[0],iNumElemEnd,aMedEntity,aMedType,MED_NOD);
577 if (ret < 0) throw std::runtime_error("LoadCellsOnEntity >> MEDelementsLire(...)");
579 VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = theMeshOnEntity.myCellsConn[aVtkType];
580 aConnForCellType.resize(iNumElemEnd);
581 valarray<med_int> aConnect(nbMedNodes);
582 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) {
583 VISU::TMeshOnEntity::TConnect& anArray = aConnForCellType[iNumElem];
584 anArray.resize(nbVtkNodes);
585 for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++) {
586 aConnect[k] = conn[kj+k] - 1;
591 anArray[0] = aConnect[0];
592 anArray[1] = aConnect[1];
593 anArray[2] = aConnect[3];
594 anArray[3] = aConnect[2];
598 anArray[0] = aConnect[0];
599 anArray[1] = aConnect[3];
600 anArray[2] = aConnect[2];
601 anArray[3] = aConnect[1];
602 anArray[4] = aConnect[4];
605 for (int k = 0; k < nbVtkNodes; k++)
606 anArray[k] = aConnect[k];
608 for (int k = 0; k < nbVtkNodes; k++)
609 if(anArray[k] < 0 || aNbPoints <= anArray[k]){
610 static QString aString;
611 aString.sprintf("ImportCells >> aNbPoints(%d) <= anArray[%d][%d](%d) < 0",aNbPoints,iNumElem,k,anArray[k]);
612 throw std::runtime_error(aString.latin1());
616 //Filling aFamily SubMesh
618 VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[aVtkType];
619 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
620 if(num_fam_elem[iNumElem] == aFamily.myId)
621 aSubMeshOnCellType.insert(iNumElem);
626 }catch(std::runtime_error& exc){
627 theMeshOnEntity.myCellsConn.clear();
628 throw std::runtime_error(exc.what());
630 theMeshOnEntity.myCellsConn.clear();
631 throw std::runtime_error("Unknown exception !!!");
636 int VISU_MedConvertor::LoadField(const med_idt& fid, const VISU::TMeshOnEntity& theMeshOnEntity,
637 const VISU::TField& theField, VISU::TField::TValForTime& theValForTime)
638 throw (std::runtime_error&)
640 //Check on loading already done
641 if(!theValForTime.myValForCells.empty()) return 0;
643 med_int ncomp = MEDnChamp(fid,theField.myId);
644 if(ncomp < 0) throw std::runtime_error("LoadField >> MEDnChamp(fid,i)");
645 valarray<char> comp('\0',ncomp*MED_TAILLE_PNOM + 1);
646 valarray<char> unit('\0',ncomp*MED_TAILLE_PNOM + 1);
647 char aFieldName[MED_TAILLE_NOM + 1] = "";
648 med_type_champ type_field;
649 if(MEDchampInfo(fid,theField.myId,aFieldName,&type_field,&comp[0],&unit[0],ncomp) < 0)
650 throw std::runtime_error(string("LoadField >> MEDchampInfo(...)"));
652 med_geometrie_element* aGeomElemVector;
653 const VISU::TEntity& anEntity = theField.myEntity;
654 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
655 med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
657 MESSAGE("LoadField - aFieldName = '"<<aFieldName<<"'; anEntity = "<<anEntity<<"; iGeomElemEnd = "<<iGeomElemEnd);
658 MESSAGE("LoadField - ncomp = "<<ncomp<<"; type_field = "<<type_field<<"; myId = "<<theValForTime.myId);
660 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
661 med_geometrie_element& aGeom = aGeomElemVector[iGeomElem];
662 med_int iTimeStampEnd = MEDnPasdetemps(fid,aFieldName,aMedEntity,aGeom);
663 if(iTimeStampEnd > 0) {
664 char aMeshName[MED_TAILLE_NOM+1] = "";
665 med_int ngauss = 0, numdt = 0, numo = 0;
666 char dt_unit[MED_TAILLE_PNOM+1] = "";
668 ret = MEDpasdetempsInfo(fid,aFieldName,aMedEntity,aGeom,theValForTime.myId,
669 aMeshName,&ngauss,&numdt,dt_unit,&dt,&numo);
670 if(ret < 0) throw std::runtime_error("LoadField >> MEDpasdetempsInfo(...)");
671 med_int nval = MEDnVal(fid,aFieldName,aMedEntity,aGeom,numdt,numo);
672 if (nval <= 0) throw std::runtime_error("LoadField >> MEDnVal(...) - nval <= 0");
674 //Checking for accordance between the mesh and the field on number of geomterical elements
675 int aVtkType = med2vtkCellType(aGeom);
676 const VISU::TMeshOnEntity::TCellsConn& aCellsConn = theMeshOnEntity.myCellsConn;
677 VISU::TMeshOnEntity::TCellsConn::const_iterator aCellsConnIter = aCellsConn.find(aVtkType);
678 if(aCellsConnIter == aCellsConn.end()) throw std::runtime_error("LoadField - There is no the geom. elem. on the mesh !!!");
679 const VISU::TMeshOnEntity::TConnForCellType aConnForCellType = aCellsConnIter->second;
680 if(aConnForCellType.size() != nval) throw std::runtime_error("LoadField - Size of values and size of mesh not equal !!!");
681 if(MYDEBUG) MESSAGE("LoadField - aGeom = "<<aGeom<<"; nval = "<<nval<<"; iTimeStampEnd = "<<iTimeStampEnd);
682 VISU::TField::TValForCellsWithType &anArray = theValForTime.myValForCells[aVtkType];
683 int jEnd = theField.myNbComp*nval;
684 anArray.resize(jEnd);
685 char pflname[MED_TAILLE_NOM + 1] = "";
688 valarray<med_float> valr(jEnd);
689 ret = MEDchampLire(fid,aMeshName,aFieldName,(unsigned char*)&valr[0],MED_FULL_INTERLACE,MED_ALL,
690 pflname,aMedEntity,aGeom,numdt,numo);
691 for (med_int j = 0; j < jEnd; j++) anArray[j] = valr[j];
694 //case MED_INT64 : //valarray<long long> valr(jEnd);
695 case MED_INT32 : //valarray<long int> valr(jEnd);
697 valarray<med_int> valr(jEnd);
698 ret = MEDchampLire(fid,aMeshName,aFieldName,(unsigned char*)&valr[0],MED_FULL_INTERLACE,MED_ALL,
699 pflname,aMedEntity,aGeom,numdt,numo);
700 for (med_int j = 0; j < jEnd; j++) anArray[j] = valr[j];
704 throw std::runtime_error("LoadField >> Value of med_type_champ for the field is wrong !!!");
706 if(ret < 0) throw std::runtime_error("ChampLire >> MEDchampLire(...)");