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