]> SALOME platform Git repositories - modules/visu.git/blob - src/VISU_I/VISU_MedConvertor.cxx
Salome HOME
NRI : Merge from V1_2.
[modules/visu.git] / src / VISU_I / VISU_MedConvertor.cxx
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : VISU_MedConvertor.cxx
6 //  Author : Alexey PETROV
7 //  Module : VISU
8
9 using namespace std;
10 #include "VISU_MedConvertor.hxx"
11 #include <valarray>     
12 #include <vtkCellType.h>
13 #define USER_INTERLACE MED_FULL_INTERLACE
14 using namespace std;
15
16 #ifdef DEBUG
17 static int MYDEBUG = 0;
18 #else
19 static int MYDEBUG = 0;
20 #endif
21 static med_err ret = 0;
22
23 typedef map<VISU::TEntity,med_entite_maillage> TVisu2MedEntity;
24 static TVisu2MedEntity aVisu2MedEntity;
25 static int INIT = (
26                    aVisu2MedEntity[VISU::NODE_ENTITY] = MED_NOEUD,
27                    aVisu2MedEntity[VISU::EDGE_ENTITY] = MED_ARETE,
28                    aVisu2MedEntity[VISU::FACE_ENTITY] = MED_FACE,
29                    aVisu2MedEntity[VISU::CELL_ENTITY] = MED_MAILLE,
30                    1);
31
32 static med_geometrie_element NODEGEOM[1] = {MED_POINT1};
33 static med_geometrie_element EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
34   MED_SEG2, MED_SEG3
35   };
36 static med_geometrie_element FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
37   MED_TRIA3, MED_QUAD4, MED_TRIA6, MED_QUAD8
38   };
39 static med_geometrie_element  CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
40   MED_POINT1, MED_SEG2, MED_SEG3, MED_TRIA3,
41   MED_QUAD4, MED_TRIA6, MED_QUAD8, MED_TETRA4,
42   MED_PYRA5, MED_PENTA6, MED_HEXA8, MED_TETRA10, 
43   MED_PYRA13, MED_PENTA15, MED_HEXA20
44   };
45 void GetEntity2Geom(const VISU::TEntity& theEntity, med_geometrie_element*& theVector, int* theEnd) 
46      throw (std::runtime_error&)
47 {
48   switch(theEntity){
49   case VISU::CELL_ENTITY: theVector = CELLGEOM; *theEnd = MED_NBR_GEOMETRIE_MAILLE; break;
50   case VISU::FACE_ENTITY: theVector = FACEGEOM; *theEnd = MED_NBR_GEOMETRIE_FACE; break;
51   case VISU::EDGE_ENTITY: theVector = EDGEGEOM; *theEnd = MED_NBR_GEOMETRIE_ARETE; break;
52   case VISU::NODE_ENTITY: theVector = NODEGEOM; *theEnd = 1; break;
53   default:
54     throw std::runtime_error("GetEntity2Geom >> theEntity is uncorrect");
55   }
56 }
57
58 extern "C"
59 VISU_Convertor* CreateMedConvertor(const string& theFileName) throw(std::runtime_error&){
60   return new VISU_MedConvertor(theFileName);
61 }
62
63 int med2vtkCellType(int medType){
64   for(int i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
65     if(med2vtk[i].medType == medType) return med2vtk[i].vtkType;
66   return -1;
67 }
68
69 int vtk2medCellType(int vtkType){
70   for(int i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
71     if(med2vtk[i].vtkType == vtkType) return med2vtk[i].medType;
72   return -1;
73 }
74
75 class MedFile{
76   char* myFileName;
77   med_idt myFid;
78   MedFile();
79   MedFile(const MedFile&);
80 public:
81   MedFile(const char* theFileName) throw(std::runtime_error&) :
82     myFileName(strdup(theFileName))
83   {
84     myFid = MEDouvrir(myFileName,MED_LECT);
85     if(myFid < 0){
86       free(myFileName);
87       throw std::runtime_error(string("MedFile::MedFile >> MEDouvrir(...) - ") + theFileName);
88     }
89   }
90   ~MedFile(){
91     free(myFileName);
92     if(myFid >= 0) 
93       MEDfermer(myFid);
94   }
95   const med_idt& GetFid() const { return myFid;};
96 };
97
98 VISU_MedConvertor::VISU_MedConvertor(const string& theFileName) throw (std::runtime_error&) {
99   myFileInfo.setFile(QString(theFileName.c_str()));
100   myName = (const char*)(myFileInfo.baseName());
101 }
102 VISU_Convertor* VISU_MedConvertor::Build() throw (std::runtime_error&) {
103   MedFile aMedFile(myFileInfo.absFilePath());
104   med_idt fid = aMedFile.GetFid();
105   med_int iMeshEnd = MEDnMaa(fid);  //Get number of meshes
106   if(MYDEBUG) MESSAGE("ImportInfo - MEDnMaa = "<<iMeshEnd<<"; myFileInfo = "<<myFileInfo.filePath());
107   for(int iMesh = 1; iMesh <= iMeshEnd; iMesh++){
108     med_int aMeshDim;
109     char aMeshName[MED_TAILLE_NOM+1] = "";
110     MEDmaaInfo(fid,iMesh,aMeshName,&aMeshDim);
111     if(MYDEBUG) MESSAGE("ImportInfo - aMeshName = '"<<aMeshName<<"'; aMeshDim = "<<aMeshDim);
112     VISU::TMesh &aMesh = myMeshMap[aMeshName];
113     aMesh.myDim = aMeshDim;
114     aMesh.myName = aMeshName;
115     typedef map<int,VISU::TEntity> TFamily2EntityMap;
116     TFamily2EntityMap aFamily2EntityMap;
117     TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
118     for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++) {
119       VISU::TEntity anEntity = aVisu2MedEntityIter->first;
120       int iGeomElemEnd;
121       med_geometrie_element* aGeomElemVector;
122       GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
123       med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
124       for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
125         int medId = getIdMedType(aGeomElemVector[iGeomElem]);
126         int aVtkType = med2vtk[medId].vtkType;
127         med_geometrie_element aMedType = med2vtk[medId].medType;
128         if(aMedEntity == MED_NOEUD){
129           med_geometrie_element typgeo = (med_geometrie_element)0;
130           med_connectivite typco = (med_connectivite)0;
131           med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,typgeo,typco);
132           if(iNumElemEnd > 0){
133             VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
134             aMeshOnEntity.myEntity = anEntity;
135             aMeshOnEntity.myMeshName = aMeshName;
136             if(MYDEBUG) 
137               MESSAGE("ImportInfo -\t anEntity = "<<anEntity<<"; iNumElemEnd = "<<iNumElemEnd<<
138                       "; medName = "<<med2vtk[medId].medName<<"; medId = "<<medId);
139             med_booleen iname_elem, inum_elem;
140             valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
141             valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
142             med_repere rep;
143             valarray<char> name_coord('\0',aMesh.myDim*MED_TAILLE_PNOM+1);
144             valarray<char> unit_coord('\0',aMesh.myDim*MED_TAILLE_PNOM+1);
145             valarray<med_float> coord(aMesh.myDim*iNumElemEnd);
146             ret = MEDnoeudsLire(fid,aMeshName,aMesh.myDim,&coord[0],MED_FULL_INTERLACE,&rep,
147                                 &name_coord[0],&unit_coord[0],&name_elem[0],&iname_elem,
148                                 &num_elem[0],&inum_elem,&num_fam_elem[0],iNumElemEnd);
149             if(ret < 0) throw std::runtime_error("ImportInfo >> MEDnoeudsLire(...)");
150             for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
151               if(num_fam_elem[iNumElem] != 0) 
152                 aFamily2EntityMap[num_fam_elem[iNumElem]] = anEntity;
153           }
154         }
155         //Get number of connectivities
156         med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aMedType,MED_NOD); 
157         if (iNumElemEnd > 0) {
158           VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
159           aMeshOnEntity.myEntity = anEntity;
160           aMeshOnEntity.myMeshName = aMeshName;
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_int aNbConnForElem = getNbMedConnect(aMedType,anEntity,aMesh.myDim);
165           if(MYDEBUG) 
166             MESSAGE("ImportInfo -\t anEntity = "<<anEntity<<"; iNumElemEnd = "<<iNumElemEnd<<
167                     "; medName = "<<med2vtk[medId].medName<<"; aNbConnForElem = "<<aNbConnForElem);
168           valarray<med_int> conn(0,aNbConnForElem*iNumElemEnd);
169           ret = MEDelementsLire(fid,aMeshName,aMesh.myDim,&conn[0],MED_FULL_INTERLACE,
170                                 &name_elem[0],&iname_elem,&num_elem[0],&inum_elem,
171                                 &num_fam_elem[0],iNumElemEnd,aMedEntity,aMedType,MED_NOD);
172           if (ret < 0) throw std::runtime_error("ImportInfo >> MEDelementsLire(...)");
173           for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
174             if(num_fam_elem[iNumElem] != 0) 
175               aFamily2EntityMap[num_fam_elem[iNumElem]] = anEntity;
176         }
177       }
178     }
179     med_int aNbFamily = MEDnFam(fid,aMeshName,0,MED_FAMILLE);
180     if(MYDEBUG) MESSAGE("ImportInfo - aNbFamily = "<<aNbFamily);
181     for(int aFamInd = 1; aFamInd <= aNbFamily; aFamInd++){
182       med_int aNbAttrib = MEDnFam(fid,aMeshName,aFamInd,MED_ATTR);
183       valarray<med_int> anAttId(aNbAttrib), anAttVal(aNbAttrib);
184       valarray<char> anAttDesc('\0',aNbAttrib*MED_TAILLE_DESC+1);
185       med_int aNbGroup = MEDnFam(fid,aMeshName,aFamInd,MED_GROUPE);
186       if(0 && MYDEBUG) 
187         MESSAGE("ImportInfo - aFamInd = "<<aFamInd<<"; aNbAttrib = "<<aNbAttrib<<"; aNbGroup = "<<aNbGroup);
188       valarray<char> aGroupNames('\0',aNbGroup*MED_TAILLE_LNOM+1);
189       char aFamilyName[MED_TAILLE_NOM+1] = "";
190       med_int aFamilyNum;
191       ret = MEDfamInfo(fid,aMeshName,aFamInd,aFamilyName,&aFamilyNum,
192                        &anAttId[0],&anAttVal[0],&anAttDesc[0],&aNbAttrib,
193                        &aGroupNames[0],&aNbGroup);
194       if(ret < 0) throw std::runtime_error("ImportInfo >> MEDfamInfo");
195       if(0 && MYDEBUG) 
196         MESSAGE("ImportInfo - aFamilyNum = "<<aFamilyNum<<"; aNbGroup = "<<aNbGroup);
197       if(aFamily2EntityMap.find(aFamilyNum) == aFamily2EntityMap.end()) {
198         if(MYDEBUG) MESSAGE("ImportInfo - a Family with name '"<<aFamilyName<<"' are empty !!!");
199         continue;
200       }
201       VISU::TEntity anEntity = aFamily2EntityMap[aFamilyNum];
202       VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
203       VISU::TFamily& aFamily = aMeshOnEntity.myFamilyMap[aFamilyName];
204       aFamily.myName = aFamilyName;
205       aFamily.myEntity = anEntity;
206       aFamily.myId = aFamilyNum;
207       if(MYDEBUG) 
208         MESSAGE("ImportInfo - aFamily.myEntity = "<<anEntity<<
209                 "; myName = '"<<aFamilyName<<"'; myId = "<<aFamilyNum);
210       VISU::TBindGroups& aBindGroups = aFamily.myGroups;
211       for(int iGroup = 0, iPos = 0; iGroup < aNbGroup; iGroup++, iPos += MED_TAILLE_LNOM){
212         char aGroupName[MED_TAILLE_LNOM+1];
213         strncpy(aGroupName,&aGroupNames[iPos],MED_TAILLE_LNOM);
214         aGroupName[MED_TAILLE_LNOM] = '\0';
215         if(MYDEBUG) MESSAGE("ImportInfo - aGroupName["<<iGroup<<"] = '"<<aGroupName<<"'");
216         aBindGroups.insert(aGroupName);
217       }
218     }
219     //Calculation of TMesh.TGroupMap
220     const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
221     if(aMeshOnEntityMap.empty()) continue;
222     VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
223     VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
224     for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
225       const VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
226       const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity.myFamilyMap;
227       if(aFamilyMap.empty()) continue;
228       VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
229       for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
230         const VISU::TFamily& aFamily = aFamilyMapIter->second;
231         const VISU::TBindGroups& aBindGroups = aFamily.myGroups;
232         if(aBindGroups.empty()) continue;
233         VISU::TBindGroups::const_iterator aBindGroupsIter = aBindGroups.begin();
234         for(; aBindGroupsIter != aBindGroups.end(); aBindGroupsIter++){
235           const string& aGroupName = *aBindGroupsIter;
236           VISU::TGroup& aGroup = aGroupMap[aGroupName];
237           aGroup.myName = aGroupName;
238           aGroup.myMeshName = aMesh.myName;
239           VISU::TFamilyAndEntity aFamilyAndEntity(aFamily.myName,aFamily.myEntity);
240           aGroup.myFamilyAndEntitySet.insert(aFamilyAndEntity);
241         }
242       }
243     }
244     //Displaing information for the TMesh.TGroupMap
245     VISU::TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
246     if(MYDEBUG) MESSAGE("ImportInfo - aGroupMap.size() = "<<aGroupMap.size());
247     for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
248       const string& aGroupName = aGroupMapIter->first;
249       if(MYDEBUG) MESSAGE("ImportInfo - aGroupName = '"<<aGroupName<<"' : ");
250       const VISU::TGroup& aGroup = aGroupMapIter->second;
251       const VISU::TFamilyAndEntitySet& aFamilyAndEntitySet = aGroup.myFamilyAndEntitySet;
252       VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = aFamilyAndEntitySet.begin();
253       for(; aFamilyAndEntitySetIter != aFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
254         const string& aFamilyName = aFamilyAndEntitySetIter->first;
255         if(MYDEBUG) MESSAGE("ImportInfo - \t aFamilyName = '"<<aFamilyName<<"'");
256       }
257     }
258   }
259   //Reading information about fields
260   med_int iFieldEnd = MEDnChamp(fid,0);
261   if (iFieldEnd < 0) throw std::runtime_error("ImportChamps >> MEDnChamp(fid,0)");
262   if(MYDEBUG) MESSAGE("ImportInfo - iFieldEnd = "<<iFieldEnd);
263   for(med_int iField = 1; iField <= iFieldEnd; iField++){
264     med_int ncomp = MEDnChamp(fid,iField);
265     if(ncomp < 0) throw std::runtime_error("ImportChamps >> MEDnChamp(fid,i)");
266     valarray<char> aCompNames('\0',ncomp*MED_TAILLE_PNOM + 1);
267     valarray<char> aUnitNames('\0',ncomp*MED_TAILLE_PNOM + 1);
268     char name_field[MED_TAILLE_NOM + 1] = "";
269     med_type_champ type_field;
270     if(MEDchampInfo(fid,iField,name_field,&type_field,&aCompNames[0],&aUnitNames[0],ncomp) < 0)
271       throw std::runtime_error(string("ImportInfo >> MEDchampInfo(...)"));
272     //if(type_field != MED_REEL64) continue; //There is some problem in reading INTXX values
273     TVisu2MedEntity::const_iterator aVisu2MedEntityIter = aVisu2MedEntity.begin();
274     for(; aVisu2MedEntityIter != aVisu2MedEntity.end(); aVisu2MedEntityIter++) {
275       VISU::TEntity anEntity = aVisu2MedEntityIter->first;
276       int iGeomElemEnd;
277       med_geometrie_element* aGeomElemVector;
278       GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
279       med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
280       for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
281         med_geometrie_element& aGeom = aGeomElemVector[iGeomElem];
282         med_int iTimeStampEnd = MEDnPasdetemps(fid,name_field,aMedEntity,aGeom);
283         if(iTimeStampEnd < 0) throw std::runtime_error("ImportInfo >> MEDnPasdetemps(...)");
284         if(iTimeStampEnd > 0) {
285           for(med_int iTimeStamp = 1; iTimeStamp <= iTimeStampEnd; iTimeStamp++) {
286             char aMeshName[MED_TAILLE_NOM+1] = "";
287             med_int ngauss = 0, numdt = 0, numo = 0;
288             char dt_unit[MED_TAILLE_PNOM+1] = "";
289             med_float dt = 0;
290             ret = MEDpasdetempsInfo(fid,name_field,aMedEntity,aGeom,iTimeStamp,
291                                     aMeshName,&ngauss,&numdt,dt_unit,&dt,&numo);
292             if(ret < 0) throw std::runtime_error("ImportInfo >> MEDpasdetempsInfo(...) < 0");
293             if(myMeshMap.find(aMeshName) == myMeshMap.end())
294               throw std::runtime_error("ImportInfo >> MEDpasdetempsInfo(...)");
295             VISU::TMesh &aMesh = myMeshMap[aMeshName];
296             VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
297             VISU::TFieldMap::iterator aFieldMapIter = aMeshOnEntity.myFieldMap.find(name_field);
298             //if(MYDEBUG && aFieldMapIter == aMeshOnEntity.myFieldMap.end()){
299             VISU::TField& aField = aMeshOnEntity.myFieldMap[name_field];
300             if(iTimeStamp == 1){
301               if(MYDEBUG){
302                 MESSAGE("ImportInfo - aField.myName = '"<<name_field<<"'; myNbComp = "<<ncomp);
303                 MESSAGE("ImportInfo -\t myMeshName = '"<<aMeshName<<"'; myEntity = "<<anEntity);
304               }
305               aField.myId = iField;
306               aField.myName = name_field;
307               aField.myEntity = anEntity;
308               aField.myMeshName = aMeshName;
309               aField.myNbComp = ncomp;
310               aField.myCompNames.resize(ncomp);
311               aField.myUnitNames.resize(ncomp);
312               for(int iComp = 0, iPos = 0; iComp < ncomp; iComp++, iPos += MED_TAILLE_PNOM){
313                 char aCompName[MED_TAILLE_PNOM+1], aUnitName[MED_TAILLE_PNOM+1];
314                 strncpy(aCompName,&aCompNames[iPos],MED_TAILLE_PNOM);
315                 aCompName[MED_TAILLE_PNOM] = '\0';
316                 aField.myCompNames[iComp] = aCompName;
317                 strncpy(aUnitName,&aUnitNames[iPos],MED_TAILLE_PNOM);
318                 aUnitName[MED_TAILLE_PNOM] = '\0';
319                 aField.myUnitNames[iComp] = aUnitName;
320                 if(MYDEBUG){
321                   MESSAGE("ImportInfo - aCompName["<<iComp<<"] = '"<<aCompName<<"'");
322                   MESSAGE("ImportInfo - aUnitName["<<iComp<<"] = '"<<aUnitName<<"'");
323                 }
324               }
325               
326             }
327             VISU::TField::TValForTime& aValForTime = aField.myValField[iTimeStamp];
328             aValForTime.myId = iTimeStamp;
329             aValForTime.myTime = VISU::TField::TTime(dt,dt_unit);
330             if(MYDEBUG && iGeomElem == 0) 
331               MESSAGE("ImportInfo -\t aField.myTime = "<<dt<<", "<<dt_unit);
332           }
333         }
334       }
335     }
336   }
337   return this; 
338 }
339
340 int VISU_MedConvertor::LoadMeshOnEntity(VISU::TMeshOnEntity& theMeshOnEntity, 
341                                         const string& theFamilyName)
342   throw (std::runtime_error&)
343 {
344   //Open the med file (it will be closed by call of destructor)
345   MedFile aMedFile(myFileInfo.absFilePath());
346   med_idt fid = aMedFile.GetFid();
347   //Main part of code
348   const string& aMeshName = theMeshOnEntity.myMeshName;
349   const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
350   VISU::TMesh& aMesh = myMeshMap[aMeshName];
351   int isPointsUpdated;
352   if(anEntity == VISU::NODE_ENTITY) 
353     isPointsUpdated = LoadPoints(fid,aMesh,theFamilyName);
354   else 
355     isPointsUpdated = LoadPoints(fid,aMesh);
356   int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity,theFamilyName);
357
358   return (isPointsUpdated || isCellsOnEntityUpdated);
359 }
360
361 int VISU_MedConvertor::LoadMeshOnGroup(VISU::TMesh& theMesh, 
362                                        const VISU::TFamilyAndEntitySet& theFamilyAndEntitySet)
363      throw (std::runtime_error&)
364 {
365   //Open the med file (it will be closed by call of destructor)
366   MedFile aMedFile(myFileInfo.absFilePath());
367   med_idt fid = aMedFile.GetFid();
368   //Main part of code
369   int isPointsUpdated = 0;
370   int isCellsOnEntityUpdated = 0;
371   VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = theFamilyAndEntitySet.begin();
372   for(; aFamilyAndEntitySetIter != theFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
373     const string& aFamilyName = aFamilyAndEntitySetIter->first;
374     const VISU::TEntity& anEntity = aFamilyAndEntitySetIter->second;
375     VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[anEntity];
376     if(anEntity == VISU::NODE_ENTITY){
377       isPointsUpdated += LoadPoints(fid,theMesh,aFamilyName);
378       isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity);
379     }else{
380       isPointsUpdated += LoadPoints(fid,theMesh);
381       isCellsOnEntityUpdated += LoadCellsOnEntity(fid,aMeshOnEntity,aFamilyName);
382     }
383   }
384
385   return (isPointsUpdated || isCellsOnEntityUpdated);
386 }
387
388 int VISU_MedConvertor::LoadFieldOnMesh(VISU::TMesh& theMesh, 
389                                        VISU::TMeshOnEntity& theMeshOnEntity, 
390                                        VISU::TField& theField, 
391                                        VISU::TField::TValForTime& theValForTime)
392   throw (std::runtime_error&)
393 {
394   //Open the med file (it will be closed by call of destructor)
395   MedFile aMedFile(myFileInfo.absFilePath());
396   med_idt fid = aMedFile.GetFid();
397   //Main part of code
398   int isPointsUpdated = LoadPoints(fid,theMesh);
399   int isCellsOnEntityUpdated = LoadCellsOnEntity(fid,theMeshOnEntity);
400   int isFieldUpdated = LoadField(fid,theMeshOnEntity,theField,theValForTime);
401   
402   return (isPointsUpdated || isCellsOnEntityUpdated || isFieldUpdated);
403 }
404
405 int VISU_MedConvertor::LoadPoints(const med_idt& fid, VISU::TMesh& theMesh, const string& theFamilyName) 
406   throw (std::runtime_error&)
407 {
408   try{
409     //Check on existing family
410     VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[VISU::NODE_ENTITY];
411     aMeshOnEntity.myEntity = VISU::NODE_ENTITY;
412     aMeshOnEntity.myMeshName = theMesh.myName;
413     VISU::TFamily* pFamily = VISU::GetFamily(aMeshOnEntity,theFamilyName);
414     bool isFamilyPresent = (pFamily != NULL);
415     VISU::TFamily& aFamily = *pFamily;
416     //Check on loading already done
417     bool isPointsLoaded = !theMesh.myPointsCoord.empty();
418     if(isPointsLoaded) 
419       if(!isFamilyPresent) return 0;
420       else if(!aFamily.mySubMesh.empty()) return 0;
421     if(MYDEBUG) 
422       MESSAGE("LoadPoints - isPointsLoaded = "<<isPointsLoaded<<"; theFamilyName = '"<<theFamilyName<<"'");
423     //Main part of code
424     char aMeshName[MED_TAILLE_NOM+1] = "";
425     strcpy(aMeshName,theMesh.myName.c_str());
426     med_geometrie_element typgeo = (med_geometrie_element)0; //MED_POINT1
427     med_connectivite typco = (med_connectivite)0; //MED_NOD
428     med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_COOR,MED_NOEUD,typgeo,typco);
429     if (iNumElemEnd <= 0) throw std::runtime_error("LoadPoints >> MEDnEntMaa(...)");
430     if(MYDEBUG) MESSAGE("LoadPoints - iNumElemEnd = "<<iNumElemEnd);
431     med_repere rep;
432     med_booleen iname_elem, inum_elem;
433     valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
434     valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
435     valarray<char> name_coord('\0',theMesh.myDim*MED_TAILLE_PNOM+1);
436     valarray<char> unit_coord('\0',theMesh.myDim*MED_TAILLE_PNOM+1);
437     valarray<med_float> coord(theMesh.myDim*iNumElemEnd);
438     ret = MEDnoeudsLire(fid,aMeshName,theMesh.myDim,&coord[0],MED_FULL_INTERLACE,&rep,
439                         &name_coord[0],&unit_coord[0],&name_elem[0],&iname_elem,
440                         &num_elem[0],&inum_elem,&num_fam_elem[0],iNumElemEnd);
441     if(ret < 0) throw std::runtime_error("LoadPoints >> MEDnoeudsLire(...)");
442     if(!isPointsLoaded){
443       VISU::TMesh::TPointsCoord& aPointsCoord = theMesh.myPointsCoord;
444       aPointsCoord.resize(iNumElemEnd*theMesh.myDim);
445       if(MYDEBUG) MESSAGE("LoadPoints - Filling coordinates of the mesh - inum_elem = "<<inum_elem);
446       inum_elem = MED_FAUX; // It is workaround
447       if(inum_elem == MED_FAUX)
448         for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) 
449           for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
450             aPointsCoord[iNumElem2Dim] = coord[iNumElem2Dim];
451       else
452         for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) 
453           for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
454             aPointsCoord[num_elem[iNumElem2Dim]] = coord[iNumElem2Dim];
455       if(MYDEBUG) MESSAGE("LoadPoints - Filling aMeshOnEntity with type NODE_ENTITY");
456       VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = aMeshOnEntity.myCellsConn[VTK_VERTEX];
457       aConnForCellType.resize(iNumElemEnd);
458       for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
459         aConnForCellType[iNumElem] = VISU::TMeshOnEntity::TConnect(1,iNumElem);
460     }
461     if(isFamilyPresent && iNumElemEnd > 0){
462       if(MYDEBUG) MESSAGE("LoadPoints - Filling aFamily SubMesh");
463       VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[VTK_VERTEX];
464       for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) 
465         if(num_fam_elem[iNumElem] == aFamily.myId)
466           aSubMeshOnCellType.insert(iNumElem);
467     }
468     return 1;
469   }catch(std::runtime_error& exc){
470     theMesh.myPointsCoord.clear();
471     throw std::runtime_error(exc.what());
472   }catch(...){
473     theMesh.myPointsCoord.clear();
474     throw std::runtime_error("Unknown exception !!!");
475   }
476   return 0;
477 }
478
479 int VISU_MedConvertor::LoadCellsOnEntity(const med_idt& fid, VISU::TMeshOnEntity& theMeshOnEntity,
480                                          const string& theFamilyName)
481   throw (std::runtime_error&)
482 {
483   try{
484     //Check on existing family
485     VISU::TFamily* pFamily = VISU::GetFamily(theMeshOnEntity,theFamilyName);
486     bool isFamilyPresent = (pFamily != NULL);
487     VISU::TFamily& aFamily = *pFamily;
488     //Check on loading already done
489     bool isCellsLoaded = !theMeshOnEntity.myCellsConn.empty();
490     if(isCellsLoaded) 
491       if(!isFamilyPresent) return 0;
492       else if(!aFamily.mySubMesh.empty()) return 0;
493     if(MYDEBUG) {
494       MESSAGE("LoadCellsOnEntity - theFamilyName = '"<<theFamilyName<<"'");
495       MESSAGE("LoadCellsOnEntity - isCellsLoaded = "<<isCellsLoaded<<"; isFamilyPresent = "<<isFamilyPresent);
496     }
497     //Main part of code
498     int iGeomElemEnd;
499     med_geometrie_element* aGeomElemVector;
500     const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
501     GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
502     const med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
503     char aMeshName[MED_TAILLE_NOM+1] = "";
504     strcpy(aMeshName,theMeshOnEntity.myMeshName.c_str());
505     if(MYDEBUG) 
506       MESSAGE("LoadCellsOnEntity - theMeshOnEntity.myEntity = "<<theMeshOnEntity.myEntity<<
507               "; iGeomElemEnd = "<<iGeomElemEnd<<"; theFamilyName = '"<<theFamilyName<<"'");
508     VISU::TMesh &aMesh = myMeshMap[theMeshOnEntity.myMeshName];
509     int aNbPoints = aMesh.myPointsCoord.size()/aMesh.myDim;
510     for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
511       int medId = getIdMedType(aGeomElemVector[iGeomElem]);
512       int nbMedNodes = med2vtk[medId].medNbNodes;
513       int nbVtkNodes = med2vtk[medId].vtkNbNodes;
514       int aVtkType = med2vtk[medId].vtkType;
515       med_geometrie_element aMedType = med2vtk[medId].medType;
516       med_int iNumElemEnd = MEDnEntMaa(fid,aMeshName,MED_CONN,aMedEntity,aMedType,MED_NOD);
517       if (iNumElemEnd > 0) {
518         med_booleen iname_elem, inum_elem;
519         valarray<med_int> num_elem(iNumElemEnd), num_fam_elem(iNumElemEnd);
520         valarray<char> name_elem('\0',iNumElemEnd*MED_TAILLE_PNOM+1);
521         med_int aNbConnForElem = getNbMedConnect(aMedType,anEntity,aMesh.myDim);
522         if(MYDEBUG) MESSAGE("LoadCellsOnEntity - medName = "<<med2vtk[medId].medName<<
523                             "; iNumElemEnd = "<<iNumElemEnd<<"; aNbConnForElem = "<<aNbConnForElem);
524         valarray<med_int> conn(aNbConnForElem*iNumElemEnd);
525         ret = MEDelementsLire(fid,aMeshName,aMesh.myDim,&conn[0],MED_FULL_INTERLACE,
526                               &name_elem[0],&iname_elem,&num_elem[0],&inum_elem,
527                               &num_fam_elem[0],iNumElemEnd,aMedEntity,aMedType,MED_NOD);
528         if (ret < 0) throw std::runtime_error("LoadCellsOnEntity >> MEDelementsLire(...)");
529         if(!isCellsLoaded){
530           VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = theMeshOnEntity.myCellsConn[aVtkType];
531           aConnForCellType.resize(iNumElemEnd);
532           valarray<med_int> aConnect(nbMedNodes);
533           for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) {
534             VISU::TMeshOnEntity::TConnect& anArray = aConnForCellType[iNumElem];
535             anArray.resize(nbVtkNodes);
536             for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++) {
537               aConnect[k] = conn[kj+k] - 1;
538             }
539             switch(aMedType){
540             case MED_TETRA4 :
541             case MED_TETRA10 :
542               anArray[0] = aConnect[0];
543               anArray[1] = aConnect[1];
544               anArray[2] = aConnect[3];  
545               anArray[3] = aConnect[2];  
546               break;
547             case MED_PYRA5 :
548             case MED_PYRA13 :
549               anArray[0] = aConnect[0];
550               anArray[1] = aConnect[3];  
551               anArray[2] = aConnect[2];
552               anArray[3] = aConnect[1];  
553               anArray[4] = aConnect[4];
554               break;
555             default:
556               for (int k = 0; k < nbVtkNodes; k++) 
557                 anArray[k] = aConnect[k];
558             }
559             for (int k = 0; k < nbVtkNodes; k++) 
560               if(anArray[k] < 0 || aNbPoints <= anArray[k]){
561                 static QString aString;
562                 aString.sprintf("ImportCells >> aNbPoints(%d) <= anArray[%d][%d](%d) < 0",aNbPoints,iNumElem,k,anArray[k]);
563                 throw std::runtime_error(aString.latin1());
564               }
565           }
566         }
567         //Filling aFamily SubMesh
568         if(isFamilyPresent){
569           VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[aVtkType];
570           for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) 
571             if(num_fam_elem[iNumElem] == aFamily.myId)
572               aSubMeshOnCellType.insert(iNumElem);
573         }
574       }
575     }
576     return 1;
577   }catch(std::runtime_error& exc){
578     theMeshOnEntity.myCellsConn.clear();
579     throw std::runtime_error(exc.what());
580   }catch(...){
581     theMeshOnEntity.myCellsConn.clear();
582     throw std::runtime_error("Unknown exception !!!");
583   }
584   return 0;
585 }
586
587 int VISU_MedConvertor::LoadField(const med_idt& fid, const VISU::TMeshOnEntity& theMeshOnEntity,
588                                  const VISU::TField& theField, VISU::TField::TValForTime& theValForTime)
589      throw (std::runtime_error&)
590 {
591   //Check on loading already done
592   if(!theValForTime.myValForCells.empty()) return 0;
593   //Main part of code
594   med_int ncomp = MEDnChamp(fid,theField.myId);
595   if(ncomp < 0) throw std::runtime_error("LoadField >> MEDnChamp(fid,i)");
596   valarray<char> comp('\0',ncomp*MED_TAILLE_PNOM + 1);
597   valarray<char> unit('\0',ncomp*MED_TAILLE_PNOM + 1);
598   char aFieldName[MED_TAILLE_NOM + 1] = "";
599   med_type_champ type_field;
600   if(MEDchampInfo(fid,theField.myId,aFieldName,&type_field,&comp[0],&unit[0],ncomp) < 0)
601     throw std::runtime_error(string("LoadField >> MEDchampInfo(...)"));
602   int iGeomElemEnd;
603   med_geometrie_element* aGeomElemVector;
604   const VISU::TEntity& anEntity = theField.myEntity;
605   GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
606   med_entite_maillage& aMedEntity = aVisu2MedEntity[anEntity];
607   if(MYDEBUG) {
608     MESSAGE("LoadField - aFieldName = '"<<aFieldName<<"'; anEntity = "<<anEntity<<"; iGeomElemEnd = "<<iGeomElemEnd);
609     MESSAGE("LoadField - ncomp = "<<ncomp<<"; type_field = "<<type_field<<"; myId = "<<theValForTime.myId);
610   }
611   for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
612     med_geometrie_element& aGeom = aGeomElemVector[iGeomElem];
613     med_int iTimeStampEnd = MEDnPasdetemps(fid,aFieldName,aMedEntity,aGeom);
614     if(iTimeStampEnd > 0) {
615       char aMeshName[MED_TAILLE_NOM+1] = "";
616       med_int ngauss = 0, numdt = 0, numo = 0;
617       char dt_unit[MED_TAILLE_PNOM+1] = "";
618       med_float dt = 0;
619       ret = MEDpasdetempsInfo(fid,aFieldName,aMedEntity,aGeom,theValForTime.myId,
620                               aMeshName,&ngauss,&numdt,dt_unit,&dt,&numo);
621       if(ret < 0) throw std::runtime_error("LoadField >> MEDpasdetempsInfo(...)");
622       med_int nval = MEDnVal(fid,aFieldName,aMedEntity,aGeom,numdt,numo);
623       if (nval <= 0) throw std::runtime_error("LoadField >> MEDnVal(...) - nval <= 0");
624       else{
625         //Checking for accordance between the mesh and the field on number of geomterical elements 
626         int aVtkType = med2vtkCellType(aGeom);
627         const VISU::TMeshOnEntity::TCellsConn& aCellsConn = theMeshOnEntity.myCellsConn;
628         VISU::TMeshOnEntity::TCellsConn::const_iterator aCellsConnIter = aCellsConn.find(aVtkType);
629         if(aCellsConnIter == aCellsConn.end()) throw std::runtime_error("LoadField - There is no the geom. elem. on the mesh !!!");
630         const VISU::TMeshOnEntity::TConnForCellType aConnForCellType = aCellsConnIter->second;
631         if(aConnForCellType.size() != nval) throw std::runtime_error("LoadField - Size of values and size of mesh not equal !!!");
632         if(MYDEBUG) MESSAGE("LoadField - aGeom = "<<aGeom<<"; nval = "<<nval<<"; iTimeStampEnd = "<<iTimeStampEnd);
633         VISU::TField::TValForCellsWithType &anArray = theValForTime.myValForCells[aVtkType];
634         int jEnd = theField.myNbComp*nval;
635         anArray.resize(jEnd);
636         char pflname[MED_TAILLE_NOM + 1] = "";
637         switch(type_field){
638         case MED_REEL64 : {
639           valarray<med_float> valr(jEnd);
640           ret = MEDchampLire(fid,aMeshName,aFieldName,(unsigned char*)&valr[0],MED_FULL_INTERLACE,MED_ALL,
641                              pflname,aMedEntity,aGeom,numdt,numo);
642           for (med_int j = 0; j < jEnd; j++) anArray[j] = valr[j];
643           break;
644         }
645         //case MED_INT64 : //valarray<long long> valr(jEnd);
646         case MED_INT32 : //valarray<long int> valr(jEnd);
647         case MED_INT : {
648           valarray<med_int> valr(jEnd);
649           ret = MEDchampLire(fid,aMeshName,aFieldName,(unsigned char*)&valr[0],MED_FULL_INTERLACE,MED_ALL,
650                              pflname,aMedEntity,aGeom,numdt,numo);
651           for (med_int j = 0; j < jEnd; j++) anArray[j] = valr[j];
652           break;
653         }
654           default :
655             throw std::runtime_error("LoadField >> Value of med_type_champ for the field is wrong !!!");
656         }
657         if(ret < 0) throw std::runtime_error("ChampLire >> MEDchampLire(...)");
658       }
659     }
660   }
661   return 1; 
662 }
663
664