Salome HOME
9587f53f9c48aaf8517fe0c34b0ff291b3379ec9
[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 <valarray>     
30 #include <vtkCellType.h>
31 #define USER_INTERLACE MED_FULL_INTERLACE
32
33 using namespace std;
34
35 #ifdef _DEBUG_
36 static int MYDEBUG = 0;
37 #else
38 static int MYDEBUG = 0;
39 #endif
40
41 static med_err ret = 0;
42
43 typedef map<VISU::TEntity,med_entite_maillage> TVisu2MedEntity;
44
45 static TVisu2MedEntity aVisu2MedEntity;
46
47 static int INIT = (
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,
52                    1);
53
54 static med_geometrie_element NODEGEOM[1] = {MED_POINT1};
55
56 static med_geometrie_element EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
57   MED_SEG2, MED_SEG3
58   };
59
60 static med_geometrie_element FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
61   MED_TRIA3, MED_QUAD4, MED_TRIA6, MED_QUAD8
62   };
63
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
69   };
70
71 void GetEntity2Geom(const VISU::TEntity& theEntity, med_geometrie_element*& theVector, int* theEnd) 
72      throw (std::runtime_error&)
73 {
74   switch(theEntity){
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;
79   default:
80     throw std::runtime_error("GetEntity2Geom >> theEntity is uncorrect");
81   }
82 }
83
84 extern "C"
85 VISU_Convertor* CreateMedConvertor(const string& theFileName) throw(std::runtime_error&){
86   return new VISU_MedConvertor(theFileName);
87 }
88
89 class MedFile{
90   char* myFileName;
91   med_idt myFid;
92   MedFile();
93   MedFile(const MedFile&);
94 public:
95   MedFile(const char* theFileName) throw(std::runtime_error&) :
96     myFileName(strdup(theFileName))
97   {
98     myFid = MEDouvrir(myFileName,MED_LECT);
99     if(myFid < 0){
100       free(myFileName);
101       throw std::runtime_error(string("MedFile::MedFile >> MEDouvrir(...) - ") + theFileName);
102     }
103   }
104   ~MedFile(){
105     free(myFileName);
106     if(myFid >= 0) 
107       MEDfermer(myFid);
108   }
109   const med_idt& GetFid() const { return myFid;};
110 };
111
112 VISU_MedConvertor::VISU_MedConvertor(const string& theFileName) throw (std::runtime_error&) {
113   myFileInfo.setFile(QString(theFileName.c_str()));
114   myName = myFileInfo.baseName().latin1();
115 }
116
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++){
123     med_int aMeshDim;
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;
137       int iGeomElemEnd;
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);
149           if(iNumElemEnd > 0){
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;
156             if(MYDEBUG) 
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);
164             med_repere rep;
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;
177               }
178           }
179         }
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);
192           if(MYDEBUG) 
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;
208             } 
209         }
210       }
211     }
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);
219       if(0 && MYDEBUG) 
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] = "";
223       med_int aFamilyNum;
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");
228       if(0 && MYDEBUG) 
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 !!!");
232         continue;
233       }
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];
242       if(MYDEBUG) 
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);
255       }
256     }
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;
281         }
282       }
283     }
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<<"'");
299       }
300     }
301   }
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;
319       int iGeomElemEnd;
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] = "";
332             med_float dt = 0;
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];
343             if(iTimeStamp == 1){
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);
353               if(MYDEBUG)
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;
367                 if(MYDEBUG)
368                   MESSAGE("ImportInfo - aCompName = '"<<aCompName<<"'; aUnitName = '"<<aUnitName<<"'");
369               }
370               
371             }
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);
381           }
382         }
383       }
384     }
385   }
386   return this; 
387 }
388
389 int VISU_MedConvertor::LoadMeshOnEntity(VISU::TMeshOnEntity& theMeshOnEntity, 
390                                         const string& theFamilyName)
391   throw (std::runtime_error&)
392 {
393   //Open the med file (it will be closed by call of destructor)
394   MedFile aMedFile(myFileInfo.absFilePath());
395   med_idt fid = aMedFile.GetFid();
396   //Main part of code
397   const string& aMeshName = theMeshOnEntity.myMeshName;
398   const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
399   VISU::TMesh& aMesh = myMeshMap[aMeshName];
400   int isPointsUpdated;
401   if(anEntity == VISU::NODE_ENTITY) 
402     isPointsUpdated = LoadPoints(fid,aMesh,theFamilyName);
403   else 
404     isPointsUpdated = LoadPoints(fid,aMesh);
405   int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity,theFamilyName);
406
407   return (isPointsUpdated || isCellsOnEntityUpdated);
408 }
409
410 int VISU_MedConvertor::LoadMeshOnGroup(VISU::TMesh& theMesh, 
411                                        const VISU::TFamilyAndEntitySet& theFamilyAndEntitySet)
412      throw (std::runtime_error&)
413 {
414   //Open the med file (it will be closed by call of destructor)
415   MedFile aMedFile(myFileInfo.absFilePath());
416   med_idt fid = aMedFile.GetFid();
417   //Main part of code
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);
428     }else{
429       isPointsUpdated += LoadPoints(fid,theMesh);
430       isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity,aFamilyName);
431     }
432   }
433
434   return (isPointsUpdated || isCellsOnEntityUpdated);
435 }
436
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&)
442 {
443   //Open the med file (it will be closed by call of destructor)
444   MedFile aMedFile(myFileInfo.absFilePath());
445   med_idt fid = aMedFile.GetFid();
446   //Main part of code
447   int isPointsUpdated = LoadPoints(fid,theMesh);
448   int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity);
449   int isFieldUpdated = LoadField(fid,theMeshOnEntity,theField,theValForTime);
450   
451   return (isPointsUpdated || isCellsOnEntityUpdated || isFieldUpdated);
452 }
453
454 int VISU_MedConvertor::LoadPoints(const med_idt& fid, VISU::TMesh& theMesh, const string& theFamilyName) 
455   throw (std::runtime_error&)
456 {
457   try{
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();
467     if(isPointsLoaded) 
468       if(!isFamilyPresent) return 0;
469       else if(!aFamily.mySubMesh.empty()) return 0;
470     if(MYDEBUG) 
471       MESSAGE("LoadPoints - isPointsLoaded = "<<isPointsLoaded<<"; theFamilyName = '"<<theFamilyName<<"'");
472     //Main part of code
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);
480     med_repere rep;
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(...)");
491     if(!isPointsLoaded){
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];
500       else
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);
509     }
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);
516     }
517     return 1;
518   }catch(std::runtime_error& exc){
519     theMesh.myPointsCoord.clear();
520     throw std::runtime_error(exc.what());
521   }catch(...){
522     theMesh.myPointsCoord.clear();
523     throw std::runtime_error("Unknown exception !!!");
524   }
525   return 0;
526 }
527
528 int VISU_MedConvertor::LoadCellsOnEntity(const med_idt& fid, VISU::TMeshOnEntity& theMeshOnEntity,
529                                          const string& theFamilyName)
530   throw (std::runtime_error&)
531 {
532   try{
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();
539     if(isCellsLoaded) 
540       if(!isFamilyPresent) return 0;
541       else if(!aFamily.mySubMesh.empty()) return 0;
542     if(MYDEBUG) {
543       MESSAGE("LoadCellsOnEntity - theFamilyName = '"<<theFamilyName<<"'");
544       MESSAGE("LoadCellsOnEntity - isCellsLoaded = "<<isCellsLoaded<<"; isFamilyPresent = "<<isFamilyPresent);
545     }
546     //Main part of code
547     int iGeomElemEnd;
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());
554     if(MYDEBUG) 
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(...)");
578         if(!isCellsLoaded){
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;
587             }
588             switch(aMedType){
589             case MED_TETRA4 :
590             case MED_TETRA10 :
591               anArray[0] = aConnect[0];
592               anArray[1] = aConnect[1];
593               anArray[2] = aConnect[3];  
594               anArray[3] = aConnect[2];  
595               break;
596             case MED_PYRA5 :
597             case MED_PYRA13 :
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];
603               break;
604             default:
605               for (int k = 0; k < nbVtkNodes; k++) 
606                 anArray[k] = aConnect[k];
607             }
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());
613               }
614           }
615         }
616         //Filling aFamily SubMesh
617         if(isFamilyPresent){
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);
622         }
623       }
624     }
625     return 1;
626   }catch(std::runtime_error& exc){
627     theMeshOnEntity.myCellsConn.clear();
628     throw std::runtime_error(exc.what());
629   }catch(...){
630     theMeshOnEntity.myCellsConn.clear();
631     throw std::runtime_error("Unknown exception !!!");
632   }
633   return 0;
634 }
635
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&)
639 {
640   //Check on loading already done
641   if(!theValForTime.myValForCells.empty()) return 0;
642   //Main part of code
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(...)"));
651   int iGeomElemEnd;
652   med_geometrie_element* aGeomElemVector;
653   const VISU::TEntity& anEntity = theField.myEntity;
654   GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
655   med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
656   if(MYDEBUG) {
657     MESSAGE("LoadField - aFieldName = '"<<aFieldName<<"'; anEntity = "<<anEntity<<"; iGeomElemEnd = "<<iGeomElemEnd);
658     MESSAGE("LoadField - ncomp = "<<ncomp<<"; type_field = "<<type_field<<"; myId = "<<theValForTime.myId);
659   }
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] = "";
667       med_float dt = 0;
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");
673       else{
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] = "";
686         switch(type_field){
687         case MED_REEL64 : {
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];
692           break;
693         }
694         //case MED_INT64 : //valarray<long long> valr(jEnd);
695         case MED_INT32 : //valarray<long int> valr(jEnd);
696         case MED_INT : {
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];
701           break;
702         }
703           default :
704             throw std::runtime_error("LoadField >> Value of med_type_champ for the field is wrong !!!");
705         }
706         if(ret < 0) throw std::runtime_error("ChampLire >> MEDchampLire(...)");
707       }
708     }
709   }
710   return 1; 
711 }