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