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