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