Salome HOME
SMH: Preparation version 3.0.0 - merge (HEAD+POLYWORK)
[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 #ifdef _EDF_NODE_IDS_
293                 if (anIsNodeNum) {
294                   for (TInt inode = 0; inode < nbNodes; inode++) {
295                     nodes_ids[inode] = aNodeInfo->GetElemNum(aConn[aCurrPG_FirstNodeIndex + inode] - 1);
296                   }
297                 } else {
298                   for (TInt inode = 0; inode < nbNodes; inode++) {
299                     nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
300                   }
301                 }
302 #else
303                 for (TInt inode = 0; inode < nbNodes; inode++) {
304                   nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
305                 }
306 #endif
307
308                 bool isRenum = false;
309                 SMDS_MeshElement* anElement = NULL;
310                 TInt aFamNum = aPolygoneInfo->GetFamNum(iPG);
311
312                 try {
313                   if (anIsElemNum) {
314                     anElement = myMesh->AddPolygonalFaceWithID
315                       (nodes_ids, aPolygoneInfo->GetElemNum(iPG));
316                   }
317                   if (!anElement) {
318                     std::vector<const SMDS_MeshNode*> nodes (nbNodes);
319                     for (int inode = 0; inode < nbNodes; inode++) {
320                       nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
321                     }
322                     anElement = myMesh->AddPolygonalFace(nodes);
323                     isRenum = anIsElemNum;
324                   }
325                 } catch (const std::exception& exc) {
326                   aResult = DRS_FAIL;
327                 } catch (...) {
328                   aResult = DRS_FAIL;
329                 }
330
331                 if (!anElement) {
332                   aResult = DRS_WARN_SKIP_ELEM;
333                 } else {
334                   if (isRenum) {
335                     anIsElemNum = eFAUX;
336                     takeNumbers = false;
337                     if (aResult < DRS_WARN_RENUMBER)
338                       aResult = DRS_WARN_RENUMBER;
339                   }
340                   if (myFamilies.find(aFamNum) != myFamilies.end()) {
341                     // Save reference to this element from its family
342                     myFamilies[aFamNum]->AddElement(anElement);
343                     myFamilies[aFamNum]->SetType(anElement->GetType());
344                   }
345                 }
346               } // for (TInt iPG = 0; iPG < nbPolygons; iPG++)
347               continue;
348
349             } else if (aGeom == ePOLYEDRE) {
350               PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
351               EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
352
353               TElemNum aConn       = aPolyedreInfo->GetConnectivite();
354               TElemNum aFacesIndex = aPolyedreInfo->GetFacesIndex();
355               TElemNum aIndex      = aPolyedreInfo->GetIndex();
356
357               TInt nbPolyedres = aPolyedreInfo->GetNbElem();
358
359               for (int iPE = 0; iPE < nbPolyedres; iPE++) {
360                 // get faces
361                 int aCurrPE_FirstFaceIndex = aIndex[iPE] - 1;
362                 int aNextPE_FirstFaceIndex = aIndex[iPE + 1] - 1;
363                 int nbFaces = aNextPE_FirstFaceIndex - aCurrPE_FirstFaceIndex;
364                 std::vector<int> quantities (nbFaces);
365                 for (int iFa = 0; iFa < nbFaces; iFa++) {
366                   int aCurrFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa] - 1;
367                   int aNextFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa + 1] - 1;
368
369                   int nbNodes = aNextFace_FirstNodeIndex - aCurrFace_FirstNodeIndex;
370                   quantities[iFa] = nbNodes;
371                 }
372
373                 // get nodes
374                 int aCurrPE_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex] - 1;
375                 int nbPENodes = aPolyedreInfo->GetNbConn(iPE);
376                 std::vector<int> nodes_ids (nbPENodes);
377                 //for (int inode = 0; inode < nbPENodes; inode++) {
378                 //  nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
379                 //}
380 #ifdef _EDF_NODE_IDS_
381                 if (anIsNodeNum) {
382                   for (int inode = 0; inode < nbPENodes; inode++) {
383                     nodes_ids[inode] = aNodeInfo->GetElemNum(aConn[aCurrPE_FirstNodeIndex + inode] - 1);
384                   }
385                 } else {
386                   for (int inode = 0; inode < nbPENodes; inode++) {
387                     nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
388                   }
389                 }
390 #else
391                 for (int inode = 0; inode < nbPENodes; inode++) {
392                   nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
393                 }
394 #endif
395
396                 bool isRenum = false;
397                 SMDS_MeshElement* anElement = NULL;
398                 TInt aFamNum = aPolyedreInfo->GetFamNum(iPE);
399
400                 try {
401                   if (anIsElemNum) {
402                     anElement = myMesh->AddPolyhedralVolumeWithID
403                       (nodes_ids, quantities, aPolyedreInfo->GetElemNum(iPE));
404                   }
405                   if (!anElement) {
406                     std::vector<const SMDS_MeshNode*> nodes (nbPENodes);
407                     for (int inode = 0; inode < nbPENodes; inode++) {
408                       nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
409                     }
410                     anElement = myMesh->AddPolyhedralVolume(nodes, quantities);
411                     isRenum = anIsElemNum;
412                   }
413                 } catch (const std::exception& exc) {
414                   aResult = DRS_FAIL;
415                 } catch (...) {
416                   aResult = DRS_FAIL;
417                 }
418
419                 if (!anElement) {
420                   aResult = DRS_WARN_SKIP_ELEM;
421                 } else {
422                   if (isRenum) {
423                     anIsElemNum = eFAUX;
424                     takeNumbers = false;
425                     if (aResult < DRS_WARN_RENUMBER)
426                       aResult = DRS_WARN_RENUMBER;
427                   }
428                   if (myFamilies.find(aFamNum) != myFamilies.end()) {
429                     // Save reference to this element from its family
430                     myFamilies[aFamNum]->AddElement(anElement);
431                     myFamilies[aFamNum]->SetType(anElement->GetType());
432                   }
433                 }
434               } // for (int iPE = 0; iPE < nbPolyedres; iPE++)
435               continue;
436
437             } else {
438             }
439
440             PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
441             EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
442             TInt aNbElems = aCellInfo->GetNbElem();
443             if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
444             if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
445
446             for(int iElem = 0; iElem < aNbElems; iElem++){
447               TInt aNbNodes = -1;
448               switch(aGeom){
449               case eSEG2:
450               case eSEG3:
451                 aNbNodes = 2;
452                 break;
453               case eTRIA3:
454               case eTRIA6:
455                 aNbNodes = 3;
456                 break;
457                 break;
458               case eQUAD4:
459               case eQUAD8:
460                 aNbNodes = 4;
461                 break;
462               case eTETRA4:
463               case eTETRA10:
464                 aNbNodes = 4;
465                 break;
466               case ePYRA5:
467               case ePYRA13:
468                 aNbNodes = 5;
469                 break;
470               case ePENTA6:
471               case ePENTA15:
472                 aNbNodes = 6;
473                 break;
474               case eHEXA8:
475               case eHEXA20:
476                 aNbNodes = 8;
477                 break;
478               }
479               vector<TInt> aNodeIds(aNbNodes);
480               bool anIsValidConnect = false;
481
482               try{
483 #ifdef _EDF_NODE_IDS_
484                 if(anIsNodeNum) {
485                   for(int i = 0; i < aNbNodes; i++){
486                     aNodeIds[i] = aNodeInfo->GetElemNum(aCellInfo->GetConn(iElem,i)-1);
487                   }
488                 }else{
489                   for(int i = 0; i < aNbNodes; i++){
490                     aNodeIds[i] = aCellInfo->GetConn(iElem,i);
491                   }
492                 }
493 #else
494                 for(int i = 0; i < aNbNodes; i++){
495                   aNodeIds[i] = aCellInfo->GetConn(iElem,i);
496                 }
497 #endif
498                 anIsValidConnect = true;
499               }catch(const std::exception& exc){
500                 //INFOS("Follow exception was cought:\n\t"<<exc.what());
501                 aResult = DRS_FAIL;
502               }catch(...){
503                 //INFOS("Unknown exception was cought !!!");
504                 aResult = DRS_FAIL;
505               }
506               
507               if(!anIsValidConnect)
508                 continue;
509
510               bool isRenum = false;
511               SMDS_MeshElement* anElement = NULL;
512               TInt aFamNum = aCellInfo->GetFamNum(iElem);
513               try{
514                 //MESSAGE("Try to create element # " << iElem << " with id = "
515                 //        << aCellInfo->GetElemNum(iElem));
516                 switch(aGeom){
517                 case eSEG2:
518                 case eSEG3:
519                   if(anIsElemNum)
520                     anElement = myMesh->AddEdgeWithID(aNodeIds[0],
521                                                       aNodeIds[1],
522                                                       aCellInfo->GetElemNum(iElem));
523                   if (!anElement) {
524                     anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
525                                                 FindNode(myMesh,aNodeIds[1]));
526                     isRenum = anIsElemNum;
527                   }
528                   break;
529                 case eTRIA3:
530                 case eTRIA6:
531                   aNbNodes = 3;
532                   if(anIsElemNum)
533                     anElement = myMesh->AddFaceWithID(aNodeIds[0],
534                                                       aNodeIds[1],
535                                                       aNodeIds[2],
536                                                       aCellInfo->GetElemNum(iElem));
537                   if (!anElement) {
538                     anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
539                                                 FindNode(myMesh,aNodeIds[1]),
540                                                 FindNode(myMesh,aNodeIds[2]));
541                     isRenum = anIsElemNum;
542                   }
543                   break;
544                 case eQUAD4:
545                 case eQUAD8:
546                   aNbNodes = 4;
547                   // There is some differnce between SMDS and MED
548                   if(anIsElemNum)
549                     anElement = myMesh->AddFaceWithID(aNodeIds[0],
550                                                       aNodeIds[1],
551                                                       aNodeIds[2],
552                                                       aNodeIds[3],
553                                                       aCellInfo->GetElemNum(iElem));
554                   if (!anElement) {
555                     anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
556                                                 FindNode(myMesh,aNodeIds[1]),
557                                                 FindNode(myMesh,aNodeIds[2]),
558                                                 FindNode(myMesh,aNodeIds[3]));
559                     isRenum = anIsElemNum;
560                   }
561                   break;
562                 case eTETRA4:
563                 case eTETRA10:
564                   aNbNodes = 4;
565                   if(anIsElemNum)
566                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
567                                                         aNodeIds[1],
568                                                         aNodeIds[2],
569                                                         aNodeIds[3],
570                                                         aCellInfo->GetElemNum(iElem));
571                   if (!anElement) {
572                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
573                                                   FindNode(myMesh,aNodeIds[1]),
574                                                   FindNode(myMesh,aNodeIds[2]),
575                                                   FindNode(myMesh,aNodeIds[3]));
576                     isRenum = anIsElemNum;
577                   }
578                   break;
579                 case ePYRA5:
580                 case ePYRA13:
581                   aNbNodes = 5;
582                   // There is some differnce between SMDS and MED
583                   if(anIsElemNum)
584                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
585                                                         aNodeIds[1],
586                                                         aNodeIds[2],
587                                                         aNodeIds[3],
588                                                         aNodeIds[4],
589                                                         aCellInfo->GetElemNum(iElem));
590                   if (!anElement) {
591                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
592                                                   FindNode(myMesh,aNodeIds[1]),
593                                                   FindNode(myMesh,aNodeIds[2]),
594                                                   FindNode(myMesh,aNodeIds[3]),
595                                                   FindNode(myMesh,aNodeIds[4]));
596                     isRenum = anIsElemNum;
597                   }
598                   break;
599                 case ePENTA6:
600                 case ePENTA15:
601                   aNbNodes = 6;
602                   if(anIsElemNum)
603                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
604                                                         aNodeIds[1],
605                                                         aNodeIds[2],
606                                                         aNodeIds[3],
607                                                         aNodeIds[4],
608                                                         aNodeIds[5],
609                                                         aCellInfo->GetElemNum(iElem));
610                   if (!anElement) {
611                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
612                                                   FindNode(myMesh,aNodeIds[1]),
613                                                   FindNode(myMesh,aNodeIds[2]),
614                                                   FindNode(myMesh,aNodeIds[3]),
615                                                   FindNode(myMesh,aNodeIds[4]),
616                                                   FindNode(myMesh,aNodeIds[5]));
617                     isRenum = anIsElemNum;
618                   }
619                   break;
620                 case eHEXA8:
621                 case eHEXA20:
622                   aNbNodes = 8;
623                   if(anIsElemNum)
624                     anElement = myMesh->AddVolumeWithID(aNodeIds[0],
625                                                         aNodeIds[1],
626                                                         aNodeIds[2],
627                                                         aNodeIds[3],
628                                                         aNodeIds[4],
629                                                         aNodeIds[5],
630                                                         aNodeIds[6],
631                                                         aNodeIds[7],
632                                                         aCellInfo->GetElemNum(iElem));
633                   if (!anElement) {
634                     anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
635                                                   FindNode(myMesh,aNodeIds[1]),
636                                                   FindNode(myMesh,aNodeIds[2]),
637                                                   FindNode(myMesh,aNodeIds[3]),
638                                                   FindNode(myMesh,aNodeIds[4]),
639                                                   FindNode(myMesh,aNodeIds[5]),
640                                                   FindNode(myMesh,aNodeIds[6]),
641                                                   FindNode(myMesh,aNodeIds[7]));
642                     isRenum = anIsElemNum;
643                   }
644                   break;
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                 
654               if (!anElement) {
655                 aResult = DRS_WARN_SKIP_ELEM;
656               }
657               else {
658                 if (isRenum) {
659                   anIsElemNum = eFAUX;
660                   takeNumbers = false;
661                   if (aResult < DRS_WARN_RENUMBER)
662                     aResult = DRS_WARN_RENUMBER;
663                 }
664                 if (myFamilies.find(aFamNum) != myFamilies.end()) {
665                   // Save reference to this element from its family
666                   myFamilies[aFamNum]->AddElement(anElement);
667                   myFamilies[aFamNum]->SetType(anElement->GetType());
668                 }
669               }
670             }
671           }
672         }
673         break;
674       }
675     }
676   }catch(const std::exception& exc){
677     INFOS("Follow exception was cought:\n\t"<<exc.what());
678     aResult = DRS_FAIL;
679   }catch(...){
680     INFOS("Unknown exception was cought !!!");
681     aResult = DRS_FAIL;
682   }
683   if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
684   return aResult;
685 }
686
687 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
688 {
689   list<string> aMeshNames;
690
691   try {
692     if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
693     theStatus = DRS_OK;
694     PWrapper aMed = CrWrapper(myFile);
695
696     if (TInt aNbMeshes = aMed->GetNbMeshes()) {
697       for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
698         // Reading the MED mesh
699         //---------------------
700         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
701         aMeshNames.push_back(aMeshInfo->GetName());
702       }
703     }
704   }catch(const std::exception& exc){
705     INFOS("Follow exception was cought:\n\t"<<exc.what());
706     theStatus = DRS_FAIL;
707   }catch(...){
708     INFOS("Unknown exception was cought !!!");
709     theStatus = DRS_FAIL;
710   }
711
712   return aMeshNames;
713 }
714
715 list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
716 {
717   list<string> aResult;
718   set<string> aResGroupNames;
719
720   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
721   for (; aFamsIter != myFamilies.end(); aFamsIter++)
722   {
723     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
724     const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
725     set<string>::iterator aGrNamesIter = aGroupNames.begin();
726     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
727     {
728       string aName = *aGrNamesIter;
729       // Check, if this is a Group or SubMesh name
730 //if (aName.substr(0, 5) == string("Group")) {
731         if (aResGroupNames.find(aName) == aResGroupNames.end()) {
732           aResGroupNames.insert(aName);
733           aResult.push_back(aName);
734         }
735 //    }
736     }
737   }
738
739   return aResult;
740 }
741
742 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
743 {
744   string aGroupName (theGroup->GetStoreName());
745   if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
746
747   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
748   for (; aFamsIter != myFamilies.end(); aFamsIter++)
749   {
750     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
751     if (aFamily->MemberOf(aGroupName))
752     {
753       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
754       set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
755       const SMDS_MeshElement * element = 0;
756       for (; anElemsIter != anElements.end(); anElemsIter++)
757       {
758         element = *anElemsIter;
759         theGroup->SMDSGroup().Add(element);
760       }
761       if ( element )
762         theGroup->SetType( element->GetType() );
763     }
764   }
765 }
766
767 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
768                                            const int theId)
769 {
770   char submeshGrpName[ 30 ];
771   sprintf( submeshGrpName, "SubMesh %d", theId );
772   string aName (submeshGrpName);
773   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
774   for (; aFamsIter != myFamilies.end(); aFamsIter++)
775   {
776     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
777     if (aFamily->MemberOf(aName))
778     {
779       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
780       set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
781       if (aFamily->GetType() == SMDSAbs_Node)
782       {
783         for (; anElemsIter != anElements.end(); anElemsIter++)
784         {
785           const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
786           theSubMesh->AddNode(node);
787         }
788       }
789       else
790       {
791         for (; anElemsIter != anElements.end(); anElemsIter++)
792         {
793           theSubMesh->AddElement(*anElemsIter);
794         }
795       }
796     }
797   }
798 }
799
800 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
801 {
802   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
803   for (; aFamsIter != myFamilies.end(); aFamsIter++)
804   {
805     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
806     MED::TStringSet aGroupNames = aFamily->GetGroupNames();
807     set<string>::iterator aGrNamesIter = aGroupNames.begin();
808     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
809     {
810       string aName = *aGrNamesIter;
811       // Check, if this is a Group or SubMesh name
812       if (aName.substr(0, 7) == string("SubMesh"))
813       {
814         int Id = atoi(string(aName).substr(7).c_str());
815         set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
816         set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
817         if (aFamily->GetType() == SMDSAbs_Node)
818         {
819           for (; anElemsIter != anElements.end(); anElemsIter++)
820           {
821             SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
822               ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
823             // find out a shape type
824             TopoDS_Shape aShape = myMesh->IndexToShape( Id );
825             int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
826             switch ( aShapeType ) {
827             case TopAbs_FACE:
828               myMesh->SetNodeOnFace(node, Id); break;
829             case TopAbs_EDGE:
830               myMesh->SetNodeOnEdge(node, Id); break;
831             case TopAbs_VERTEX:
832               myMesh->SetNodeOnVertex(node, Id); break;
833             default:
834               myMesh->SetNodeInVolume(node, Id);
835             }
836           }
837         }
838         else
839         {
840           for (; anElemsIter != anElements.end(); anElemsIter++)
841           {
842             myMesh->SetMeshElementOnShape(*anElemsIter, Id);
843           }
844         }
845       }
846     }
847   }
848 }