Salome HOME
NRI : First integration.
[modules/visu.git] / src / VISU_I / VISU_CorbaMedConvertor.cxx
1 using namespace std;
2 // File:        VISU_CorbaMedConvertor.cxx
3 // Created:     Fri Jan 10 12:04:54 2003
4 // Author:      Alexey PETROV
5 //              <apo@ivanox.nnov.matra-dtv.fr>
6
7
8 #include "VISU_CorbaMedConvertor.hxx"
9 using namespace VISU;
10 #include <valarray>     
11 #include <vtkCellType.h>
12
13 #define USER_INTERLACE MED_FULL_INTERLACE
14
15 #ifdef DEBUG
16 static int MYDEBUG = 1;
17 #else
18 static int MYDEBUG = 0;
19 #endif
20 static med_err ret = 0;
21
22 extern "C"
23   VISU_Convertor* CreateMEDConvertor(SALOMEDS::SObject_ptr theMedSObject) throw(std::runtime_error&){
24     return new VISU_MEDConvertor(theMedSObject);
25   }
26
27 typedef map<VISU::TEntity,SALOME_MED::medEntityMesh> TVisu2MedEntity;
28 static TVisu2MedEntity aVisu2MedEntity;
29 typedef map<SALOME_MED::medEntityMesh,VISU::TEntity> TMed2VisuEntity;
30 static TMed2VisuEntity aMed2VisuEntity;
31 static int INIT = (
32                    aVisu2MedEntity[VISU::CELL_ENTITY] = SALOME_MED::MED_CELL,
33                    aVisu2MedEntity[VISU::FACE_ENTITY] = SALOME_MED::MED_FACE,
34                    aVisu2MedEntity[VISU::EDGE_ENTITY] = SALOME_MED::MED_EDGE,
35                    aVisu2MedEntity[VISU::NODE_ENTITY] = SALOME_MED::MED_NODE,
36
37                    aMed2VisuEntity[SALOME_MED::MED_CELL] = VISU::CELL_ENTITY,
38                    aMed2VisuEntity[SALOME_MED::MED_FACE] = VISU::FACE_ENTITY,
39                    aMed2VisuEntity[SALOME_MED::MED_EDGE] = VISU::EDGE_ENTITY,
40                    aMed2VisuEntity[SALOME_MED::MED_NODE] = VISU::NODE_ENTITY,
41
42                    1);
43
44 static int CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
45   SALOME_MED::MED_POINT1,
46   SALOME_MED::MED_SEG2,
47   SALOME_MED::MED_SEG3,
48   SALOME_MED::MED_TRIA3,
49   SALOME_MED::MED_QUAD4,
50   SALOME_MED::MED_TRIA6,
51   SALOME_MED::MED_QUAD8,
52   SALOME_MED::MED_TETRA4,
53   SALOME_MED::MED_PYRA5,
54   SALOME_MED::MED_PENTA6,
55   SALOME_MED::MED_TETRA10,
56   SALOME_MED::MED_HEXA8,
57   SALOME_MED::MED_PYRA13,
58   SALOME_MED::MED_PENTA15,
59   SALOME_MED::MED_HEXA20
60 };
61
62 static const int VTKCELLGEOMEND = 8;
63 static int VTKCELLGEOM[VTKCELLGEOMEND] = {
64   SALOME_MED::MED_POINT1,
65   SALOME_MED::MED_SEG2,
66   SALOME_MED::MED_TRIA3,
67   SALOME_MED::MED_QUAD4,
68   SALOME_MED::MED_TETRA4,
69   SALOME_MED::MED_PYRA5,
70   SALOME_MED::MED_PENTA6,
71   SALOME_MED::MED_HEXA8
72 };
73
74 static int FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
75   SALOME_MED::MED_TRIA3,
76   SALOME_MED::MED_QUAD4,
77   SALOME_MED::MED_TRIA6,
78   SALOME_MED::MED_QUAD8
79 };
80
81 static int EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
82   SALOME_MED::MED_SEG2,
83   SALOME_MED::MED_SEG3
84 };
85
86 static int NODEGEOM[1] = {
87   SALOME_MED::MED_POINT1,
88 };
89
90 void GetEntity2Geom(const VISU::TEntity& theEntity, int*& theVector, int* theEnd)
91      throw (std::runtime_error&)
92 {
93   switch(theEntity){
94   case VISU::CELL_ENTITY: theVector = CELLGEOM; *theEnd = MED_NBR_GEOMETRIE_MAILLE; break;
95   case VISU::FACE_ENTITY: theVector = FACEGEOM; *theEnd = MED_NBR_GEOMETRIE_FACE; break;
96   case VISU::EDGE_ENTITY: theVector = EDGEGEOM; *theEnd = MED_NBR_GEOMETRIE_ARETE; break;
97   case VISU::NODE_ENTITY: theVector = NODEGEOM; *theEnd = 1; break;
98   default:
99     throw std::runtime_error("GetEntity2Geom >> theEntity is uncorrect !!!");
100   }
101 }
102
103 struct SalomeMed2vtk {
104   SALOME_MED::medGeometryElement medType;
105   char *medName;
106   int medNbNodes;
107   int vtkType;
108   char *vtkName;
109   int vtkNbNodes;
110 };
111
112 #define CORBAMED2VTK(MEDTYPE,VTKTYPE,VTKNBNODES) \
113  {SALOME_MED::MEDTYPE,#MEDTYPE,getNbMedNodes(MEDTYPE),VTKTYPE,#VTKTYPE,VTKNBNODES}
114 static SalomeMed2vtk salome_med2vtk[SALOME_MED::MED_ALL_ELEMENTS] = {
115   {SALOME_MED::MED_NONE,"MED_NONE",0,VTK_EMPTY_CELL,"VTK_EMPTY_CELL",0},
116   CORBAMED2VTK(MED_POINT1,VTK_VERTEX,1),
117   CORBAMED2VTK(MED_SEG2,VTK_LINE,2),
118   CORBAMED2VTK(MED_SEG3,VTK_LINE,2),
119   CORBAMED2VTK(MED_TRIA3,VTK_TRIANGLE,3),
120   CORBAMED2VTK(MED_QUAD4,VTK_QUAD,4),
121   CORBAMED2VTK(MED_TRIA6,VTK_TRIANGLE,3),
122   CORBAMED2VTK(MED_QUAD8,VTK_QUAD,4),
123   CORBAMED2VTK(MED_TETRA4,VTK_TETRA,4),
124   CORBAMED2VTK(MED_PYRA5,VTK_PYRAMID,5),
125   CORBAMED2VTK(MED_PENTA6,VTK_WEDGE,6),
126   CORBAMED2VTK(MED_TETRA10,VTK_TETRA,4),
127   CORBAMED2VTK(MED_HEXA8,VTK_HEXAHEDRON,8),
128   CORBAMED2VTK(MED_PYRA13,VTK_PYRAMID,5),
129   CORBAMED2VTK(MED_PENTA15,VTK_WEDGE,6),
130   CORBAMED2VTK(MED_HEXA20,VTK_HEXAHEDRON,8)
131 };
132 #undef CORBAMED2VTK
133
134 int GetIdMEDType(int medType){
135   for(int i = 0; i < SALOME_MED::MED_ALL_ELEMENTS; i++)
136     if(salome_med2vtk[i].medType == medType) return i;
137   return -1;
138 }
139
140 string GetName(SALOMEDS::SObject_ptr aSObject){
141   SALOMEDS::GenericAttribute_var anAttr;
142   if (aSObject->FindAttribute(anAttr,"AttributeName")) {
143     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
144     CORBA::String_var aString = aName->Value();
145     return aString.in();
146   }
147   return "";
148 }
149
150 VISU_Convertor* VISU_MEDConvertor::Build() throw (std::runtime_error&){
151   if(mySObject->_is_nil()) 
152     throw std::runtime_error("VISU_MEDConvertor::Build >> mySObject->_is_nil() !!!");
153   myStudy = mySObject->GetStudy();
154   CORBA::Short aTag = mySObject->Tag();
155   SALOMEDS::SObject_var aMedCompSObj = mySObject->GetFather();
156   SALOMEDS::SObject_var aMeshSObj;
157   CORBA::Boolean aBool = aMedCompSObj->FindSubObject(aTag+1,aMeshSObj);
158   if(!aBool) throw std::runtime_error("VISU_MEDConvertor::Build >> Cann't find MEDMESH label !!!");
159   if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - MEDMESH found.");
160   SALOMEDS::ChildIterator_var aMeshIterator = myStudy->NewChildIterator(aMeshSObj);
161   for(; aMeshIterator->More(); aMeshIterator->Next()){
162     aMeshSObj = aMeshIterator->Value();
163     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aMeshSObj = '"<<::GetName(aMeshSObj)<<"'");
164     CORBA::Object_var aMedMesh = SObjectToObject(aMeshSObj);
165     if(CORBA::is_nil(aMedMesh)) continue;
166     SALOME_MED::MESH_var aMEDMesh = SALOME_MED::MESH::_narrow(aMedMesh);
167     if(aMEDMesh->_is_nil()) continue;
168     CORBA::String_var aMeshName = aMEDMesh->getName();
169     VISU::TMesh &aMesh = myMeshMap[aMeshName.in()];
170     aMesh.myDim = aMEDMesh->getSpaceDimension();
171     aMesh.myName = aMeshName.in();
172     VISUMED::TMesh &aMesh2 = myMeshMap2[aMeshName.in()];
173     aMesh2.myMesh = aMEDMesh;
174     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aMeshName = "<<aMeshName<<"; myDim = "<<aMesh.myDim);
175     SALOMEDS::ChildIterator_var aSupportIterator = myStudy->NewChildIterator(aMeshSObj);
176     for(; aSupportIterator->More(); aSupportIterator->Next()){
177       SALOMEDS::SObject_var aSupportSObj = aSupportIterator->Value();
178       CORBA::Object_var aMedSupport = SObjectToObject(aSupportSObj);
179       if(CORBA::is_nil(aMedSupport)) continue;
180       SALOME_MED::SUPPORT_var aMEDSupport = SALOME_MED::SUPPORT::_narrow(aMedSupport); 
181       if(aMEDSupport->_is_nil()) continue;
182       SALOME_MED::medEntityMesh aMEDEntity = aMEDSupport->getEntity();
183       VISU::TEntity anEntity = aMed2VisuEntity[aMEDEntity];
184       CORBA::String_var aSupportName = aMEDSupport->getName();
185       bool isDataPresent = false;
186       if(aMEDSupport->isOnAllElements()){
187         if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - Support isOnAllElements = '"<<aSupportName<<"' anEntity = "<<anEntity);
188         //Check, if there is any data on the support?
189         SALOME_MED::MESH_var aMeshOnSupport = aMEDSupport->getMesh();
190         if(anEntity == VISU::NODE_ENTITY){
191           if(aMeshOnSupport->getNumberOfNodes() > 0) 
192             isDataPresent = true;
193         }else{
194           int iGeomElemEnd;
195           int* aGeomElemVector;
196           GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
197           const SALOME_MED::medEntityMesh& aMedEntity = aVisu2MedEntity[anEntity];
198           for (int iGeomElem = 0, aCounter = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
199             int medId = GetIdMEDType(aGeomElemVector[iGeomElem]);
200             SALOME_MED::medGeometryElement aMedType = salome_med2vtk[medId].medType;
201             med_int iNumElemEnd = aMeshOnSupport->getNumberOfElements(aMedEntity,aMedType);
202             if(iNumElemEnd > 0) {
203               isDataPresent = true;
204               break;
205             }
206           }
207         }
208         if(!isDataPresent) continue;
209         VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
210         aMeshOnEntity.myEntity = anEntity;
211         aMeshOnEntity.myMeshName = aMeshName.in();
212         VISUMED::TMeshOnEntity& aMeshOnEntity2 = aMesh2.myMeshOnEntityMap[anEntity];
213         aMeshOnEntity2.mySupport = aMEDSupport;
214       }else{
215         SALOME_MED::FAMILY_var aMEDFamily = SALOME_MED::FAMILY::_narrow(aMedSupport);
216         if(!aMEDFamily->_is_nil()) {
217           if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aFamily = '"<<aSupportName<<"' anEntity = "<<anEntity);
218           VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
219           VISU::TFamily& aFamily = aMeshOnEntity.myFamilyMap[aSupportName.in()];
220           aFamily.myName = aSupportName.in();
221           aFamily.myEntity = anEntity;
222           aFamily.myId = aMEDFamily->getIdentifier();
223           VISUMED::TMeshOnEntity& aMeshOnEntity2 = aMesh2.myMeshOnEntityMap[anEntity];
224           VISUMED::TFamily& aFamily2 = aMeshOnEntity2.myFamilyMap[aSupportName.in()];
225           aFamily2.myFamily = aMEDFamily;
226         }
227         SALOME_MED::GROUP_var aMEDGroup = SALOME_MED::GROUP::_narrow(aMedSupport);
228         if(!aMEDGroup->_is_nil()) {
229           if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aGroup = '"<<aSupportName<<"' anEntity = "<<anEntity);
230           VISUMED::TGroupMap& aGroupMap2 = aMesh2.myGroupMap;
231           VISUMED::TGroup& aGroup2 = aGroupMap2[aSupportName.in()];
232           aGroup2.myGroup = aMEDGroup;
233           //VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
234           //VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
235           //VISU::TGroup& aGroup = aGroupMap[aSupportName.in()];
236           //aGroup.myName = aSupportName.in();
237           //aGroup.myMeshName = aMesh.myName;
238           SALOME_MED::Family_array_var aFamilies = aMEDGroup->getFamilies();
239           int iFamilyEnd = aFamilies->length();
240           for(int iFamaily = 0; iFamaily < iFamilyEnd; iFamaily++){
241             aMEDFamily = aFamilies[iFamaily];
242             CORBA::String_var aFamilyName = aMEDFamily->getName();
243             VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
244             VISU::TFamily& aFamily = aMeshOnEntity.myFamilyMap[aFamilyName.in()];
245             VISU::TBindGroups& aBindGroups = aFamily.myGroups;
246             aBindGroups.insert(aSupportName.in());
247           }
248         }
249       }
250     }
251     //Correction of TMesh.TGroupMap
252     const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh.myMeshOnEntityMap;
253     if(aMeshOnEntityMap.empty()) continue;
254     VISU::TGroupMap& aGroupMap = aMesh.myGroupMap;
255     VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
256     for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
257       const VISU::TMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
258       const VISU::TFamilyMap& aFamilyMap = aMeshOnEntity.myFamilyMap;
259       if(aFamilyMap.empty()) continue;
260       VISU::TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
261       for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
262         const VISU::TFamily& aFamily = aFamilyMapIter->second;
263         const VISU::TBindGroups& aBindGroups = aFamily.myGroups;
264         if(aBindGroups.empty()) continue;
265         VISU::TBindGroups::const_iterator aBindGroupsIter = aBindGroups.begin();
266         for(; aBindGroupsIter != aBindGroups.end(); aBindGroupsIter++){
267           const string& aGroupName = *aBindGroupsIter;
268           VISU::TGroup& aGroup = aGroupMap[aGroupName];
269           aGroup.myName = aGroupName;
270           aGroup.myMeshName = aMesh.myName;
271           VISU::TFamilyAndEntity aFamilyAndEntity(aFamily.myName,aFamily.myEntity);
272           aGroup.myFamilyAndEntitySet.insert(aFamilyAndEntity);
273         }
274       }
275     }
276   }
277   SALOMEDS::SObject_var aFieldSObj;
278   aBool = aMedCompSObj->FindSubObject(aTag+2,aFieldSObj);
279   if(aBool){
280     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - MEDFIELD found.");
281     SALOMEDS::ChildIterator_var aFieldIterator = myStudy->NewChildIterator(aFieldSObj);
282     for(int iField = 0; aFieldIterator->More(); aFieldIterator->Next(), iField++){
283       aFieldSObj = aFieldIterator->Value();
284       if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aFieldName = '"<<::GetName(aFieldSObj)<<"'");
285       SALOMEDS::ChildIterator_var aTimeStampIterator = myStudy->NewChildIterator(aFieldSObj);
286       for(; aTimeStampIterator->More(); aTimeStampIterator->Next()){
287         SALOMEDS::SObject_var aTimeStampSObj = aTimeStampIterator->Value();
288         if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aTimeStampSObj = '"<<::GetName(aTimeStampSObj)<<"'");
289         CORBA::Object_var aMedField = SObjectToObject(aTimeStampSObj);
290         if(CORBA::is_nil(aMedField)) continue;
291         SALOME_MED::FIELD_var aMEDField = SALOME_MED::FIELD::_narrow(aMedField);
292         if(aMEDField->_is_nil()) continue;
293         SALOME_MED::SUPPORT_var aMEDSupport = aMEDField->getSupport();
294         if(aMEDSupport->_is_nil()) continue;
295         SALOME_MED::medEntityMesh aMEDEntity = aMEDSupport->getEntity();
296         VISU::TEntity anEntity = aMed2VisuEntity[aMEDEntity];
297         SALOME_MED::MESH_var aMEDMesh = aMEDSupport->getMesh();
298         if(aMEDMesh->_is_nil()) continue;
299         CORBA::String_var aMeshName = aMEDMesh->getName();
300         CORBA::String_var aFieldName = aMEDField->getName();
301         VISU::TMesh &aMesh = myMeshMap[aMeshName.in()];
302         VISU::TMeshOnEntity& aMeshOnEntity = aMesh.myMeshOnEntityMap[anEntity];
303         VISU::TField& aField = aMeshOnEntity.myFieldMap[aFieldName.in()];
304         aField.myId = iField;
305         aField.myName = aFieldName.in();
306         aField.myEntity = anEntity;
307         aField.myMeshName = aMeshName.in();
308         aField.myNbComp = aMEDField->getNumberOfComponents();
309         //int iTimeStamp = aMEDField->getOrderNumber();
310         int iTimeStamp = aMEDField->getIterationNumber();
311         VISU::TField::TValForTime& aValForTime = aField.myValField[iTimeStamp];
312         aValForTime.myId = iTimeStamp;
313         double dt = aMEDField->getTime();
314         aValForTime.myTime = VISU::TField::TTime(dt,"");
315         VISUMED::TMesh &aMesh2 = myMeshMap2[aMeshName.in()];
316         VISUMED::TMeshOnEntity& aMeshOnEntity2 = aMesh2.myMeshOnEntityMap[anEntity];
317         VISUMED::TField& aField2 = aMeshOnEntity2.myFieldMap[aFieldName.in()];
318         VISUMED::TField::TValForTime& aValForTime2 = aField2.myValField[iTimeStamp];
319         aValForTime2.myField = aMEDField;
320         if(MYDEBUG) 
321           MESSAGE("VISU_MEDConvertor::Build - aMeshName = '"<<aMeshName<<"'; myEntity = "<<anEntity<<"; myTime = "<<dt);
322       }      
323     }
324   }
325   return this; 
326 }
327
328 int VISU_MEDConvertor::LoadMeshOnEntity(VISU::TMeshOnEntity& theMeshOnEntity, 
329                                         const string& theFamilyName)
330      throw (std::runtime_error&) 
331 {
332   //Main part of code
333   const string& aMeshName = theMeshOnEntity.myMeshName;
334   const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
335   VISU::TMesh& aMesh = myMeshMap[aMeshName];
336   int isPointsUpdated;
337   if(anEntity == VISU::NODE_ENTITY) 
338     isPointsUpdated = LoadPoints(aMesh,theFamilyName);
339   else 
340     isPointsUpdated = LoadPoints(aMesh);
341   int isCellsOnEntityUpdated = LoadCellsOnEntity(theMeshOnEntity,theFamilyName);
342
343   return (isPointsUpdated || isCellsOnEntityUpdated);
344 }
345   
346 int VISU_MEDConvertor::LoadMeshOnGroup(VISU::TMesh& theMesh, 
347                                        const VISU::TFamilyAndEntitySet& theFamilyAndEntitySet)
348      throw (std::runtime_error&)
349 {
350   //Main part of code
351   int isPointsUpdated = 0;
352   int isCellsOnEntityUpdated = 0;
353   VISU::TFamilyAndEntitySet::const_iterator aFamilyAndEntitySetIter = theFamilyAndEntitySet.begin();
354   for(; aFamilyAndEntitySetIter != theFamilyAndEntitySet.end(); aFamilyAndEntitySetIter++){
355     const string& aFamilyName = aFamilyAndEntitySetIter->first;
356     const VISU::TEntity& anEntity = aFamilyAndEntitySetIter->second;
357     VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[anEntity];
358     if(anEntity == VISU::NODE_ENTITY){
359       isPointsUpdated += LoadPoints(theMesh,aFamilyName);
360       isCellsOnEntityUpdated += LoadCellsOnEntity(aMeshOnEntity);
361     }else{
362       isPointsUpdated += LoadPoints(theMesh);
363       isCellsOnEntityUpdated += LoadCellsOnEntity(aMeshOnEntity,aFamilyName);
364     }
365   }
366
367   return (isPointsUpdated || isCellsOnEntityUpdated);
368 }
369
370 int VISU_MEDConvertor::LoadFieldOnMesh(VISU::TMesh& theMesh, 
371                                        VISU::TMeshOnEntity& theMeshOnEntity, 
372                                        VISU::TField& theField, 
373                                        VISU::TField::TValForTime& theValForTime)
374   throw (std::runtime_error&)
375 {
376   //Main part of code
377   int isPointsUpdated = LoadPoints(theMesh);
378   int isCellsOnEntityUpdated = LoadCellsOnEntity(theMeshOnEntity);
379   int isFieldUpdated = LoadField(theMeshOnEntity,theField,theValForTime);
380   
381   return (isPointsUpdated || isCellsOnEntityUpdated || isFieldUpdated);
382 }
383
384 int VISU_MEDConvertor::LoadPoints(VISU::TMesh& theMesh, const string& theFamilyName)
385   throw (std::runtime_error&) 
386 {
387   //Check on existing family
388   VISU::TMeshOnEntity& aMeshOnEntity = theMesh.myMeshOnEntityMap[VISU::NODE_ENTITY];
389   aMeshOnEntity.myEntity = VISU::NODE_ENTITY;
390   aMeshOnEntity.myMeshName = theMesh.myName;
391   VISU::TFamily* pFamily = VISU::GetFamily(aMeshOnEntity,theFamilyName);
392   bool isFamilyPresent = (pFamily != NULL);
393   VISU::TFamily& aFamily = *pFamily;
394   //Check on loading already done
395   bool isPointsLoaded = !theMesh.myPointsCoord.empty();
396   if(isPointsLoaded) 
397     if(!isFamilyPresent) return 0;
398     else if(!aFamily.mySubMesh.empty()) return 0;
399   VISUMED::TMesh& aMesh2 = myMeshMap2[theMesh.myName];
400   SALOME_MED::MESH_var& aMedMesh = aMesh2.myMesh;
401   VISUMED::TMeshOnEntity& aMeshOnEntity2 = aMesh2.myMeshOnEntityMap[VISU::NODE_ENTITY];
402   if(MYDEBUG) 
403     MESSAGE("LoadPoints - isPointsLoaded = "<<isPointsLoaded<<"; theFamilyName = '"<<theFamilyName<<"'");
404   theMesh.myDim = aMedMesh->getSpaceDimension();
405   int iNumElemEnd = aMedMesh->getNumberOfNodes();
406   VISU::TMesh::TPointsCoord& aPointsCoord = theMesh.myPointsCoord;
407   if(MYDEBUG) MESSAGE("LoadPoints - iNumElemEnd = "<<iNumElemEnd);
408   if (iNumElemEnd <= 0) throw std::runtime_error("LoadPoints >> There is no points in the mesh !!!");
409   aPointsCoord.resize(theMesh.myDim*iNumElemEnd,0.0);
410   Engines::double_array_var coord = aMedMesh->getCoordinates(SALOME_MED::MED_FULL_INTERLACE);
411   if(!isPointsLoaded){
412     for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) 
413       for(int iDim = 0, iNumElem2Dim = iNumElem*theMesh.myDim; iDim < theMesh.myDim; iDim++, iNumElem2Dim++)
414         aPointsCoord[iNumElem2Dim] = coord[iNumElem2Dim];
415     if(MYDEBUG) MESSAGE("LoadPoints - Filling aMeshOnEntity with type NODE_ENTITY");
416     VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = aMeshOnEntity.myCellsConn[VTK_VERTEX];
417     aConnForCellType.resize(iNumElemEnd);
418     for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
419       aConnForCellType[iNumElem] = VISU::TMeshOnEntity::TConnect(1,iNumElem);
420   }
421   if(isFamilyPresent){
422     if(MYDEBUG) MESSAGE("LoadPoints - Filling aFamily SubMesh");
423     VISUMED::TFamily aFamily2 = aMeshOnEntity2.myFamilyMap[aFamily.myName];
424     SALOME_MED::FAMILY_var aMedFamily = aFamily2.myFamily;
425     VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[VTK_VERTEX];
426     SALOME_MED::medGeometryElement_array_var aGeom = aMedFamily->getTypes();
427     Engines::long_array_var aCellNumForType = aMedFamily->getNumber(aGeom[0]);
428     int iNumElemEndTmp = iNumElemEnd;
429     iNumElemEnd = aCellNumForType->length();
430     for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) {
431       int tmp = aCellNumForType[iNumElem]-1;
432       if(0 > tmp || tmp >= iNumElemEndTmp) {
433         static QString aString;
434         aString.sprintf("LoadPoints >> iNumElemEndTmp(%d) <= aCellNumForType[%d]=%d < 0 !!!",iNumElemEnd,iNumElem,tmp);
435         throw std::runtime_error(aString.latin1());
436       }
437       aSubMeshOnCellType.insert(tmp);
438     }
439   }
440   return 1;
441 }
442
443 int VISU_MEDConvertor::LoadCellsOnEntity(VISU::TMeshOnEntity& theMeshOnEntity, const string& theFamilyName)
444      throw (std::runtime_error&) 
445 {
446   //Check on existing family
447   VISU::TFamily* pFamily = VISU::GetFamily(theMeshOnEntity,theFamilyName);
448   bool isFamilyPresent = (pFamily != NULL);
449   VISU::TFamily& aFamily = *pFamily;
450   //Check on loading already done
451   bool isCellsLoaded = !theMeshOnEntity.myCellsConn.empty();
452   if(isCellsLoaded) 
453     if(!isFamilyPresent) return 0;
454     else if(!aFamily.mySubMesh.empty()) return 0;
455   VISUMED::TMesh& aMesh2 = myMeshMap2[theMeshOnEntity.myMeshName];
456   VISUMED::TMeshOnEntity& aMeshOnEntity2 = aMesh2.myMeshOnEntityMap[theMeshOnEntity.myEntity];
457   SALOME_MED::SUPPORT_var& aMedSupport = aMeshOnEntity2.mySupport;
458   SALOME_MED::MESH_var aMedMesh = aMedSupport->getMesh();
459   if(MYDEBUG) {
460     MESSAGE("LoadCellsOnEntity - theFamilyName = '"<<theFamilyName<<"'");
461     MESSAGE("LoadCellsOnEntity - isCellsLoaded = "<<isCellsLoaded<<"; isFamilyPresent = "<<isFamilyPresent);
462   }
463   //Main part of code
464   int iGeomElemEnd;
465   int* aGeomElemVector;
466   const VISU::TEntity& anEntity = theMeshOnEntity.myEntity;
467   GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
468   const SALOME_MED::medEntityMesh& aMedEntity = aVisu2MedEntity[anEntity];
469   VISU::TMesh &aMesh = myMeshMap[theMeshOnEntity.myMeshName];
470   int aNbPoints = aMesh.myPointsCoord.size()/aMesh.myDim;
471   if(!isCellsLoaded){
472     for (int iGeomElem = 0, aCounter = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
473       int medId = GetIdMEDType(aGeomElemVector[iGeomElem]);
474       int nbMedNodes = salome_med2vtk[medId].medNbNodes;
475       int nbVtkNodes = salome_med2vtk[medId].vtkNbNodes;
476       int aVtkType = salome_med2vtk[medId].vtkType;
477       SALOME_MED::medGeometryElement aMedType = salome_med2vtk[medId].medType;
478       med_int iNumElemEnd = aMedMesh->getNumberOfElements(aMedEntity,aMedType);
479       if (iNumElemEnd > 0) {
480         Engines::long_array_var conn = 
481           aMedMesh->getConnectivity(SALOME_MED::MED_FULL_INTERLACE,SALOME_MED::MED_NODAL,aMedEntity,aMedType);
482         VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = theMeshOnEntity.myCellsConn[aVtkType];
483         //APO - aConnForCellType.resize(iNumElemEnd);
484         valarray<med_int> aConnect(nbMedNodes);
485         int aNbConnForElem = conn->length()/iNumElemEnd;
486         if(MYDEBUG) MESSAGE("LoadCellsOnEntity - medName = "<<salome_med2vtk[medId].medName<<
487                             "; iNumElemEnd = "<<iNumElemEnd<<"; aNbConnForElem = "<<aNbConnForElem);
488         for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) {
489           //APO - VISU::TMeshOnEntity::TConnect& anArray = aConnForCellType[iNumElem];
490           //APO - anArray.resize(nbVtkNodes);
491           VISU::TMeshOnEntity::TConnect anArray(nbVtkNodes);
492           for (int k = 0, kj = iNumElem*aNbConnForElem; k < nbMedNodes; k++) {
493             aConnect[k] = conn[kj+k] - 1;
494           }
495           switch(aMedType){
496           case SALOME_MED::MED_TETRA4 :
497           case SALOME_MED::MED_TETRA10 :
498             anArray[0] = aConnect[0];
499             anArray[1] = aConnect[1];
500             anArray[2] = aConnect[3];  
501             anArray[3] = aConnect[2];  
502             break;
503           case SALOME_MED::MED_PYRA5 :
504           case SALOME_MED::MED_PYRA13 :
505             anArray[0] = aConnect[0];
506             anArray[1] = aConnect[3];  
507             anArray[2] = aConnect[2];
508             anArray[3] = aConnect[1];  
509             anArray[4] = aConnect[4];
510             break;
511           default:
512             for (int k = 0; k < nbVtkNodes; k++) 
513               anArray[k] = aConnect[k];
514           }
515           for (int k = 0; k < nbVtkNodes; k++) 
516             if(anArray[k] < 0 || aNbPoints <= anArray[k]){
517               static QString aString;
518               aString.sprintf("ImportCells >> aNbPoints(%d) <= anArray[%d][%d]=%d < 0 !!!",aNbPoints,iNumElem,k,anArray[k]);
519               throw std::runtime_error(aString.latin1());
520             }
521           aConnForCellType.push_back(anArray);
522         }
523         //Workaround for MED Component data structure
524         int aSize = aConnForCellType.size();
525         aMeshOnEntity2.myCellsFirstIndex[aMedType] = VISUMED::TMeshOnEntity::TIndexAndSize(aCounter,aSize);
526         aCounter += aSize;
527       }
528     }
529   }
530   //Filling aFamily SubMesh
531   if(isFamilyPresent){
532     VISUMED::TFamily aFamily2 = aMeshOnEntity2.myFamilyMap[aFamily.myName];
533     SALOME_MED::FAMILY_var aMedFamily = aFamily2.myFamily;
534     SALOME_MED::medGeometryElement_array_var aGeom = aMedFamily->getTypes();
535     iGeomElemEnd = aGeom->length();
536     if(MYDEBUG) MESSAGE("LoadCellsOnEntity - iGeomElemEnd = "<<iGeomElemEnd);
537     for (int iGeomElem = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
538       SALOME_MED::medGeometryElement aGeomType = aGeom[iGeomElem];
539       Engines::long_array_var aCellNumForType = aMedFamily->getNumber(aGeomType);
540       int medId = GetIdMEDType(aGeomType);
541       int aVtkType = salome_med2vtk[medId].vtkType;
542       SALOME_MED::medGeometryElement aMedType = salome_med2vtk[medId].medType;
543       VISU::TFamily::TSubMeshOnCellType& aSubMeshOnCellType = aFamily.mySubMesh[aVtkType]; 
544       med_int iNumElemEndTmp = theMeshOnEntity.myCellsConn[aVtkType].size();
545       med_int iNumElemEnd = aCellNumForType->length();
546       int aCounter = aMeshOnEntity2.myCellsFirstIndex[aMedType].first;
547       if(MYDEBUG) 
548         MESSAGE("LoadCellsOnEntity - medName = "<<salome_med2vtk[medId].medName<<
549                 "; iNumElemEnd = "<<iNumElemEnd<<"; aCounter = "<<aCounter);
550       for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) {
551         int tmp = aCellNumForType[iNumElem]-aCounter-1;
552         if(0 > tmp || tmp >= iNumElemEndTmp) {
553           static QString aString;
554           aString.sprintf("LoadCellsOnEntity >> iNumElemEndTmp(%d) <= aCellNumForType[%d]=%d < 0 !!!",iNumElemEndTmp,iNumElem,tmp);
555           throw std::runtime_error(aString.latin1());
556         }
557         aSubMeshOnCellType.insert(tmp);
558       }
559     }
560   }
561   return 1;
562 }
563
564 template<class TArray> int ImportField(TArray& theArray, 
565                                        const VISU::TMesh& theMesh,
566                                        const VISU::TField& theField,
567                                        VISU::TField::TValForTime& theValForTime,
568                                        const VISU::TMeshOnEntity& theMeshOnEntity,
569                                        const VISUMED::TMeshOnEntity& theMeshOnEntity2)
570 {
571   if(theField.myEntity == VISU::NODE_ENTITY){
572     VISU::TField::TValForCellsWithType& aValForCellsWithType = theValForTime.myValForCells[VTK_VERTEX];
573     int iNumElemEnd = theMesh.myPointsCoord.size()/theMesh.myDim*theField.myNbComp;
574     if(MYDEBUG) MESSAGE("ImportField - iNumElemEnd = "<<iNumElemEnd);
575     aValForCellsWithType.resize(iNumElemEnd);
576     for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++) 
577       aValForCellsWithType[iNumElem] = theArray[iNumElem];
578   }else{
579     int iGeomElemEnd;
580     int* aGeomElemVector;
581     const VISU::TEntity& anEntity = theField.myEntity;
582     GetEntity2Geom(anEntity,aGeomElemVector,&iGeomElemEnd);
583     for (int iGeomElem = 0, aCounter = 0; iGeomElem < iGeomElemEnd; iGeomElem++) {
584       int medId = GetIdMEDType(aGeomElemVector[iGeomElem]);
585       int aVtkType = salome_med2vtk[medId].vtkType;
586       SALOME_MED::medGeometryElement aMedType = salome_med2vtk[medId].medType;
587       const VISUMED::TMeshOnEntity::TCellsFirstIndex& aCellsFirstIndex = theMeshOnEntity2.myCellsFirstIndex;
588       VISUMED::TMeshOnEntity::TCellsFirstIndex::const_iterator aCellsFirstIndexIter = aCellsFirstIndex.find(aMedType);
589       if(aCellsFirstIndexIter != aCellsFirstIndex.end()){
590         const VISU::TMeshOnEntity::TCellsConn& aCellsConn = theMeshOnEntity.myCellsConn;
591         VISU::TMeshOnEntity::TCellsConn::const_iterator aCellsConnIter = aCellsConn.find(aVtkType);
592         const VISU::TMeshOnEntity::TConnForCellType& aConnForCellType = aCellsConnIter->second;
593         const VISUMED::TMeshOnEntity::TIndexAndSize& aIndexAndSize = aCellsFirstIndexIter->second;
594         int iNumElemEnd = aIndexAndSize.second;
595         if(MYDEBUG) 
596           MESSAGE("ImportField - medName = "<<salome_med2vtk[medId].medName<<
597                   "; aIndexAndSize = {"<<aIndexAndSize.first<<","<<aIndexAndSize.second<<"}");
598         VISU::TField::TValForCellsWithType& aValForCellsWithType = theValForTime.myValForCells[aVtkType];
599         aValForCellsWithType.resize(iNumElemEnd*theField.myNbComp);
600         for (int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
601           for (int k = 0, kj = iNumElem*theField.myNbComp; k < theField.myNbComp; k++)
602             aValForCellsWithType[kj+k] = theArray[aIndexAndSize.first*theField.myNbComp+kj+k];
603       }
604     }
605   }
606   return 1;
607 }
608
609 int VISU_MEDConvertor::LoadField(const VISU::TMeshOnEntity& theMeshOnEntity,
610                                  const VISU::TField& theField, VISU::TField::TValForTime& theValForTime)
611      throw (std::runtime_error&)
612 {
613   //Check on loading already done
614   if(!theValForTime.myValForCells.empty()) return 0;
615   VISU::TMesh& aMesh = myMeshMap[theMeshOnEntity.myMeshName];
616   VISUMED::TMesh& aMesh2 = myMeshMap2[theMeshOnEntity.myMeshName];
617   VISUMED::TMeshOnEntity& aMeshOnEntity2 = aMesh2.myMeshOnEntityMap[theMeshOnEntity.myEntity];
618   VISUMED::TField& aField2 = aMeshOnEntity2.myFieldMap[theField.myName];
619   VISUMED::TField::TValForTime& aValForTime2 = aField2.myValField[theValForTime.myId];
620   SALOME_MED::FIELD_var aMEDField = aValForTime2.myField;
621   //Main part of code
622   SALOME_MED::FIELDDOUBLE_ptr aFieldDouble = SALOME_MED::FIELDDOUBLE::_narrow(aMEDField);
623   if(!aFieldDouble->_is_nil()){
624     Engines::double_array_var anArray = aFieldDouble->getValue(SALOME_MED::MED_FULL_INTERLACE);
625     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::LoadField - There is FIELDDOUBLE = "<<anArray->length());
626     ::ImportField(anArray,aMesh,theField,theValForTime,theMeshOnEntity,aMeshOnEntity2);
627   }
628   SALOME_MED::FIELDINT_ptr aFieldInt = SALOME_MED::FIELDINT::_narrow(aMEDField);
629   if(!aFieldInt->_is_nil()){
630     Engines::long_array_var anArray = aFieldInt->getValue(SALOME_MED::MED_FULL_INTERLACE);
631     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::LoadField - There is FIELDINT = "<<anArray->length());
632     ::ImportField(anArray,aMesh,theField,theValForTime,theMeshOnEntity,aMeshOnEntity2);
633   }
634   return 1;
635 }