Salome HOME
To port on new version of MEDWrapper
[modules/smesh.git] / src / DriverMED / DriverMED_R_SMESHDS_Mesh.cxx
1 //  SMESH DriverMED : driver to read and write 'med' files
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : DriverMED_R_SMESHDS_Mesh.cxx
25 //  Module : SMESH
26
27 #include "DriverMED_R_SMESHDS_Mesh.h"
28 #include "DriverMED_R_SMDS_Mesh.h"
29 #include "SMESHDS_Mesh.hxx"
30 #include "utilities.h"
31
32 #include "DriverMED_Family.h"
33
34 #include "SMESHDS_Group.hxx"
35
36 #include "MED_Factory.hxx"
37 #include "MED_CoordUtils.hxx"
38 #include "MED_Utilities.hxx"
39
40 #include <stdlib.h>
41
42 #ifdef _DEBUG_
43 static int MYDEBUG = 0;
44 #else
45 static int MYDEBUG = 0;
46 #endif
47
48 #define _EDF_NODE_IDS_
49
50 using namespace MED;
51
52 void
53 DriverMED_R_SMESHDS_Mesh
54 ::SetMeshName(string theMeshName)
55 {
56   myMeshName = theMeshName;
57 }
58
59 static const SMDS_MeshNode* 
60 FindNode(const SMDS_Mesh* theMesh, TInt theId){
61   const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
62   if(aNode) return aNode;
63   EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
64 }
65
66
67 Driver_Mesh::Status 
68 DriverMED_R_SMESHDS_Mesh
69 ::Perform()
70 {
71   Status aResult = DRS_FAIL;
72   try{
73     myFamilies.clear();
74     if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
75     PWrapper aMed = CrWrapper(myFile);
76
77     aResult = DRS_EMPTY;
78     if(TInt aNbMeshes = aMed->GetNbMeshes()){
79       for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
80         // Reading the MED mesh
81         //---------------------
82         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
83         string aMeshName;
84         if (myMeshId != -1) {
85           ostringstream aMeshNameStr;
86           aMeshNameStr<<myMeshId;
87           aMeshName = aMeshNameStr.str();
88         } else {
89           aMeshName = myMeshName;
90         }
91         if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
92         if(aMeshName != aMeshInfo->GetName()) continue;
93         aResult = DRS_OK;
94         //TInt aMeshDim = aMeshInfo->GetDim();
95         
96         // Reading MED families to the temporary structure
97         //------------------------------------------------
98         TErr anErr;
99         TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
100         if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
101         for (TInt iFam = 0; iFam < aNbFams; iFam++) {
102           PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
103           if(anErr >= 0){
104             TInt aFamId = aFamilyInfo->GetId();
105             if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
106             
107             DriverMED_FamilyPtr aFamily (new DriverMED_Family);
108             
109             TInt aNbGrp = aFamilyInfo->GetNbGroup();
110             if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
111             for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
112               string aGroupName = aFamilyInfo->GetGroupName(iGr);
113               if(MYDEBUG) MESSAGE(aGroupName);
114               aFamily->AddGroupName(aGroupName);
115             }
116             myFamilies[aFamId] = aFamily;
117           }
118         }
119
120         // Reading MED nodes to the corresponding SMDS structure
121         //------------------------------------------------------
122         PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
123
124         PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
125
126         EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
127         TInt aNbElems = aNodeInfo->GetNbElem();
128         if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
129         for(TInt iElem = 0; iElem < aNbElems; iElem++){
130           TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
131           double aCoords[3] = {0.0, 0.0, 0.0};
132           for(TInt iDim = 0; iDim < 3; iDim++)
133             aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
134           const SMDS_MeshNode* aNode;
135           if(anIsNodeNum) {
136             aNode = myMesh->AddNodeWithID
137               (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
138           } else {
139             aNode = myMesh->AddNode
140               (aCoords[0],aCoords[1],aCoords[2]);
141           }
142           //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
143
144           // Save reference to this node from its family
145           TInt aFamNum = aNodeInfo->GetFamNum(iElem);
146           if (myFamilies.find(aFamNum) != myFamilies.end())
147           {
148             myFamilies[aFamNum]->AddElement(aNode);
149             myFamilies[aFamNum]->SetType(SMDSAbs_Node);
150           }
151         }
152
153         // Reading pre information about all MED cells
154         //--------------------------------------------
155         typedef std::vector<int> TNodeIds;
156         bool takeNumbers = true;  // initially we trust the numbers from file
157         MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo);
158         MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
159         for(; anEntityIter != aEntityInfo.end(); anEntityIter++){
160           const EEntiteMaillage& anEntity = anEntityIter->first;
161           if(anEntity == eNOEUD) continue;
162           // Reading MED cells to the corresponding SMDS structure
163           //------------------------------------------------------
164           const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
165           MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
166           for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
167             const EGeometrieElement& aGeom = aGeom2SizeIter->first;
168
169             switch(aGeom){
170             case ePOINT1:
171               break;
172             case ePOLYGONE: {
173               PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
174               EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
175               
176               TInt aNbElem = aPolygoneInfo->GetNbElem();
177               for(TInt iElem = 0; iElem < aNbElem; iElem++){
178                 MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
179                 TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
180                 TNodeIds aNodeIds(aNbConn);
181 #ifdef _EDF_NODE_IDS_
182                 if(anIsNodeNum)
183                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
184                     aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
185                 else
186                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
187                     aNodeIds[iConn] = aConnSlice[iConn];
188 #else
189                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
190                   aNodeIds[iConn] = aConnSlice[iConn];
191 #endif
192                 bool isRenum = false;
193                 SMDS_MeshElement* anElement = NULL;
194                 TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
195
196                 try{
197                   if(anIsElemNum){
198                     TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
199                     anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
200                   }
201                   if(!anElement){
202                     std::vector<const SMDS_MeshNode*> aNodes(aNbConn);
203                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
204                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
205                     anElement = myMesh->AddPolygonalFace(aNodes);
206                     isRenum = anIsElemNum;
207                   }
208                 }catch(const std::exception& exc){
209                   aResult = DRS_FAIL;
210                 }catch (...){
211                   aResult = DRS_FAIL;
212                 }
213
214                 if(!anElement){
215                   aResult = DRS_WARN_SKIP_ELEM;
216                 }else{
217                   if(isRenum){
218                     anIsElemNum = eFAUX;
219                     takeNumbers = false;
220                     if(aResult < DRS_WARN_RENUMBER)
221                       aResult = DRS_WARN_RENUMBER;
222                   }
223                   if(myFamilies.find(aFamNum) != myFamilies.end()){
224                     // Save reference to this element from its family
225                     myFamilies[aFamNum]->AddElement(anElement);
226                     myFamilies[aFamNum]->SetType(anElement->GetType());
227                   }
228                 }
229               } // for (TInt iPG = 0; iPG < nbPolygons; iPG++)
230               break;
231             }
232             case ePOLYEDRE: {
233               PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
234               EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
235
236               TInt aNbElem = aPolyedreInfo->GetNbElem();
237               for(TInt iElem = 0; iElem < aNbElem; iElem++){
238                 MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
239                 TInt aNbFaces = aConnSliceArr.size();
240                 typedef std::vector<int> TQuantities;
241                 TQuantities aQuantities(aNbFaces);
242                 TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
243                 TNodeIds aNodeIds(aNbNodes);
244                 for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
245                   MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
246                   TInt aNbConn = aConnSlice.size();
247                   aQuantities[iFace] = aNbConn;
248 #ifdef _EDF_NODE_IDS_
249                   if(anIsNodeNum)
250                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
251                       aNodeIds[iNode++] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
252                   else
253                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
254                       aNodeIds[iNode++] = aConnSlice[iConn];
255 #else
256                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
257                     aNodeIds[iNode++] = aConnSlice[iConn];
258 #endif
259                 }
260                 
261                 bool isRenum = false;
262                 SMDS_MeshElement* anElement = NULL;
263                 TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
264
265                 try{
266                   if(anIsElemNum){
267                     TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
268                     anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
269                   }
270                   if(!anElement){
271                     std::vector<const SMDS_MeshNode*> aNodes(aNbNodes);
272                     for(TInt iConn = 0; iConn < aNbNodes; iConn++)
273                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
274                     anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
275                     isRenum = anIsElemNum;
276                   }
277                 }catch(const std::exception& exc){
278                   aResult = DRS_FAIL;
279                 }catch(...){
280                   aResult = DRS_FAIL;
281                 }
282
283                 if(!anElement){
284                   aResult = DRS_WARN_SKIP_ELEM;
285                 }else{
286                   if(isRenum){
287                     anIsElemNum = eFAUX;
288                     takeNumbers = false;
289                     if (aResult < DRS_WARN_RENUMBER)
290                       aResult = DRS_WARN_RENUMBER;
291                   }
292                   if(myFamilies.find(aFamNum) != myFamilies.end()){
293                     // Save reference to this element from its family
294                     myFamilies[aFamNum]->AddElement(anElement);
295                     myFamilies[aFamNum]->SetType(anElement->GetType());
296                   }
297                 }
298               } // for (int iPE = 0; iPE < nbPolyedres; iPE++)
299               break;
300             }
301             default: {
302               PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
303               EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
304               TInt aNbElems = aCellInfo->GetNbElem();
305               if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
306               if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
307               
308               for(int iElem = 0; iElem < aNbElems; iElem++){
309                 TInt aNbNodes = -1;
310                 switch(aGeom){
311                 case eSEG2:
312                 case eSEG3:
313                   aNbNodes = 2;
314                   break;
315                 case eTRIA3:
316                 case eTRIA6:
317                   aNbNodes = 3;
318                   break;
319                   break;
320                 case eQUAD4:
321                 case eQUAD8:
322                   aNbNodes = 4;
323                   break;
324                 case eTETRA4:
325                 case eTETRA10:
326                   aNbNodes = 4;
327                   break;
328                 case ePYRA5:
329                 case ePYRA13:
330                   aNbNodes = 5;
331                   break;
332                 case ePENTA6:
333                 case ePENTA15:
334                   aNbNodes = 6;
335                   break;
336                 case eHEXA8:
337                 case eHEXA20:
338                   aNbNodes = 8;
339                   break;
340                 }
341                 TNodeIds aNodeIds(aNbNodes);
342                 bool anIsValidConnect = false;
343                 TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
344                 try{
345 #ifdef _EDF_NODE_IDS_
346                   if(anIsNodeNum)
347                     for(int iNode = 0; iNode < aNbNodes; iNode++)
348                       aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
349                   else
350                     for(int iNode = 0; iNode < aNbNodes; iNode++)
351                       aNodeIds[iNode] = aConnSlice[iNode];
352 #else
353                   for(int iNode = 0; iNode < aNbNodes; iNode++)
354                     aNodeIds[iNode] = aConnSlice[iNode];
355 #endif
356                   anIsValidConnect = true;
357                 }catch(const std::exception& exc){
358                   //INFOS("Follow exception was cought:\n\t"<<exc.what());
359                   aResult = DRS_FAIL;
360                 }catch(...){
361                   //INFOS("Unknown exception was cought !!!");
362                   aResult = DRS_FAIL;
363                 }
364                 
365                 if(!anIsValidConnect)
366                   continue;
367                 
368                 bool isRenum = false;
369                 SMDS_MeshElement* anElement = NULL;
370                 TInt aFamNum = aCellInfo->GetFamNum(iElem);
371                 try{
372                   //MESSAGE("Try to create element # " << iElem << " with id = "
373                   //        << aCellInfo->GetElemNum(iElem));
374                   switch(aGeom){
375                   case eSEG2:
376                   case eSEG3:
377                     if(anIsElemNum)
378                       anElement = myMesh->AddEdgeWithID(aNodeIds[0],
379                                                         aNodeIds[1],
380                                                         aCellInfo->GetElemNum(iElem));
381                     if (!anElement) {
382                       anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
383                                                   FindNode(myMesh,aNodeIds[1]));
384                       isRenum = anIsElemNum;
385                     }
386                     break;
387                   case eTRIA3:
388                   case eTRIA6:
389                     aNbNodes = 3;
390                     if(anIsElemNum)
391                       anElement = myMesh->AddFaceWithID(aNodeIds[0],
392                                                         aNodeIds[1],
393                                                         aNodeIds[2],
394                                                         aCellInfo->GetElemNum(iElem));
395                     if (!anElement) {
396                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
397                                                   FindNode(myMesh,aNodeIds[1]),
398                                                   FindNode(myMesh,aNodeIds[2]));
399                       isRenum = anIsElemNum;
400                     }
401                     break;
402                   case eQUAD4:
403                   case eQUAD8:
404                     aNbNodes = 4;
405                     // There is some differnce between SMDS and MED
406                     if(anIsElemNum)
407                       anElement = myMesh->AddFaceWithID(aNodeIds[0],
408                                                         aNodeIds[1],
409                                                         aNodeIds[2],
410                                                         aNodeIds[3],
411                                                         aCellInfo->GetElemNum(iElem));
412                     if (!anElement) {
413                       anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
414                                                   FindNode(myMesh,aNodeIds[1]),
415                                                   FindNode(myMesh,aNodeIds[2]),
416                                                   FindNode(myMesh,aNodeIds[3]));
417                       isRenum = anIsElemNum;
418                     }
419                     break;
420                   case eTETRA4:
421                   case eTETRA10:
422                     aNbNodes = 4;
423                     if(anIsElemNum)
424                       anElement = myMesh->AddVolumeWithID(aNodeIds[0],
425                                                           aNodeIds[1],
426                                                           aNodeIds[2],
427                                                           aNodeIds[3],
428                                                           aCellInfo->GetElemNum(iElem));
429                     if (!anElement) {
430                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
431                                                     FindNode(myMesh,aNodeIds[1]),
432                                                     FindNode(myMesh,aNodeIds[2]),
433                                                     FindNode(myMesh,aNodeIds[3]));
434                       isRenum = anIsElemNum;
435                     }
436                     break;
437                   case ePYRA5:
438                   case ePYRA13:
439                     aNbNodes = 5;
440                     // There is some differnce between SMDS and MED
441                     if(anIsElemNum)
442                       anElement = myMesh->AddVolumeWithID(aNodeIds[0],
443                                                           aNodeIds[1],
444                                                           aNodeIds[2],
445                                                           aNodeIds[3],
446                                                           aNodeIds[4],
447                                                           aCellInfo->GetElemNum(iElem));
448                     if (!anElement) {
449                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
450                                                     FindNode(myMesh,aNodeIds[1]),
451                                                     FindNode(myMesh,aNodeIds[2]),
452                                                     FindNode(myMesh,aNodeIds[3]),
453                                                     FindNode(myMesh,aNodeIds[4]));
454                       isRenum = anIsElemNum;
455                     }
456                     break;
457                   case ePENTA6:
458                   case ePENTA15:
459                     aNbNodes = 6;
460                     if(anIsElemNum)
461                       anElement = myMesh->AddVolumeWithID(aNodeIds[0],
462                                                           aNodeIds[1],
463                                                           aNodeIds[2],
464                                                           aNodeIds[3],
465                                                           aNodeIds[4],
466                                                           aNodeIds[5],
467                                                           aCellInfo->GetElemNum(iElem));
468                     if (!anElement) {
469                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
470                                                     FindNode(myMesh,aNodeIds[1]),
471                                                     FindNode(myMesh,aNodeIds[2]),
472                                                     FindNode(myMesh,aNodeIds[3]),
473                                                     FindNode(myMesh,aNodeIds[4]),
474                                                     FindNode(myMesh,aNodeIds[5]));
475                       isRenum = anIsElemNum;
476                     }
477                     break;
478                   case eHEXA8:
479                   case eHEXA20:
480                     aNbNodes = 8;
481                     if(anIsElemNum)
482                       anElement = myMesh->AddVolumeWithID(aNodeIds[0],
483                                                           aNodeIds[1],
484                                                           aNodeIds[2],
485                                                           aNodeIds[3],
486                                                           aNodeIds[4],
487                                                           aNodeIds[5],
488                                                           aNodeIds[6],
489                                                           aNodeIds[7],
490                                                           aCellInfo->GetElemNum(iElem));
491                     if (!anElement) {
492                       anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
493                                                     FindNode(myMesh,aNodeIds[1]),
494                                                     FindNode(myMesh,aNodeIds[2]),
495                                                     FindNode(myMesh,aNodeIds[3]),
496                                                     FindNode(myMesh,aNodeIds[4]),
497                                                     FindNode(myMesh,aNodeIds[5]),
498                                                     FindNode(myMesh,aNodeIds[6]),
499                                                     FindNode(myMesh,aNodeIds[7]));
500                       isRenum = anIsElemNum;
501                     }
502                     break;
503                   }
504                 }catch(const std::exception& exc){
505                   //INFOS("Follow exception was cought:\n\t"<<exc.what());
506                   aResult = DRS_FAIL;
507                 }catch(...){
508                   //INFOS("Unknown exception was cought !!!");
509                   aResult = DRS_FAIL;
510                 }
511                 
512                 if (!anElement) {
513                   aResult = DRS_WARN_SKIP_ELEM;
514                 }
515                 else {
516                   if (isRenum) {
517                     anIsElemNum = eFAUX;
518                     takeNumbers = false;
519                     if (aResult < DRS_WARN_RENUMBER)
520                       aResult = DRS_WARN_RENUMBER;
521                   }
522                   if (myFamilies.find(aFamNum) != myFamilies.end()) {
523                     // Save reference to this element from its family
524                     myFamilies[aFamNum]->AddElement(anElement);
525                     myFamilies[aFamNum]->SetType(anElement->GetType());
526                   }
527                 }
528               }
529             }}
530           }
531         }
532       }
533     }
534   }catch(const std::exception& exc){
535     INFOS("Follow exception was cought:\n\t"<<exc.what());
536     aResult = DRS_FAIL;
537   }catch(...){
538     INFOS("Unknown exception was cought !!!");
539     aResult = DRS_FAIL;
540   }
541   if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
542   return aResult;
543 }
544
545 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
546 {
547   list<string> aMeshNames;
548
549   try {
550     if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
551     theStatus = DRS_OK;
552     PWrapper aMed = CrWrapper(myFile);
553
554     if (TInt aNbMeshes = aMed->GetNbMeshes()) {
555       for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
556         // Reading the MED mesh
557         //---------------------
558         PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
559         aMeshNames.push_back(aMeshInfo->GetName());
560       }
561     }
562   }catch(const std::exception& exc){
563     INFOS("Follow exception was cought:\n\t"<<exc.what());
564     theStatus = DRS_FAIL;
565   }catch(...){
566     INFOS("Unknown exception was cought !!!");
567     theStatus = DRS_FAIL;
568   }
569
570   return aMeshNames;
571 }
572
573 list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
574 {
575   list<string> aResult;
576   set<string> aResGroupNames;
577
578   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
579   for (; aFamsIter != myFamilies.end(); aFamsIter++)
580   {
581     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
582     const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
583     set<string>::iterator aGrNamesIter = aGroupNames.begin();
584     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
585     {
586       string aName = *aGrNamesIter;
587       // Check, if this is a Group or SubMesh name
588 //if (aName.substr(0, 5) == string("Group")) {
589         if (aResGroupNames.find(aName) == aResGroupNames.end()) {
590           aResGroupNames.insert(aName);
591           aResult.push_back(aName);
592         }
593 //    }
594     }
595   }
596
597   return aResult;
598 }
599
600 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
601 {
602   string aGroupName (theGroup->GetStoreName());
603   if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
604
605   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
606   for (; aFamsIter != myFamilies.end(); aFamsIter++)
607   {
608     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
609     if (aFamily->MemberOf(aGroupName))
610     {
611       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
612       set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
613       const SMDS_MeshElement * element = 0;
614       for (; anElemsIter != anElements.end(); anElemsIter++)
615       {
616         element = *anElemsIter;
617         theGroup->SMDSGroup().Add(element);
618       }
619       if ( element )
620         theGroup->SetType( element->GetType() );
621     }
622   }
623 }
624
625 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
626                                            const int theId)
627 {
628   char submeshGrpName[ 30 ];
629   sprintf( submeshGrpName, "SubMesh %d", theId );
630   string aName (submeshGrpName);
631   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
632   for (; aFamsIter != myFamilies.end(); aFamsIter++)
633   {
634     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
635     if (aFamily->MemberOf(aName))
636     {
637       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
638       set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
639       if (aFamily->GetType() == SMDSAbs_Node)
640       {
641         for (; anElemsIter != anElements.end(); anElemsIter++)
642         {
643           const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
644           theSubMesh->AddNode(node);
645         }
646       }
647       else
648       {
649         for (; anElemsIter != anElements.end(); anElemsIter++)
650         {
651           theSubMesh->AddElement(*anElemsIter);
652         }
653       }
654     }
655   }
656 }
657
658 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
659 {
660   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
661   for (; aFamsIter != myFamilies.end(); aFamsIter++)
662   {
663     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
664     MED::TStringSet aGroupNames = aFamily->GetGroupNames();
665     set<string>::iterator aGrNamesIter = aGroupNames.begin();
666     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
667     {
668       string aName = *aGrNamesIter;
669       // Check, if this is a Group or SubMesh name
670       if (aName.substr(0, 7) == string("SubMesh"))
671       {
672         int Id = atoi(string(aName).substr(7).c_str());
673         set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
674         set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
675         if (aFamily->GetType() == SMDSAbs_Node)
676         {
677           for (; anElemsIter != anElements.end(); anElemsIter++)
678           {
679             SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
680               ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
681             // find out a shape type
682             TopoDS_Shape aShape = myMesh->IndexToShape( Id );
683             int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
684             switch ( aShapeType ) {
685             case TopAbs_FACE:
686               myMesh->SetNodeOnFace(node, Id); break;
687             case TopAbs_EDGE:
688               myMesh->SetNodeOnEdge(node, Id); break;
689             case TopAbs_VERTEX:
690               myMesh->SetNodeOnVertex(node, Id); break;
691             default:
692               myMesh->SetNodeInVolume(node, Id);
693             }
694           }
695         }
696         else
697         {
698           for (; anElemsIter != anElements.end(); anElemsIter++)
699           {
700             myMesh->SetMeshElementOnShape(*anElemsIter, Id);
701           }
702         }
703       }
704     }
705   }
706 }