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