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