Salome HOME
Changes according MEDWrapper API modifications
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMESHDS_Mesh.cxx
1 //  SMESH DriverMED : driver to read and write 'med' files
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   : DriverMED_W_SMESHDS_Mesh.cxx
25 //  Module : SMESH
26
27 #include <sstream>
28
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "DriverMED_W_SMDS_Mesh.h"
31 #include "DriverMED_Family.h"
32
33 #include "SMESHDS_Mesh.hxx"
34 #include "SMDS_MeshElement.hxx"
35 #include "SMDS_MeshNode.hxx"
36 #include "utilities.h"
37
38 #include "MED_Utilities.hxx"
39
40 #define _EDF_NODE_IDS_
41 //#define _ELEMENTS_BY_DIM_
42
43 using namespace std;
44 using namespace MED;
45
46
47 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
48   myAllSubMeshes (false),
49   myDoGroupOfNodes (false),
50   myDoGroupOfEdges (false),
51   myDoGroupOfFaces (false),
52   myDoGroupOfVolumes (false)
53 {}
54
55 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, 
56                                        MED::EVersion theId)
57 {
58   myMed = CrWrapper(theFileName,theId);
59   Driver_SMESHDS_Mesh::SetFile(theFileName);
60 }
61
62 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
63 {
64   return SetFile(theFileName,MED::eV2_1);
65 }
66
67 void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName)
68 {
69   myMeshName = theMeshName;
70 }
71
72 void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup)
73 {
74   myGroups.push_back(theGroup);
75 }
76
77 void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes()
78 {
79   myAllSubMeshes = true;
80 }
81
82 void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
83 {
84   mySubMeshes[theID] = theSubMesh;
85 }
86
87 void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
88 {
89   myDoGroupOfNodes = true;
90 }
91
92 void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges()
93 {
94   myDoGroupOfEdges = true;
95 }
96
97 void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces()
98 {
99   myDoGroupOfFaces = true;
100 }
101
102 void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
103 {
104   myDoGroupOfVolumes = true;
105 }
106
107 namespace{
108   typedef double (SMDS_MeshNode::* TGetCoord)() const;
109   typedef const char* TName;
110   typedef const char* TUnit;
111   
112   TUnit aUnit[3] = {"m","m","m"};
113
114   TGetCoord aXYZGetCoord[3] = {
115     &SMDS_MeshNode::X, 
116     &SMDS_MeshNode::Y, 
117     &SMDS_MeshNode::Z
118   };
119   TName aXYZName[3] = {"x","y","z"};
120   
121   
122   TGetCoord aXYGetCoord[2] = {
123     &SMDS_MeshNode::X, 
124     &SMDS_MeshNode::Y
125   };
126   TName aXYName[2] = {"x","y"};
127
128   TGetCoord aYZGetCoord[2] = {
129     &SMDS_MeshNode::Y, 
130     &SMDS_MeshNode::Z
131   };
132   TName aYZName[2] = {"y","z"};
133
134   TGetCoord aXZGetCoord[2] = {
135     &SMDS_MeshNode::X, 
136     &SMDS_MeshNode::Z
137   };
138   TName aXZName[2] = {"x","z"};
139
140
141   TGetCoord aXGetCoord[1] = {
142     &SMDS_MeshNode::X
143   };
144   TName aXName[1] = {"x"};
145
146   TGetCoord aYGetCoord[1] = {
147     &SMDS_MeshNode::Y
148   };
149   TName aYName[1] = {"y"};
150
151   TGetCoord aZGetCoord[1] = {
152     &SMDS_MeshNode::Z
153   };
154   TName aZName[1] = {"z"};
155
156
157   class TCoordHelper{
158     SMDS_NodeIteratorPtr myNodeIter;
159     const SMDS_MeshNode* myCurrentNode;
160     TGetCoord* myGetCoord;
161     TName* myName;
162     TUnit* myUnit;
163   public:
164     TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter,
165                  TGetCoord* theGetCoord,
166                  TName* theName,
167                  TUnit* theUnit = aUnit):
168       myNodeIter(theNodeIter),
169       myGetCoord(theGetCoord),
170       myName(theName),
171       myUnit(theUnit)
172     {}
173     virtual ~TCoordHelper(){}
174     bool Next(){ 
175       return myNodeIter->more() && 
176         (myCurrentNode = myNodeIter->next());
177     }
178     const SMDS_MeshNode* GetNode(){
179       return myCurrentNode;
180     }
181     MED::TIntVector::value_type GetID(){
182       return myCurrentNode->GetID();
183     }
184     MED::TFloatVector::value_type GetCoord(TInt theCoodId){
185       return (myCurrentNode->*myGetCoord[theCoodId])();
186     }
187     MED::TStringVector::value_type GetName(TInt theDimId){
188       return myName[theDimId];
189     }
190     MED::TStringVector::value_type GetUnit(TInt theDimId){
191       return myUnit[theDimId];
192     }
193   };
194   typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
195   
196 }
197
198   
199 Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
200 {
201   Status aResult = DRS_OK;
202   if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
203     INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
204     return DRS_FAIL;
205   }
206   try{
207     MESSAGE("Perform - myFile : "<<myFile);
208
209     // Creating the MED mesh for corresponding SMDS structure
210     //-------------------------------------------------------
211     string aMeshName;
212     if (myMeshId != -1) {
213       ostringstream aMeshNameStr;
214       aMeshNameStr<<myMeshId;
215       aMeshName = aMeshNameStr.str();
216     } else {
217       aMeshName = myMeshName;
218     }
219
220     // Mesh dimension definition
221     TInt aMeshDimension;
222     TCoordHelperPtr aCoordHelperPtr;
223     {  
224       bool anIsXDimension = false;
225       bool anIsYDimension = false;
226       bool anIsZDimension = false;
227       {
228         SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
229         double aBounds[6];
230         if(aNodesIter->more()){
231           const SMDS_MeshNode* aNode = aNodesIter->next();
232           aBounds[0] = aBounds[1] = aNode->X();
233           aBounds[2] = aBounds[3] = aNode->Y();
234           aBounds[4] = aBounds[5] = aNode->Z();
235         }
236         while(aNodesIter->more()){
237           const SMDS_MeshNode* aNode = aNodesIter->next();
238           aBounds[0] = min(aBounds[0],aNode->X());
239           aBounds[1] = max(aBounds[1],aNode->X());
240           
241           aBounds[2] = min(aBounds[2],aNode->Y());
242           aBounds[3] = max(aBounds[3],aNode->Y());
243           
244           aBounds[4] = min(aBounds[4],aNode->Z());
245           aBounds[5] = max(aBounds[5],aNode->Z());
246         }
247
248         double EPS = 1.0E-7;
249         anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
250         anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
251         anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
252         aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension;
253         if(!aMeshDimension)
254           aMeshDimension = 3;
255       }
256
257       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
258       switch(aMeshDimension){
259       case 3:
260         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
261         break;
262       case 2:
263         if(anIsXDimension && anIsYDimension)
264           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
265         if(anIsYDimension && anIsZDimension)
266           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
267         if(anIsXDimension && anIsZDimension)
268           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
269         break;
270       case 1:
271         if(anIsXDimension)
272           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
273         if(anIsYDimension)
274           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
275         if(anIsZDimension)
276           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
277         break;
278       }
279     }
280
281     
282     PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aMeshName);
283     MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
284     myMed->SetMeshInfo(aMeshInfo);
285
286     // Storing SMDS groups and sub-meshes
287     //-----------------------------------
288     int myNodesDefaultFamilyId = 0;
289     int myEdgesDefaultFamilyId = 0;
290     int myFacesDefaultFamilyId = 0;
291     int myVolumesDefaultFamilyId = 0;
292     if (myDoGroupOfNodes)
293       myNodesDefaultFamilyId = REST_NODES_FAMILY;
294     if (myDoGroupOfEdges)
295       myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
296     if (myDoGroupOfFaces)
297       myFacesDefaultFamilyId = REST_FACES_FAMILY;
298     if (myDoGroupOfVolumes)
299       myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
300
301     MESSAGE("Perform - aFamilyInfo");
302     map<const SMDS_MeshElement *, int> anElemFamMap;
303     list<DriverMED_FamilyPtr> aFamilies;
304     if (myAllSubMeshes) {
305       aFamilies = DriverMED_Family::MakeFamilies
306         (myMesh->SubMeshes(), myGroups,
307          myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
308     } else {
309       aFamilies = DriverMED_Family::MakeFamilies
310         (mySubMeshes, myGroups,
311          myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
312     }
313     list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
314
315     for (; aFamsIter != aFamilies.end(); aFamsIter++)
316     {
317       PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo);
318       myMed->SetFamilyInfo(aFamilyInfo);
319       int aFamId = (*aFamsIter)->GetId();
320
321       const set<const SMDS_MeshElement *>& anElems = (*aFamsIter)->GetElements();
322       set<const SMDS_MeshElement *>::iterator anElemsIter = anElems.begin();
323       for (; anElemsIter != anElems.end(); anElemsIter++)
324       {
325         anElemFamMap[*anElemsIter] = aFamId;
326       }
327 //      delete (*aFamsIter);
328     }
329
330     // Storing SMDS nodes to the MED file for the MED mesh
331     //----------------------------------------------------
332 #ifdef _EDF_NODE_IDS_
333     typedef map<TInt,TInt> TNodeIdMap;
334     TNodeIdMap aNodeIdMap;
335 #endif
336     TInt aNbElems = myMesh->NbNodes();
337     MED::TIntVector anElemNums(aNbElems);
338     MED::TIntVector aFamilyNums(aNbElems);
339     MED::TFloatVector aCoordinates(aNbElems*aMeshDimension);
340     for(TInt iNode = 0, aStartId = 0; aCoordHelperPtr->Next(); iNode++, aStartId += aMeshDimension){
341       for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
342         aCoordinates[aStartId+iCoord] = aCoordHelperPtr->GetCoord(iCoord);
343       }
344       int aNodeID = aCoordHelperPtr->GetID();
345       anElemNums[iNode] = aNodeID;
346 #ifdef _EDF_NODE_IDS_
347       aNodeIdMap[aNodeID] = iNode+1;
348 #endif
349       const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode();
350       if (anElemFamMap.find(aNode) != anElemFamMap.end())
351         aFamilyNums[iNode] = anElemFamMap[aNode];
352       else
353         aFamilyNums[iNode] = myNodesDefaultFamilyId;
354     }
355
356     MED::TStringVector aCoordNames(aMeshDimension);
357     MED::TStringVector aCoordUnits(aMeshDimension);
358     for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
359       aCoordNames[iCoord] = aCoordHelperPtr->GetName(iCoord);
360       aCoordUnits[iCoord] = aCoordHelperPtr->GetUnit(iCoord);
361     }
362
363     const ERepere SMDS_COORDINATE_SYSTEM = eCART;
364
365     PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo,
366                                             SMDS_COORDINATE_SYSTEM,
367                                             aCoordinates,
368                                             aCoordNames,
369                                             aCoordUnits,
370                                             aFamilyNums,
371                                             anElemNums);
372     MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems);
373     myMed->SetNodeInfo(aNodeInfo);
374
375
376     // Storing others SMDS elements to the MED file for the MED mesh
377     //--------------------------------------------------------------
378     EEntiteMaillage SMDS_MED_ENTITY = eMAILLE;
379     const EConnectivite SMDS_MED_CONNECTIVITY = eNOD;
380
381     // Storing SMDS Edges
382     if(TInt aNbElems = myMesh->NbEdges()){
383 #ifdef _ELEMENTS_BY_DIM_
384       SMDS_MED_ENTITY = eARETE;
385 #endif
386       SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
387       TInt aNbConnectivity = MED::GetNbNodes(eSEG2);
388       MED::TIntVector anElemNums(aNbElems);
389       MED::TIntVector aFamilyNums(aNbElems);
390       MED::TIntVector aConnectivity(aNbElems*aNbConnectivity);
391
392       for(TInt iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){
393         const SMDS_MeshEdge* anElem = anIter->next();
394         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
395         for(TInt iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){
396           const SMDS_MeshElement* aNode = aNodesIter->next();
397 #ifdef _EDF_NODE_IDS_
398           aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()];
399 #else
400           aConnectivity[iConn+iNode] = aNode->GetID();
401 #endif
402         }
403         anElemNums[iElem] = anElem->GetID();
404
405         if (anElemFamMap.find(anElem) != anElemFamMap.end())
406           aFamilyNums[iElem] = anElemFamMap[anElem];
407         else
408           aFamilyNums[iElem] = myEdgesDefaultFamilyId;
409       }
410       
411       PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
412                                               SMDS_MED_ENTITY,
413                                               eSEG2,
414                                               SMDS_MED_CONNECTIVITY,
415                                               aConnectivity,
416                                               aFamilyNums,
417                                               anElemNums);
418       myMed->SetCellInfo(aCellInfo);
419     }
420
421     // Storing SMDS Faces
422     if(TInt aNbElems = myMesh->NbFaces()){
423       SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
424 #ifdef _ELEMENTS_BY_DIM_
425       SMDS_MED_ENTITY = eFACE;
426 #endif
427       TInt aNbTriaConn = MED::GetNbNodes(eTRIA3);
428       MED::TIntVector anTriaElemNums; 
429       anTriaElemNums.reserve(aNbElems);
430       MED::TIntVector aTriaFamilyNums;
431       aTriaFamilyNums.reserve(aNbElems);
432       MED::TIntVector aTriaConn;
433       aTriaConn.reserve(aNbElems*aNbTriaConn);
434
435       TInt aNbQuadConn = MED::GetNbNodes(eQUAD4);
436       MED::TIntVector aQuadElemNums;
437       aQuadElemNums.reserve(aNbElems);
438       MED::TIntVector aQuadFamilyNums;
439       aQuadFamilyNums.reserve(aNbElems);
440       MED::TIntVector aQuadConn;
441       aQuadConn.reserve(aNbElems*aNbQuadConn);
442
443       for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
444         const SMDS_MeshFace* anElem = anIter->next();
445         TInt aNbNodes = anElem->NbNodes();
446         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
447         TInt aNbConnectivity;
448         MED::TIntVector* anElemNums;
449         MED::TIntVector* aFamilyNums;
450         MED::TIntVector* aConnectivity;
451         switch(aNbNodes){
452         case 3:
453           aNbConnectivity = aNbTriaConn;
454           anElemNums = &anTriaElemNums;
455           aFamilyNums = &aTriaFamilyNums;
456           aConnectivity = &aTriaConn;
457           break;
458         case 4:
459           aNbConnectivity = aNbQuadConn;
460           anElemNums = &aQuadElemNums;
461           aFamilyNums = &aQuadFamilyNums;
462           aConnectivity = &aQuadConn;
463           break;
464         }
465         MED::TIntVector aVector(aNbNodes);
466         for(TInt iNode = 0; aNodesIter->more(); iNode++){
467           const SMDS_MeshElement* aNode = aNodesIter->next();
468           aVector[iNode] = aNode->GetID();
469         }
470
471         TInt aSize = aConnectivity->size();
472         aConnectivity->resize(aSize+aNbConnectivity);
473         // There is some differnce between SMDS and MED in cells mapping
474 #ifdef _EDF_NODE_IDS_
475         switch(aNbNodes){
476         case 4:
477           (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]];
478           (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[1]];
479           (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[3]];  
480           (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[2]];  
481         default:
482           for(TInt iNode = 0; iNode < aNbNodes; iNode++) 
483             (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]];
484         }
485 #else
486         switch(aNbNodes){
487         case 4:
488           (*aConnectivity)[aSize+0] = aVector[0];
489           (*aConnectivity)[aSize+1] = aVector[1];
490           (*aConnectivity)[aSize+2] = aVector[3];  
491           (*aConnectivity)[aSize+3] = aVector[2];  
492         default:
493           for(TInt iNode = 0; iNode < aNbNodes; iNode++) 
494             (*aConnectivity)[aSize+iNode] = aVector[iNode];
495         }
496 #endif
497         anElemNums->push_back(anElem->GetID());
498
499         if (anElemFamMap.find(anElem) != anElemFamMap.end())
500           aFamilyNums->push_back(anElemFamMap[anElem]);
501         else
502           aFamilyNums->push_back(myFacesDefaultFamilyId);
503       }
504       if(TInt aNbElems = anTriaElemNums.size()){
505         PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
506                                                 SMDS_MED_ENTITY,
507                                                 eTRIA3,
508                                                 SMDS_MED_CONNECTIVITY,
509                                                 aTriaConn,
510                                                 aTriaFamilyNums,
511                                                 anTriaElemNums);
512         MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTRIA3<<"; aNbElems = "<<aNbElems);
513         myMed->SetCellInfo(aCellInfo);
514       }
515       if(TInt aNbElems = aQuadElemNums.size()){
516         PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
517                                                 SMDS_MED_ENTITY,
518                                                 eQUAD4,
519                                                 SMDS_MED_CONNECTIVITY,
520                                                 aQuadConn,
521                                                 aQuadFamilyNums,
522                                                 aQuadElemNums);
523         MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD4<<"; aNbElems = "<<aNbElems);
524         myMed->SetCellInfo(aCellInfo);
525       }
526     }
527
528     // Storing SMDS Volumes
529     if(TInt aNbElems = myMesh->NbVolumes()){
530       SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
531 #ifdef _ELEMENTS_BY_DIM_
532       SMDS_MED_ENTITY = eMAILLE;
533 #endif
534       TInt aNbTetraConn = MED::GetNbNodes(eTETRA4);
535       MED::TIntVector anTetraElemNums; 
536       anTetraElemNums.reserve(aNbElems);
537       MED::TIntVector aTetraFamilyNums;
538       aTetraFamilyNums.reserve(aNbElems);
539       MED::TIntVector aTetraConn;
540       aTetraConn.reserve(aNbElems*aNbTetraConn);
541
542       TInt aNbPyraConn = MED::GetNbNodes(ePYRA5);
543       MED::TIntVector anPyraElemNums; 
544       anPyraElemNums.reserve(aNbElems);
545       MED::TIntVector aPyraFamilyNums;
546       aPyraFamilyNums.reserve(aNbElems);
547       MED::TIntVector aPyraConn;
548       aPyraConn.reserve(aNbElems*aNbPyraConn);
549
550       TInt aNbPentaConn = MED::GetNbNodes(ePENTA6);
551       MED::TIntVector anPentaElemNums; 
552       anPentaElemNums.reserve(aNbElems);
553       MED::TIntVector aPentaFamilyNums;
554       aPentaFamilyNums.reserve(aNbElems);
555       MED::TIntVector aPentaConn;
556       aPentaConn.reserve(aNbElems*aNbPentaConn);
557
558       TInt aNbHexaConn = MED::GetNbNodes(eHEXA8);
559       MED::TIntVector aHexaElemNums;
560       aHexaElemNums.reserve(aNbElems);
561       MED::TIntVector aHexaFamilyNums;
562       aHexaFamilyNums.reserve(aNbElems);
563       MED::TIntVector aHexaConn;
564       aHexaConn.reserve(aNbElems*aNbHexaConn);
565
566       for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
567         const SMDS_MeshVolume* anElem = anIter->next();
568         TInt aNbNodes = anElem->NbNodes();
569         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
570         TInt aNbConnectivity;
571         MED::TIntVector* anElemNums;
572         MED::TIntVector* aFamilyNums;
573         MED::TIntVector* aConnectivity;
574         switch(aNbNodes){
575         case 4:
576           aNbConnectivity = aNbTetraConn;
577           anElemNums = &anTetraElemNums;
578           aFamilyNums = &aTetraFamilyNums;
579           aConnectivity = &aTetraConn;
580           break;
581         case 5:
582           aNbConnectivity = aNbPyraConn;
583           anElemNums = &anPyraElemNums;
584           aFamilyNums = &aPyraFamilyNums;
585           aConnectivity = &aPyraConn;
586           break;
587         case 6:
588           aNbConnectivity = aNbPentaConn;
589           anElemNums = &anPentaElemNums;
590           aFamilyNums = &aPentaFamilyNums;
591           aConnectivity = &aPentaConn;
592           break;
593         case 8:
594           aNbConnectivity = aNbHexaConn;
595           anElemNums = &aHexaElemNums;
596           aFamilyNums = &aHexaFamilyNums;
597           aConnectivity = &aHexaConn;
598         }
599
600         MED::TIntVector aVector(aNbNodes);
601         for(TInt iNode = 0; aNodesIter->more(); iNode++){
602           const SMDS_MeshElement* aNode = aNodesIter->next();
603           aVector[iNode] = aNode->GetID();
604         }
605         TInt aSize = aConnectivity->size();
606         aConnectivity->resize(aSize+aNbConnectivity);
607         // There is some difference between SMDS and MED in cells mapping
608 #ifdef _EDF_NODE_IDS_
609         switch(aNbNodes){
610         case 5:
611           (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]];
612           (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[3]];
613           (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[2]];  
614           (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[1]];  
615           (*aConnectivity)[aSize+4] = aNodeIdMap[aVector[4]];  
616         default:
617           for(TInt iNode = 0; iNode < aNbNodes; iNode++) 
618             (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]];
619         }
620 #else
621         switch(aNbNodes){
622         case 5:
623           (*aConnectivity)[aSize+0] = aVector[0];
624           (*aConnectivity)[aSize+1] = aVector[3];
625           (*aConnectivity)[aSize+2] = aVector[2];  
626           (*aConnectivity)[aSize+3] = aVector[1];  
627           (*aConnectivity)[aSize+4] = aVector[4];  
628         default:
629           for(TInt iNode = 0; iNode < aNbNodes; iNode++) 
630             (*aConnectivity)[aSize+iNode] = aVector[iNode];
631         }
632 #endif
633         anElemNums->push_back(anElem->GetID());
634
635         if (anElemFamMap.find(anElem) != anElemFamMap.end())
636           aFamilyNums->push_back(anElemFamMap[anElem]);
637         else
638           aFamilyNums->push_back(myVolumesDefaultFamilyId);
639       }
640
641       if(TInt aNbElems = anTetraElemNums.size()){
642         PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
643                                                 SMDS_MED_ENTITY,
644                                                 eTETRA4,
645                                                 SMDS_MED_CONNECTIVITY,
646                                                 aTetraConn,
647                                                 aTetraFamilyNums,
648                                                 anTetraElemNums);
649         MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eTETRA4<<"; aNbElems = "<<aNbElems);
650         myMed->SetCellInfo(aCellInfo);
651       }
652       if(TInt aNbElems = anPyraElemNums.size()){
653         PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
654                                                 SMDS_MED_ENTITY,
655                                                 ePYRA5,
656                                                 SMDS_MED_CONNECTIVITY,
657                                                 aPyraConn,
658                                                 aPyraFamilyNums,
659                                                 anPyraElemNums);
660         MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePYRA5<<"; aNbElems = "<<aNbElems);
661         myMed->SetCellInfo(aCellInfo);
662       }
663       if(TInt aNbElems = anPentaElemNums.size()){
664         PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
665                                                 SMDS_MED_ENTITY,
666                                                 ePENTA6,
667                                                 SMDS_MED_CONNECTIVITY,
668                                                 aPentaConn,
669                                                 aPentaFamilyNums,
670                                                 anPentaElemNums);
671         MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePENTA6<<"; aNbElems = "<<aNbElems);
672         myMed->SetCellInfo(aCellInfo);
673       }
674       if(TInt aNbElems = aHexaElemNums.size()){
675         PCellInfo aCellInfo = myMed->CrCellInfo(aMeshInfo,
676                                                 SMDS_MED_ENTITY,
677                                                 eHEXA8,
678                                                 SMDS_MED_CONNECTIVITY,
679                                                 aHexaConn,
680                                                 aHexaFamilyNums,
681                                                 aHexaElemNums);
682         MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA8<<"; aNbElems = "<<aNbElems);
683         myMed->SetCellInfo(aCellInfo);
684       }
685     }
686   }catch(const std::exception& exc){
687     INFOS("Follow exception was cought:\n\t"<<exc.what());
688   }catch(...){
689     INFOS("Unknown exception was cought !!!");
690   }
691
692   myMeshId = -1;
693   myGroups.clear();
694   mySubMeshes.clear();
695   return aResult;
696 }