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