Salome HOME
e69db1a8827bd8e2d5f20e440f98a04835c2792c
[modules/visu.git] / src / VISU_I / VISU_CorbaMedConvertor.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : VISU_CorbaMedConvertor.cxx
25 //  Author : Alexey PETROV
26 //  Module : VISU
27 //  $Header$
28 //  Copyright (C) 2003  CEA/DEN, EDF R&D
29
30 #include "VISU_CorbaMedConvertor.hxx"
31
32 #include <vtkCellType.h>
33
34 #include <boost/tuple/tuple.hpp>
35
36 using namespace std;
37 using namespace VISU;
38
39 #define USER_INTERLACE MED_FULL_INTERLACE
40
41 #ifdef _DEBUG_
42 static int MYDEBUG = 0;
43 #else
44 static int MYDEBUG = 0;
45 #endif
46
47 extern "C" {
48   VISU_Convertor* 
49   CreateMEDConvertor(SALOMEDS::SObject_ptr theMedSObject) 
50   {
51     return new VISU_MEDConvertor(theMedSObject);
52   }
53
54   VISU_Convertor* 
55   CreateMEDFieldConvertor(SALOME_MED::FIELD_ptr theField) 
56   {
57     return new VISU_MEDFieldConvertor(theField);
58   }
59 }
60
61 namespace
62 {
63   using namespace SALOME_MED;
64   
65   const int MED_NBR_GEOMETRIE_MAILLE = 15;
66   
67   medGeometryElement 
68   CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
69     MED_POINT1,
70     MED_SEG2,
71     MED_SEG3,
72     MED_TRIA3,
73     MED_QUAD4,
74     MED_TRIA6,
75     MED_QUAD8,
76     MED_TETRA4,
77     MED_PYRA5,
78     MED_PENTA6,
79     MED_HEXA8,
80     MED_TETRA10,
81     MED_PYRA13,
82     MED_PENTA15,
83     MED_HEXA20
84   };
85   
86   const int MED_NBR_GEOMETRIE_FACE = 4;
87   
88   medGeometryElement
89   FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
90     MED_TRIA3,
91     MED_QUAD4,
92     MED_TRIA6,
93     MED_QUAD8
94   };
95   
96   const int MED_NBR_GEOMETRIE_ARETE = 2;
97   
98   medGeometryElement
99   EDGEGEOM[MED_NBR_GEOMETRIE_ARETE] = {
100     MED_SEG2,
101     MED_SEG3
102   };
103   
104   const int MED_NBR_GEOMETRIE_NODE = 1;
105   
106   medGeometryElement
107   NODEGEOM[MED_NBR_GEOMETRIE_NODE] = {
108     MED_POINT1,
109   };
110   
111
112   //---------------------------------------------------------------
113   int
114   GetEntity2Geom(const VISU::TEntity& theEntity, medGeometryElement*& theVector)
115   {
116     switch(theEntity){
117     case CELL_ENTITY: theVector = CELLGEOM; return MED_NBR_GEOMETRIE_MAILLE; break;
118     case FACE_ENTITY: theVector = FACEGEOM; return MED_NBR_GEOMETRIE_FACE; break;
119     case EDGE_ENTITY: theVector = EDGEGEOM; return MED_NBR_GEOMETRIE_ARETE; break;
120     case NODE_ENTITY: theVector = NODEGEOM; return MED_NBR_GEOMETRIE_NODE; break;
121     }
122     return -1;
123   }
124   
125
126   //---------------------------------------------------------------
127   int
128   MEDGeom2NbNodes(int theMEDGeomType)
129   { 
130     switch(theMEDGeomType){
131     case MED_NONE: return 0;
132     case MED_POINT1: return 1;
133     case MED_SEG2: return 2;
134     case MED_SEG3: return 3;
135     case MED_TRIA3: return 3;
136     case MED_TRIA6: return 6;
137     case MED_QUAD4: return 4;
138     case MED_QUAD8: return 8;
139     case MED_TETRA4: return 4;
140     case MED_TETRA10: return 10;
141     case MED_HEXA8: return 8;
142     case MED_HEXA20: return 20;
143     case MED_PENTA6: return 6;
144     case MED_PENTA15: return 15;
145     case MED_PYRA5: return 5;
146     case MED_PYRA13: return 13;
147     }
148     return -1;
149   }
150   
151
152   //---------------------------------------------------------------
153   VISU::EGeometry
154   MEDGeom2VISU(medGeometryElement theGeom)
155   { 
156     switch(theGeom){
157     case MED_POINT1: return VISU::ePOINT1;
158     case MED_SEG2: return VISU::eSEG2;
159     case MED_SEG3: return VISU::eSEG3;
160     case MED_TRIA3: return VISU::eTRIA3;
161     case MED_TRIA6: return VISU::eTRIA6;
162     case MED_QUAD4: return VISU::eQUAD4;
163     case MED_QUAD8: return VISU::eQUAD8;
164     case MED_TETRA4: return VISU::eTETRA4;
165     case MED_TETRA10: return VISU::eTETRA10;
166     case MED_HEXA8: return VISU::eHEXA8;
167     case MED_HEXA20: return VISU::eHEXA20;
168     case MED_PENTA6: return VISU::ePENTA6;
169     case MED_PENTA15: return VISU::ePENTA15;
170     case MED_PYRA5: return VISU::ePYRA5;
171     case MED_PYRA13: return VISU::ePYRA13;
172     }
173     return VISU::eNONE;
174   }
175   
176
177   //---------------------------------------------------------------
178   medGeometryElement 
179   VTKGeomToMED(int theVTKGeomType)
180   { 
181     switch(theVTKGeomType){
182     case VTK_VERTEX: return MED_POINT1;
183     case VTK_LINE: return MED_SEG2;
184     case VTK_TRIANGLE: return MED_TRIA3;
185     case VTK_QUAD: return MED_QUAD4;
186     case VTK_TETRA: return MED_TETRA4;
187     case VTK_HEXAHEDRON: return MED_HEXA8;
188     case VTK_WEDGE: return MED_PENTA6;
189     case VTK_PYRAMID: return MED_PYRA5;
190     }
191     return medGeometryElement(-1);
192   }
193   
194   //---------------------------------------------------------------
195   VISU::TEntity
196   MEDEntityToVTK(medEntityMesh theMEDEntity)
197   {
198     switch(theMEDEntity){
199     case MED_NODE: return NODE_ENTITY;
200     case MED_EDGE: return EDGE_ENTITY;
201     case MED_FACE: return FACE_ENTITY;
202     case MED_CELL: return CELL_ENTITY;
203     }
204     return VISU::TEntity(-1);
205   }
206   
207   //---------------------------------------------------------------
208   medEntityMesh 
209   VTKEntityToMED(VISU::TEntity theVTKEntity)
210   {
211     switch(theVTKEntity){
212     case NODE_ENTITY: return MED_NODE;
213     case EDGE_ENTITY: return MED_EDGE;
214     case FACE_ENTITY: return MED_FACE;
215     case CELL_ENTITY: return MED_CELL;
216     }
217     return medEntityMesh(-1);
218   }
219
220   
221   //---------------------------------------------------------------
222   std::string 
223   GetSObjectName(SALOMEDS::SObject_ptr aSObject)
224   {
225     SALOMEDS::GenericAttribute_var anAttr;
226     if (aSObject->FindAttribute(anAttr,"AttributeName")) {
227       SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
228       CORBA::String_var aString = aName->Value();
229       return aString.in();
230     }
231     return "";
232   }
233   
234
235   //---------------------------------------------------------------
236   void 
237   GetCellsSize(vtkIdType& theNbCells, 
238                vtkIdType& theCellsSize,
239                SALOME_MED::MESH_ptr theMEDMesh,
240                const VISU::TEntity& theVEntity)
241   {
242     medGeometryElement* aGeomElems;
243     theNbCells = theCellsSize = 0;
244     int iGeomEnd = GetEntity2Geom(theVEntity,aGeomElems);
245     const medEntityMesh& aMEntity = VTKEntityToMED(theVEntity);
246     if(MYDEBUG) MESSAGE("GetCellsSize - theVEntity = "<<theVEntity);
247     for(int iGeom = 0; iGeom < iGeomEnd; iGeom++){
248       medGeometryElement aMEDGeom = aGeomElems[iGeom];
249       int iNumElemEnd = theMEDMesh->getNumberOfElements(aMEntity,aMEDGeom);
250       if(iNumElemEnd > 0){
251         if(MYDEBUG) MESSAGE("GetCellsSize - iNumElemEnd = "<<iNumElemEnd);
252         theCellsSize += iNumElemEnd*(MEDGeom2NbNodes(aMEDGeom) + 1);
253         theNbCells += iNumElemEnd;
254       }
255     }
256   }
257   
258   
259   //---------------------------------------------------------------
260   void 
261   GetCellsSize(vtkIdType& theNbCells, 
262                vtkIdType& theCellsSize,
263                SALOME_MED::FAMILY_ptr theMEDFamily)
264   {
265     medGeometryElement_array_var aGeom = theMEDFamily->getTypes();
266     int iGeomEnd = aGeom->length();
267     theNbCells = theCellsSize = 0;
268     if(MYDEBUG) MESSAGE("GetCellsSize - iGeomEnd = "<<iGeomEnd);
269     for(int iGeom = 0; iGeom < iGeomEnd; iGeom++) {
270       medGeometryElement aMEDGeom = aGeom[iGeom];
271       long_array_var aCellNumForType = theMEDFamily->getNumber(aMEDGeom);
272       int iNumElemEnd = aCellNumForType->length();
273       if(iNumElemEnd > 0){
274         if(MYDEBUG) MESSAGE("GetCellsSize - iNumElemEnd = "<<iNumElemEnd);
275         theNbCells += iNumElemEnd;
276         theCellsSize += iNumElemEnd*(MEDGeom2NbNodes(aMEDGeom) + 1);
277       }
278     }
279   }
280   
281   
282   //---------------------------------------------------------------
283   void
284   GetCellsSize(VISU::PCMesh theMesh, 
285                SALOME_MED::MESH_ptr theMEDMesh, 
286                const VISU::TEntity& theEntity)
287   {
288     TMeshOnEntityMap& aMeshOnEntityMap = theMesh->myMeshOnEntityMap;
289     VISU::PCMeshOnEntity aMeshOnEntity = aMeshOnEntityMap[theEntity];
290     if(theEntity == NODE_ENTITY){
291       aMeshOnEntity->myNbCells = theMesh->myNbPoints;
292       aMeshOnEntity->myCellsSize = 2*theMesh->myNbPoints;
293     }else{
294       GetCellsSize(aMeshOnEntity->myNbCells,aMeshOnEntity->myCellsSize,theMEDMesh,theEntity);
295     }
296   }
297  
298
299   //---------------------------------------------------------------
300   PCMeshOnEntity 
301   InitMeshOnEntity(const VISU::PCMesh& theMesh,
302                    const VISU::TEntity& theEntity,
303                    const VISU::PCMeshOnEntity& theMeshOnEntity)
304   {
305     PCMeshOnEntity aMeshOnEntity;
306     TMeshOnEntityMap& aMeshOnEntityMap = theMesh->myMeshOnEntityMap;
307     TMeshOnEntityMap::const_iterator anIter = aMeshOnEntityMap.find(theEntity);
308     if(anIter == aMeshOnEntityMap.end()){
309       aMeshOnEntity.reset(new TCMeshOnEntity());
310       *aMeshOnEntity = *theMeshOnEntity;
311       aMeshOnEntity->myEntity = theEntity;
312       aMeshOnEntityMap[theEntity] = aMeshOnEntity;
313     }else
314       aMeshOnEntity = anIter->second;
315
316     GetCellsSize(theMesh,theMesh->myMesh,theEntity);
317
318     return aMeshOnEntity;
319   }
320  
321 }
322
323
324 //---------------------------------------------------------------
325 VISU_Convertor* 
326 VISU_MEDFieldConvertor::Build()
327 {
328   if(myField->_is_nil()) 
329     throw std::runtime_error("VISU_MEDFieldConvertor::Build >> myField->_is_nil() !!!");
330   
331   SALOME_MED::SUPPORT_var aMEDSupport = myField->getSupport();
332   if(aMEDSupport->_is_nil()) 
333     throw std::runtime_error("VISU_MEDFieldConvertor::Build >> aMEDSupport->_is_nil() !!!");
334
335   SALOME_MED::medEntityMesh aMEntity = aMEDSupport->getEntity();
336   TEntity aVEntity = MEDEntityToVTK(aMEntity);
337   SALOME_MED::MESH_var aMEDMesh = aMEDSupport->getMesh();
338   if(aMEDMesh->_is_nil()) 
339     throw std::runtime_error("VISU_MEDFieldConvertor::Build >> aMEDMesh->_is_nil() !!!");
340
341   CORBA::String_var aMeshName = aMEDMesh->getName();
342   CORBA::String_var aFieldName = myField->getName();
343
344   PCMesh aMesh = myMeshMap[aMeshName.in()](new TCMesh());
345   aMesh->myNamedPointCoords(new TNamedPointCoords());
346   aMesh->myNbPoints = aMEDMesh->getNumberOfNodes();
347   aMesh->myDim = aMEDMesh->getSpaceDimension();
348   aMesh->myName = aMeshName.in();
349   aMesh->myMesh = aMEDMesh;
350
351   TNamedPointCoords& aCoords = aMesh->myNamedPointCoords;
352   aCoords.Init(aMesh->myNbPoints,aMesh->myDim);
353
354   if(MYDEBUG) MESSAGE("VISU_MEDFieldConvertor::Build - aMeshName = "<<aMeshName<<"; myDim = "<<aMesh->myDim);
355
356   TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
357   PCMeshOnEntity aMeshOnEntity = aMeshOnEntityMap[aVEntity](new TCMeshOnEntity());
358   aMeshOnEntity->myEntity = aVEntity;
359   aMeshOnEntity->myMeshName = aMeshName.in();
360   aMeshOnEntity->mySupport = aMEDSupport;
361
362   if(aVEntity == NODE_ENTITY)
363     ::InitMeshOnEntity(aMesh,CELL_ENTITY,aMeshOnEntity);
364   else
365     ::InitMeshOnEntity(aMesh,NODE_ENTITY,aMeshOnEntity);
366
367   ::GetCellsSize(aMesh,aMEDMesh,aVEntity);
368
369   TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
370   PCField aField = aFieldMap[aFieldName.in()](new TCField());
371   aField->myId = myField->getOrderNumber();
372   aField->myName = aFieldName.in();
373   aField->myEntity = aVEntity;
374   aField->myMeshName = aMeshName.in();
375   aField->InitArrays(myField->getNumberOfComponents());
376   aField->myDataSize = aMeshOnEntity->myNbCells * aField->myNbComp;
377
378   if(MYDEBUG) MESSAGE("VISU_MEDFieldConvertor::Build - aMeshName = "<<aMeshName<<"; myDim = "<<aMesh->myDim);
379
380   TValField& aValField = aField->myValField;
381   int anId = myField->getIterationNumber();
382   PCValForTime aValForTime = aValField[anId](new TCValForTime());
383   aValForTime->myId = anId;
384   CORBA::Double aDT = myField->getTime();
385   aValForTime->myTime = TTime(aDT,"");
386   aValForTime->myField = myField;
387
388   if(MYDEBUG) 
389     MESSAGE("VISU_MEDFieldConvertor::Build - aFieldName = '"<<aFieldName<<
390             "'; myId = "<<anId<<"; myTime = "<<aDT);
391
392   return this;
393 }
394
395
396 //---------------------------------------------------------------
397 VISU_Convertor* 
398 VISU_MEDConvertor::Build() 
399 {
400   if(mySObject->_is_nil()) 
401     throw std::runtime_error("VISU_MEDConvertor::Build >> mySObject->_is_nil() !!!");
402   SALOMEDS::Study_var aStudy = mySObject->GetStudy();
403
404   CORBA::Object_var aMedObject = VISU::SObjectToObject(mySObject);
405   if(!CORBA::is_nil(aMedObject)){
406     SALOME_MED::MED_var aMED = SALOME_MED::MED::_narrow(aMedObject);
407     return Build(aMED);
408   }
409
410   SALOMEDS::ChildIterator_var aTimeStampIterator = aStudy->NewChildIterator(mySObject);
411   return Build(aTimeStampIterator);
412 }
413
414
415 namespace{
416
417   using namespace boost;
418
419   //---------------------------------------------------------------
420   struct TSObjectByName
421   {
422     std::string myName;
423     typedef tuple<SALOMEDS::SObject_var> TRet;
424
425     TSObjectByName(const std::string& theName):
426       myName(theName)
427     {}
428
429     TRet operator()(SALOMEDS::SObject_ptr theSObj, bool& theIsSuccess)
430     {
431       SALOMEDS::GenericAttribute_var anAttr;
432       if(theSObj->FindAttribute(anAttr,"AttributeName")){
433         SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
434         CORBA::String_var aValue = aName->Value();
435         theIsSuccess = (myName == aValue.in());
436         if(theIsSuccess)
437           return TRet(SALOMEDS::SObject::_duplicate(theSObj));
438       }
439       return TRet();
440     }
441
442   };
443
444
445   //---------------------------------------------------------------
446   struct TMeshByName
447   {
448     std::string myName;
449     typedef tuple<SALOME_MED::MESH_var,SALOMEDS::SObject_var> TRet;
450
451     TMeshByName(const std::string& theName):
452       myName(theName)
453     {}
454
455     TRet operator()(SALOMEDS::SObject_ptr theSObj, bool& theIsSuccess)
456     {
457       CORBA::Object_var anObj = VISU::SObjectToObject(theSObj);
458       if(!CORBA::is_nil(anObj)){
459         SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
460         if(!CORBA::is_nil(aMesh)){
461           CORBA::String_var aName = aMesh->getName();
462           theIsSuccess = (myName == aName.in());
463           if(theIsSuccess)
464             return TRet(aMesh,SALOMEDS::SObject::_duplicate(theSObj));
465         }
466       }
467       return TRet();
468     }
469   };
470
471
472   //---------------------------------------------------------------
473   template<typename TFun>
474   typename TFun::TRet
475   Find(SALOMEDS::SObject_ptr theStartSObj, 
476        SALOMEDS::Study_ptr theStudy,
477        TFun theFun,
478        bool& theIsSuccess,
479        bool theIsAllLevels = true)
480   {
481     SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator(theStartSObj);
482     anIter->InitEx(theIsAllLevels);
483     for(; anIter->More(); anIter->Next()){
484       SALOMEDS::SObject_var aSObj = anIter->Value();
485       typename TFun::TRet aRet = theFun(aSObj,theIsSuccess);
486       if(theIsSuccess)
487         return aRet;
488     }
489     return typename TFun::TRet();
490   }
491
492 }
493
494
495 //---------------------------------------------------------------
496 VISU_Convertor* 
497 VISU_MEDConvertor::Build(SALOME_MED::MED_ptr theMED)
498 {
499   if(CORBA::is_nil(theMED)) 
500     return NULL;
501
502   CORBA::Long aNbMeshes = theMED->getNumberOfMeshes();
503   SALOME_MED::string_array_var aMeshNames = theMED->getMeshNames();
504   if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aNbMeshes = "<<aNbMeshes);
505
506   SALOMEDS::Study_var aStudy = mySObject->GetStudy();
507   SALOMEDS::SObject_var aMedCompSObj = mySObject->GetFather();
508
509   bool anIsSuccess = false;
510   TSObjectByName::TRet aSObjectByNameRet = 
511     Find(aMedCompSObj,aStudy,TSObjectByName("MEDMESH"),anIsSuccess);
512   if(MYDEBUG) 
513     MESSAGE("VISU_MEDConvertor::Build - Find ('"<<"MEDMESH"<<"') = "<<anIsSuccess);
514   if(anIsSuccess){
515     SALOMEDS::SObject_var aMeshesSObj = boost::get<0>(aSObjectByNameRet);
516     for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
517       anIsSuccess = false;
518       CORBA::String_var aMeshName = aMeshNames[iMesh];
519       TMeshByName::TRet aMeshByNameRet = 
520         Find(aMeshesSObj,aStudy,TMeshByName(aMeshName.in()),anIsSuccess);
521       if(MYDEBUG) 
522         MESSAGE("VISU_MEDConvertor::Build - Find aMeshName('"<<aMeshName.in()<<"') = "<<anIsSuccess);
523       if(!anIsSuccess)
524         continue;
525
526       PCMesh aMesh = myMeshMap[aMeshName.in()](new TCMesh());
527       SALOME_MED::MESH_var aMEDMesh = boost::get<0>(aMeshByNameRet);
528       aMesh->myNamedPointCoords(new TNamedPointCoords());
529       aMesh->myNbPoints = aMEDMesh->getNumberOfNodes();
530       aMesh->myDim = aMEDMesh->getSpaceDimension();
531       aMesh->myName = aMeshName.in();
532       aMesh->myMesh = aMEDMesh;
533
534       TNamedPointCoords& aCoords = aMesh->myNamedPointCoords;
535       aCoords.Init(aMesh->myNbPoints,aMesh->myDim);
536
537       if(MYDEBUG) 
538         MESSAGE("VISU_MEDConvertor::Build - aMeshName = "<<aMeshName<<"; myDim = "<<aMesh->myDim);
539
540       std::string aName = aMeshName.in();
541       std::replace(aName.begin(),aName.end(),' ','_');
542
543       anIsSuccess = false;
544       std::ostringstream aStream;
545       aStream<<"MEDSUPPORTS_OF_"<<aName;
546       std::string aSupportsName(aStream.str());
547       TSObjectByName::TRet aSObjectByNameRet = 
548         Find(aMeshesSObj,aStudy,TSObjectByName(aSupportsName.c_str()),anIsSuccess);
549       if(MYDEBUG) 
550         MESSAGE("VISU_MEDConvertor::Build - Find aSupportsName('"<<aSupportsName<<"') = "<<anIsSuccess);
551       if(!anIsSuccess)
552         continue;
553
554       TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
555       SALOMEDS::SObject_var aSupportsSObj = boost::get<0>(aSObjectByNameRet);
556       SALOMEDS::ChildIterator_var aSupportIterator = aStudy->NewChildIterator(aSupportsSObj);
557
558       // Fill all MeshOnEntity
559       aSupportIterator->InitEx(true);
560       for(; aSupportIterator->More(); aSupportIterator->Next()){
561         SALOMEDS::SObject_var aSupportSObj = aSupportIterator->Value();
562         
563         CORBA::Object_var aMedSupport = VISU::SObjectToObject(aSupportSObj);
564         if(CORBA::is_nil(aMedSupport)) 
565           continue;
566         
567         SALOME_MED::SUPPORT_var aMEDSupport = SALOME_MED::SUPPORT::_narrow(aMedSupport); 
568         if(aMEDSupport->_is_nil()) 
569           continue;
570         
571         SALOME_MED::MESH_var aMeshOnSupport = aMEDSupport->getMesh();
572         SALOME_MED::medEntityMesh aMEntity = aMEDSupport->getEntity();
573         VISU::TEntity aVEntity = MEDEntityToVTK(aMEntity);
574         CORBA::String_var aSupportName = aMEDSupport->getName();
575         
576         if(aMEDSupport->isOnAllElements() && strcmp(aSupportName.in(),"SupportOnAll_MED_") > 0){
577           if(MYDEBUG) 
578             MESSAGE("VISU_MEDConvertor::Build - Support isOnAllElements = '"<<aSupportName<<
579                     "' aVEntity = "<<aVEntity);
580           int aNbCells, aCellsSize;
581           //Check, if there is any data on the support?
582           if(aVEntity == NODE_ENTITY){
583             aMesh->myNbPoints = aMeshOnSupport->getNumberOfNodes();
584             aNbCells = aMesh->myNbPoints;
585             aCellsSize = 2*aMesh->myNbPoints;
586           }else
587             ::GetCellsSize(aNbCells,aCellsSize,aMeshOnSupport,aVEntity);
588           
589           if(aNbCells > 0){
590             TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.find(aVEntity);
591             if(aMeshOnEntityMapIter == aMeshOnEntityMap.end()){
592               PCMeshOnEntity aMeshOnEntity(new TCMeshOnEntity());
593               aMeshOnEntity->myMeshName = aMeshName.in();
594               aMeshOnEntity->myEntity = aVEntity;
595               aMeshOnEntity->myNbCells = aNbCells;
596               aMeshOnEntity->myCellsSize = aCellsSize;
597               aMeshOnEntity->mySupport = aMEDSupport;
598               aMeshOnEntityMap[aVEntity] = aMeshOnEntity;
599             }
600           }
601         }
602       }
603
604       // Fill all Family
605       aSupportIterator->InitEx(true);
606       for(; aSupportIterator->More(); aSupportIterator->Next()){
607         SALOMEDS::SObject_var aSupportSObj = aSupportIterator->Value();
608         
609         CORBA::Object_var aMedSupport = VISU::SObjectToObject(aSupportSObj);
610         if(CORBA::is_nil(aMedSupport)) 
611           continue;
612         
613         SALOME_MED::SUPPORT_var aMEDSupport = SALOME_MED::SUPPORT::_narrow(aMedSupport); 
614         if(aMEDSupport->_is_nil()) 
615           continue;
616         
617         SALOME_MED::MESH_var aMeshOnSupport = aMEDSupport->getMesh();
618         SALOME_MED::medEntityMesh aMEntity = aMEDSupport->getEntity();
619         VISU::TEntity aVEntity = MEDEntityToVTK(aMEntity);
620         CORBA::String_var aSupportName = aMEDSupport->getName();
621         
622         SALOME_MED::FAMILY_var aMEDFamily = SALOME_MED::FAMILY::_narrow(aMedSupport);
623         if(!aMEDFamily->_is_nil()) {
624           TMeshOnEntityMap::iterator aMeshOnEntityMapIter = aMeshOnEntityMap.find(aVEntity);
625           if(aMeshOnEntityMapIter == aMeshOnEntityMap.end())
626             continue;
627           PCMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
628
629           int aNbCells = aMeshOnEntity->myNbCells, aCellsSize = aMeshOnEntity->myCellsSize;
630           CORBA::Boolean anIsOnAllElements = aMEDSupport->isOnAllElements();
631           if(!anIsOnAllElements)
632             ::GetCellsSize(aNbCells,aCellsSize,aMEDFamily);
633
634           if(MYDEBUG) 
635             MESSAGE("VISU_MEDConvertor::Build "<<
636                     "- aFamily = '"<<aSupportName<<"'"<<
637                     "; anIsOnAllElements = "<<anIsOnAllElements<<
638                     "; aVEntity = "<<aVEntity<<
639                     "; aNbCells = "<<aNbCells);
640
641           if(aNbCells > 0){
642             TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
643             TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.find(aSupportName.in());
644             if(aFamilyMapIter == aFamilyMap.end()){
645               PCFamily aFamily(new TCFamily());
646               aFamily->myEntity = aVEntity;
647               aFamily->myNbCells = aNbCells;
648               aFamily->myCellsSize = aCellsSize;
649               aFamily->myId = aMEDFamily->getIdentifier();
650               aFamily->myName = aSupportName.in();
651               aFamily->myFamily = aMEDFamily;
652               aFamilyMap[aSupportName.in()] = aFamily;
653             }
654           }
655         }
656       }
657         
658       // Fill all Groups
659       aSupportIterator->InitEx(true);
660       for(; aSupportIterator->More(); aSupportIterator->Next()){
661         SALOMEDS::SObject_var aSupportSObj = aSupportIterator->Value();
662         
663         CORBA::Object_var aMedSupport = VISU::SObjectToObject(aSupportSObj);
664         if(CORBA::is_nil(aMedSupport)) 
665           continue;
666         
667         SALOME_MED::SUPPORT_var aMEDSupport = SALOME_MED::SUPPORT::_narrow(aMedSupport); 
668         if(aMEDSupport->_is_nil()) 
669           continue;
670         
671         SALOME_MED::MESH_var aMeshOnSupport = aMEDSupport->getMesh();
672         SALOME_MED::medEntityMesh aMEntity = aMEDSupport->getEntity();
673         VISU::TEntity aVEntity = MEDEntityToVTK(aMEntity);
674         CORBA::String_var aSupportName = aMEDSupport->getName();
675         
676         SALOME_MED::GROUP_var aMEDGroup = SALOME_MED::GROUP::_narrow(aMedSupport);
677         if(!aMEDGroup->_is_nil()){
678           CORBA::Boolean anIsOnAllElements = aMEDSupport->isOnAllElements();
679
680           if(MYDEBUG) 
681             MESSAGE("VISU_MEDConvertor::Build "<<
682                     "- aGroup = '"<<aSupportName<<"'"<<
683                     "; anIsOnAllElements = "<<anIsOnAllElements<<
684                     "; aVEntity = "<<aVEntity);
685
686           PCGroup aGroup(new TCGroup());
687           aGroup->myGroup = aMEDGroup;
688           VISU::TFamilySet& aFamilySet = aGroup->myFamilySet;
689           
690           SALOME_MED::Family_array_var aFamilies = aMEDGroup->getFamilies();
691           int iFamilyEnd = aFamilies->length();
692           for(int iFamaily = 0; iFamaily < iFamilyEnd; iFamaily++){
693             SALOME_MED::FAMILY_var aMEDFamily = aFamilies[iFamaily];
694             CORBA::String_var aFamilyName = aMEDFamily->getName();
695             TFindFamilyOnEntity aFindFamilyOnEntity = 
696               FindFamilyOnEntity(aMeshName.in(),aVEntity,aFamilyName.in());
697             PCFamily aFamily = boost::get<2>(aFindFamilyOnEntity);
698             if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aGroup - aFamilyName = '"<<aFamilyName.in()<<"' = "<<bool(aFamily));
699             if(aFamily){
700               aFamilySet.insert(aFamily);
701             }
702           }
703           
704           if(!aFamilySet.empty()){
705             TGroupMap& aGroupMap = aMesh->myGroupMap;
706             aGroupMap[aSupportName.in()] = aGroup;
707           }
708
709         }
710       }
711     }
712   }
713
714   anIsSuccess = false;
715   aSObjectByNameRet = Find(aMedCompSObj,aStudy,TSObjectByName("MEDFIELD"),anIsSuccess);
716   if(anIsSuccess){
717     SALOMEDS::SObject_var aFieldsSObj = boost::get<0>(aSObjectByNameRet);
718     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - MEDFIELD found.");
719     SALOMEDS::ChildIterator_var aFieldIterator = aStudy->NewChildIterator(aFieldsSObj);
720     for(int iField = 0; aFieldIterator->More(); aFieldIterator->Next(), iField++){
721       SALOMEDS::SObject_var aFieldSObj = aFieldIterator->Value();
722       if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aFieldName = '"<<GetSObjectName(aFieldSObj)<<"'");
723       SALOMEDS::ChildIterator_var aTimeStampIterator = aStudy->NewChildIterator(aFieldSObj);
724       for(; aTimeStampIterator->More(); aTimeStampIterator->Next()){
725         SALOMEDS::SObject_var aTimeStampSObj = aTimeStampIterator->Value();
726         if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aTimeStampSObj = '"<<GetSObjectName(aTimeStampSObj)<<"'");
727         CORBA::Object_var aMedField = VISU::SObjectToObject(aTimeStampSObj);
728         if(CORBA::is_nil(aMedField)) 
729           continue;
730
731         SALOME_MED::FIELD_var aMEDField = SALOME_MED::FIELD::_narrow(aMedField);
732         if(aMEDField->_is_nil()) 
733           continue;
734
735         SALOME_MED::SUPPORT_var aMEDSupport = aMEDField->getSupport();
736         if(aMEDSupport->_is_nil()) 
737           continue;
738
739         SALOME_MED::medEntityMesh aMEntity = aMEDSupport->getEntity();
740         VISU::TEntity anEntity = MEDEntityToVTK(aMEntity);
741         SALOME_MED::MESH_var aMEDMesh = aMEDSupport->getMesh();
742         if(aMEDMesh->_is_nil()) 
743           continue;
744
745         CORBA::String_var aMeshName = aMEDMesh->getName();
746         CORBA::String_var aFieldName = aMEDField->getName();
747         
748         TMeshMap::iterator aMeshMapIter = myMeshMap.find(aMeshName.in());
749         if(aMeshMapIter == myMeshMap.end())
750           continue;
751
752         PCMesh aMesh = aMeshMapIter->second;
753         TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
754         TMeshOnEntityMap::iterator aMeshOnEntityMapIter = aMeshOnEntityMap.find(anEntity);
755         if(aMeshOnEntityMapIter == aMeshOnEntityMap.end())
756           continue;
757
758         PCMeshOnEntity aMeshOnEntity = aMeshOnEntityMapIter->second;
759         TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
760         TFieldMap::iterator aFieldMapIter = aFieldMap.find(aFieldName.in());
761         PCField aField;
762         if(aFieldMapIter == aFieldMap.end()){
763           aField = aFieldMap[aFieldName.in()](new TCField());
764           aField->myId = iField;
765           aField->myName = aFieldName.in();
766           aField->myEntity = anEntity;
767           aField->myMeshName = aMeshName.in();
768           aField->InitArrays(aMEDField->getNumberOfComponents());
769           aField->myDataSize = aMeshOnEntity->myNbCells * aField->myNbComp;
770           if(MYDEBUG) 
771             MESSAGE("VISU_MEDConvertor::Build - aMeshOnEntity->myNbCells = "<<aMeshOnEntity->myNbCells);
772         }else
773           aField = aFieldMapIter->second;
774
775         TValField& aValField = aField->myValField;
776         int anId = aMEDField->getIterationNumber();
777         PCValForTime aValForTime = aValField[anId](new TCValForTime());
778         aValForTime->myId = anId;
779         CORBA::Double aDT = aMEDField->getTime();
780         aValForTime->myTime = TTime(aDT,"");
781         aValForTime->myField = aMEDField;
782         if(MYDEBUG) 
783           MESSAGE("VISU_MEDConvertor::Build - aMeshName = '"<<aMeshName<<
784                   "'; myEntity = "<<anEntity<<"; myTime = "<<aDT);
785       }      
786     }
787   }
788   return this; 
789 }
790  
791
792 //---------------------------------------------------------------
793 VISU_Convertor* 
794 VISU_MEDConvertor::Build(SALOMEDS::ChildIterator_ptr theTimeStampIterator)
795 {
796   if(theTimeStampIterator->_is_nil()) return NULL;
797   for(; theTimeStampIterator->More(); theTimeStampIterator->Next()){
798     SALOMEDS::SObject_var aTimeStampSObj = theTimeStampIterator->Value();
799     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::Build - aTimeStampSObj = '"<<GetSObjectName(aTimeStampSObj)<<"'");
800
801     CORBA::Object_var aMedField = VISU::SObjectToObject(aTimeStampSObj);
802     if(CORBA::is_nil(aMedField)) 
803       continue;
804
805     SALOME_MED::FIELD_var aMEDField = SALOME_MED::FIELD::_narrow(aMedField);
806     if(aMEDField->_is_nil()) 
807       continue;
808
809     SALOME_MED::SUPPORT_var aMEDSupport = aMEDField->getSupport();
810     if(aMEDSupport->_is_nil()) 
811       continue;
812
813     SALOME_MED::medEntityMesh aMEntity = aMEDSupport->getEntity();
814     TEntity aVEntity = MEDEntityToVTK(aMEntity);
815     SALOME_MED::MESH_var aMEDMesh = aMEDSupport->getMesh();
816     if(aMEDMesh->_is_nil()) continue;
817     CORBA::String_var aMeshName = aMEDMesh->getName();
818     CORBA::String_var aFieldName = aMEDField->getName();
819
820     PCMesh aMesh;
821     TMeshMap::const_iterator aMeshMapIter = myMeshMap.find(aMeshName.in());
822     if(aMeshMapIter == myMeshMap.end()){
823       aMesh.reset(new TCMesh());
824       aMesh->myNamedPointCoords(new TNamedPointCoords());
825       aMesh->myNbPoints = aMEDMesh->getNumberOfNodes();
826       aMesh->myDim = aMEDMesh->getSpaceDimension();
827       aMesh->myName = aMeshName.in();
828       aMesh->myMesh = aMEDMesh;
829       
830       TNamedPointCoords& aCoords = aMesh->myNamedPointCoords;
831       aCoords.Init(aMesh->myNbPoints,aMesh->myDim);
832
833       myMeshMap[aMeshName.in()] = aMesh;
834
835       if(MYDEBUG) 
836         MESSAGE("VISU_MEDConvertor::Build "<<
837                 "- aMeshName = '"<<aMeshName<<"'"<<
838                 "; aDim = "<<aMesh->myDim);
839     }else
840       aMesh = aMeshMapIter->second;
841
842     PCMeshOnEntity aMeshOnEntity;
843     TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
844     TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.find(aVEntity);
845     if(aMeshOnEntityMapIter == aMeshOnEntityMap.end()){
846       aMeshOnEntity.reset(new TCMeshOnEntity());
847       aMeshOnEntity->myEntity = aVEntity;
848       aMeshOnEntity->myMeshName = aMeshName.in();
849       aMeshOnEntity->mySupport = aMEDSupport;
850       aMeshOnEntityMap[aVEntity] = aMeshOnEntity;
851     }else
852       aMeshOnEntity = aMeshOnEntityMapIter->second;
853
854     if(aVEntity == NODE_ENTITY)
855       ::InitMeshOnEntity(aMesh,CELL_ENTITY,aMeshOnEntity);
856     else
857       ::InitMeshOnEntity(aMesh,NODE_ENTITY,aMeshOnEntity);
858
859     ::GetCellsSize(aMesh,aMEDMesh,aVEntity);
860
861     PCField aField;
862     TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
863     TFieldMap::const_iterator aFieldMapIter = aFieldMap.find(aFieldName.in());
864     if(aFieldMapIter == aFieldMap.end()){
865       aField.reset(new TCField());
866       aField->myId = mySObject->Tag();
867       aField->myName = aFieldName.in();
868       aField->myEntity = aVEntity;
869       aField->myMeshName = aMeshName.in();
870       aField->InitArrays(aMEDField->getNumberOfComponents());
871       aField->myDataSize = aMeshOnEntity->myNbCells * aField->myNbComp;
872       
873       aFieldMap[aFieldName.in()] = aField;
874
875       if(MYDEBUG) 
876         MESSAGE("VISU_MEDConvertor::Build - aMeshOnEntity->myNbCells = "<<aMeshOnEntity->myNbCells);
877     }else
878       aField = aFieldMapIter->second;
879
880     TValField& aValField = aField->myValField;
881     int anId = aMEDField->getIterationNumber();
882     PCValForTime aValForTime = aValField[anId](new TCValForTime());
883     aValForTime->myId = anId;
884     CORBA::Double aDT = aMEDField->getTime();
885     aValForTime->myTime = TTime(aDT,"");
886     aValForTime->myField = aMEDField;
887     if(MYDEBUG) 
888       MESSAGE("VISU_MEDConvertor::Build "<<
889               "- aMeshName = '"<<aMeshName<<"'"<<
890               "; myEntity = "<<aVEntity<<
891               "; myTime = "<<aDT<<
892               "; anId = "<<anId);
893   }
894   return this; 
895 }
896
897
898 //---------------------------------------------------------------
899 int
900 VISU_MEDConvertor
901 ::LoadMeshOnEntity(VISU::PMeshImpl theMesh,
902                    VISU::PMeshOnEntityImpl theMeshOnEntity)
903 {
904   int anIsUpdated = LoadPoints(theMesh);
905   const TEntity& aVEntity = theMeshOnEntity->myEntity;
906   if(aVEntity != NODE_ENTITY)
907     anIsUpdated |= LoadCellsOnEntity(theMesh,theMeshOnEntity);
908
909   return anIsUpdated;
910 }
911  
912  
913 //---------------------------------------------------------------
914 int
915 VISU_MEDConvertor
916 ::LoadFamilyOnEntity(VISU::PMeshImpl theMesh,
917                      VISU::PMeshOnEntityImpl theMeshOnEntity, 
918                      VISU::PFamilyImpl theFamily)
919 {
920   int anIsUpdated = LoadPoints(theMesh);
921   const TEntity& anEntity = theMeshOnEntity->myEntity;
922   if(anEntity == NODE_ENTITY){
923     anIsUpdated |= LoadPointsOnFamily(theMesh,theFamily);
924   }else{
925     anIsUpdated |= LoadCellsOnEntity(theMesh,theMeshOnEntity);
926     anIsUpdated |= LoadCellsOnFamily(theMesh,theMeshOnEntity,theFamily);
927   }
928
929   return anIsUpdated;
930 }
931
932
933 //---------------------------------------------------------------
934 int 
935 VISU_MEDConvertor
936 ::LoadMeshOnGroup(VISU::PMeshImpl theMesh, 
937                   const VISU::TFamilySet& theFamilySet)
938 {
939   //Main part of code
940   int anIsUpdated = LoadPoints(theMesh);
941   TFamilySet::const_iterator aFamilyIter = theFamilySet.begin();
942   for(; aFamilyIter != theFamilySet.end(); aFamilyIter++){
943     PCFamily aFamily = *aFamilyIter;
944     const VISU::TEntity& aVEntity = aFamily->myEntity;
945     PCMeshOnEntity aMeshOnEntity = theMesh->myMeshOnEntityMap[aVEntity];
946     if(aVEntity == VISU::NODE_ENTITY){
947       anIsUpdated |= LoadPointsOnFamily(theMesh,aFamily);
948     }else{
949       anIsUpdated |= LoadCellsOnEntity(theMesh,aMeshOnEntity);
950       anIsUpdated |= LoadCellsOnFamily(theMesh,aMeshOnEntity,aFamily);
951     }
952   }
953
954   return anIsUpdated;
955 }
956
957
958 //---------------------------------------------------------------
959 int 
960 VISU_MEDConvertor
961 ::LoadValForTimeOnMesh(VISU::PMeshImpl theMesh, 
962                        VISU::PMeshOnEntityImpl theMeshOnEntity, 
963                        VISU::PFieldImpl theField, 
964                        VISU::PValForTimeImpl theValForTime)
965 {
966   //Main part of code
967   int anIsUpdated = LoadPoints(theMesh);
968   const TEntity& aVEntity = theMeshOnEntity->myEntity;
969   if(aVEntity != NODE_ENTITY)
970     anIsUpdated |= LoadCellsOnEntity(theMesh,theMeshOnEntity);
971
972   anIsUpdated |= LoadField(theMesh,theMeshOnEntity,theField,theValForTime);
973   
974   return anIsUpdated;
975 }
976
977
978 //---------------------------------------------------------------
979 int 
980 VISU_MEDConvertor
981 ::LoadPoints(VISU::PCMesh theMesh)
982 {
983   //Check on existing family
984   PCMeshOnEntity aMeshOnEntity = theMesh->myMeshOnEntityMap[VISU::NODE_ENTITY];
985   
986   //Check on loading already done
987   if(theMesh->myIsDone) 
988     return 0;
989   
990   SALOME_MED::MESH_var& aMedMesh = theMesh->myMesh;
991   int aDim = theMesh->myDim;
992   TNamedPointCoords& aCoords = theMesh->myNamedPointCoords;
993   int aNbElem = aCoords.GetNbPoints();
994
995   if(MYDEBUG) MESSAGE("LoadPoints - aNbElem = "<<aNbElem);
996
997   if(aNbElem <= 0) 
998     throw std::runtime_error("LoadPoints >> There is no points in the mesh !!!");
999
1000   SALOME_MED::double_array_var aCCoord = aMedMesh->getCoordinates(SALOME_MED::MED_FULL_INTERLACE);
1001   for(int iElem = 0, anId = 0; iElem < aNbElem; iElem++){
1002     VISU::TCoordSlice aCoordSlice = aCoords.GetCoordSlice(iElem);
1003     for(int iDim = 0; iDim < aDim; iDim++)
1004       aCoordSlice[iDim] = aCCoord[anId++];
1005   }
1006   
1007   if(MYDEBUG) MESSAGE("LoadPoints - Filling aMeshOnEntity with type NODE_ENTITY");
1008   
1009   TGeom2SubMesh& aGeom2SubMesh = aMeshOnEntity->myGeom2SubMesh;
1010   PSubMeshImpl aSubMesh = aGeom2SubMesh[VISU::ePOINT1](new TCSubMesh());
1011
1012   aSubMesh->myNbCells = theMesh->myNbPoints;
1013   aSubMesh->myCellsSize = 2*theMesh->myNbPoints;
1014
1015   TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
1016   aCell2Connect.resize(aNbElem);
1017   for(int iElem = 0; iElem < aNbElem; iElem++)
1018     aCell2Connect[iElem] = TConnect(1,iElem);
1019   
1020   theMesh->myIsDone = true;
1021
1022   return 1;
1023 }
1024
1025
1026 //---------------------------------------------------------------
1027 int 
1028 VISU_MEDConvertor
1029 ::LoadPointsOnFamily(VISU::PCMesh theMesh, 
1030                      VISU::PCFamily theFamily)
1031 {
1032   PCMeshOnEntity aMeshOnEntity = theMesh->myMeshOnEntityMap[VISU::NODE_ENTITY];
1033
1034   if(theFamily->myIsDone) 
1035     return 0;
1036
1037   TNamedPointCoords& aCoords = theMesh->myNamedPointCoords;
1038   int aNbElem = aCoords.GetNbPoints();
1039
1040   SALOME_MED::FAMILY_var aMedFamily = theFamily->myFamily;
1041   CORBA::Boolean anIsOnAllElements = aMedFamily->isOnAllElements();
1042   TSubMeshID& aSubMeshID = theFamily->myGeom2SubMeshID[VISU::ePOINT1];
1043   
1044   if(!anIsOnAllElements){
1045     SALOME_MED::medGeometryElement_array_var aGeom = aMedFamily->getTypes();
1046     SALOME_MED::long_array_var aCellNumForType = aMedFamily->getNumber(aGeom[0]);
1047     int aSize = aNbElem;
1048     aNbElem = aCellNumForType->length();
1049     for(int iElem = 0; iElem < aNbElem; iElem++){
1050       int anID = aCellNumForType[iElem] - 1;
1051       if(0 > anID || anID >= aSize){
1052         static QString aString;
1053         aString.sprintf("LoadPointsOnFamily - aSize(%d) <= aCellNumForType[%d] = %d < 0",aSize,iElem,anID);
1054         throw std::runtime_error(aString.latin1());
1055       }
1056       aSubMeshID.push_back(anID);
1057     }
1058   }else{
1059     for(int iElem = 0; iElem < aNbElem; iElem++){
1060       aSubMeshID.push_back(iElem);
1061     }
1062   }
1063   
1064   theFamily->myIsDone = true;
1065
1066   return 1;
1067 }
1068
1069
1070 //---------------------------------------------------------------
1071 int 
1072 VISU_MEDConvertor
1073 ::LoadCellsOnEntity(VISU::PCMesh theMesh,
1074                     VISU::PCMeshOnEntity theMeshOnEntity)
1075 {
1076   if(theMeshOnEntity->myIsDone) 
1077     return 0;
1078
1079   SALOME_MED::SUPPORT_var& aMedSupport = theMeshOnEntity->mySupport;
1080   SALOME_MED::MESH_var aMedMesh = aMedSupport->getMesh();
1081
1082   //Main part of code
1083   SALOME_MED::medGeometryElement* aGeomElems;
1084   const TEntity& aVEntity = theMeshOnEntity->myEntity;
1085   int iGeomEnd = GetEntity2Geom(aVEntity,aGeomElems);
1086   const SALOME_MED::medEntityMesh& aMEntity = VTKEntityToMED(aVEntity);
1087   const TNamedPointCoords& aCoords = theMesh->myNamedPointCoords;
1088   TGeom2SubMesh& aGeom2SubMesh = theMeshOnEntity->myGeom2SubMesh;
1089   int aNbPoints = aCoords.GetNbPoints();
1090
1091   for(int iGeom = 0, aCounter = 0; iGeom < iGeomEnd; iGeom++){
1092     SALOME_MED::medGeometryElement aMGeom = aGeomElems[iGeom];
1093     int aMNbNodes = MEDGeom2NbNodes(aMGeom);
1094     VISU::EGeometry aEGeom = MEDGeom2VISU(aMGeom);
1095     int aVNbNodes = VISUGeom2NbNodes(aEGeom);
1096     int aNbElem = aMedMesh->getNumberOfElements(aMEntity,aMGeom);
1097     if (aNbElem > 0) {
1098       using namespace SALOME_MED;
1099       SALOME_MED::long_array_var conn = 
1100         aMedMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,aMEntity,aMGeom);
1101       PSubMeshImpl aSubMesh = aGeom2SubMesh[aEGeom](new TCSubMesh());
1102
1103       aSubMesh->myNbCells = aNbElem;      
1104       aSubMesh->myCellsSize = aNbElem*(aVNbNodes+1);
1105
1106       TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
1107       std::vector<int> aConnect(aMNbNodes);
1108       int aNbConnForElem = conn->length()/aNbElem;
1109
1110       if(MYDEBUG) MESSAGE("LoadCellsOnEntity - aMGeom = "<<aMGeom<<
1111                           "; aNbElem = "<<aNbElem<<
1112                           "; aMNbNodes = "<<aMNbNodes<<
1113                           "; aVNbNodes = "<<aVNbNodes<<
1114                           "; aNbConnForElem = "<<aNbConnForElem);
1115
1116       for(int iElem = 0; iElem < aNbElem; iElem++){
1117         VISU::TConnect anArray(aVNbNodes);
1118         for(int k = 0, kj = iElem*aNbConnForElem; k < aMNbNodes; k++)
1119           aConnect[k] = conn[kj+k] - 1;
1120
1121         switch(aMGeom){
1122 #if !(defined(VTK_QUADRATIC_EDGE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
1123         case SALOME_MED::MED_SEG3:
1124           anArray[0] = aConnect[0];
1125           anArray[2] = aConnect[1];  
1126           
1127           anArray[1] = aConnect[2];
1128           break;
1129 #endif
1130 #if !(defined(VTK_QUADRATIC_TRIANGLE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
1131         case SALOME_MED::MED_TRIA6:
1132           anArray[0] = aConnect[0];
1133           anArray[2] = aConnect[1];  
1134           anArray[4] = aConnect[2];  
1135           
1136           anArray[1] = aConnect[3];
1137           anArray[3] = aConnect[4];  
1138           anArray[5] = aConnect[5];  
1139           break;
1140 #endif
1141 #if !(defined(VTK_QUADRATIC_QUAD) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
1142         case SALOME_MED::MED_QUAD8:
1143           anArray[0] = aConnect[0];
1144           anArray[2] = aConnect[1];  
1145           anArray[4] = aConnect[2];  
1146           anArray[6] = aConnect[3];  
1147           
1148           anArray[1] = aConnect[4];
1149           anArray[3] = aConnect[5];  
1150           anArray[5] = aConnect[6];  
1151           anArray[7] = aConnect[7];  
1152           break;
1153 #endif
1154 #if (defined(VTK_QUADRATIC_TETRA) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
1155         case SALOME_MED::MED_TETRA10 :
1156 #endif
1157         case SALOME_MED::MED_TETRA4 :
1158           anArray[0] = aConnect[0];
1159           anArray[1] = aConnect[1];
1160           anArray[2] = aConnect[3];  
1161           anArray[3] = aConnect[2];  
1162           break;
1163 #if (defined(VTK_QUADRATIC_PYRAMID) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
1164         case SALOME_MED::MED_PYRA13:
1165 #endif
1166         case SALOME_MED::MED_PYRA5 :
1167           anArray[0] = aConnect[0];
1168           anArray[1] = aConnect[3];  
1169           anArray[2] = aConnect[2];
1170           anArray[3] = aConnect[1];  
1171           anArray[4] = aConnect[4];
1172           break;
1173         default:
1174           for (int k = 0; k < aVNbNodes; k++) 
1175             anArray[k] = aConnect[k];
1176         }
1177         for (int k = 0; k < aVNbNodes; k++) 
1178           if(anArray[k] < 0 || aNbPoints <= anArray[k]){
1179             static QString aString;
1180             aString.sprintf("LoadCellsOnEntity >> aNbPoints(%d) <= anArray[%d][%d]=%d < 0 !!!",aNbPoints,iElem,k,anArray[k]);
1181             throw std::runtime_error(aString.latin1());
1182           }
1183         aCell2Connect.push_back(anArray);
1184       }
1185       //Workaround for MED Component data structure
1186       int aSize = aCell2Connect.size();
1187       if(MYDEBUG) MESSAGE("LoadCellsOnEntity - aCounter = "<<aCounter<<"; aSize = "<<aSize);
1188       theMeshOnEntity->myCellsFirstIndex[aMGeom] = TCMeshOnEntity::TIndexAndSize(aCounter,aSize);
1189       aCounter += aSize;
1190     }
1191   }
1192
1193   theMeshOnEntity->myIsDone = true;
1194
1195   return 1;
1196 }
1197
1198
1199 //---------------------------------------------------------------
1200 int 
1201 VISU_MEDConvertor
1202 ::LoadCellsOnFamily(VISU::PCMesh theMesh,
1203                     VISU::PCMeshOnEntity theMeshOnEntity, 
1204                     VISU::PCFamily theFamily)
1205 {
1206   if(theFamily->myIsDone) 
1207     return 0;
1208
1209   SALOME_MED::FAMILY_var aMedFamily = theFamily->myFamily;
1210   CORBA::Boolean anIsOnAllElements = aMedFamily->isOnAllElements();
1211   if(!anIsOnAllElements){
1212     SALOME_MED::medGeometryElement_array_var aGeoms = aMedFamily->getTypes();
1213     int iGeomEnd = aGeoms->length();
1214     if(MYDEBUG) MESSAGE("LoadCellsOnFamily - iGeomEnd = "<<iGeomEnd);
1215     for(int iGeom = 0; iGeom < iGeomEnd; iGeom++){
1216       SALOME_MED::medGeometryElement aMGeom = aGeoms[iGeom];
1217       SALOME_MED::long_array_var aCellNumForType = aMedFamily->getNumber(aMGeom);
1218       VISU::EGeometry aEGeom = MEDGeom2VISU(aMGeom);
1219
1220       int aNbElem = aCellNumForType->length();
1221       int aCounter = theMeshOnEntity->myCellsFirstIndex[aMGeom].first;
1222       int aSize = theMeshOnEntity->myCellsFirstIndex[aMGeom].second;
1223       TSubMeshID& aSubMeshID = theFamily->myGeom2SubMeshID[aEGeom]; 
1224       
1225       if(MYDEBUG) 
1226         MESSAGE("LoadCellsOnFamily "<<
1227                 "- aMGeom = "<<aMGeom<<
1228                 "; aNbElem = "<<aNbElem<<
1229                 "; aSize = "<<aSize<<
1230                 "; aCounter = "<<aCounter);
1231       
1232       for(int iElem = 0; iElem < aNbElem; iElem++){
1233         int anID = aCellNumForType[iElem] - aCounter - 1;
1234         if(0 > anID || anID >= aSize){
1235           static QString aString;
1236           aString.sprintf("LoadCellsOnFamily - aNbElem(%d) <= aCellNumForType[%d] = %d < 0 !!!",aNbElem,iElem,anID);
1237           throw std::runtime_error(aString.latin1());
1238         }
1239         aSubMeshID.push_back(anID);
1240       }
1241     }
1242   }else{
1243     const VISU::TGeom2SubMesh& aGeom2SubMesh = theMeshOnEntity->myGeom2SubMesh;
1244     VISU::TGeom2SubMesh::const_iterator anIter = aGeom2SubMesh.begin();
1245     for(; anIter != aGeom2SubMesh.end(); anIter++){
1246       VISU::EGeometry aEGeom = anIter->first;
1247       const VISU::TSubMeshImpl& aSubMesh = anIter->second;
1248       const VISU::TCell2Connect& aCell2Connect = aSubMesh.myCell2Connect;
1249       TSubMeshID& aSubMeshID = theFamily->myGeom2SubMeshID[aEGeom];
1250       int iNumElemEnd = aCell2Connect.size();
1251       for(int iNumElem = 0; iNumElem < iNumElemEnd; iNumElem++)
1252         aSubMeshID.push_back(iNumElem);
1253     }
1254   }
1255   
1256   theFamily->myIsDone = true;
1257
1258   return 1;
1259 }
1260
1261
1262 template<class TArray> 
1263 int 
1264 ImportField(TArray& theArray, 
1265             VISU::PCMesh theMesh,
1266             VISU::PCField theField,
1267             VISU::PCValForTime theValForTime,
1268             VISU::PCMeshOnEntity theMeshOnEntity)
1269 {
1270   int aNbComp = theField->myNbComp;
1271   if(theField->myEntity == NODE_ENTITY){
1272     VISU::EGeometry aEGeom = VISU::ePOINT1;
1273     int aNbGauss = theValForTime->GetNbGauss(aEGeom);
1274     const TNamedPointCoords& aCoords = theMesh->myNamedPointCoords;
1275     int aNbElem = aCoords.GetNbPoints();
1276
1277     if(MYDEBUG) MESSAGE("ImportField - aNbElem = "<<aNbElem);
1278
1279     TMeshValue& aMeshValue = theValForTime->GetMeshValue(VISU::ePOINT1);
1280     aMeshValue.Init(aNbElem,aNbGauss,aNbComp);
1281     for(int iElem = 0, anId = 0; iElem < aNbElem; iElem++){
1282       TValueSliceArr aValueSliceArr = aMeshValue.GetGaussValueSliceArr(iElem);
1283       for(int iGauss = 0; iGauss < aNbGauss; iGauss++){
1284         TValueSlice& aValueSlice = aValueSliceArr[iGauss];
1285         for(int iComp = 0; iComp < aNbComp; iComp++){
1286           aValueSlice[iComp] = theArray[anId++];
1287         }
1288       }
1289     }
1290   }else{
1291     SALOME_MED::medGeometryElement* aGeomElems;
1292     const TEntity& aVEntity = theField->myEntity;
1293     int iGeomEnd = GetEntity2Geom(aVEntity,aGeomElems);
1294     for(int iGeom = 0; iGeom < iGeomEnd; iGeom++){
1295       SALOME_MED::medGeometryElement aMGeom = aGeomElems[iGeom];
1296       VISU::EGeometry aEGeom = MEDGeom2VISU(aMGeom);
1297       int aNbGauss = theValForTime->GetNbGauss(aEGeom);
1298       const TCMeshOnEntity::TCellsFirstIndex& aCellsFirstIndex = theMeshOnEntity->myCellsFirstIndex;
1299       TCMeshOnEntity::TCellsFirstIndex::const_iterator aCellsFirstIndexIter = aCellsFirstIndex.find(aMGeom);
1300       if(aCellsFirstIndexIter != aCellsFirstIndex.end()){
1301         const TCMeshOnEntity::TIndexAndSize& aIndexAndSize = aCellsFirstIndexIter->second;
1302         if(MYDEBUG) 
1303           MESSAGE("ImportField - aMGeom = "<<aMGeom<<
1304                   "; aIndexAndSize = {"<<aIndexAndSize.first<<
1305                   ","<<aIndexAndSize.second<<"}");
1306
1307         int aNbElem = aIndexAndSize.second;
1308         int aStart = aIndexAndSize.first*aNbComp;
1309         TMeshValue& aMeshValue = theValForTime->GetMeshValue(aEGeom);
1310         aMeshValue.Init(aNbElem,aNbGauss,aNbComp);
1311         for(int iElem = 0, anId = 0; iElem < aNbElem; iElem++, anId += aNbComp){
1312           TValueSliceArr aValueSliceArr = aMeshValue.GetGaussValueSliceArr(iElem);
1313           for(int iGauss = 0; iGauss < aNbGauss; iGauss++){
1314             TValueSlice& aValueSlice = aValueSliceArr[iGauss];
1315             for(int iComp = 0; iComp < aNbComp; iComp++)
1316               aValueSlice[iComp] = theArray[aStart+anId+iComp];
1317           }
1318         }
1319       }
1320     }
1321   }
1322   return 1;
1323 }
1324
1325 int
1326 VISU_MEDConvertor
1327 ::LoadField(VISU::PCMesh theMesh,
1328             VISU::PCMeshOnEntity theMeshOnEntity,
1329             VISU::PField theField, 
1330             VISU::PCValForTime theValForTime)
1331 {
1332   //Check on loading already done
1333   PIDMapperFilter anIDMapperFilter = theValForTime->myIDMapperFilter;
1334   if(anIDMapperFilter->myIsVTKDone) 
1335     return 0;
1336   
1337   PCProfile aProfile(new TCProfile());
1338   aProfile->myIsAll = true;
1339   theValForTime->myProfile = aProfile;
1340
1341   SALOME_MED::FIELD_var aMEDField = theValForTime->myField;
1342   SALOME_MED::FIELDDOUBLE_ptr aFieldDouble = SALOME_MED::FIELDDOUBLE::_narrow(aMEDField);
1343   if(!aFieldDouble->_is_nil()){
1344     SALOME_MED::double_array_var anArray = aFieldDouble->getValue(SALOME_MED::MED_FULL_INTERLACE);
1345     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::LoadField - There is FIELDDOUBLE = "<<anArray->length());
1346     ::ImportField(anArray,theMesh,theField,theValForTime,theMeshOnEntity);
1347   }
1348   SALOME_MED::FIELDINT_ptr aFieldInt = SALOME_MED::FIELDINT::_narrow(aMEDField);
1349   if(!aFieldInt->_is_nil()){
1350     SALOME_MED::long_array_var anArray = aFieldInt->getValue(SALOME_MED::MED_FULL_INTERLACE);
1351     if(MYDEBUG) MESSAGE("VISU_MEDConvertor::LoadField - There is FIELDINT = "<<anArray->length());
1352     ::ImportField(anArray,theMesh,theField,theValForTime,theMeshOnEntity);
1353   }
1354
1355   anIDMapperFilter->myIsVTKDone = true;
1356
1357   return 1;
1358 }