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"
29 #include "VISU_ConvertorUtils.hxx"
32 #include <vtkCellType.h>
34 #define USER_INTERLACE MED_FULL_INTERLACE
36 #define _EDF_NODE_IDS_
41 static int MYDEBUG = 0;
43 static int MYDEBUG = 0;
47 static med_err ret = 0;
49 typedef map<VISU::TEntity,med_entite_maillage> TVisu2MedEntity;
51 static TVisu2MedEntity aVisu2MedEntity;
54 aVisu2MedEntity[VISU::NODE_ENTITY] = MED_NOEUD,
55 aVisu2MedEntity[VISU::EDGE_ENTITY] = MED_ARETE,
56 aVisu2MedEntity[VISU::FACE_ENTITY] = MED_FACE,
57 aVisu2MedEntity[VISU::CELL_ENTITY] = MED_MAILLE,
60 static med_geometrie_element NODEGEOM[1] = {MED_POINT1};
62 static med_geometrie_element EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
66 static med_geometrie_element FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
67 MED_TRIA3, MED_QUAD4, MED_TRIA6, MED_QUAD8
70 static med_geometrie_element CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
71 MED_POINT1, MED_SEG2, MED_SEG3, MED_TRIA3,
72 MED_QUAD4, MED_TRIA6, MED_QUAD8, MED_TETRA4,
73 MED_PYRA5, MED_PENTA6, MED_HEXA8, MED_TETRA10,
74 MED_PYRA13, MED_PENTA15, MED_HEXA20
77 void GetEntity2Geom(const VISU::TEntity& theEntity, med_geometrie_element*& theVector, int* theEnd)
80 case VISU::CELL_ENTITY: theVector = CELLGEOM; *theEnd = MED_NBR_GEOMETRIE_MAILLE; break;
81 case VISU::FACE_ENTITY: theVector = FACEGEOM; *theEnd = MED_NBR_GEOMETRIE_FACE; break;
82 case VISU::EDGE_ENTITY: theVector = EDGEGEOM; *theEnd = MED_NBR_GEOMETRIE_ARETE; break;
83 case VISU::NODE_ENTITY: theVector = NODEGEOM; *theEnd = 1; break;
85 throw std::runtime_error("GetEntity2Geom >> theEntity is uncorrect");
90 VISU_Convertor* CreateMedConvertor(const string& theFileName) {
91 return new VISU_MedConvertor(theFileName);
98 MedFile(const MedFile&);
100 MedFile(const char* theFileName) :
101 myFileName(strdup(theFileName))
103 myFid = MEDouvrir(myFileName,MED_LECT);
106 throw std::runtime_error(string("MedFile::MedFile >> MEDouvrir(...) - ") + theFileName);
114 const med_idt& GetFid() const { return myFid;};
117 VISU_MedConvertor::VISU_MedConvertor(const string& theFileName) {
118 myFileInfo.setFile(QString(theFileName.c_str()));
119 myName = myFileInfo.baseName().latin1();
122 VISU_Convertor* VISU_MedConvertor::Build() {
123 MedFile aMedFile(myFileInfo.absFilePath());
124 med_idt fid = aMedFile.GetFid();
125 med_int iMeshEnd = MEDnMaa(fid); //Get number of meshes
126 if (iMeshEnd < 0) throw std::runtime_error(EXCEPTION("ImportInfo >> MEDnMaa(...)"));
127 if(MYDEBUG) MESSAGE("ImportInfo - MEDnMaa = "<<iMeshEnd<<"; myFileInfo = "<<myFileInfo.filePath());
128 for(int iMesh = 1; iMesh <= iMeshEnd; iMesh++){
130 char aMeshName[MED_TAILLE_NOM+1] = "";
131 MEDmaaInfo(fid,iMesh,aMeshName,&aMeshDim);
132 if(MYDEBUG) MESSAGE("ImportInfo - aMeshName = '"<<aMeshName<<"'; aMeshDim = "<<aMeshDim);
133 VISU::TMesh &aMesh = myMeshMap[aMeshName];
134 aMesh.myDim = aMeshDim;
135 aMesh.myName = aMeshName;
136 typedef map<med_int,VISU::TEntity> TFamily2EntityMap;
137 TFamily2EntityMap aFamily2EntityMap;
138 typedef map<med_int,med_int> TFamilyCounterMap;
139 TFamilyCounterMap aFamilyNbCellsCounterMap, aFamilyCellsSizeCounterMap;
140 TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
141 for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++) {
142 VISU::TEntity anEntity = aVisu2MedEntityIter->first;
144 med_geometrie_element* aGeomElemVector;
145 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
146 med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
147 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
148 int medId = getIdMedType(aGeomElemVector[iGeomElem]);
149 int aVtkType = med2vtk[medId].vtkType;
150 med_geometrie_element aMedType = med2vtk[medId].medType;
151 if(aMedEntity == MED_NOEUD){
152 med_geometrie_element typgeo = (med_geometrie_element)0;
153 med_connectivite typco = (med_connectivite)0;
154 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,typgeo,typco);
156 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
157 aMeshOnEntity.myEntity = anEntity;
158 aMeshOnEntity.myMeshName = aMeshName;
159 aMeshOnEntity.myNbCells = iNumElemEnd;
160 aMeshOnEntity.myCellsSize = 2*iNumElemEnd;
161 aMesh.myNbPoints = iNumElemEnd;
163 MESSAGE("ImportInfo -\t anEntity = "<<anEntity<<
164 "; medName = "<<med2vtk[medId].medName<<
165 "; myNbCells = "<<aMeshOnEntity.myNbCells<<
166 "; myCellsSize = "<<aMeshOnEntity.myCellsSize);
167 med_booleen iname_elem, inum_elem;
168 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
169 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
171 valarray<char> name_coord('\0',aMesh.myDim*MED_TAILLE_PNOM+1);
172 valarray<char> unit_coord('\0',aMesh.myDim*MED_TAILLE_PNOM+1);
173 valarray<med_float> coord(aMesh.myDim*iNumElemEnd);
174 ret = MEDnoeudsLire(fid,aMeshName,aMesh.myDim,&coord[0],MED_FULL_INTERLACE,&rep,
175 &name_coord[0],&unit_coord[0],&name_elem[0],&iname_elem,
176 &num_elem[0],&inum_elem,&num_fam_elem[0],iNumElemEnd);
177 if(ret < 0) throw std::runtime_error(EXCEPTION("ImportInfo >> MEDnoeudsLire(...)"));
178 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
179 if(num_fam_elem[iNumElem] != 0){
180 aFamily2EntityMap[num_fam_elem[iNumElem]] = anEntity;
181 aFamilyNbCellsCounterMap[num_fam_elem[iNumElem]] += 1;
182 aFamilyCellsSizeCounterMap[num_fam_elem[iNumElem]] += 2;
186 //Get number of connectivities
187 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aMedType,MED_NOD);
188 if (iNumElemEnd > 0) {
189 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
190 aMeshOnEntity.myEntity = anEntity;
191 aMeshOnEntity.myMeshName = aMeshName;
192 med_booleen iname_elem, inum_elem;
193 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
194 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
195 med_int aNbConnForElem = getNbMedConnect(aMedType,anEntity,aMesh.myDim);
196 aMeshOnEntity.myNbCells += iNumElemEnd;
197 aMeshOnEntity.myCellsSize += iNumElemEnd*(med2vtk[medId].vtkNbNodes + 1);
199 MESSAGE("ImportInfo -\t anEntity = "<<anEntity<<
200 "; medName = "<<med2vtk[medId].medName<<
201 "; aNbConnForElem = "<<aNbConnForElem<<
202 "; myNbCells = "<<aMeshOnEntity.myNbCells<<
203 "; myCellsSize = "<<aMeshOnEntity.myCellsSize);
204 valarray<med_int> conn(0,aNbConnForElem*iNumElemEnd);
205 ret = MEDelementsLire(fid,aMeshName,aMesh.myDim,&conn[0],MED_FULL_INTERLACE,
206 &name_elem[0],&iname_elem,&num_elem[0],&inum_elem,
207 &num_fam_elem[0],iNumElemEnd,aMedEntity,aMedType,MED_NOD);
208 if (ret < 0) throw std::runtime_error(EXCEPTION("ImportInfo >> MEDelementsLire(...)"));
209 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
210 if(num_fam_elem[iNumElem] != 0){
211 aFamily2EntityMap[num_fam_elem[iNumElem]] = anEntity;
212 aFamilyNbCellsCounterMap[num_fam_elem[iNumElem]] += 1;
213 aFamilyCellsSizeCounterMap[num_fam_elem[iNumElem]] += med2vtk[medId].vtkNbNodes + 1;
218 med_int aNbFamily = MEDnFam(fid,aMeshName,0,MED_FAMILLE);
219 if(MYDEBUG) MESSAGE("ImportInfo - aNbFamily = "<<aNbFamily);
220 for(int aFamInd = 1; aFamInd <= aNbFamily; aFamInd++){
221 med_int aNbAttrib = MEDnFam(fid,aMeshName,aFamInd,MED_ATTR);
222 valarray<med_int> anAttId(aNbAttrib), anAttVal(aNbAttrib);
223 valarray<char> anAttDesc('\0',aNbAttrib*MED_TAILLE_DESC+1);
224 med_int aNbGroup = MEDnFam(fid,aMeshName,aFamInd,MED_GROUPE);
226 MESSAGE("ImportInfo - aFamInd = "<<aFamInd<<"; aNbAttrib = "<<aNbAttrib<<"; aNbGroup = "<<aNbGroup);
227 valarray<char> aGroupNames('\0',aNbGroup*MED_TAILLE_LNOM+1);
228 char aFamilyName[MED_TAILLE_NOM+1] = "";
230 ret = MEDfamInfo(fid,aMeshName,aFamInd,aFamilyName,&aFamilyNum,
231 &anAttId[0],&anAttVal[0],&anAttDesc[0],&aNbAttrib,
232 &aGroupNames[0],&aNbGroup);
233 if(ret < 0) throw std::runtime_error(EXCEPTION("ImportInfo >> MEDfamInfo"));
235 MESSAGE("ImportInfo - aFamilyNum = "<<aFamilyNum<<"; aNbGroup = "<<aNbGroup);
236 if(aFamily2EntityMap.find(aFamilyNum) == aFamily2EntityMap.end()) {
237 if(MYDEBUG) MESSAGE("ImportInfo - a Family with name '"<<aFamilyName<<"' are empty !!!");
240 VISU::TEntity anEntity = aFamily2EntityMap[aFamilyNum];
241 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
242 VISU::TFamily& aFamily = aMeshOnEntity.myFamilyMap[aFamilyName];
243 aFamily.myName = aFamilyName;
244 aFamily.myEntity = anEntity;
245 aFamily.myId = aFamilyNum;
246 aFamily.myNbCells = aFamilyNbCellsCounterMap[aFamilyNum];
247 aFamily.myCellsSize = aFamilyCellsSizeCounterMap[aFamilyNum];
249 MESSAGE("ImportInfo - aFamily.myEntity = "<<anEntity<<
250 "; myName = '"<<aFamilyName<<
251 "'; myId = "<<aFamilyNum<<
252 "; myNbCells = "<<aFamily.myNbCells<<
253 "; myCellsSize = "<<aFamily.myCellsSize);
254 VISU::TBindGroups& aBindGroups = aFamily.myGroups;
255 for(int iGroup = 0, iPos = 0; iGroup < aNbGroup; iGroup++, iPos += MED_TAILLE_LNOM){
256 char aGroupName[MED_TAILLE_LNOM+1];
257 strncpy(aGroupName,&aGroupNames[iPos],MED_TAILLE_LNOM);
258 aGroupName[MED_TAILLE_LNOM] = '\0';
259 if(MYDEBUG) MESSAGE("ImportInfo - aGroupName["<<iGroup<<"] = '"<<aGroupName<<"'");
260 aBindGroups.insert(aGroupName);
263 //Calculation of TMesh.TGroupMap
264 const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
265 if(aMeshOnEntityMap.empty()) continue;
266 VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
267 VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
268 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
269 const VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
270 const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity.myFamilyMap;
271 if(aFamilyMap.empty()) continue;
272 VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
273 for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
274 const VISU::TFamily& aFamily = aFamilyMapIter->second;
275 const VISU::TBindGroups& aBindGroups = aFamily.myGroups;
276 if(aBindGroups.empty()) continue;
277 VISU::TBindGroups::const_iterator aBindGroupsIter = aBindGroups.begin();
278 for(; aBindGroupsIter != aBindGroups.end(); aBindGroupsIter++){
279 const string& aGroupName = *aBindGroupsIter;
280 VISU::TGroup& aGroup = aGroupMap[aGroupName];
281 aGroup.myName = aGroupName;
282 aGroup.myMeshName = aMesh.myName;
283 VISU::TFamilyAndEntity aFamilyAndEntity(aFamily.myName,aFamily.myEntity);
284 aGroup.myFamilyAndEntitySet.insert(aFamilyAndEntity);
285 aGroup.myNbCells += aFamily.myNbCells;
286 aGroup.myCellsSize += aFamily.myCellsSize;
290 //Displaing information for the TMesh.TGroupMap
291 VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
292 if(MYDEBUG) MESSAGE("ImportInfo - aGroupMap.size() = "<<aGroupMap.size());
293 for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
294 const VISU::TGroup& aCGroup = aGroupMapIter->second;
295 const string& aGroupName = aGroupMapIter->first;
296 if(MYDEBUG) MESSAGE("ImportInfo - aGroupName = '"<<aGroupName<<
297 "'; myNbCells = "<<aCGroup.myNbCells<<
298 "; myCellsSize = "<<aCGroup.myCellsSize);
299 const VISU::TGroup& aGroup = aGroupMapIter->second;
300 const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup.myFamilyAndEntitySet;
301 VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
302 for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
303 const string& aFamilyName = aFamilyAndEntitySetIter->first;
304 if(MYDEBUG) MESSAGE("ImportInfo - \t aFamilyName = '"<<aFamilyName<<"'");
308 //Reading information about fields
309 med_int iFieldEnd = MEDnChamp(fid,0);
310 if (iFieldEnd < 0) throw std::runtime_error(EXCEPTION("ImportChamps >> MEDnChamp(fid,0)"));
311 if(MYDEBUG) MESSAGE("ImportInfo - iFieldEnd = "<<iFieldEnd);
312 for(med_int iField = 1; iField <= iFieldEnd; iField++){
313 med_int ncomp = MEDnChamp(fid,iField);
314 if(ncomp < 0) throw std::runtime_error(EXCEPTION("ImportChamps >> MEDnChamp(fid,i)"));
315 valarray<char> aCompNames('\0',ncomp*MED_TAILLE_PNOM + 1);
316 valarray<char> aUnitNames('\0',ncomp*MED_TAILLE_PNOM + 1);
317 char name_field[MED_TAILLE_NOM + 1] = "";
318 med_type_champ type_field;
319 if(MEDchampInfo(fid,iField,name_field,&type_field,&aCompNames[0],&aUnitNames[0],ncomp) < 0)
320 throw std::runtime_error(EXCEPTION("ImportInfo >> MEDchampInfo(...)"));
321 //if(type_field != MED_REEL64) continue; //There is some problem in reading INTXX values
322 TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
323 for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++) {
324 VISU::TEntity anEntity = aVisu2MedEntityIter->first;
326 med_geometrie_element* aGeomElemVector;
327 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
328 med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
329 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
330 med_geometrie_element& aGeom = aGeomElemVector[iGeomElem];
331 med_int iTimeStampEnd = MEDnPasdetemps(fid,name_field,aMedEntity,aGeom);
332 if(iTimeStampEnd < 0) throw std::runtime_error(EXCEPTION("ImportInfo >> MEDnPasdetemps(...)"));
333 if(iTimeStampEnd > 0) {
334 for(med_int iTimeStamp = 1; iTimeStamp <= iTimeStampEnd; iTimeStamp++) {
335 char aMeshName[MED_TAILLE_NOM+1] = "";
336 med_int ngauss = 0, numdt = 0, numo = 0;
337 char dt_unit[MED_TAILLE_PNOM+1] = "";
339 ret = MEDpasdetempsInfo(fid,name_field,aMedEntity,aGeom,iTimeStamp,
340 aMeshName,&ngauss,&numdt,dt_unit,&dt,&numo);
341 if(ret < 0) throw std::runtime_error(EXCEPTION("ImportInfo >> MEDpasdetempsInfo(...) < 0"));
342 if(myMeshMap.find(aMeshName) == myMeshMap.end())
343 throw std::runtime_error(EXCEPTION("ImportInfo >> MEDpasdetempsInfo(...)"));
344 VISU::TMesh &aMesh = myMeshMap[aMeshName];
345 VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
346 VISU::TFieldMap::iterator aFieldMapIter = aMeshOnEntity.myFieldMap.find(name_field);
347 //if(MYDEBUG && aFieldMapIter == aMeshOnEntity.myFieldMap.end()){
348 VISU::TField& aField = aMeshOnEntity.myFieldMap[name_field];
350 aField.myId = iField;
351 aField.myName = name_field;
352 aField.myEntity = anEntity;
353 aField.myMeshName = aMeshName;
354 aField.myNbComp = ncomp;
355 aField.myNbValField = iTimeStampEnd;
356 aField.myDataSize = aMeshOnEntity.myNbCells * ncomp;
357 aField.myCompNames.resize(ncomp);
358 aField.myUnitNames.resize(ncomp);
360 MESSAGE("ImportInfo - aField.myName = '"<<name_field<<
361 "'; myMeshName = '"<<aMeshName<<
362 "'; myEntity = "<<anEntity<<
363 "; myNbComp = "<<ncomp<<
364 "; myDataSize = "<<aField.myDataSize);
365 for(int iComp = 0, iPos = 0; iComp < ncomp; iComp++, iPos += MED_TAILLE_PNOM){
366 char aCompName[MED_TAILLE_PNOM+1], aUnitName[MED_TAILLE_PNOM+1];
367 strncpy(aCompName,&aCompNames[iPos],MED_TAILLE_PNOM);
368 aCompName[MED_TAILLE_PNOM] = '\0';
369 aField.myCompNames[iComp] = aCompName;
370 strncpy(aUnitName,&aUnitNames[iPos],MED_TAILLE_PNOM);
371 aUnitName[MED_TAILLE_PNOM] = '\0';
372 aField.myUnitNames[iComp] = aUnitName;
374 MESSAGE("ImportInfo - aCompName = '"<<aCompName<<"'; aUnitName = '"<<aUnitName<<"'");
378 VISU::TField::TValForTime& aValForTime = aField.myValField[iTimeStamp];
379 aValForTime.myId = iTimeStamp;
380 aValForTime.myFieldName = aField.myName;
381 aValForTime.myEntity = aField.myEntity;
382 aValForTime.myMeshName = aField.myMeshName;
383 aValForTime.myNbComp = aField.myNbComp;
384 aValForTime.myTime = VISU::TField::TTime(dt,dt_unit);
386 MESSAGE("ImportInfo -\t aValForTime.myTime = "<<dt<<", "<<dt_unit);
395 int VISU_MedConvertor::LoadMeshOnEntity(VISU::TMeshOnEntity& theMeshOnEntity,
396 const string& theFamilyName)
398 //Open the med file (it will be closed by call of destructor)
399 MedFile aMedFile(myFileInfo.absFilePath());
400 med_idt fid = aMedFile.GetFid();
402 const string& aMeshName = theMeshOnEntity.myMeshName;
403 const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
404 VISU::TMesh& aMesh = myMeshMap[aMeshName];
406 if(anEntity == VISU::NODE_ENTITY)
407 isPointsUpdated = LoadPoints(fid,aMesh,theFamilyName);
409 isPointsUpdated = LoadPoints(fid,aMesh);
410 int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity,theFamilyName);
412 return (isPointsUpdated || isCellsOnEntityUpdated);
415 int VISU_MedConvertor::LoadMeshOnGroup(VISU::TMesh& theMesh,
416 const VISU::TFamilyAndEntitySet& theFamilyAndEntitySet)
418 //Open the med file (it will be closed by call of destructor)
419 MedFile aMedFile(myFileInfo.absFilePath());
420 med_idt fid = aMedFile.GetFid();
422 int isPointsUpdated = 0;
423 int isCellsOnEntityUpdated = 0;
424 VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = theFamilyAndEntitySet.begin();
425 for(; aFamilyAndEntitySetIter != theFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
426 const string& aFamilyName = aFamilyAndEntitySetIter->first;
427 const VISU::TEntity& anEntity = aFamilyAndEntitySetIter->second;
428 VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[anEntity];
429 if(anEntity == VISU::NODE_ENTITY){
430 isPointsUpdated += LoadPoints(fid,theMesh,aFamilyName);
431 isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity);
433 isPointsUpdated += LoadPoints(fid,theMesh);
434 isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity,aFamilyName);
438 return (isPointsUpdated || isCellsOnEntityUpdated);
441 int VISU_MedConvertor::LoadFieldOnMesh(VISU::TMesh& theMesh,
442 VISU::TMeshOnEntity& theMeshOnEntity,
443 VISU::TField& theField,
444 VISU::TField::TValForTime& theValForTime)
446 //Open the med file (it will be closed by call of destructor)
447 MedFile aMedFile(myFileInfo.absFilePath());
448 med_idt fid = aMedFile.GetFid();
450 int isPointsUpdated = LoadPoints(fid,theMesh);
451 int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity);
452 int isFieldUpdated = LoadField(fid,theMeshOnEntity,theField,theValForTime);
454 return (isPointsUpdated || isCellsOnEntityUpdated || isFieldUpdated);
457 int VISU_MedConvertor::LoadPoints(const med_idt& fid, VISU::TMesh& theMesh, const string& theFamilyName)
460 //Check on existing family
461 VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[VISU::NODE_ENTITY];
462 aMeshOnEntity.myEntity = VISU::NODE_ENTITY;
463 aMeshOnEntity.myMeshName = theMesh.myName;
464 VISU::TFamily* pFamily = VISU::GetFamily(aMeshOnEntity,theFamilyName);
465 bool isFamilyPresent = (pFamily != NULL);
466 VISU::TFamily& aFamily = *pFamily;
467 //Check on loading already done
468 bool isPointsLoaded = !theMesh.myPointsCoord.empty();
470 if(!isFamilyPresent) return 0;
471 else if(!aFamily.mySubMesh.empty()) return 0;
473 MESSAGE("LoadPoints - isPointsLoaded = "<<isPointsLoaded<<"; theFamilyName = '"<<theFamilyName<<"'");
475 char aMeshName[MED_TAILLE_NOM+1] = "";
476 strcpy(aMeshName,theMesh.myName.c_str());
477 med_geometrie_element typgeo = (med_geometrie_element)0; //MED_POINT1
478 med_connectivite typco = (med_connectivite)0; //MED_NOD
479 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,typgeo,typco);
480 if (iNumElemEnd <= 0) throw std::runtime_error(EXCEPTION("LoadPoints >> MEDnEntMaa(...)"));
481 if(MYDEBUG) MESSAGE("LoadPoints - iNumElemEnd = "<<iNumElemEnd);
483 med_booleen iname_elem, inum_elem;
484 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
485 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
486 valarray<char> name_coord('\0',theMesh.myDim*MED_TAILLE_PNOM+1);
487 valarray<char> unit_coord('\0',theMesh.myDim*MED_TAILLE_PNOM+1);
488 valarray<med_float> coord(theMesh.myDim*iNumElemEnd);
489 ret = MEDnoeudsLire(fid,aMeshName,theMesh.myDim,&coord[0],MED_FULL_INTERLACE,&rep,
490 &name_coord[0],&unit_coord[0],&name_elem[0],&iname_elem,
491 &num_elem[0],&inum_elem,&num_fam_elem[0],iNumElemEnd);
492 if(ret < 0) throw std::runtime_error(EXCEPTION("LoadPoints >> MEDnoeudsLire(...)"));
495 VISU::TMesh::TPointsDim& aPointsDim = theMesh.myPointsDim;
496 aPointsDim.resize(theMesh.myDim);
497 for(int iDim = 0, iPos = 0; iDim < theMesh.myDim; iDim++, iPos += MED_TAILLE_PNOM){
498 char aCoordName[MED_TAILLE_PNOM+1];
499 strncpy(aCoordName,&name_coord[iPos],MED_TAILLE_PNOM);
500 aCoordName[MED_TAILLE_PNOM] = '\0';
501 aPointsDim[iDim] = aCoordName;
504 VISU::TMesh::TPointsCoord& aPointsCoord = theMesh.myPointsCoord;
505 aPointsCoord.resize(iNumElemEnd*theMesh.myDim);
506 if(MYDEBUG) MESSAGE("LoadPoints - Filling coordinates of the mesh - inum_elem = "<<inum_elem);
507 inum_elem = MED_FAUX; // It is workaround
508 if(inum_elem == MED_FAUX)
509 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
510 for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
511 aPointsCoord[iNumElem2Dim] = coord[iNumElem2Dim];
513 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
514 for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
515 aPointsCoord[num_elem[iNumElem2Dim]] = coord[iNumElem2Dim];
516 if(MYDEBUG) MESSAGE("LoadPoints - Filling aMeshOnEntity with type NODE_ENTITY");
517 VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = aMeshOnEntity.myCellsConn[VTK_VERTEX];
518 aConnForCellType.resize(iNumElemEnd);
519 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
520 aConnForCellType[iNumElem] = VISU::TMeshOnEntity::TConnect(1,iNumElem);
522 if(isFamilyPresent && iNumElemEnd > 0){
523 if(MYDEBUG) MESSAGE("LoadPoints - Filling aFamily SubMesh");
524 VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[VTK_VERTEX];
525 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
526 if(num_fam_elem[iNumElem] == aFamily.myId)
527 aSubMeshOnCellType.insert(iNumElem);
530 }catch(std::runtime_error& exc){
531 theMesh.myPointsCoord.clear();
532 throw std::runtime_error(exc.what());
534 theMesh.myPointsCoord.clear();
535 throw std::runtime_error(EXCEPTION("Unknown exception !!!"));
540 int VISU_MedConvertor::LoadCellsOnEntity(const med_idt& fid, VISU::TMeshOnEntity& theMeshOnEntity,
541 const string& theFamilyName)
544 //Check on existing family
545 VISU::TFamily* pFamily = VISU::GetFamily(theMeshOnEntity,theFamilyName);
546 bool isFamilyPresent = (pFamily != NULL);
547 VISU::TFamily& aFamily = *pFamily;
548 //Check on loading already done
549 bool isCellsLoaded = !theMeshOnEntity.myCellsConn.empty();
551 if(!isFamilyPresent) return 0;
552 else if(!aFamily.mySubMesh.empty()) return 0;
554 MESSAGE("LoadCellsOnEntity - theFamilyName = '"<<theFamilyName<<"'");
555 MESSAGE("LoadCellsOnEntity - isCellsLoaded = "<<isCellsLoaded<<"; isFamilyPresent = "<<isFamilyPresent);
559 med_geometrie_element* aGeomElemVector;
560 const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
561 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
562 const med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
563 char aMeshName[MED_TAILLE_NOM+1] = "";
564 strcpy(aMeshName,theMeshOnEntity.myMeshName.c_str());
566 MESSAGE("LoadCellsOnEntity - theMeshOnEntity.myEntity = "<<theMeshOnEntity.myEntity<<
567 "; iGeomElemEnd = "<<iGeomElemEnd<<"; theFamilyName = '"<<theFamilyName<<"'");
568 VISU::TMesh &aMesh = myMeshMap[theMeshOnEntity.myMeshName];
569 int aNbPoints = aMesh.myPointsCoord.size()/aMesh.myDim;
570 valarray<med_int> num_node(aNbPoints);
571 med_booleen inum_node =
572 med_booleen(MEDnumLire(fid,aMeshName,&num_node[0],aNbPoints,MED_NOEUD,med_geometrie_element(0)) >= 0);
573 if(MYDEBUG) MESSAGE("LoadCellsOnEntity - inum_node = "<<inum_node);
574 #ifdef _EDF_NODE_IDS_
575 inum_node = MED_FAUX;
577 map<med_int,med_int> node_map;
579 for(int i = 0; i < aNbPoints; i++)
580 node_map[num_node[i]-1] = i;
581 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
582 int medId = getIdMedType(aGeomElemVector[iGeomElem]);
583 int nbMedNodes = med2vtk[medId].medNbNodes;
584 int nbVtkNodes = med2vtk[medId].vtkNbNodes;
585 int aVtkType = med2vtk[medId].vtkType;
586 med_geometrie_element aMedType = med2vtk[medId].medType;
587 med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aMedType,MED_NOD);
588 if (iNumElemEnd > 0) {
589 med_booleen iname_elem, inum_elem;
590 valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
591 valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
592 med_int aNbConnForElem = getNbMedConnect(aMedType,anEntity,aMesh.myDim);
593 if(MYDEBUG) MESSAGE("LoadCellsOnEntity - medName = "<<med2vtk[medId].medName<<
594 "; iNumElemEnd = "<<iNumElemEnd<<"; aNbConnForElem = "<<aNbConnForElem);
595 valarray<med_int> conn(aNbConnForElem*iNumElemEnd);
596 ret = MEDelementsLire(fid,aMeshName,aMesh.myDim,&conn[0],MED_FULL_INTERLACE,
597 &name_elem[0],&iname_elem,&num_elem[0],&inum_elem,
598 &num_fam_elem[0],iNumElemEnd,aMedEntity,aMedType,MED_NOD);
599 if (ret < 0) throw std::runtime_error(EXCEPTION("LoadCellsOnEntity >> MEDelementsLire(...)"));
601 VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = theMeshOnEntity.myCellsConn[aVtkType];
602 aConnForCellType.resize(iNumElemEnd);
603 valarray<med_int> aConnect(nbMedNodes);
604 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) {
605 VISU::TMeshOnEntity::TConnect& anArray = aConnForCellType[iNumElem];
606 anArray.resize(nbVtkNodes);
608 for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++)
609 aConnect[k] = node_map[conn[kj+k]-1];
611 for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++)
612 aConnect[k] = conn[kj+k] - 1;
616 anArray[0] = aConnect[0];
617 anArray[1] = aConnect[1];
618 anArray[2] = aConnect[3];
619 anArray[3] = aConnect[2];
623 anArray[0] = aConnect[0];
624 anArray[1] = aConnect[3];
625 anArray[2] = aConnect[2];
626 anArray[3] = aConnect[1];
627 anArray[4] = aConnect[4];
630 for (int k = 0; k < nbVtkNodes; k++)
631 anArray[k] = aConnect[k];
633 for (int k = 0; k < nbVtkNodes; k++)
634 if(anArray[k] < 0 || aNbPoints <= anArray[k])
635 throw std::runtime_error(EXCEPT("ImportCells >> aNbPoints(%1) <= anArray[%2][%3](%4) < 0").
636 arg(aNbPoints).arg(iNumElem).arg(k).arg(anArray[k]).latin1());
639 //Filling aFamily SubMesh
641 VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[aVtkType];
642 for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
643 if(num_fam_elem[iNumElem] == aFamily.myId)
644 aSubMeshOnCellType.insert(iNumElem);
649 }catch(std::runtime_error& exc){
650 theMeshOnEntity.myCellsConn.clear();
651 throw std::runtime_error(exc.what());
653 theMeshOnEntity.myCellsConn.clear();
654 throw std::runtime_error(EXCEPTION("Unknown exception !!!"));
659 int VISU_MedConvertor::LoadField(const med_idt& fid, const VISU::TMeshOnEntity& theMeshOnEntity,
660 VISU::TField& theField, VISU::TField::TValForTime& theValForTime)
662 //Check on loading already done
663 if(!theValForTime.myValForCells.empty()) return 0;
665 med_int ncomp = MEDnChamp(fid,theField.myId);
666 if(ncomp < 0) throw std::runtime_error(EXCEPTION("LoadField >> MEDnChamp(fid,i)"));
667 valarray<char> comp('\0',ncomp*MED_TAILLE_PNOM + 1);
668 valarray<char> unit('\0',ncomp*MED_TAILLE_PNOM + 1);
669 char aFieldName[MED_TAILLE_NOM + 1] = "";
670 char aMeshName[MED_TAILLE_NOM+1] = "";
671 strcpy(aMeshName,theValForTime.myMeshName.c_str());
672 med_type_champ type_field;
673 if(MEDchampInfo(fid,theField.myId,aFieldName,&type_field,&comp[0],&unit[0],ncomp) < 0)
674 throw std::runtime_error(EXCEPTION("LoadField >> MEDchampInfo(...)"));
676 med_geometrie_element* aGeomElemVector;
677 const VISU::TEntity& anEntity = theField.myEntity;
678 GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
679 med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
680 const VISU::TMeshOnEntity::TCellsConn& aCellsConn = theMeshOnEntity.myCellsConn;
682 MESSAGE("LoadField - aMeshName = '"<<aMeshName<<"' aFieldName = '"<<aFieldName<<"'; anEntity = "<<anEntity);
683 MESSAGE("LoadField - iGeomElemEnd = "<<iGeomElemEnd<<"; ncomp = "<<ncomp<<"; type_field = "<<type_field);
685 for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
686 const med_geometrie_element& aGeom = aGeomElemVector[iGeomElem];
687 med_int iTimeStampEnd = MEDnPasdetemps(fid,aFieldName,aMedEntity,aGeom);
688 //Checking for accordance between the mesh and the field data
689 med_int iNumElemEnd = 0;
690 if(aMedEntity == MED_NOEUD)
691 iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,med_geometrie_element(0),med_connectivite(0));
693 iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aGeom,MED_NOD);
694 int medId = getIdMedType(aGeomElemVector[iGeomElem]);
695 int aVtkType = med2vtk[medId].vtkType;
696 if(iTimeStampEnd <= 0){
698 if(!theField.myIsTrimmed){
699 theField.myIsTrimmed = true;
700 theField.myDataSize -= iNumElemEnd*theField.myNbComp;
702 //throw std::runtime_error(EXCEPT("VISU_MedConvertor::LoadField - There is no the data "
703 // "for cells with type %1 of the mesh !!!").
704 // arg(med2vtk[medId].medName).latin1());
707 med_int ngauss = 0, numdt = 0, numo = 0;
708 char dt_unit[MED_TAILLE_PNOM+1] = "";
710 ret = MEDpasdetempsInfo(fid,aFieldName,aMedEntity,aGeom,theValForTime.myId,
711 aMeshName,&ngauss,&numdt,dt_unit,&dt,&numo);
712 if(ret < 0) throw std::runtime_error(EXCEPTION("LoadField >> MEDpasdetempsInfo(...)"));
713 med_int nval = MEDnVal(fid,aFieldName,aMedEntity,aGeom,numdt,numo);
714 if(nval <= 0) throw std::runtime_error(EXCEPTION("LoadField >> MEDnVal(...) - nval <= 0"));
716 //Checking for accordance between the mesh and the field data
718 throw std::runtime_error(EXCEPTION("LoadField - There is no the geom. elem. on the mesh !!!"));
719 static int aMaxNbGaussPts = 52; // the workaround for broken files
720 if(ngauss > aMaxNbGaussPts) ngauss = 1;
721 if(iNumElemEnd*ngauss != nval)
722 throw std::runtime_error(EXCEPT("LoadField - Size of values (%1) and size of mesh (%2) not equal !!!").
723 arg(nval).arg(iNumElemEnd*ngauss).latin1());
724 VISU::TField::TValForCellsWithType &anArray = theValForTime.myValForCells[aVtkType];
725 int jEnd = theField.myNbComp*nval;
726 int kEnd = jEnd/ngauss;
727 anArray.resize(kEnd);
728 char pflname[MED_TAILLE_NOM + 1] = "";
731 valarray<med_float> valr(jEnd);
732 ret = MEDchampLire(fid,aMeshName,aFieldName,(unsigned char*)&valr[0],MED_FULL_INTERLACE,MED_ALL,
733 pflname,aMedEntity,aGeom,numdt,numo);
734 if(ret < 0) throw std::runtime_error(EXCEPTION("LoadField >> MEDchampLire(...)"));
735 for (med_int k = 0, j = 0; k < kEnd; k++, j += ngauss){
736 for (med_int iGauss = 0; iGauss < ngauss; iGauss++)
737 anArray[k] = valr[j+iGauss];
738 anArray[k] /= ngauss;
742 //case MED_INT64 : //valarray<long long> valr(jEnd);
743 case MED_INT32 : //valarray<long int> valr(jEnd);
745 valarray<med_int> valr(jEnd);
746 ret = MEDchampLire(fid,aMeshName,aFieldName,(unsigned char*)&valr[0],MED_FULL_INTERLACE,MED_ALL,
747 pflname,aMedEntity,aGeom,numdt,numo);
748 if(ret < 0) throw std::runtime_error(EXCEPTION("LoadField >> MEDchampLire(...)"));
749 for (med_int k = 0, j = 0; k < kEnd; k++, j += ngauss){
750 for (med_int iGauss = 0; iGauss < ngauss; iGauss++)
751 anArray[k] = valr[j+iGauss];
752 anArray[k] /= ngauss;
757 throw std::runtime_error(EXCEPTION("LoadField >> Value of med_type_champ for the field is wrong !!!"));
759 if(MYDEBUG) MESSAGE("LoadField - aGeom = "<<aGeom<<"; nval = "<<nval<<"; ngauss = "<<ngauss
760 <<"; iTimeStampEnd = "<<iTimeStampEnd<<"; pflname = '"<<pflname<<"'");