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