]> SALOME platform Git repositories - modules/visu.git/blob - src/CONVERTOR/VISU_MedConvertor.cxx
Salome HOME
DCQ: prepare V2.0.0
[modules/visu.git] / src / CONVERTOR / VISU_MedConvertor.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //  File   : VISU_MedConvertor.cxx
24 //  Author : Alexey PETROV
25 //  Module : VISU
26
27
28 #include "VISU_MedConvertor.hxx"
29 #include "VISU_ConvertorUtils.hxx"
30
31 #include <valarray>     
32 #include <vtkCellType.h>
33
34 #define USER_INTERLACE MED_FULL_INTERLACE
35
36 #define _EDF_NODE_IDS_
37
38 using namespace std;
39
40 #ifdef _DEBUG_
41 static int MYDEBUG = 0;
42 #else
43 static int MYDEBUG = 0;
44 #endif
45
46
47 static med_err ret = 0;
48
49 typedef map<VISU::TEntity,med_entite_maillage> TVisu2MedEntity;
50
51 static TVisu2MedEntity aVisu2MedEntity;
52
53 static int INIT = (
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,
58                    1);
59
60 static med_geometrie_element NODEGEOM[1] = {MED_POINT1};
61
62 static med_geometrie_element EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
63   MED_SEG2, MED_SEG3
64   };
65
66 static med_geometrie_element FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
67   MED_TRIA3, MED_QUAD4, MED_TRIA6, MED_QUAD8
68   };
69
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
75   };
76
77 void GetEntity2Geom(const VISU::TEntity& theEntity, med_geometrie_element*& theVector, int* theEnd) 
78 {
79   switch(theEntity){
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;
84   default:
85     throw std::runtime_error("GetEntity2Geom >> theEntity is uncorrect");
86   }
87 }
88
89 extern "C"
90 VISU_Convertor* CreateMedConvertor(const string& theFileName) {
91   return new VISU_MedConvertor(theFileName);
92 }
93
94 class MedFile{
95   char* myFileName;
96   med_idt myFid;
97   MedFile();
98   MedFile(const MedFile&);
99 public:
100   MedFile(const char* theFileName)  :
101     myFileName(strdup(theFileName))
102   {
103     myFid = MEDouvrir(myFileName,MED_LECT);
104     if(myFid < 0){
105       free(myFileName);
106       throw std::runtime_error(string("MedFile::MedFile >> MEDouvrir(...) - ") + theFileName);
107     }
108   }
109   ~MedFile(){
110     free(myFileName);
111     if(myFid >= 0) 
112       MEDfermer(myFid);
113   }
114   const med_idt& GetFid() const { return myFid;};
115 };
116
117 VISU_MedConvertor::VISU_MedConvertor(const string& theFileName)  {
118   myFileInfo.setFile(QString(theFileName.c_str()));
119   myName = myFileInfo.baseName().latin1();
120 }
121
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++){
129     med_int aMeshDim;
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;
143       int iGeomElemEnd;
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);
155           if(iNumElemEnd > 0){
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;
162             if(MYDEBUG) 
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);
170             med_repere rep;
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;
183               }
184           }
185         }
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);
198           if(MYDEBUG) 
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;
214             } 
215         }
216       }
217     }
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);
225       if(0 && MYDEBUG) 
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] = "";
229       med_int aFamilyNum;
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"));
234       if(0 && MYDEBUG) 
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 !!!");
238         continue;
239       }
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];
248       if(MYDEBUG) 
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);
261       }
262     }
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;
287         }
288       }
289     }
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<<"'");
305       }
306     }
307   }
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;
325       int iGeomElemEnd;
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] = "";
338             med_float dt = 0;
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];
349             if(iTimeStamp == 1){
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);
359               if(MYDEBUG)
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;
373                 if(MYDEBUG)
374                   MESSAGE("ImportInfo - aCompName = '"<<aCompName<<"'; aUnitName = '"<<aUnitName<<"'");
375               }
376               
377             }
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);
385             if(MYDEBUG) 
386               MESSAGE("ImportInfo -\t aValForTime.myTime = "<<dt<<", "<<dt_unit);
387           }
388         }
389       }
390     }
391   }
392   return this; 
393 }
394
395 int VISU_MedConvertor::LoadMeshOnEntity(VISU::TMeshOnEntity& theMeshOnEntity, 
396                                         const string& theFamilyName)
397 {
398   //Open the med file (it will be closed by call of destructor)
399   MedFile aMedFile(myFileInfo.absFilePath());
400   med_idt fid = aMedFile.GetFid();
401   //Main part of code
402   const string& aMeshName = theMeshOnEntity.myMeshName;
403   const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
404   VISU::TMesh& aMesh = myMeshMap[aMeshName];
405   int isPointsUpdated;
406   if(anEntity == VISU::NODE_ENTITY) 
407     isPointsUpdated = LoadPoints(fid,aMesh,theFamilyName);
408   else 
409     isPointsUpdated = LoadPoints(fid,aMesh);
410   int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity,theFamilyName);
411
412   return (isPointsUpdated || isCellsOnEntityUpdated);
413 }
414
415 int VISU_MedConvertor::LoadMeshOnGroup(VISU::TMesh& theMesh, 
416                                        const VISU::TFamilyAndEntitySet& theFamilyAndEntitySet)
417 {
418   //Open the med file (it will be closed by call of destructor)
419   MedFile aMedFile(myFileInfo.absFilePath());
420   med_idt fid = aMedFile.GetFid();
421   //Main part of code
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);
432     }else{
433       isPointsUpdated += LoadPoints(fid,theMesh);
434       isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity,aFamilyName);
435     }
436   }
437
438   return (isPointsUpdated || isCellsOnEntityUpdated);
439 }
440
441 int VISU_MedConvertor::LoadFieldOnMesh(VISU::TMesh& theMesh, 
442                                        VISU::TMeshOnEntity& theMeshOnEntity, 
443                                        VISU::TField& theField, 
444                                        VISU::TField::TValForTime& theValForTime)
445 {
446   //Open the med file (it will be closed by call of destructor)
447   MedFile aMedFile(myFileInfo.absFilePath());
448   med_idt fid = aMedFile.GetFid();
449   //Main part of code
450   int isPointsUpdated = LoadPoints(fid,theMesh);
451   int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity);
452   int isFieldUpdated = LoadField(fid,theMeshOnEntity,theField,theValForTime);
453   
454   return (isPointsUpdated || isCellsOnEntityUpdated || isFieldUpdated);
455 }
456
457 int VISU_MedConvertor::LoadPoints(const med_idt& fid, VISU::TMesh& theMesh, const string& theFamilyName) 
458 {
459   try{
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();
469     if(isPointsLoaded) 
470       if(!isFamilyPresent) return 0;
471       else if(!aFamily.mySubMesh.empty()) return 0;
472     if(MYDEBUG) 
473       MESSAGE("LoadPoints - isPointsLoaded = "<<isPointsLoaded<<"; theFamilyName = '"<<theFamilyName<<"'");
474     //Main part of code
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);
482     med_repere rep;
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(...)"));
493     if(!isPointsLoaded){
494
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;
502       }
503       
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];
512       else
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);
521     }
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);
528     }
529     return 1;
530   }catch(std::runtime_error& exc){
531     theMesh.myPointsCoord.clear();
532     throw std::runtime_error(exc.what());
533   }catch(...){
534     theMesh.myPointsCoord.clear();
535     throw std::runtime_error(EXCEPTION("Unknown exception !!!"));
536   }
537   return 0;
538 }
539
540 int VISU_MedConvertor::LoadCellsOnEntity(const med_idt& fid, VISU::TMeshOnEntity& theMeshOnEntity,
541                                          const string& theFamilyName)
542 {
543   try{
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();
550     if(isCellsLoaded) 
551       if(!isFamilyPresent) return 0;
552       else if(!aFamily.mySubMesh.empty()) return 0;
553     if(MYDEBUG) {
554       MESSAGE("LoadCellsOnEntity - theFamilyName = '"<<theFamilyName<<"'");
555       MESSAGE("LoadCellsOnEntity - isCellsLoaded = "<<isCellsLoaded<<"; isFamilyPresent = "<<isFamilyPresent);
556     }
557     //Main part of code
558     int iGeomElemEnd;
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());
565     if(MYDEBUG) 
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;
576 #endif
577     map<med_int,med_int> node_map;
578     if(inum_node) 
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(...)"));
600         if(!isCellsLoaded){
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);
607             if(inum_node)
608               for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++)
609                 aConnect[k] = node_map[conn[kj+k]-1];
610             else
611               for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++)
612                 aConnect[k] = conn[kj+k] - 1;
613             switch(aMedType){
614             case MED_TETRA4 :
615             case MED_TETRA10 :
616               anArray[0] = aConnect[0];
617               anArray[1] = aConnect[1];
618               anArray[2] = aConnect[3];  
619               anArray[3] = aConnect[2];  
620               break;
621             case MED_PYRA5 :
622             case MED_PYRA13 :
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];
628               break;
629             default:
630               for (int k = 0; k < nbVtkNodes; k++) 
631                 anArray[k] = aConnect[k];
632             }
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());
637           }
638         }
639         //Filling aFamily SubMesh
640         if(isFamilyPresent){
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);
645         }
646       }
647     }
648     return 1;
649   }catch(std::runtime_error& exc){
650     theMeshOnEntity.myCellsConn.clear();
651     throw std::runtime_error(exc.what());
652   }catch(...){
653     theMeshOnEntity.myCellsConn.clear();
654     throw std::runtime_error(EXCEPTION("Unknown exception !!!"));
655   }
656   return 0;
657 }
658
659 int VISU_MedConvertor::LoadField(const med_idt& fid, const VISU::TMeshOnEntity& theMeshOnEntity,
660                                  VISU::TField& theField, VISU::TField::TValForTime& theValForTime)
661 {
662   //Check on loading already done
663   if(!theValForTime.myValForCells.empty()) return 0;
664   //Main part of code
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(...)"));
675   int iGeomElemEnd;
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;
681   if(MYDEBUG){
682     MESSAGE("LoadField - aMeshName = '"<<aMeshName<<"' aFieldName = '"<<aFieldName<<"'; anEntity = "<<anEntity);
683     MESSAGE("LoadField - iGeomElemEnd = "<<iGeomElemEnd<<"; ncomp = "<<ncomp<<"; type_field = "<<type_field);
684   }
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));
692     else
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){
697       if(iNumElemEnd > 0){
698         if(!theField.myIsTrimmed){
699           theField.myIsTrimmed = true;
700           theField.myDataSize -= iNumElemEnd*theField.myNbComp;
701         }
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());
705       }
706     }else{
707       med_int ngauss = 0, numdt = 0, numo = 0;
708       char dt_unit[MED_TAILLE_PNOM+1] = "";
709       med_float dt = 0;
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"));
715       else{
716         //Checking for accordance between the mesh and the field data
717         if(iNumElemEnd <= 0) 
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] = "";
729         switch(type_field){
730         case MED_REEL64 : {
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;
739           }
740           break;
741         }
742         //case MED_INT64 : //valarray<long long> valr(jEnd);
743         case MED_INT32 : //valarray<long int> valr(jEnd);
744         case MED_INT : {
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;
753           }
754           break;
755         }
756         default :
757           throw std::runtime_error(EXCEPTION("LoadField >> Value of med_type_champ for the field is wrong !!!"));
758         }
759         if(MYDEBUG) MESSAGE("LoadField - aGeom = "<<aGeom<<"; nval = "<<nval<<"; ngauss = "<<ngauss
760                             <<"; iTimeStampEnd = "<<iTimeStampEnd<<"; pflname = '"<<pflname<<"'");
761       }
762     }
763   }
764   return 1; 
765 }