Salome HOME
Polygons and polyhedral volumes support
[modules/smesh.git] / src / DriverMED / DriverMED_R_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_R_SMESHDS_Mesh.cxx
25 //  Module : SMESH
26
27 #include "DriverMED_R_SMESHDS_Mesh.h"
28 #include "DriverMED_R_SMDS_Mesh.h"
29 #include "SMESHDS_Mesh.hxx"
30 #include "utilities.h"
31
32 #include "DriverMED_Family.h"
33
34 #include "SMESHDS_Group.hxx"
35
36 #include "MED_Factory.hxx"
37 #include "MED_Utilities.hxx"
38
39 #include <stdlib.h>
40
41 #ifdef _DEBUG_
42 static int MYDEBUG = 0;
43 #else
44 static int MYDEBUG = 0;
45 #endif
46
47 #define _EDF_NODE_IDS_
48
49 using namespace MED;
50
51 void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
52 {
53   myMeshName = theMeshName;
54 }
55
56 static const SMDS_MeshNode* 
57 FindNode(const SMDS_Mesh* theMesh, TInt theId){
58   const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
59   if(aNode) return aNode;
60   EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
61 }
62
63
64 enum ECoordName{eX, eY, eZ, eNone};
65 typedef TFloat (*TGetCoord)(MED::PNodeInfo&, TInt);
66
67 template<ECoordName TheCoordId>
68 TFloat GetCoord(MED::PNodeInfo& thePNodeInfo, TInt theElemId){
69   return thePNodeInfo->GetNodeCoord(theElemId,TheCoordId);
70 }
71
72 template<>
73 TFloat GetCoord<eNone>(MED::PNodeInfo& thePNodeInfo, TInt theElemId){
74   return 0.0;
75 }
76
77
78 static TGetCoord aXYZGetCoord[3] = {
79   &GetCoord<eX>, 
80   &GetCoord<eY>, 
81   &GetCoord<eZ>
82 };
83
84
85 static TGetCoord aXYGetCoord[3] = {
86   &GetCoord<eX>, 
87   &GetCoord<eY>, 
88   &GetCoord<eNone>
89 };
90
91 static TGetCoord aYZGetCoord[3] = {
92   &GetCoord<eNone>,
93   &GetCoord<eX>, 
94   &GetCoord<eY>
95 };
96
97 static TGetCoord aXZGetCoord[3] = {
98   &GetCoord<eX>, 
99   &GetCoord<eNone>,
100   &GetCoord<eY>
101 };
102
103
104 static TGetCoord aXGetCoord[3] = {
105   &GetCoord<eX>, 
106   &GetCoord<eNone>,
107   &GetCoord<eNone>
108 };
109
110 static TGetCoord aYGetCoord[3] = {
111   &GetCoord<eNone>,
112   &GetCoord<eX>, 
113   &GetCoord<eNone>
114 };
115
116 static TGetCoord aZGetCoord[3] = {
117   &GetCoord<eNone>,
118   &GetCoord<eNone>,
119   &GetCoord<eX>
120 };
121
122
123 class TCoordHelper{
124   MED::PNodeInfo myPNodeInfo;
125   TGetCoord* myGetCoord;
126 public:
127   TCoordHelper(const MED::PNodeInfo& thePNodeInfo,
128                TGetCoord* theGetCoord):
129     myPNodeInfo(thePNodeInfo),
130     myGetCoord(theGetCoord)
131   {}
132   virtual ~TCoordHelper(){}
133   TFloat GetCoord(TInt theElemId, TInt theCoodId){
134     return (*myGetCoord[theCoodId])(myPNodeInfo,theElemId);
135   }
136 };
137 typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
138
139
140 Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
141 {
142   Status aResult = DRS_FAIL;
143   try{
144     myFamilies.clear();
145     if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
146     PWrapper aMed = CrWrapper(myFile);
147
148     aResult = DRS_EMPTY;
149     if(TInt aNbMeshes = aMed->GetNbMeshes()){
150       for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
151         // Reading the MED mesh
152         //---------------------
153         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
154         string aMeshName;
155         if (myMeshId != -1) {
156           ostringstream aMeshNameStr;
157           aMeshNameStr<<myMeshId;
158           aMeshName = aMeshNameStr.str();
159         } else {
160           aMeshName = myMeshName;
161         }
162         if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
163         if(aMeshName != aMeshInfo->GetName()) continue;
164         aResult = DRS_OK;
165         //TInt aMeshDim = aMeshInfo->GetDim();
166         
167         // Reading MED families to the temporary structure
168         //------------------------------------------------
169         TErr anErr;
170         TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
171         if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
172         for (TInt iFam = 0; iFam < aNbFams; iFam++) {
173           PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
174           if(anErr >= 0){
175             TInt aFamId = aFamilyInfo->GetId();
176             if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
177             
178             DriverMED_FamilyPtr aFamily (new DriverMED_Family);
179             
180             TInt aNbGrp = aFamilyInfo->GetNbGroup();
181             if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
182             for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
183               string aGroupName = aFamilyInfo->GetGroupName(iGr);
184               if(MYDEBUG) MESSAGE(aGroupName);
185               aFamily->AddGroupName(aGroupName);
186             }
187             myFamilies[aFamId] = aFamily;
188           }
189         }
190
191         // Reading MED nodes to the corresponding SMDS structure
192         //------------------------------------------------------
193         PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
194
195         TCoordHelperPtr aCoordHelperPtr;
196         {
197           TInt aMeshDimension = aMeshInfo->GetDim();
198           bool anIsDimPresent[3] = {false, false, false};
199           for(TInt iDim = 0; iDim < aMeshDimension; iDim++){
200             string aDimName = aNodeInfo->GetCoordName(iDim);
201             if(aDimName == "x" || aDimName == "X")
202               anIsDimPresent[eX] = true;
203             else if(aDimName == "y" || aDimName == "Y")
204               anIsDimPresent[eY] = true;
205             else if(aDimName == "z" || aDimName == "Z")
206               anIsDimPresent[eZ] = true;
207           }
208           switch(aMeshDimension){
209           case 3:
210             aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aXYZGetCoord));
211             break;
212           case 2:
213             if(anIsDimPresent[eY] && anIsDimPresent[eZ])
214               aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aYZGetCoord));
215             else if(anIsDimPresent[eX] && anIsDimPresent[eZ])
216               aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aXZGetCoord));
217             else
218               aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aXYGetCoord));
219             break;
220           case 1:
221             if(anIsDimPresent[eY])
222               aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aYGetCoord));
223             else if(anIsDimPresent[eZ])
224               aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aZGetCoord));
225             else
226               aCoordHelperPtr.reset(new TCoordHelper(aNodeInfo,aXGetCoord));
227             break;
228           }
229         }
230
231         EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
232         TInt aNbElems = aNodeInfo->GetNbElem();
233         if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
234         for(TInt iElem = 0; iElem < aNbElems; iElem++){
235           double aCoords[3] = {0.0, 0.0, 0.0};
236           for(TInt iDim = 0; iDim < 3; iDim++)
237             aCoords[iDim] = aCoordHelperPtr->GetCoord(iElem,iDim);
238           const SMDS_MeshNode* aNode;
239           if(anIsNodeNum) {
240             aNode = myMesh->AddNodeWithID
241               (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
242           } else {
243             aNode = myMesh->AddNode
244               (aCoords[0],aCoords[1],aCoords[2]);
245           }
246           //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
247
248           // Save reference to this node from its family
249           TInt aFamNum = aNodeInfo->GetFamNum(iElem);
250           if (myFamilies.find(aFamNum) != myFamilies.end())
251           {
252             myFamilies[aFamNum]->AddElement(aNode);
253             myFamilies[aFamNum]->SetType(SMDSAbs_Node);
254           }
255         }
256
257         // Reading pre information about all MED cells
258         //--------------------------------------------
259         bool takeNumbers = true;  // initially we trust the numbers from file
260         MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo);
261         MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
262         for(; anEntityIter != aEntityInfo.end(); anEntityIter++){
263           const EEntiteMaillage& anEntity = anEntityIter->first;
264           if(anEntity == eNOEUD) continue;
265           // Reading MED cells to the corresponding SMDS structure
266           //------------------------------------------------------
267           const MED::TGeom& aTGeom = anEntityIter->second;
268           MED::TGeom::const_iterator anTGeomIter = aTGeom.begin();
269           for(; anTGeomIter != aTGeom.end(); anTGeomIter++){
270             const EGeometrieElement& aGeom = anTGeomIter->first;
271
272             if (aGeom == ePOINT1) {
273               continue;
274
275             } else if (aGeom == ePOLYGONE) {
276               PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
277               EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
278
279               TElemNum aConn  = aPolygoneInfo->GetConnectivite();
280               TElemNum aIndex = aPolygoneInfo->GetIndex();
281
282               TInt nbPolygons = aPolygoneInfo->GetNbElem();
283
284               for (TInt iPG = 0; iPG < nbPolygons; iPG++) {
285                 // get nodes
286                 TInt aCurrPG_FirstNodeIndex = aIndex[iPG] - 1;
287                 int nbNodes = aPolygoneInfo->GetNbConn(iPG);
288                 std::vector<int> nodes_ids (nbNodes);
289                 for (TInt inode = 0; inode < nbNodes; inode++) {
290                   nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
291                 }
292
293                 bool isRenum = false;
294                 SMDS_MeshElement* anElement = NULL;
295                 TInt aFamNum = aPolygoneInfo->GetFamNum(iPG);
296
297                 try {
298                   if (anIsElemNum) {
299                     anElement = myMesh->AddPolygonalFaceWithID
300                       (nodes_ids, aPolygoneInfo->GetElemNum(iPG));
301                   }
302                   if (!anElement) {
303                     std::vector<const SMDS_MeshNode*> nodes (nbNodes);
304                     for (int inode = 0; inode < nbNodes; inode++) {
305                       nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
306                     }
307                     anElement = myMesh->AddPolygonalFace(nodes);
308                     isRenum = anIsElemNum;
309                   }
310                 } catch (const std::exception& exc) {
311                   aResult = DRS_FAIL;
312                 } catch (...) {
313                   aResult = DRS_FAIL;
314                 }
315
316                 if (!anElement) {
317                   aResult = DRS_WARN_SKIP_ELEM;
318                 } else {
319                   if (isRenum) {
320                     anIsElemNum = eFAUX;
321                     takeNumbers = false;
322                     if (aResult < DRS_WARN_RENUMBER)
323                       aResult = DRS_WARN_RENUMBER;
324                   }
325                   if (myFamilies.find(aFamNum) != myFamilies.end()) {
326                     // Save reference to this element from its family
327                     myFamilies[aFamNum]->AddElement(anElement);
328                     myFamilies[aFamNum]->SetType(anElement->GetType());
329                   }
330                 }
331               } // for (TInt iPG = 0; iPG < nbPolygons; iPG++)
332               continue;
333
334             } else if (aGeom == ePOLYEDRE) {
335               PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
336               EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
337
338               TElemNum aConn       = aPolyedreInfo->GetConnectivite();
339               TElemNum aFacesIndex = aPolyedreInfo->GetFacesIndex();
340               TElemNum aIndex      = aPolyedreInfo->GetIndex();
341
342               TInt nbPolyedres = aPolyedreInfo->GetNbElem();
343
344               for (int iPE = 0; iPE < nbPolyedres; iPE++) {
345                 // get faces
346                 int aCurrPE_FirstFaceIndex = aIndex[iPE] - 1;
347                 int aNextPE_FirstFaceIndex = aIndex[iPE + 1] - 1;
348                 int nbFaces = aNextPE_FirstFaceIndex - aCurrPE_FirstFaceIndex;
349                 std::vector<int> quantities (nbFaces);
350                 for (int iFa = 0; iFa < nbFaces; iFa++) {
351                   int aCurrFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa] - 1;
352                   int aNextFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa + 1] - 1;
353
354                   int nbNodes = aNextFace_FirstNodeIndex - aCurrFace_FirstNodeIndex;
355                   quantities[iFa] = nbNodes;
356                 }
357
358                 // get nodes
359                 int aCurrPE_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex] - 1;
360                 int nbPENodes = aPolyedreInfo->GetNbConn(iPE);
361                 std::vector<int> nodes_ids (nbPENodes);
362                 for (int inode = 0; inode < nbPENodes; inode++) {
363                   nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
364                 }
365
366                 bool isRenum = false;
367                 SMDS_MeshElement* anElement = NULL;
368                 TInt aFamNum = aPolyedreInfo->GetFamNum(iPE);
369
370                 try {
371                   if (anIsElemNum) {
372                     anElement = myMesh->AddPolyhedralVolumeWithID
373                       (nodes_ids, quantities, aPolyedreInfo->GetElemNum(iPE));
374                   }
375                   if (!anElement) {
376                     std::vector<const SMDS_MeshNode*> nodes (nbPENodes);
377                     for (int inode = 0; inode < nbPENodes; inode++) {
378                       nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
379                     }
380                     anElement = myMesh->AddPolyhedralVolume(nodes, quantities);
381                     isRenum = anIsElemNum;
382                   }
383                 } catch (const std::exception& exc) {
384                   aResult = DRS_FAIL;
385                 } catch (...) {
386                   aResult = DRS_FAIL;
387                 }
388
389                 if (!anElement) {
390                   aResult = DRS_WARN_SKIP_ELEM;
391                 } else {
392                   if (isRenum) {
393                     anIsElemNum = eFAUX;
394                     takeNumbers = false;
395                     if (aResult < DRS_WARN_RENUMBER)
396                       aResult = DRS_WARN_RENUMBER;
397                   }
398                   if (myFamilies.find(aFamNum) != myFamilies.end()) {
399                     // Save reference to this element from its family
400                     myFamilies[aFamNum]->AddElement(anElement);
401                     myFamilies[aFamNum]->SetType(anElement->GetType());
402                   }
403                 }
404               } // for (int iPE = 0; iPE < nbPolyedres; iPE++)
405               continue;
406
407             } else {
408             }
409
410             PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
411             EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
412             TInt aNbElems = aCellInfo->GetNbElem();
413             if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
414             if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
415
416             for(int iElem = 0; iElem < aNbElems; iElem++){
417               TInt aNbNodes = -1;
418               switch(aGeom){
419               case eSEG2:
420               case eSEG3:
421                 aNbNodes = 2;
422                 break;
423               case eTRIA3:
424               case eTRIA6:
425                 aNbNodes = 3;
426                 break;
427                 break;
428               case eQUAD4:
429               case eQUAD8:
430                 aNbNodes = 4;
431                 break;
432               case eTETRA4:
433               case eTETRA10:
434                 aNbNodes = 4;
435                 break;
436               case ePYRA5:
437               case ePYRA13:
438                 aNbNodes = 5;
439                 break;
440               case ePENTA6:
441               case ePENTA15:
442                 aNbNodes = 6;
443                 break;
444               case eHEXA8:
445               case eHEXA20:
446                 aNbNodes = 8;
447                 break;
448               }
449               vector<TInt> aNodeIds(aNbNodes);
450               bool anIsValidConnect = false;
451
452               try{
453 #ifdef _EDF_NODE_IDS_
454                 if(anIsNodeNum) {
455                   for(int i = 0; i < aNbNodes; i++){
456                     aNodeIds[i] = aNodeInfo->GetElemNum(aCellInfo->GetConn(iElem,i)-1);
457                   }
458                 }else{
459                   for(int i = 0; i < aNbNodes; i++){
460                     aNodeIds[i] = aCellInfo->GetConn(iElem,i);
461                   }
462                 }
463 #else
464                 for(int i = 0; i < aNbNodes; i++){
465                   aNodeIds[i] = aCellInfo->GetConn(iElem,i);
466                 }
467 #endif
468                 anIsValidConnect = true;
469               }catch(const std::exception& exc){
470                 //INFOS("Follow exception was cought:\n\t"<<exc.what());
471                 aResult = DRS_FAIL;
472               }catch(...){
473                 //INFOS("Unknown exception was cought !!!");
474                 aResult = DRS_FAIL;
475               }
476               
477               if(!anIsValidConnect)
478                 continue;
479
480               bool isRenum = false;
481               SMDS_MeshElement* anElement = NULL;
482               TInt aFamNum = aCellInfo->GetFamNum(iElem);
483               try{
484                 //MESSAGE("Try to create element # " << iElem << " with id = "
485                 //        << aCellInfo->GetElemNum(iElem));
486                 switch(aGeom){
487                 case eSEG2:
488                 case eSEG3:
489                   if(anIsElemNum)
490                     anElement = myMesh->AddEdgeWithID(aNodeIds[0],
491                                                       aNodeIds[1],
492                                                       aCellInfo->GetElemNum(iElem));
493                   if (!anElement) {
494                     anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
495                                                 FindNode(myMesh,aNodeIds[1]));
496                     isRenum = anIsElemNum;
497                   }
498                   break;
499                 case eTRIA3:
500                 case eTRIA6:
501                   aNbNodes = 3;
502                   if(anIsElemNum)
503                     anElement = myMesh->AddFaceWithID(aNodeIds[0],
504                                                       aNodeIds[1],
505                                                       aNodeIds[2],
506                                                       aCellInfo->GetElemNum(iElem));
507                   if (!anElement) {
508                     anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
509                                                 FindNode(myMesh,aNodeIds[1]),
510                                                 FindNode(myMesh,aNodeIds[2]));
511                     isRenum = anIsElemNum;
512                   }
513                   break;
514                 case eQUAD4:
515                 case eQUAD8:
516                   aNbNodes = 4;
517                   // There is some differnce between SMDS and MED
518                   if(anIsElemNum)
519                     anElement = myMesh->AddFaceWithID(aNodeIds[0],
520                                                       aNodeIds[1],
521                                                       aNodeIds[2],
522                                                       aNodeIds[3],
523                                                       aCellInfo->GetElemNum(iElem));
524                   if (!anElement) {
525                     anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
526                                                 FindNode(myMesh,aNodeIds[1]),
527                                                 FindNode(myMesh,aNodeIds[2]),
528                                                 FindNode(myMesh,aNodeIds[3]));
529                     isRenum = anIsElemNum;
530                   }
531                   break;
532                 case eTETRA4:
533                 case eTETRA10:
534                   aNbNodes = 4;
535                   if(anIsElemNum)
536                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
537                                                         aNodeIds[1],
538                                                         aNodeIds[2],
539                                                         aNodeIds[3],
540                                                         aCellInfo->GetElemNum(iElem));
541                   if (!anElement) {
542                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
543                                                   FindNode(myMesh,aNodeIds[1]),
544                                                   FindNode(myMesh,aNodeIds[2]),
545                                                   FindNode(myMesh,aNodeIds[3]));
546                     isRenum = anIsElemNum;
547                   }
548                   break;
549                 case ePYRA5:
550                 case ePYRA13:
551                   aNbNodes = 5;
552                   // There is some differnce between SMDS and MED
553                   if(anIsElemNum)
554                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
555                                                         aNodeIds[1],
556                                                         aNodeIds[2],
557                                                         aNodeIds[3],
558                                                         aNodeIds[4],
559                                                         aCellInfo->GetElemNum(iElem));
560                   if (!anElement) {
561                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
562                                                   FindNode(myMesh,aNodeIds[1]),
563                                                   FindNode(myMesh,aNodeIds[2]),
564                                                   FindNode(myMesh,aNodeIds[3]),
565                                                   FindNode(myMesh,aNodeIds[4]));
566                     isRenum = anIsElemNum;
567                   }
568                   break;
569                 case ePENTA6:
570                 case ePENTA15:
571                   aNbNodes = 6;
572                   if(anIsElemNum)
573                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
574                                                         aNodeIds[1],
575                                                         aNodeIds[2],
576                                                         aNodeIds[3],
577                                                         aNodeIds[4],
578                                                         aNodeIds[5],
579                                                         aCellInfo->GetElemNum(iElem));
580                   if (!anElement) {
581                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
582                                                   FindNode(myMesh,aNodeIds[1]),
583                                                   FindNode(myMesh,aNodeIds[2]),
584                                                   FindNode(myMesh,aNodeIds[3]),
585                                                   FindNode(myMesh,aNodeIds[4]),
586                                                   FindNode(myMesh,aNodeIds[5]));
587                     isRenum = anIsElemNum;
588                   }
589                   break;
590                 case eHEXA8:
591                 case eHEXA20:
592                   aNbNodes = 8;
593                   if(anIsElemNum)
594                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
595                                                         aNodeIds[1],
596                                                         aNodeIds[2],
597                                                         aNodeIds[3],
598                                                         aNodeIds[4],
599                                                         aNodeIds[5],
600                                                         aNodeIds[6],
601                                                         aNodeIds[7],
602                                                         aCellInfo->GetElemNum(iElem));
603                   if (!anElement) {
604                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
605                                                   FindNode(myMesh,aNodeIds[1]),
606                                                   FindNode(myMesh,aNodeIds[2]),
607                                                   FindNode(myMesh,aNodeIds[3]),
608                                                   FindNode(myMesh,aNodeIds[4]),
609                                                   FindNode(myMesh,aNodeIds[5]),
610                                                   FindNode(myMesh,aNodeIds[6]),
611                                                   FindNode(myMesh,aNodeIds[7]));
612                     isRenum = anIsElemNum;
613                   }
614                   break;
615                 }
616               }catch(const std::exception& exc){
617                 //INFOS("Follow exception was cought:\n\t"<<exc.what());
618                 aResult = DRS_FAIL;
619               }catch(...){
620                 //INFOS("Unknown exception was cought !!!");
621                 aResult = DRS_FAIL;
622               }
623                 
624               if (!anElement) {
625                 aResult = DRS_WARN_SKIP_ELEM;
626               }
627               else {
628                 if (isRenum) {
629                   anIsElemNum = eFAUX;
630                   takeNumbers = false;
631                   if (aResult < DRS_WARN_RENUMBER)
632                     aResult = DRS_WARN_RENUMBER;
633                 }
634                 if (myFamilies.find(aFamNum) != myFamilies.end()) {
635                   // Save reference to this element from its family
636                   myFamilies[aFamNum]->AddElement(anElement);
637                   myFamilies[aFamNum]->SetType(anElement->GetType());
638                 }
639               }
640             }
641           }
642         }
643         break;
644       }
645     }
646   }catch(const std::exception& exc){
647     INFOS("Follow exception was cought:\n\t"<<exc.what());
648     aResult = DRS_FAIL;
649   }catch(...){
650     INFOS("Unknown exception was cought !!!");
651     aResult = DRS_FAIL;
652   }
653   if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
654   return aResult;
655 }
656
657 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
658 {
659   list<string> aMeshNames;
660
661   try {
662     if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
663     theStatus = DRS_OK;
664     PWrapper aMed = CrWrapper(myFile);
665
666     if (TInt aNbMeshes = aMed->GetNbMeshes()) {
667       for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
668         // Reading the MED mesh
669         //---------------------
670         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
671         aMeshNames.push_back(aMeshInfo->GetName());
672       }
673     }
674   }catch(const std::exception& exc){
675     INFOS("Follow exception was cought:\n\t"<<exc.what());
676     theStatus = DRS_FAIL;
677   }catch(...){
678     INFOS("Unknown exception was cought !!!");
679     theStatus = DRS_FAIL;
680   }
681
682   return aMeshNames;
683 }
684
685 list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
686 {
687   list<string> aResult;
688   set<string> aResGroupNames;
689
690   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
691   for (; aFamsIter != myFamilies.end(); aFamsIter++)
692   {
693     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
694     const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
695     set<string>::iterator aGrNamesIter = aGroupNames.begin();
696     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
697     {
698       string aName = *aGrNamesIter;
699       // Check, if this is a Group or SubMesh name
700 //if (aName.substr(0, 5) == string("Group")) {
701         if (aResGroupNames.find(aName) == aResGroupNames.end()) {
702           aResGroupNames.insert(aName);
703           aResult.push_back(aName);
704         }
705 //    }
706     }
707   }
708
709   return aResult;
710 }
711
712 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
713 {
714   string aGroupName (theGroup->GetStoreName());
715   if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
716
717   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
718   for (; aFamsIter != myFamilies.end(); aFamsIter++)
719   {
720     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
721     if (aFamily->MemberOf(aGroupName))
722     {
723       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
724       set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
725       const SMDS_MeshElement * element = 0;
726       for (; anElemsIter != anElements.end(); anElemsIter++)
727       {
728         element = *anElemsIter;
729         theGroup->SMDSGroup().Add(element);
730       }
731       if ( element )
732         theGroup->SetType( element->GetType() );
733     }
734   }
735 }
736
737 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
738                                            const int theId)
739 {
740   char submeshGrpName[ 30 ];
741   sprintf( submeshGrpName, "SubMesh %d", theId );
742   string aName (submeshGrpName);
743   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
744   for (; aFamsIter != myFamilies.end(); aFamsIter++)
745   {
746     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
747     if (aFamily->MemberOf(aName))
748     {
749       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
750       set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
751       if (aFamily->GetType() == SMDSAbs_Node)
752       {
753         for (; anElemsIter != anElements.end(); anElemsIter++)
754         {
755           const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
756           theSubMesh->AddNode(node);
757         }
758       }
759       else
760       {
761         for (; anElemsIter != anElements.end(); anElemsIter++)
762         {
763           theSubMesh->AddElement(*anElemsIter);
764         }
765       }
766     }
767   }
768 }
769
770 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
771 {
772   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
773   for (; aFamsIter != myFamilies.end(); aFamsIter++)
774   {
775     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
776     MED::TStringSet aGroupNames = aFamily->GetGroupNames();
777     set<string>::iterator aGrNamesIter = aGroupNames.begin();
778     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
779     {
780       string aName = *aGrNamesIter;
781       // Check, if this is a Group or SubMesh name
782       if (aName.substr(0, 7) == string("SubMesh"))
783       {
784         int Id = atoi(string(aName).substr(7).c_str());
785         set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
786         set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
787         if (aFamily->GetType() == SMDSAbs_Node)
788         {
789           for (; anElemsIter != anElements.end(); anElemsIter++)
790           {
791             SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
792               ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
793             // find out a shape type
794             TopoDS_Shape aShape = myMesh->IndexToShape( Id );
795             int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
796             switch ( aShapeType ) {
797             case TopAbs_FACE:
798               myMesh->SetNodeOnFace(node, Id); break;
799             case TopAbs_EDGE:
800               myMesh->SetNodeOnEdge(node, Id); break;
801             case TopAbs_VERTEX:
802               myMesh->SetNodeOnVertex(node, Id); break;
803             default:
804               myMesh->SetNodeInVolume(node, Id);
805             }
806           }
807         }
808         else
809         {
810           for (; anElemsIter != anElements.end(); anElemsIter++)
811           {
812             myMesh->SetMeshElementOnShape(*anElemsIter, Id);
813           }
814         }
815       }
816     }
817   }
818 }