Salome HOME
Merge from V6_main 19/03/2013
[modules/smesh.git] / src / DriverMED / DriverMED_R_SMESHDS_Mesh.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 //  SMESH DriverMED : driver to read and write 'med' files
23 //  File   : DriverMED_R_SMESHDS_Mesh.cxx
24 //  Module : SMESH
25
26 #include "DriverMED_R_SMESHDS_Mesh.h"
27 #include "SMESHDS_Mesh.hxx"
28 #include "utilities.h"
29
30 #include "DriverMED_Family.h"
31
32 #include "SMESHDS_Group.hxx"
33
34 #include "MED_Factory.hxx"
35 #include "MED_CoordUtils.hxx"
36 #include "MED_Utilities.hxx"
37
38 #include <NCollection_Map.hxx>
39
40 #include <stdlib.h>
41
42 #ifdef _DEBUG_
43 static int MYDEBUG = 1;
44 //#define _DEXCEPT_
45 #else
46 static int MYDEBUG = 0;
47 #endif
48
49 #define _EDF_NODE_IDS_
50
51 using namespace MED;
52 using namespace std;
53
54 void
55 DriverMED_R_SMESHDS_Mesh
56 ::SetMeshName(string theMeshName)
57 {
58   myMeshName = theMeshName;
59 }
60
61 static const SMDS_MeshNode* 
62 FindNode(const SMDS_Mesh* theMesh, TInt theId)
63 {
64   const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
65   if(aNode) return aNode;
66   EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
67 }
68
69
70 Driver_Mesh::Status 
71 DriverMED_R_SMESHDS_Mesh
72 ::Perform()
73 {
74   Status aResult = DRS_FAIL;
75   bool isDescConn = false; // Mantis issue 0020483
76 #ifndef _DEXCEPT_
77   try{
78 #endif
79     myFamilies.clear();
80     if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
81     PWrapper aMed = CrWrapper(myFile,true);
82
83     aResult = DRS_EMPTY;
84     if(TInt aNbMeshes = aMed->GetNbMeshes()){
85       for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
86         // Reading the MED mesh
87         //---------------------
88         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
89
90         string aMeshName;
91         if (myMeshId != -1) {
92           ostringstream aMeshNameStr;
93           aMeshNameStr<<myMeshId;
94           aMeshName = aMeshNameStr.str();
95         } else {
96           aMeshName = myMeshName;
97         }
98         if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
99         if(aMeshName != aMeshInfo->GetName()) continue;
100         aResult = DRS_OK;
101
102         // Reading MED families to the temporary structure
103         //------------------------------------------------
104         TErr anErr;
105         TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
106         if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
107         for (TInt iFam = 0; iFam < aNbFams; iFam++) {
108           PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
109           if(anErr >= 0){
110             TInt aFamId = aFamilyInfo->GetId();
111             if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
112             
113             DriverMED_FamilyPtr aFamily (new DriverMED_Family);
114             
115             TInt aNbGrp = aFamilyInfo->GetNbGroup();
116             if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
117             bool isAttrOk = false;
118             if(aFamilyInfo->GetNbAttr() == aNbGrp)
119               isAttrOk = true;
120             for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
121               string aGroupName = aFamilyInfo->GetGroupName(iGr);
122               if(isAttrOk){
123                 TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
124                 aFamily->SetGroupAttributVal(anAttrVal);
125               }
126               
127               if(MYDEBUG) MESSAGE(aGroupName);
128               aFamily->AddGroupName(aGroupName);
129               
130             }
131             aFamily->SetId( aFamId );
132             myFamilies[aFamId] = aFamily;
133           }
134         }
135
136         if (aMeshInfo->GetType() == MED::eSTRUCTURE){
137           /*bool aRes = */buildMeshGrille(aMed,aMeshInfo);
138           continue;
139         }
140
141         // Reading MED nodes to the corresponding SMDS structure
142         //------------------------------------------------------
143         PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
144         if (!aNodeInfo) {
145           aResult = DRS_FAIL;
146           continue;
147         }
148         aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
149         PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
150
151         EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
152         TInt aNbElems = aNodeInfo->GetNbElem();
153         if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
154         DriverMED_FamilyPtr aFamily;
155         for(TInt iElem = 0; iElem < aNbElems; iElem++){
156           TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
157           double aCoords[3] = {0.0, 0.0, 0.0};
158           for(TInt iDim = 0; iDim < 3; iDim++)
159             aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
160           const SMDS_MeshNode* aNode;
161           if(anIsNodeNum) {
162             aNode = myMesh->AddNodeWithID
163               (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
164           } else {
165             aNode = myMesh->AddNodeWithID
166               (aCoords[0],aCoords[1],aCoords[2], iElem+1);
167           }
168
169           // Save reference to this node from its family
170           TInt aFamNum = aNodeInfo->GetFamNum(iElem);
171           if ( checkFamilyID ( aFamily, aFamNum ))
172           {
173             aFamily->AddElement(aNode);
174             aFamily->SetType(SMDSAbs_Node);
175           }
176         }
177
178         // Are there any MED cells in descending connectivity
179         // Mantis issue 0020483
180         //---------------------------------------------------
181         NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
182         if (!isDescConn) {
183           MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
184           MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
185           //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
186           for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
187             const EEntiteMaillage& anEntity = anEntityIterDesc->first;
188             aDescendingEntitiesMap.Add(anEntity);
189             //if (anEntity != eNOEUD) isDescConn = true;
190           }
191         }
192
193         // Reading pre information about all MED cells
194         //--------------------------------------------
195         typedef MED::TVector<int> TNodeIds;
196         bool takeNumbers = true;  // initially we trust the numbers from file
197         MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD);
198         MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
199         for (; anEntityIter != aEntityInfo.end(); anEntityIter++) {
200           const EEntiteMaillage& anEntity = anEntityIter->first;
201           aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
202           if (anEntity == eNOEUD) continue;
203           // Reading MED cells to the corresponding SMDS structure
204           //------------------------------------------------------
205           const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
206           MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
207           for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
208             const EGeometrieElement& aGeom = aGeom2SizeIter->first;
209
210             if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
211             {
212               PBallInfo aBallInfo = aMed->GetPBallInfo(aMeshInfo);
213               TInt      aNbBalls  = aBallInfo->GetNbElem();
214
215               EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
216               if ( anIsElemNum && aBallInfo->myElemNum->empty() )
217                 anIsElemNum = eFAUX;
218
219               // get supporting nodes
220               TNodeIds aNodeIds;
221 #ifdef _EDF_NODE_IDS_
222               if(anIsNodeNum) {
223                 aNodeIds.resize( aNbBalls );
224                 for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
225                 {
226                   aNodeIds[iBall] = aNodeInfo->GetElemNum( (*aBallInfo->myConn)[ iBall ]-1 );
227                   anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
228                 }
229               }
230 #endif
231               if ( !anIsNodeNum )
232                 aNodeIds.swap( *(aBallInfo->myConn ));
233
234               // allocate array of diameters
235               vtkIdType maxID = myMesh->MaxElementID() + aNbBalls;
236               if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
237                 maxID = *std::max_element( aBallInfo->myElemNum->begin(),
238                                            aBallInfo->myElemNum->end() );
239               myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
240
241               // create balls
242               SMDS_MeshElement* anElement;
243               DriverMED_FamilyPtr aFamily;
244               for ( TInt iBall = 0; iBall < aNbBalls; iBall++)
245               {
246                 anElement = 0;
247                 if ( anIsElemNum ) {
248                   if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
249                                                            aBallInfo->myDiameters[iBall],
250                                                            aBallInfo->GetElemNum(iBall))))
251                     anIsElemNum = eFAUX;
252                 }
253                 if ( !anElement )
254                   myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
255                                    aBallInfo->myDiameters[iBall] );
256
257                 // Save reference to this element from its family
258                 TInt aFamNum = aBallInfo->GetFamNum(iBall);
259                 if ( checkFamilyID ( aFamily, aFamNum ))
260                 {
261                   aFamily->AddElement(anElement);
262                   aFamily->SetType( SMDSAbs_Ball );
263                 }
264               }
265
266               if ( !anIsElemNum &&
267                    ( takeNumbers && aBallInfo->IsElemNum() && !aBallInfo->myElemNum->empty() ))
268                 if ( aResult < DRS_WARN_RENUMBER )
269                   aResult = DRS_WARN_RENUMBER;
270
271               continue;
272             } // MED_BALL
273
274             switch(aGeom) {
275 //          case ePOINT1: ## PAL16410
276 //            break;
277             case ePOLYGONE: {
278               PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
279               EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
280               
281               TInt aNbElem = aPolygoneInfo->GetNbElem();
282               for(TInt iElem = 0; iElem < aNbElem; iElem++){
283                 MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
284                 TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
285                 TNodeIds aNodeIds(aNbConn);
286 #ifdef _EDF_NODE_IDS_
287                 if(anIsNodeNum)
288                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
289                     aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
290                 else
291                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
292                     aNodeIds[iConn] = aConnSlice[iConn];
293 #else
294                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
295                   aNodeIds[iConn] = aConnSlice[iConn];
296 #endif
297                 bool isRenum = false;
298                 SMDS_MeshElement* anElement = NULL;
299                 TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
300
301 #ifndef _DEXCEPT_
302                 try{
303 #endif
304                   if(anIsElemNum){
305                     TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
306                     anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
307                   }
308                   if(!anElement){
309                     vector<const SMDS_MeshNode*> aNodes(aNbConn);
310                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
311                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
312                     anElement = myMesh->AddPolygonalFace(aNodes);
313                     isRenum = anIsElemNum;
314                   }
315 #ifndef _DEXCEPT_
316                 }catch(const std::exception& exc){
317                   aResult = DRS_FAIL;
318                 }catch (...){
319                   aResult = DRS_FAIL;
320                 }
321 #endif
322                 if(!anElement){
323                   aResult = DRS_WARN_SKIP_ELEM;
324                 }else{
325                   if(isRenum){
326                     anIsElemNum = eFAUX;
327                     takeNumbers = false;
328                     if(aResult < DRS_WARN_RENUMBER)
329                       aResult = DRS_WARN_RENUMBER;
330                   }
331                   if ( checkFamilyID ( aFamily, aFamNum ))
332                   {
333                     // Save reference to this element from its family
334                     aFamily->AddElement(anElement);
335                     aFamily->SetType(anElement->GetType());
336                   }
337                 }
338               }
339               break;
340             }
341             case ePOLYEDRE: {
342               PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
343               EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
344
345               TInt aNbElem = aPolyedreInfo->GetNbElem();
346               for(TInt iElem = 0; iElem < aNbElem; iElem++){
347                 MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
348                 TInt aNbFaces = aConnSliceArr.size();
349                 typedef MED::TVector<int> TQuantities;
350                 TQuantities aQuantities(aNbFaces);
351                 TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
352                 TNodeIds aNodeIds(aNbNodes);
353                 for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
354                   MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
355                   TInt aNbConn = aConnSlice.size();
356                   aQuantities[iFace] = aNbConn;
357 #ifdef _EDF_NODE_IDS_
358                   if(anIsNodeNum)
359                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
360                       {
361                       aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
362                       iNode++;
363                       }
364                   else
365                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
366                       {
367                       aNodeIds[iNode++] = aConnSlice[iConn];
368                       }
369 #else
370                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
371                     {
372                     aNodeIds[iNode++] = aConnSlice[iConn];
373                     }
374 #endif          
375                 }
376
377                 bool isRenum = false;
378                 SMDS_MeshElement* anElement = NULL;
379                 TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
380                 
381 #ifndef _DEXCEPT_
382                 try{
383 #endif
384                   if(anIsElemNum){
385                     TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
386                     anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
387                   }
388                   if(!anElement){
389                     vector<const SMDS_MeshNode*> aNodes(aNbNodes);
390                     for(TInt iConn = 0; iConn < aNbNodes; iConn++)
391                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
392                     anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
393                     isRenum = anIsElemNum;
394                   }
395 #ifndef _DEXCEPT_
396                 }catch(const std::exception& exc){
397                   aResult = DRS_FAIL;
398                 }catch(...){
399                   aResult = DRS_FAIL;
400                 }
401 #endif          
402                 if(!anElement){
403                   aResult = DRS_WARN_SKIP_ELEM;
404                 }else{
405                   if(isRenum){
406                     anIsElemNum = eFAUX;
407                     takeNumbers = false;
408                     if (aResult < DRS_WARN_RENUMBER)
409                       aResult = DRS_WARN_RENUMBER;
410                   }
411                   if ( checkFamilyID ( aFamily, aFamNum )) {
412                     // Save reference to this element from its family
413                     aFamily->AddElement(anElement);
414                     aFamily->SetType(anElement->GetType());
415                   }
416                 }
417               }
418               break;
419             }
420             default: {
421               PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
422               EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
423               TInt aNbElems = aCellInfo->GetNbElem();
424               if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
425               if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
426
427               TInt aNbNodes = -1;
428               switch(aGeom){
429               case eSEG2:    aNbNodes = 2;  break;
430               case eSEG3:    aNbNodes = 3;  break;
431               case eTRIA3:   aNbNodes = 3;  break;
432               case eTRIA6:   aNbNodes = 6;  break;
433               case eQUAD4:   aNbNodes = 4;  break;
434               case eQUAD8:   aNbNodes = 8;  break;
435               case eQUAD9:   aNbNodes = 9;  break;
436               case eTETRA4:  aNbNodes = 4;  break;
437               case eTETRA10: aNbNodes = 10; break;
438               case ePYRA5:   aNbNodes = 5;  break;
439               case ePYRA13:  aNbNodes = 13; break;
440               case ePENTA6:  aNbNodes = 6;  break;
441               case ePENTA15: aNbNodes = 15; break;
442               case eHEXA8:   aNbNodes = 8;  break;
443               case eHEXA20:  aNbNodes = 20; break;
444               case eHEXA27:  aNbNodes = 27; break;
445               case eOCTA12:  aNbNodes = 12; break;
446               case ePOINT1:  aNbNodes = 1;  break;
447               default:;
448               }
449               vector<TInt> aNodeIds(aNbNodes);
450               for(int iElem = 0; iElem < aNbElems; iElem++){
451                 bool anIsValidConnect = false;
452                 TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
453 #ifndef _DEXCEPT_
454                 try{
455 #endif
456 #ifdef _EDF_NODE_IDS_
457                   if(anIsNodeNum)
458                     for(int iNode = 0; iNode < aNbNodes; iNode++)
459                       aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
460                   else
461                     for(int iNode = 0; iNode < aNbNodes; iNode++)
462                       aNodeIds[iNode] = aConnSlice[iNode];
463 #else
464                   for(int iNode = 0; iNode < aNbNodes; iNode++)
465                     aNodeIds[iNode] = aConnSlice[iNode];
466 #endif
467                   anIsValidConnect = true;
468 #ifndef _DEXCEPT_
469                 }catch(const std::exception& exc){
470                   INFOS("Following exception was caught:\n\t"<<exc.what());
471                   aResult = DRS_FAIL;
472                 }catch(...){
473                   INFOS("Unknown exception was caught !!!");
474                   aResult = DRS_FAIL;
475                 }
476 #endif          
477                 if(!anIsValidConnect)
478                   continue;
479
480                 bool isRenum = false;
481                 const SMDS_MeshElement* anElement = NULL;
482                 TInt aFamNum = aCellInfo->GetFamNum(iElem);
483 #ifndef _DEXCEPT_
484                 try{
485 #endif
486                   //MESSAGE("Try to create element # " << iElem << " with id = "
487                   //        << aCellInfo->GetElemNum(iElem));
488                   switch(aGeom) {
489                   case ePOINT1:
490                     //anElement = FindNode(myMesh,aNodeIds[0]);
491                     if(anIsElemNum)
492                       anElement = myMesh->Add0DElementWithID
493                         (aNodeIds[0], aCellInfo->GetElemNum(iElem));
494                     if (!anElement) {
495                       anElement = myMesh->Add0DElement(FindNode(myMesh,aNodeIds[0]));
496                       isRenum = anIsElemNum;
497                     }
498                     break;
499                   case eSEG2:
500                     if(anIsElemNum)
501                       anElement = myMesh->AddEdgeWithID(aNodeIds[0],
502                                                         aNodeIds[1],
503                                                         aCellInfo->GetElemNum(iElem));
504                     if (!anElement) {
505                       anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
506                                                   FindNode(myMesh,aNodeIds[1]));
507                       isRenum = anIsElemNum;
508                     }
509                     break;
510                   case eSEG3:
511                     if(anIsElemNum)
512                       anElement = myMesh->AddEdgeWithID(aNodeIds[0],
513                                                         aNodeIds[1],
514                                                         aNodeIds[2],
515                                                         aCellInfo->GetElemNum(iElem));
516                     if (!anElement) {
517                       anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
518                                                   FindNode(myMesh,aNodeIds[1]),
519                                                   FindNode(myMesh,aNodeIds[2]));
520                       isRenum = anIsElemNum;
521                     }
522                     break;
523                   case eTRIA3:
524                     aNbNodes = 3;
525                     if(anIsElemNum)
526                       anElement = myMesh->AddFaceWithID(aNodeIds[0],
527                                                         aNodeIds[1],
528                                                         aNodeIds[2],
529                                                         aCellInfo->GetElemNum(iElem));
530                     if (!anElement) {
531                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
532                                                   FindNode(myMesh,aNodeIds[1]),
533                                                   FindNode(myMesh,aNodeIds[2]));
534                       isRenum = anIsElemNum;
535                     }
536                     break;
537                   case eTRIA6:
538                     aNbNodes = 6;
539                     if(anIsElemNum)
540                       anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
541                                                         aNodeIds[2], aNodeIds[3],
542                                                         aNodeIds[4], aNodeIds[5],
543                                                         aCellInfo->GetElemNum(iElem));
544                     if (!anElement) {
545                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
546                                                   FindNode(myMesh,aNodeIds[1]),
547                                                   FindNode(myMesh,aNodeIds[2]),
548                                                   FindNode(myMesh,aNodeIds[3]),
549                                                   FindNode(myMesh,aNodeIds[4]),
550                                                   FindNode(myMesh,aNodeIds[5]));
551                       isRenum = anIsElemNum;
552                     }
553                     break;
554                   case eQUAD4:
555                     aNbNodes = 4;
556                     if(anIsElemNum)
557                       anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
558                                                         aNodeIds[2], aNodeIds[3],
559                                                         aCellInfo->GetElemNum(iElem));
560                     if (!anElement) {
561                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
562                                                   FindNode(myMesh,aNodeIds[1]),
563                                                   FindNode(myMesh,aNodeIds[2]),
564                                                   FindNode(myMesh,aNodeIds[3]));
565                       isRenum = anIsElemNum;
566                     }
567                     break;
568                   case eQUAD8:
569                     aNbNodes = 8;
570                     if(anIsElemNum)
571                       anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
572                                                         aNodeIds[2], aNodeIds[3],
573                                                         aNodeIds[4], aNodeIds[5],
574                                                         aNodeIds[6], aNodeIds[7],
575                                                         aCellInfo->GetElemNum(iElem));
576                     if (!anElement) {
577                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
578                                                   FindNode(myMesh,aNodeIds[1]),
579                                                   FindNode(myMesh,aNodeIds[2]),
580                                                   FindNode(myMesh,aNodeIds[3]),
581                                                   FindNode(myMesh,aNodeIds[4]),
582                                                   FindNode(myMesh,aNodeIds[5]),
583                                                   FindNode(myMesh,aNodeIds[6]),
584                                                   FindNode(myMesh,aNodeIds[7]));
585                       isRenum = anIsElemNum;
586                     }
587                     break;
588                   case eQUAD9:
589                     aNbNodes = 9;
590                     if(anIsElemNum)
591                       anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
592                                                         aNodeIds[2], aNodeIds[3],
593                                                         aNodeIds[4], aNodeIds[5],
594                                                         aNodeIds[6], aNodeIds[7], aNodeIds[8],
595                                                         aCellInfo->GetElemNum(iElem));
596                     if (!anElement) {
597                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
598                                                   FindNode(myMesh,aNodeIds[1]),
599                                                   FindNode(myMesh,aNodeIds[2]),
600                                                   FindNode(myMesh,aNodeIds[3]),
601                                                   FindNode(myMesh,aNodeIds[4]),
602                                                   FindNode(myMesh,aNodeIds[5]),
603                                                   FindNode(myMesh,aNodeIds[6]),
604                                                   FindNode(myMesh,aNodeIds[7]),
605                                                   FindNode(myMesh,aNodeIds[8]));
606                       isRenum = anIsElemNum;
607                     }
608                     break;
609                   case eTETRA4:
610                     aNbNodes = 4;
611                     if(anIsElemNum)
612                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
613                                                           aNodeIds[2], aNodeIds[3],
614                                                           aCellInfo->GetElemNum(iElem));
615                     if (!anElement) {
616                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
617                                                     FindNode(myMesh,aNodeIds[1]),
618                                                     FindNode(myMesh,aNodeIds[2]),
619                                                     FindNode(myMesh,aNodeIds[3]));
620                       isRenum = anIsElemNum;
621                     }
622                     break;
623                   case eTETRA10:
624                     aNbNodes = 10;
625                     if(anIsElemNum)
626                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
627                                                           aNodeIds[2], aNodeIds[3],
628                                                           aNodeIds[4], aNodeIds[5],
629                                                           aNodeIds[6], aNodeIds[7],
630                                                           aNodeIds[8], aNodeIds[9],
631                                                           aCellInfo->GetElemNum(iElem));
632                     if (!anElement) {
633                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
634                                                     FindNode(myMesh,aNodeIds[1]),
635                                                     FindNode(myMesh,aNodeIds[2]),
636                                                     FindNode(myMesh,aNodeIds[3]),
637                                                     FindNode(myMesh,aNodeIds[4]),
638                                                     FindNode(myMesh,aNodeIds[5]),
639                                                     FindNode(myMesh,aNodeIds[6]),
640                                                     FindNode(myMesh,aNodeIds[7]),
641                                                     FindNode(myMesh,aNodeIds[8]),
642                                                     FindNode(myMesh,aNodeIds[9]));
643                       isRenum = anIsElemNum;
644                     }
645                     break;
646                   case ePYRA5:
647                     aNbNodes = 5;
648                     if(anIsElemNum)
649                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
650                                                           aNodeIds[2], aNodeIds[3],
651                                                           aNodeIds[4],
652                                                           aCellInfo->GetElemNum(iElem));
653                     if (!anElement) {
654                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
655                                                     FindNode(myMesh,aNodeIds[1]),
656                                                     FindNode(myMesh,aNodeIds[2]),
657                                                     FindNode(myMesh,aNodeIds[3]),
658                                                     FindNode(myMesh,aNodeIds[4]));
659                       isRenum = anIsElemNum;
660                     }
661                     break;
662                   case ePYRA13:
663                     aNbNodes = 13;
664                     if(anIsElemNum)
665                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
666                                                           aNodeIds[2], aNodeIds[3],
667                                                           aNodeIds[4], aNodeIds[5],
668                                                           aNodeIds[6], aNodeIds[7],
669                                                           aNodeIds[8], aNodeIds[9],
670                                                           aNodeIds[10], aNodeIds[11],
671                                                           aNodeIds[12],
672                                                           aCellInfo->GetElemNum(iElem));
673                     if (!anElement) {
674                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
675                                                     FindNode(myMesh,aNodeIds[1]),
676                                                     FindNode(myMesh,aNodeIds[2]),
677                                                     FindNode(myMesh,aNodeIds[3]),
678                                                     FindNode(myMesh,aNodeIds[4]),
679                                                     FindNode(myMesh,aNodeIds[5]),
680                                                     FindNode(myMesh,aNodeIds[6]),
681                                                     FindNode(myMesh,aNodeIds[7]),
682                                                     FindNode(myMesh,aNodeIds[8]),
683                                                     FindNode(myMesh,aNodeIds[9]),
684                                                     FindNode(myMesh,aNodeIds[10]),
685                                                     FindNode(myMesh,aNodeIds[11]),
686                                                     FindNode(myMesh,aNodeIds[12]));
687                       isRenum = anIsElemNum;
688                     }
689                     break;
690                   case ePENTA6:
691                     aNbNodes = 6;
692                     if(anIsElemNum)
693                       anElement = myMesh->AddVolumeWithID(aNodeIds[0],
694                                                           aNodeIds[1],
695                                                           aNodeIds[2],
696                                                           aNodeIds[3],
697                                                           aNodeIds[4],
698                                                           aNodeIds[5],
699                                                           aCellInfo->GetElemNum(iElem));
700                     if (!anElement) {
701                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
702                                                     FindNode(myMesh,aNodeIds[1]),
703                                                     FindNode(myMesh,aNodeIds[2]),
704                                                     FindNode(myMesh,aNodeIds[3]),
705                                                     FindNode(myMesh,aNodeIds[4]),
706                                                     FindNode(myMesh,aNodeIds[5]));
707                       isRenum = anIsElemNum;
708                     }
709                     break;
710                   case ePENTA15:
711                     aNbNodes = 15;
712                     if(anIsElemNum)
713                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
714                                                           aNodeIds[2], aNodeIds[3],
715                                                           aNodeIds[4], aNodeIds[5],
716                                                           aNodeIds[6], aNodeIds[7],
717                                                           aNodeIds[8], aNodeIds[9],
718                                                           aNodeIds[10], aNodeIds[11],
719                                                           aNodeIds[12], aNodeIds[13],
720                                                           aNodeIds[14],
721                                                           aCellInfo->GetElemNum(iElem));
722                     if (!anElement) {
723                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
724                                                     FindNode(myMesh,aNodeIds[1]),
725                                                     FindNode(myMesh,aNodeIds[2]),
726                                                     FindNode(myMesh,aNodeIds[3]),
727                                                   FindNode(myMesh,aNodeIds[4]),
728                                                     FindNode(myMesh,aNodeIds[5]),
729                                                     FindNode(myMesh,aNodeIds[6]),
730                                                     FindNode(myMesh,aNodeIds[7]),
731                                                     FindNode(myMesh,aNodeIds[8]),
732                                                     FindNode(myMesh,aNodeIds[9]),
733                                                     FindNode(myMesh,aNodeIds[10]),
734                                                     FindNode(myMesh,aNodeIds[11]),
735                                                     FindNode(myMesh,aNodeIds[12]),
736                                                     FindNode(myMesh,aNodeIds[13]),
737                                                     FindNode(myMesh,aNodeIds[14]));
738                       isRenum = anIsElemNum;
739                     }
740                     break;
741                   case eHEXA8:
742                     aNbNodes = 8;
743                     if(anIsElemNum)
744                       anElement = myMesh->AddVolumeWithID(aNodeIds[0],
745                                                           aNodeIds[1],
746                                                           aNodeIds[2],
747                                                           aNodeIds[3],
748                                                           aNodeIds[4],
749                                                           aNodeIds[5],
750                                                           aNodeIds[6],
751                                                           aNodeIds[7],
752                                                           aCellInfo->GetElemNum(iElem));
753                     if (!anElement) {
754                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
755                                                     FindNode(myMesh,aNodeIds[1]),
756                                                     FindNode(myMesh,aNodeIds[2]),
757                                                     FindNode(myMesh,aNodeIds[3]),
758                                                     FindNode(myMesh,aNodeIds[4]),
759                                                     FindNode(myMesh,aNodeIds[5]),
760                                                     FindNode(myMesh,aNodeIds[6]),
761                                                     FindNode(myMesh,aNodeIds[7]));
762                       isRenum = anIsElemNum;
763                     }
764                     break;
765
766                   case eHEXA20:
767                     aNbNodes = 20;
768                     if(anIsElemNum)
769                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
770                                                           aNodeIds[2], aNodeIds[3],
771                                                           aNodeIds[4], aNodeIds[5],
772                                                           aNodeIds[6], aNodeIds[7],
773                                                           aNodeIds[8], aNodeIds[9],
774                                                           aNodeIds[10], aNodeIds[11],
775                                                           aNodeIds[12], aNodeIds[13],
776                                                           aNodeIds[14], aNodeIds[15],
777                                                           aNodeIds[16], aNodeIds[17],
778                                                           aNodeIds[18], aNodeIds[19],
779                                                           aCellInfo->GetElemNum(iElem));
780                     if (!anElement) {
781                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
782                                                     FindNode(myMesh,aNodeIds[1]),
783                                                     FindNode(myMesh,aNodeIds[2]),
784                                                     FindNode(myMesh,aNodeIds[3]),
785                                                     FindNode(myMesh,aNodeIds[4]),
786                                                     FindNode(myMesh,aNodeIds[5]),
787                                                     FindNode(myMesh,aNodeIds[6]),
788                                                     FindNode(myMesh,aNodeIds[7]),
789                                                     FindNode(myMesh,aNodeIds[8]),
790                                                     FindNode(myMesh,aNodeIds[9]),
791                                                     FindNode(myMesh,aNodeIds[10]),
792                                                     FindNode(myMesh,aNodeIds[11]),
793                                                     FindNode(myMesh,aNodeIds[12]),
794                                                     FindNode(myMesh,aNodeIds[13]),
795                                                     FindNode(myMesh,aNodeIds[14]),
796                                                     FindNode(myMesh,aNodeIds[15]),
797                                                     FindNode(myMesh,aNodeIds[16]),
798                                                     FindNode(myMesh,aNodeIds[17]),
799                                                     FindNode(myMesh,aNodeIds[18]),
800                                                     FindNode(myMesh,aNodeIds[19]));
801                       isRenum = anIsElemNum;
802                     }
803                     break;
804
805                   case eHEXA27:
806                     aNbNodes = 27;
807                     if(anIsElemNum)
808                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
809                                                           aNodeIds[2], aNodeIds[3],
810                                                           aNodeIds[4], aNodeIds[5],
811                                                           aNodeIds[6], aNodeIds[7],
812                                                           aNodeIds[8], aNodeIds[9],
813                                                           aNodeIds[10], aNodeIds[11],
814                                                           aNodeIds[12], aNodeIds[13],
815                                                           aNodeIds[14], aNodeIds[15],
816                                                           aNodeIds[16], aNodeIds[17],
817                                                           aNodeIds[18], aNodeIds[19],
818                                                           aNodeIds[20], aNodeIds[21],
819                                                           aNodeIds[22], aNodeIds[23],
820                                                           aNodeIds[24], aNodeIds[25],
821                                                           aNodeIds[26],
822                                                           aCellInfo->GetElemNum(iElem));
823                     if (!anElement) {
824                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
825                                                     FindNode(myMesh,aNodeIds[1]),
826                                                     FindNode(myMesh,aNodeIds[2]),
827                                                     FindNode(myMesh,aNodeIds[3]),
828                                                     FindNode(myMesh,aNodeIds[4]),
829                                                     FindNode(myMesh,aNodeIds[5]),
830                                                     FindNode(myMesh,aNodeIds[6]),
831                                                     FindNode(myMesh,aNodeIds[7]),
832                                                     FindNode(myMesh,aNodeIds[8]),
833                                                     FindNode(myMesh,aNodeIds[9]),
834                                                     FindNode(myMesh,aNodeIds[10]),
835                                                     FindNode(myMesh,aNodeIds[11]),
836                                                     FindNode(myMesh,aNodeIds[12]),
837                                                     FindNode(myMesh,aNodeIds[13]),
838                                                     FindNode(myMesh,aNodeIds[14]),
839                                                     FindNode(myMesh,aNodeIds[15]),
840                                                     FindNode(myMesh,aNodeIds[16]),
841                                                     FindNode(myMesh,aNodeIds[17]),
842                                                     FindNode(myMesh,aNodeIds[18]),
843                                                     FindNode(myMesh,aNodeIds[19]),
844                                                     FindNode(myMesh,aNodeIds[20]),
845                                                     FindNode(myMesh,aNodeIds[21]),
846                                                     FindNode(myMesh,aNodeIds[22]),
847                                                     FindNode(myMesh,aNodeIds[23]),
848                                                     FindNode(myMesh,aNodeIds[24]),
849                                                     FindNode(myMesh,aNodeIds[25]),
850                                                     FindNode(myMesh,aNodeIds[26]));
851                       isRenum = anIsElemNum;
852                     }
853                     break;
854
855                   case eOCTA12:
856                     aNbNodes = 12;
857                     if(anIsElemNum)
858                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
859                                                           aNodeIds[2], aNodeIds[3],
860                                                           aNodeIds[4], aNodeIds[5],
861                                                           aNodeIds[6], aNodeIds[7],
862                                                           aNodeIds[8], aNodeIds[9],
863                                                           aNodeIds[10], aNodeIds[11],
864                                                           aCellInfo->GetElemNum(iElem));
865                     if (!anElement) {
866                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
867                                                     FindNode(myMesh,aNodeIds[1]),
868                                                     FindNode(myMesh,aNodeIds[2]),
869                                                     FindNode(myMesh,aNodeIds[3]),
870                                                     FindNode(myMesh,aNodeIds[4]),
871                                                     FindNode(myMesh,aNodeIds[5]),
872                                                     FindNode(myMesh,aNodeIds[6]),
873                                                     FindNode(myMesh,aNodeIds[7]),
874                                                     FindNode(myMesh,aNodeIds[8]),
875                                                     FindNode(myMesh,aNodeIds[9]),
876                                                     FindNode(myMesh,aNodeIds[10]),
877                                                     FindNode(myMesh,aNodeIds[11]));
878                       isRenum = anIsElemNum;
879                     }
880                     break;
881
882                   } // switch(aGeom)
883
884 #ifndef _DEXCEPT_
885                 }catch(const std::exception& exc){
886                   INFOS("The following exception was caught:\n\t"<<exc.what());
887                   aResult = DRS_FAIL;
888                 }catch(...){
889                   INFOS("Unknown exception was caught !!!");
890                   aResult = DRS_FAIL;
891                 }
892 #endif          
893                 if (!anElement) {
894                   aResult = DRS_WARN_SKIP_ELEM;
895                 }
896                 else {
897                   if (isRenum) {
898                     anIsElemNum = eFAUX;
899                     takeNumbers = false;
900                     if (aResult < DRS_WARN_RENUMBER)
901                       aResult = DRS_WARN_RENUMBER;
902                   }
903                   if ( checkFamilyID ( aFamily, aFamNum )) {
904                     // Save reference to this element from its family
905                     myFamilies[aFamNum]->AddElement(anElement);
906                     myFamilies[aFamNum]->SetType(anElement->GetType());
907                   }
908                 }
909               }
910             }}
911           }
912         }
913         if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
914       } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
915     } // if aNbMeshes
916 #ifndef _DEXCEPT_
917   }catch(const std::exception& exc){
918     INFOS("The following exception was caught:\n\t"<<exc.what());
919     aResult = DRS_FAIL;
920   }catch(...){
921     INFOS("Unknown exception was caught !!!");
922     aResult = DRS_FAIL;
923   }
924 #endif
925   if (myMesh)
926     myMesh->compactMesh();
927
928   // Mantis issue 0020483
929   if (aResult == DRS_OK && isDescConn) {
930     INFOS("There are some elements in descending connectivity in med file. They were not read !!!");
931     aResult = DRS_WARN_DESCENDING;
932   }
933
934   if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
935   return aResult;
936 }
937
938 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
939 {
940   list<string> aMeshNames;
941
942   try {
943     if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
944     theStatus = DRS_OK;
945     PWrapper aMed = CrWrapper(myFile);
946
947     if (TInt aNbMeshes = aMed->GetNbMeshes()) {
948       for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
949         // Reading the MED mesh
950         //---------------------
951         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
952         aMeshNames.push_back(aMeshInfo->GetName());
953       }
954     }
955   } catch(const std::exception& exc) {
956     INFOS("Following exception was caught:\n\t"<<exc.what());
957     theStatus = DRS_FAIL;
958   } catch(...) {
959     INFOS("Unknown exception was caught !!!");
960     theStatus = DRS_FAIL;
961   }
962
963   return aMeshNames;
964 }
965
966 list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
967 {
968   list<TNameAndType> aResult;
969   set<TNameAndType> aResGroupNames;
970
971   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
972   for (; aFamsIter != myFamilies.end(); aFamsIter++)
973   {
974     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
975     const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
976     set<string>::const_iterator aGrNamesIter = aGroupNames.begin();
977     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
978     {
979       const set< SMDSAbs_ElementType >& types = aFamily->GetTypes();
980       set< SMDSAbs_ElementType >::const_iterator type = types.begin();
981       for ( ; type != types.end(); ++type )
982       {
983         TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type );
984         if ( aResGroupNames.insert( aNameAndType ).second ) {
985           aResult.push_back( aNameAndType );
986         }
987       }
988     }
989   }
990
991   return aResult;
992 }
993
994 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
995 {
996   string aGroupName (theGroup->GetStoreName());
997   if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
998
999   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1000   for (; aFamsIter != myFamilies.end(); aFamsIter++)
1001   {
1002     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1003     if (aFamily->GetTypes().count( theGroup->GetType() ) && aFamily->MemberOf(aGroupName))
1004     {
1005       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
1006       set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
1007       for (; anElemsIter != anElements.end(); anElemsIter++)
1008       {
1009         const SMDS_MeshElement * element = *anElemsIter;
1010         if ( element->GetType() == theGroup->GetType() ) // Issue 0020576
1011           theGroup->SMDSGroup().Add(element);
1012       }
1013       int aGroupAttrVal = aFamily->GetGroupAttributVal();
1014       if( aGroupAttrVal != 0)
1015         theGroup->SetColorGroup(aGroupAttrVal);
1016 //       if ( element ) -- Issue 0020576
1017 //         theGroup->SetType( theGroup->SMDSGroup().GetType() );
1018     }
1019   }
1020 }
1021
1022 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
1023                                            const int theId)
1024 {
1025   char submeshGrpName[ 30 ];
1026   sprintf( submeshGrpName, "SubMesh %d", theId );
1027   string aName (submeshGrpName);
1028   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1029   for (; aFamsIter != myFamilies.end(); aFamsIter++)
1030   {
1031     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1032     if (aFamily->MemberOf(aName))
1033     {
1034       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
1035       set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
1036       if (aFamily->GetType() == SMDSAbs_Node)
1037       {
1038         for (; anElemsIter != anElements.end(); anElemsIter++)
1039         {
1040           const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
1041           theSubMesh->AddNode(node);
1042         }
1043       }
1044       else
1045       {
1046         for (; anElemsIter != anElements.end(); anElemsIter++)
1047         {
1048           theSubMesh->AddElement(*anElemsIter);
1049         }
1050       }
1051     }
1052   }
1053 }
1054
1055 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
1056 {
1057   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1058   for (; aFamsIter != myFamilies.end(); aFamsIter++)
1059   {
1060     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1061     MED::TStringSet aGroupNames = aFamily->GetGroupNames();
1062     set<string>::iterator aGrNamesIter = aGroupNames.begin();
1063     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
1064     {
1065       string aName = *aGrNamesIter;
1066       // Check, if this is a Group or SubMesh name
1067       if (aName.substr(0, 7) == string("SubMesh"))
1068       {
1069         int Id = atoi(string(aName).substr(7).c_str());
1070         set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
1071         set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
1072         if (aFamily->GetType() == SMDSAbs_Node)
1073         {
1074           for (; anElemsIter != anElements.end(); anElemsIter++)
1075           {
1076             SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
1077               ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
1078             // find out a shape type
1079             TopoDS_Shape aShape = myMesh->IndexToShape( Id );
1080             int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
1081             switch ( aShapeType ) {
1082             case TopAbs_FACE:
1083               myMesh->SetNodeOnFace(node, Id); break;
1084             case TopAbs_EDGE:
1085               myMesh->SetNodeOnEdge(node, Id); break;
1086             case TopAbs_VERTEX:
1087               myMesh->SetNodeOnVertex(node, Id); break;
1088             default:
1089               myMesh->SetNodeInVolume(node, Id);
1090             }
1091           }
1092         }
1093         else
1094         {
1095           for (; anElemsIter != anElements.end(); anElemsIter++)
1096           {
1097             myMesh->SetMeshElementOnShape(*anElemsIter, Id);
1098           }
1099         }
1100       }
1101     }
1102   }
1103 }
1104 /*!
1105  * \brief Ensure aFamily to have required ID
1106  * \param aFamily - a family to check and update
1107  * \param anID - an ID aFamily should have
1108  * \retval bool  - true if successful
1109  */
1110 bool DriverMED_R_SMESHDS_Mesh::checkFamilyID(DriverMED_FamilyPtr & aFamily, int anID) const
1111 {
1112   if ( !aFamily || aFamily->GetId() != anID ) {
1113     map<int, DriverMED_FamilyPtr>::const_iterator i_fam = myFamilies.find(anID);
1114     if ( i_fam == myFamilies.end() )
1115       return false;
1116     aFamily = i_fam->second;
1117   }
1118   return ( aFamily->GetId() == anID );
1119 }
1120
1121
1122 /*! \brief Reading the structured mesh and convert to non structured (by filling of smesh structure for non structured mesh)
1123  * \param theWrapper  - PWrapper const pointer
1124  * \param theMeshInfo - PMeshInfo const pointer
1125  * \return TRUE, if successfully. Else FALSE
1126  */
1127 bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
1128                                                const MED::PMeshInfo& theMeshInfo)
1129 {
1130   bool res = true;
1131
1132   MED::PGrilleInfo aGrilleInfo = theWrapper->GetPGrilleInfo(theMeshInfo);
1133   MED::TInt aNbNodes = aGrilleInfo->GetNbNodes();
1134   MED::TInt aNbCells = aGrilleInfo->GetNbCells();
1135   MED::TInt aMeshDim = theMeshInfo->GetDim();
1136   DriverMED_FamilyPtr aFamily;
1137   for(MED::TInt iNode=0;iNode < aNbNodes; iNode++){
1138     double aCoords[3] = {0.0, 0.0, 0.0};
1139     const SMDS_MeshNode* aNode;
1140     MED::TNodeCoord aMEDNodeCoord = aGrilleInfo->GetCoord(iNode);
1141     for(MED::TInt iDim=0;iDim<aMeshDim;iDim++)
1142       aCoords[(int)iDim] = aMEDNodeCoord[(int)iDim];
1143     aNode = myMesh->AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],iNode+1);
1144     if (!aNode) {
1145       EXCEPTION(runtime_error,"buildMeshGrille Error. Node not created! "<<(int)iNode);
1146     }
1147
1148     if((aGrilleInfo->myFamNumNode).size() > 0){
1149       TInt aFamNum = aGrilleInfo->GetFamNumNode(iNode);
1150       if ( checkFamilyID ( aFamily, aFamNum ))
1151         {
1152           aFamily->AddElement(aNode);
1153           aFamily->SetType(SMDSAbs_Node);
1154         }
1155     }
1156     
1157   }
1158
1159   SMDS_MeshElement* anElement = NULL;
1160   MED::TIntVector aNodeIds;
1161   for(MED::TInt iCell=0;iCell < aNbCells; iCell++){
1162     aNodeIds = aGrilleInfo->GetConn(iCell);
1163     switch(aGrilleInfo->GetGeom()){
1164     case MED::eSEG2:
1165       if(aNodeIds.size() != 2){
1166         res = false;
1167         EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 2!="<<aNodeIds.size());
1168       }
1169       anElement = myMesh->AddEdgeWithID(aNodeIds[0]+1,
1170                                         aNodeIds[1]+1,
1171                                         iCell+1);
1172       break;
1173     case MED::eQUAD4:
1174       if(aNodeIds.size() != 4){
1175         res = false;
1176         EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 4!="<<aNodeIds.size());
1177       }
1178       anElement = myMesh->AddFaceWithID(aNodeIds[0]+1,
1179                                         aNodeIds[2]+1,
1180                                         aNodeIds[3]+1,
1181                                         aNodeIds[1]+1,
1182                                         iCell+1);
1183       break;
1184     case MED::eHEXA8:
1185       if(aNodeIds.size() != 8){
1186         res = false;
1187         EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 8!="<<aNodeIds.size());
1188       }
1189       anElement = myMesh->AddVolumeWithID(aNodeIds[0]+1,
1190                                           aNodeIds[2]+1,
1191                                           aNodeIds[3]+1,
1192                                           aNodeIds[1]+1,
1193                                           aNodeIds[4]+1,
1194                                           aNodeIds[6]+1,
1195                                           aNodeIds[7]+1,
1196                                           aNodeIds[5]+1,
1197                                           iCell+1);
1198       break;
1199     default:
1200       break;
1201     }
1202     if (!anElement) {
1203       EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<<iCell);
1204     }
1205     if((aGrilleInfo->myFamNum).size() > 0){
1206       TInt aFamNum = aGrilleInfo->GetFamNum(iCell);
1207       if ( checkFamilyID ( aFamily, aFamNum )){
1208         aFamily->AddElement(anElement);
1209         aFamily->SetType(anElement->GetType());
1210       }
1211     }
1212   }
1213
1214   return res;
1215 }