1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH DriverMED : driver to read and write 'med' files
24 // File : DriverMED_R_SMESHDS_Mesh.cxx
27 #include "DriverMED_R_SMESHDS_Mesh.h"
28 #include "SMESHDS_Mesh.hxx"
29 #include "utilities.h"
31 #include "DriverMED_Family.h"
33 #include "SMESHDS_Group.hxx"
35 #include "MED_Factory.hxx"
36 #include "MED_CoordUtils.hxx"
37 #include "MED_Utilities.hxx"
39 #include <NCollection_Map.hxx>
44 static int MYDEBUG = 1;
47 static int MYDEBUG = 0;
50 #define _EDF_NODE_IDS_
56 DriverMED_R_SMESHDS_Mesh
57 ::SetMeshName(string theMeshName)
59 myMeshName = theMeshName;
62 static const SMDS_MeshNode*
63 FindNode(const SMDS_Mesh* theMesh, TInt theId)
65 const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
66 if(aNode) return aNode;
67 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
72 DriverMED_R_SMESHDS_Mesh
75 Status aResult = DRS_FAIL;
76 bool isDescConn = false; // Mantis issue 0020483
81 if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
82 PWrapper aMed = CrWrapper(myFile,true);
85 if(TInt aNbMeshes = aMed->GetNbMeshes()){
86 for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
87 // Reading the MED mesh
88 //---------------------
89 PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
93 ostringstream aMeshNameStr;
94 aMeshNameStr<<myMeshId;
95 aMeshName = aMeshNameStr.str();
97 aMeshName = myMeshName;
99 if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
100 if(aMeshName != aMeshInfo->GetName()) continue;
103 // Reading MED families to the temporary structure
104 //------------------------------------------------
106 TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
107 if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
108 for (TInt iFam = 0; iFam < aNbFams; iFam++) {
109 PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
111 TInt aFamId = aFamilyInfo->GetId();
112 if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
114 DriverMED_FamilyPtr aFamily (new DriverMED_Family);
116 TInt aNbGrp = aFamilyInfo->GetNbGroup();
117 if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
118 bool isAttrOk = false;
119 if(aFamilyInfo->GetNbAttr() == aNbGrp)
121 for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
122 string aGroupName = aFamilyInfo->GetGroupName(iGr);
124 TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
125 aFamily->SetGroupAttributVal(anAttrVal);
128 if(MYDEBUG) MESSAGE(aGroupName);
129 aFamily->AddGroupName(aGroupName);
132 aFamily->SetId( aFamId );
133 myFamilies[aFamId] = aFamily;
137 if (aMeshInfo->GetType() == MED::eSTRUCTURE){
138 /*bool aRes = */buildMeshGrille(aMed,aMeshInfo);
142 // Reading MED nodes to the corresponding SMDS structure
143 //------------------------------------------------------
144 PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
149 aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
150 PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
152 EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
153 TInt aNbElems = aNodeInfo->GetNbElem();
154 if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
155 DriverMED_FamilyPtr aFamily;
156 for(TInt iElem = 0; iElem < aNbElems; iElem++){
157 TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
158 double aCoords[3] = {0.0, 0.0, 0.0};
159 for(TInt iDim = 0; iDim < 3; iDim++)
160 aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
161 const SMDS_MeshNode* aNode;
163 aNode = myMesh->AddNodeWithID
164 (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
166 aNode = myMesh->AddNodeWithID
167 (aCoords[0],aCoords[1],aCoords[2], iElem+1);
170 // Save reference to this node from its family
171 TInt aFamNum = aNodeInfo->GetFamNum(iElem);
172 if ( checkFamilyID ( aFamily, aFamNum ))
174 aFamily->AddElement(aNode);
175 aFamily->SetType(SMDSAbs_Node);
179 // Are there any MED cells in descending connectivity
180 // Mantis issue 0020483
181 //---------------------------------------------------
182 NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
184 MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
185 MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
186 //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
187 for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
188 const EEntiteMaillage& anEntity = anEntityIterDesc->first;
189 aDescendingEntitiesMap.Add(anEntity);
190 //if (anEntity != eNOEUD) isDescConn = true;
194 // Reading pre information about all MED cells
195 //--------------------------------------------
196 typedef MED::TVector<int> TNodeIds;
197 bool takeNumbers = true; // initially we trust the numbers from file
198 MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD);
199 MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
200 for (; anEntityIter != aEntityInfo.end(); anEntityIter++) {
201 const EEntiteMaillage& anEntity = anEntityIter->first;
202 aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
203 if (anEntity == eNOEUD) continue;
204 // Reading MED cells to the corresponding SMDS structure
205 //------------------------------------------------------
206 const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
207 MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
208 for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
209 const EGeometrieElement& aGeom = aGeom2SizeIter->first;
211 if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
213 PBallInfo aBallInfo = aMed->GetPBallInfo(aMeshInfo);
214 TInt aNbBalls = aBallInfo->GetNbElem();
216 EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
217 if ( anIsElemNum && aBallInfo->myElemNum->empty() )
220 // get supporting nodes
222 #ifdef _EDF_NODE_IDS_
224 aNodeIds.resize( aNbBalls );
225 for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
227 aNodeIds[iBall] = aNodeInfo->GetElemNum( (*aBallInfo->myConn)[ iBall ]-1 );
228 anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
233 aNodeIds.swap( *(aBallInfo->myConn ));
235 // allocate array of diameters
236 vtkIdType maxID = myMesh->MaxElementID() + aNbBalls;
237 if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
238 maxID = *std::max_element( aBallInfo->myElemNum->begin(),
239 aBallInfo->myElemNum->end() );
240 myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
243 SMDS_MeshElement* anElement;
244 DriverMED_FamilyPtr aFamily;
245 for ( TInt iBall = 0; iBall < aNbBalls; iBall++)
249 if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
250 aBallInfo->myDiameters[iBall],
251 aBallInfo->GetElemNum(iBall))))
255 myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
256 aBallInfo->myDiameters[iBall] );
258 // Save reference to this element from its family
259 TInt aFamNum = aBallInfo->GetFamNum(iBall);
260 if ( checkFamilyID ( aFamily, aFamNum ))
262 aFamily->AddElement(anElement);
263 aFamily->SetType( SMDSAbs_Ball );
268 ( takeNumbers && aBallInfo->IsElemNum() && !aBallInfo->myElemNum->empty() ))
269 if ( aResult < DRS_WARN_RENUMBER )
270 aResult = DRS_WARN_RENUMBER;
276 // case ePOINT1: ## PAL16410
279 PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
280 EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
282 TInt aNbElem = aPolygoneInfo->GetNbElem();
283 for(TInt iElem = 0; iElem < aNbElem; iElem++){
284 MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
285 TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
286 TNodeIds aNodeIds(aNbConn);
287 #ifdef _EDF_NODE_IDS_
289 for(TInt iConn = 0; iConn < aNbConn; iConn++)
290 aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
292 for(TInt iConn = 0; iConn < aNbConn; iConn++)
293 aNodeIds[iConn] = aConnSlice[iConn];
295 for(TInt iConn = 0; iConn < aNbConn; iConn++)
296 aNodeIds[iConn] = aConnSlice[iConn];
298 bool isRenum = false;
299 SMDS_MeshElement* anElement = NULL;
300 TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
306 TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
307 anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
310 vector<const SMDS_MeshNode*> aNodes(aNbConn);
311 for(TInt iConn = 0; iConn < aNbConn; iConn++)
312 aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
313 anElement = myMesh->AddPolygonalFace(aNodes);
314 isRenum = anIsElemNum;
317 }catch(const std::exception& exc){
324 aResult = DRS_WARN_SKIP_ELEM;
329 if(aResult < DRS_WARN_RENUMBER)
330 aResult = DRS_WARN_RENUMBER;
332 if ( checkFamilyID ( aFamily, aFamNum ))
334 // Save reference to this element from its family
335 aFamily->AddElement(anElement);
336 aFamily->SetType(anElement->GetType());
343 PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
344 EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
346 TInt aNbElem = aPolyedreInfo->GetNbElem();
347 for(TInt iElem = 0; iElem < aNbElem; iElem++){
348 MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
349 TInt aNbFaces = aConnSliceArr.size();
350 typedef MED::TVector<int> TQuantities;
351 TQuantities aQuantities(aNbFaces);
352 TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
353 TNodeIds aNodeIds(aNbNodes);
354 for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
355 MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
356 TInt aNbConn = aConnSlice.size();
357 aQuantities[iFace] = aNbConn;
358 #ifdef _EDF_NODE_IDS_
360 for(TInt iConn = 0; iConn < aNbConn; iConn++)
362 aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
366 for(TInt iConn = 0; iConn < aNbConn; iConn++)
368 aNodeIds[iNode++] = aConnSlice[iConn];
371 for(TInt iConn = 0; iConn < aNbConn; iConn++)
373 aNodeIds[iNode++] = aConnSlice[iConn];
378 bool isRenum = false;
379 SMDS_MeshElement* anElement = NULL;
380 TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
386 TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
387 anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
390 vector<const SMDS_MeshNode*> aNodes(aNbNodes);
391 for(TInt iConn = 0; iConn < aNbNodes; iConn++)
392 aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
393 anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
394 isRenum = anIsElemNum;
397 }catch(const std::exception& exc){
404 aResult = DRS_WARN_SKIP_ELEM;
409 if (aResult < DRS_WARN_RENUMBER)
410 aResult = DRS_WARN_RENUMBER;
412 if ( checkFamilyID ( aFamily, aFamNum )) {
413 // Save reference to this element from its family
414 aFamily->AddElement(anElement);
415 aFamily->SetType(anElement->GetType());
422 PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
423 EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
424 TInt aNbElems = aCellInfo->GetNbElem();
425 if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
426 if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
430 case eSEG2: aNbNodes = 2; break;
431 case eSEG3: aNbNodes = 3; break;
432 case eTRIA3: aNbNodes = 3; break;
433 case eTRIA6: aNbNodes = 6; break;
434 case eTRIA7: aNbNodes = 7; break;
435 case eQUAD4: aNbNodes = 4; break;
436 case eQUAD8: aNbNodes = 8; break;
437 case eQUAD9: aNbNodes = 9; break;
438 case eTETRA4: aNbNodes = 4; break;
439 case eTETRA10: aNbNodes = 10; break;
440 case ePYRA5: aNbNodes = 5; break;
441 case ePYRA13: aNbNodes = 13; break;
442 case ePENTA6: aNbNodes = 6; break;
443 case ePENTA15: aNbNodes = 15; break;
444 case eHEXA8: aNbNodes = 8; break;
445 case eHEXA20: aNbNodes = 20; break;
446 case eHEXA27: aNbNodes = 27; break;
447 case eOCTA12: aNbNodes = 12; break;
448 case ePOINT1: aNbNodes = 1; break;
451 vector<TInt> aNodeIds(aNbNodes);
452 for(int iElem = 0; iElem < aNbElems; iElem++){
453 bool anIsValidConnect = false;
454 TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
458 #ifdef _EDF_NODE_IDS_
460 for(int iNode = 0; iNode < aNbNodes; iNode++)
461 aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
463 for(int iNode = 0; iNode < aNbNodes; iNode++)
464 aNodeIds[iNode] = aConnSlice[iNode];
466 for(int iNode = 0; iNode < aNbNodes; iNode++)
467 aNodeIds[iNode] = aConnSlice[iNode];
469 anIsValidConnect = true;
471 }catch(const std::exception& exc){
472 INFOS("Following exception was caught:\n\t"<<exc.what());
475 INFOS("Unknown exception was caught !!!");
479 if(!anIsValidConnect)
482 bool isRenum = false;
483 const SMDS_MeshElement* anElement = NULL;
484 TInt aFamNum = aCellInfo->GetFamNum(iElem);
488 //MESSAGE("Try to create element # " << iElem << " with id = "
489 // << aCellInfo->GetElemNum(iElem));
492 //anElement = FindNode(myMesh,aNodeIds[0]);
494 anElement = myMesh->Add0DElementWithID
495 (aNodeIds[0], aCellInfo->GetElemNum(iElem));
497 anElement = myMesh->Add0DElement(FindNode(myMesh,aNodeIds[0]));
498 isRenum = anIsElemNum;
503 anElement = myMesh->AddEdgeWithID(aNodeIds[0],
505 aCellInfo->GetElemNum(iElem));
507 anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
508 FindNode(myMesh,aNodeIds[1]));
509 isRenum = anIsElemNum;
514 anElement = myMesh->AddEdgeWithID(aNodeIds[0],
517 aCellInfo->GetElemNum(iElem));
519 anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
520 FindNode(myMesh,aNodeIds[1]),
521 FindNode(myMesh,aNodeIds[2]));
522 isRenum = anIsElemNum;
528 anElement = myMesh->AddFaceWithID(aNodeIds[0],
531 aCellInfo->GetElemNum(iElem));
533 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
534 FindNode(myMesh,aNodeIds[1]),
535 FindNode(myMesh,aNodeIds[2]));
536 isRenum = anIsElemNum;
542 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
543 aNodeIds[2], aNodeIds[3],
544 aNodeIds[4], aNodeIds[5],
545 aCellInfo->GetElemNum(iElem));
547 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
548 FindNode(myMesh,aNodeIds[1]),
549 FindNode(myMesh,aNodeIds[2]),
550 FindNode(myMesh,aNodeIds[3]),
551 FindNode(myMesh,aNodeIds[4]),
552 FindNode(myMesh,aNodeIds[5]));
553 isRenum = anIsElemNum;
559 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
560 aNodeIds[2], aNodeIds[3],
561 aNodeIds[4], aNodeIds[5], aNodeIds[6],
562 aCellInfo->GetElemNum(iElem));
564 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
565 FindNode(myMesh,aNodeIds[1]),
566 FindNode(myMesh,aNodeIds[2]),
567 FindNode(myMesh,aNodeIds[3]),
568 FindNode(myMesh,aNodeIds[4]),
569 FindNode(myMesh,aNodeIds[5]),
570 FindNode(myMesh,aNodeIds[6]));
571 isRenum = anIsElemNum;
577 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
578 aNodeIds[2], aNodeIds[3],
579 aCellInfo->GetElemNum(iElem));
581 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
582 FindNode(myMesh,aNodeIds[1]),
583 FindNode(myMesh,aNodeIds[2]),
584 FindNode(myMesh,aNodeIds[3]));
585 isRenum = anIsElemNum;
591 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
592 aNodeIds[2], aNodeIds[3],
593 aNodeIds[4], aNodeIds[5],
594 aNodeIds[6], aNodeIds[7],
595 aCellInfo->GetElemNum(iElem));
597 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
598 FindNode(myMesh,aNodeIds[1]),
599 FindNode(myMesh,aNodeIds[2]),
600 FindNode(myMesh,aNodeIds[3]),
601 FindNode(myMesh,aNodeIds[4]),
602 FindNode(myMesh,aNodeIds[5]),
603 FindNode(myMesh,aNodeIds[6]),
604 FindNode(myMesh,aNodeIds[7]));
605 isRenum = anIsElemNum;
611 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
612 aNodeIds[2], aNodeIds[3],
613 aNodeIds[4], aNodeIds[5],
614 aNodeIds[6], aNodeIds[7], aNodeIds[8],
615 aCellInfo->GetElemNum(iElem));
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 FindNode(myMesh,aNodeIds[8]));
626 isRenum = anIsElemNum;
632 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
633 aNodeIds[2], aNodeIds[3],
634 aCellInfo->GetElemNum(iElem));
636 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
637 FindNode(myMesh,aNodeIds[1]),
638 FindNode(myMesh,aNodeIds[2]),
639 FindNode(myMesh,aNodeIds[3]));
640 isRenum = anIsElemNum;
646 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
647 aNodeIds[2], aNodeIds[3],
648 aNodeIds[4], aNodeIds[5],
649 aNodeIds[6], aNodeIds[7],
650 aNodeIds[8], aNodeIds[9],
651 aCellInfo->GetElemNum(iElem));
653 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
654 FindNode(myMesh,aNodeIds[1]),
655 FindNode(myMesh,aNodeIds[2]),
656 FindNode(myMesh,aNodeIds[3]),
657 FindNode(myMesh,aNodeIds[4]),
658 FindNode(myMesh,aNodeIds[5]),
659 FindNode(myMesh,aNodeIds[6]),
660 FindNode(myMesh,aNodeIds[7]),
661 FindNode(myMesh,aNodeIds[8]),
662 FindNode(myMesh,aNodeIds[9]));
663 isRenum = anIsElemNum;
669 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
670 aNodeIds[2], aNodeIds[3],
672 aCellInfo->GetElemNum(iElem));
674 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
675 FindNode(myMesh,aNodeIds[1]),
676 FindNode(myMesh,aNodeIds[2]),
677 FindNode(myMesh,aNodeIds[3]),
678 FindNode(myMesh,aNodeIds[4]));
679 isRenum = anIsElemNum;
685 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
686 aNodeIds[2], aNodeIds[3],
687 aNodeIds[4], aNodeIds[5],
688 aNodeIds[6], aNodeIds[7],
689 aNodeIds[8], aNodeIds[9],
690 aNodeIds[10], aNodeIds[11],
692 aCellInfo->GetElemNum(iElem));
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 FindNode(myMesh,aNodeIds[5]),
700 FindNode(myMesh,aNodeIds[6]),
701 FindNode(myMesh,aNodeIds[7]),
702 FindNode(myMesh,aNodeIds[8]),
703 FindNode(myMesh,aNodeIds[9]),
704 FindNode(myMesh,aNodeIds[10]),
705 FindNode(myMesh,aNodeIds[11]),
706 FindNode(myMesh,aNodeIds[12]));
707 isRenum = anIsElemNum;
713 anElement = myMesh->AddVolumeWithID(aNodeIds[0],
719 aCellInfo->GetElemNum(iElem));
721 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
722 FindNode(myMesh,aNodeIds[1]),
723 FindNode(myMesh,aNodeIds[2]),
724 FindNode(myMesh,aNodeIds[3]),
725 FindNode(myMesh,aNodeIds[4]),
726 FindNode(myMesh,aNodeIds[5]));
727 isRenum = anIsElemNum;
733 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
734 aNodeIds[2], aNodeIds[3],
735 aNodeIds[4], aNodeIds[5],
736 aNodeIds[6], aNodeIds[7],
737 aNodeIds[8], aNodeIds[9],
738 aNodeIds[10], aNodeIds[11],
739 aNodeIds[12], aNodeIds[13],
741 aCellInfo->GetElemNum(iElem));
743 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
744 FindNode(myMesh,aNodeIds[1]),
745 FindNode(myMesh,aNodeIds[2]),
746 FindNode(myMesh,aNodeIds[3]),
747 FindNode(myMesh,aNodeIds[4]),
748 FindNode(myMesh,aNodeIds[5]),
749 FindNode(myMesh,aNodeIds[6]),
750 FindNode(myMesh,aNodeIds[7]),
751 FindNode(myMesh,aNodeIds[8]),
752 FindNode(myMesh,aNodeIds[9]),
753 FindNode(myMesh,aNodeIds[10]),
754 FindNode(myMesh,aNodeIds[11]),
755 FindNode(myMesh,aNodeIds[12]),
756 FindNode(myMesh,aNodeIds[13]),
757 FindNode(myMesh,aNodeIds[14]));
758 isRenum = anIsElemNum;
764 anElement = myMesh->AddVolumeWithID(aNodeIds[0],
772 aCellInfo->GetElemNum(iElem));
774 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
775 FindNode(myMesh,aNodeIds[1]),
776 FindNode(myMesh,aNodeIds[2]),
777 FindNode(myMesh,aNodeIds[3]),
778 FindNode(myMesh,aNodeIds[4]),
779 FindNode(myMesh,aNodeIds[5]),
780 FindNode(myMesh,aNodeIds[6]),
781 FindNode(myMesh,aNodeIds[7]));
782 isRenum = anIsElemNum;
789 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
790 aNodeIds[2], aNodeIds[3],
791 aNodeIds[4], aNodeIds[5],
792 aNodeIds[6], aNodeIds[7],
793 aNodeIds[8], aNodeIds[9],
794 aNodeIds[10], aNodeIds[11],
795 aNodeIds[12], aNodeIds[13],
796 aNodeIds[14], aNodeIds[15],
797 aNodeIds[16], aNodeIds[17],
798 aNodeIds[18], aNodeIds[19],
799 aCellInfo->GetElemNum(iElem));
801 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
802 FindNode(myMesh,aNodeIds[1]),
803 FindNode(myMesh,aNodeIds[2]),
804 FindNode(myMesh,aNodeIds[3]),
805 FindNode(myMesh,aNodeIds[4]),
806 FindNode(myMesh,aNodeIds[5]),
807 FindNode(myMesh,aNodeIds[6]),
808 FindNode(myMesh,aNodeIds[7]),
809 FindNode(myMesh,aNodeIds[8]),
810 FindNode(myMesh,aNodeIds[9]),
811 FindNode(myMesh,aNodeIds[10]),
812 FindNode(myMesh,aNodeIds[11]),
813 FindNode(myMesh,aNodeIds[12]),
814 FindNode(myMesh,aNodeIds[13]),
815 FindNode(myMesh,aNodeIds[14]),
816 FindNode(myMesh,aNodeIds[15]),
817 FindNode(myMesh,aNodeIds[16]),
818 FindNode(myMesh,aNodeIds[17]),
819 FindNode(myMesh,aNodeIds[18]),
820 FindNode(myMesh,aNodeIds[19]));
821 isRenum = anIsElemNum;
828 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
829 aNodeIds[2], aNodeIds[3],
830 aNodeIds[4], aNodeIds[5],
831 aNodeIds[6], aNodeIds[7],
832 aNodeIds[8], aNodeIds[9],
833 aNodeIds[10], aNodeIds[11],
834 aNodeIds[12], aNodeIds[13],
835 aNodeIds[14], aNodeIds[15],
836 aNodeIds[16], aNodeIds[17],
837 aNodeIds[18], aNodeIds[19],
838 aNodeIds[20], aNodeIds[21],
839 aNodeIds[22], aNodeIds[23],
840 aNodeIds[24], aNodeIds[25],
842 aCellInfo->GetElemNum(iElem));
844 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
845 FindNode(myMesh,aNodeIds[1]),
846 FindNode(myMesh,aNodeIds[2]),
847 FindNode(myMesh,aNodeIds[3]),
848 FindNode(myMesh,aNodeIds[4]),
849 FindNode(myMesh,aNodeIds[5]),
850 FindNode(myMesh,aNodeIds[6]),
851 FindNode(myMesh,aNodeIds[7]),
852 FindNode(myMesh,aNodeIds[8]),
853 FindNode(myMesh,aNodeIds[9]),
854 FindNode(myMesh,aNodeIds[10]),
855 FindNode(myMesh,aNodeIds[11]),
856 FindNode(myMesh,aNodeIds[12]),
857 FindNode(myMesh,aNodeIds[13]),
858 FindNode(myMesh,aNodeIds[14]),
859 FindNode(myMesh,aNodeIds[15]),
860 FindNode(myMesh,aNodeIds[16]),
861 FindNode(myMesh,aNodeIds[17]),
862 FindNode(myMesh,aNodeIds[18]),
863 FindNode(myMesh,aNodeIds[19]),
864 FindNode(myMesh,aNodeIds[20]),
865 FindNode(myMesh,aNodeIds[21]),
866 FindNode(myMesh,aNodeIds[22]),
867 FindNode(myMesh,aNodeIds[23]),
868 FindNode(myMesh,aNodeIds[24]),
869 FindNode(myMesh,aNodeIds[25]),
870 FindNode(myMesh,aNodeIds[26]));
871 isRenum = anIsElemNum;
878 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
879 aNodeIds[2], aNodeIds[3],
880 aNodeIds[4], aNodeIds[5],
881 aNodeIds[6], aNodeIds[7],
882 aNodeIds[8], aNodeIds[9],
883 aNodeIds[10], aNodeIds[11],
884 aCellInfo->GetElemNum(iElem));
886 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
887 FindNode(myMesh,aNodeIds[1]),
888 FindNode(myMesh,aNodeIds[2]),
889 FindNode(myMesh,aNodeIds[3]),
890 FindNode(myMesh,aNodeIds[4]),
891 FindNode(myMesh,aNodeIds[5]),
892 FindNode(myMesh,aNodeIds[6]),
893 FindNode(myMesh,aNodeIds[7]),
894 FindNode(myMesh,aNodeIds[8]),
895 FindNode(myMesh,aNodeIds[9]),
896 FindNode(myMesh,aNodeIds[10]),
897 FindNode(myMesh,aNodeIds[11]));
898 isRenum = anIsElemNum;
905 }catch(const std::exception& exc){
906 INFOS("The following exception was caught:\n\t"<<exc.what());
909 INFOS("Unknown exception was caught !!!");
914 aResult = DRS_WARN_SKIP_ELEM;
920 if (aResult < DRS_WARN_RENUMBER)
921 aResult = DRS_WARN_RENUMBER;
923 if ( checkFamilyID ( aFamily, aFamNum )) {
924 // Save reference to this element from its family
925 myFamilies[aFamNum]->AddElement(anElement);
926 myFamilies[aFamNum]->SetType(anElement->GetType());
933 if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
934 } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
937 }catch(const std::exception& exc){
938 INFOS("The following exception was caught:\n\t"<<exc.what());
941 INFOS("Unknown exception was caught !!!");
946 myMesh->compactMesh();
948 // Mantis issue 0020483
949 if (aResult == DRS_OK && isDescConn) {
950 INFOS("There are some elements in descending connectivity in med file. They were not read !!!");
951 aResult = DRS_WARN_DESCENDING;
954 if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
958 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
960 list<string> aMeshNames;
963 if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
965 PWrapper aMed = CrWrapper(myFile);
967 if (TInt aNbMeshes = aMed->GetNbMeshes()) {
968 for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
969 // Reading the MED mesh
970 //---------------------
971 PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
972 aMeshNames.push_back(aMeshInfo->GetName());
975 } catch(const std::exception& exc) {
976 INFOS("Following exception was caught:\n\t"<<exc.what());
977 theStatus = DRS_FAIL;
979 INFOS("Unknown exception was caught !!!");
980 theStatus = DRS_FAIL;
986 list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
988 list<TNameAndType> aResult;
989 set<TNameAndType> aResGroupNames;
991 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
992 for (; aFamsIter != myFamilies.end(); aFamsIter++)
994 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
995 const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
996 set<string>::const_iterator aGrNamesIter = aGroupNames.begin();
997 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
999 const set< SMDSAbs_ElementType >& types = aFamily->GetTypes();
1000 set< SMDSAbs_ElementType >::const_iterator type = types.begin();
1001 for ( ; type != types.end(); ++type )
1003 TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type );
1004 if ( aResGroupNames.insert( aNameAndType ).second ) {
1005 aResult.push_back( aNameAndType );
1014 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
1016 string aGroupName (theGroup->GetStoreName());
1017 if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
1019 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1020 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1022 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1023 if (aFamily->GetTypes().count( theGroup->GetType() ) && aFamily->MemberOf(aGroupName))
1025 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
1026 set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
1027 for (; anElemsIter != anElements.end(); anElemsIter++)
1029 const SMDS_MeshElement * element = *anElemsIter;
1030 if ( element->GetType() == theGroup->GetType() ) // Issue 0020576
1031 theGroup->SMDSGroup().Add(element);
1033 int aGroupAttrVal = aFamily->GetGroupAttributVal();
1034 if( aGroupAttrVal != 0)
1035 theGroup->SetColorGroup(aGroupAttrVal);
1036 // if ( element ) -- Issue 0020576
1037 // theGroup->SetType( theGroup->SMDSGroup().GetType() );
1042 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
1045 char submeshGrpName[ 30 ];
1046 sprintf( submeshGrpName, "SubMesh %d", theId );
1047 string aName (submeshGrpName);
1048 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1049 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1051 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1052 if (aFamily->MemberOf(aName))
1054 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
1055 set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
1056 if (aFamily->GetType() == SMDSAbs_Node)
1058 for (; anElemsIter != anElements.end(); anElemsIter++)
1060 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
1061 theSubMesh->AddNode(node);
1066 for (; anElemsIter != anElements.end(); anElemsIter++)
1068 theSubMesh->AddElement(*anElemsIter);
1075 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
1077 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1078 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1080 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1081 MED::TStringSet aGroupNames = aFamily->GetGroupNames();
1082 set<string>::iterator aGrNamesIter = aGroupNames.begin();
1083 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
1085 string aName = *aGrNamesIter;
1086 // Check, if this is a Group or SubMesh name
1087 if (aName.substr(0, 7) == string("SubMesh"))
1089 int Id = atoi(string(aName).substr(7).c_str());
1090 set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
1091 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
1092 if (aFamily->GetType() == SMDSAbs_Node)
1094 for (; anElemsIter != anElements.end(); anElemsIter++)
1096 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
1097 ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
1098 // find out a shape type
1099 TopoDS_Shape aShape = myMesh->IndexToShape( Id );
1100 int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
1101 switch ( aShapeType ) {
1103 myMesh->SetNodeOnFace(node, Id); break;
1105 myMesh->SetNodeOnEdge(node, Id); break;
1107 myMesh->SetNodeOnVertex(node, Id); break;
1109 myMesh->SetNodeInVolume(node, Id);
1115 for (; anElemsIter != anElements.end(); anElemsIter++)
1117 myMesh->SetMeshElementOnShape(*anElemsIter, Id);
1125 * \brief Ensure aFamily to have required ID
1126 * \param aFamily - a family to check and update
1127 * \param anID - an ID aFamily should have
1128 * \retval bool - true if successful
1130 bool DriverMED_R_SMESHDS_Mesh::checkFamilyID(DriverMED_FamilyPtr & aFamily, int anID) const
1132 if ( !aFamily || aFamily->GetId() != anID ) {
1133 map<int, DriverMED_FamilyPtr>::const_iterator i_fam = myFamilies.find(anID);
1134 if ( i_fam == myFamilies.end() )
1136 aFamily = i_fam->second;
1138 return ( aFamily->GetId() == anID );
1142 /*! \brief Reading the structured mesh and convert to non structured (by filling of smesh structure for non structured mesh)
1143 * \param theWrapper - PWrapper const pointer
1144 * \param theMeshInfo - PMeshInfo const pointer
1145 * \return TRUE, if successfully. Else FALSE
1147 bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
1148 const MED::PMeshInfo& theMeshInfo)
1152 MED::PGrilleInfo aGrilleInfo = theWrapper->GetPGrilleInfo(theMeshInfo);
1153 MED::TInt aNbNodes = aGrilleInfo->GetNbNodes();
1154 MED::TInt aNbCells = aGrilleInfo->GetNbCells();
1155 MED::TInt aMeshDim = theMeshInfo->GetDim();
1156 DriverMED_FamilyPtr aFamily;
1157 for(MED::TInt iNode=0;iNode < aNbNodes; iNode++){
1158 double aCoords[3] = {0.0, 0.0, 0.0};
1159 const SMDS_MeshNode* aNode;
1160 MED::TNodeCoord aMEDNodeCoord = aGrilleInfo->GetCoord(iNode);
1161 for(MED::TInt iDim=0;iDim<aMeshDim;iDim++)
1162 aCoords[(int)iDim] = aMEDNodeCoord[(int)iDim];
1163 aNode = myMesh->AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],iNode+1);
1165 EXCEPTION(runtime_error,"buildMeshGrille Error. Node not created! "<<(int)iNode);
1168 if((aGrilleInfo->myFamNumNode).size() > 0){
1169 TInt aFamNum = aGrilleInfo->GetFamNumNode(iNode);
1170 if ( checkFamilyID ( aFamily, aFamNum ))
1172 aFamily->AddElement(aNode);
1173 aFamily->SetType(SMDSAbs_Node);
1179 SMDS_MeshElement* anElement = NULL;
1180 MED::TIntVector aNodeIds;
1181 for(MED::TInt iCell=0;iCell < aNbCells; iCell++){
1182 aNodeIds = aGrilleInfo->GetConn(iCell);
1183 switch(aGrilleInfo->GetGeom()){
1185 if(aNodeIds.size() != 2){
1187 EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 2!="<<aNodeIds.size());
1189 anElement = myMesh->AddEdgeWithID(aNodeIds[0]+1,
1194 if(aNodeIds.size() != 4){
1196 EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 4!="<<aNodeIds.size());
1198 anElement = myMesh->AddFaceWithID(aNodeIds[0]+1,
1205 if(aNodeIds.size() != 8){
1207 EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 8!="<<aNodeIds.size());
1209 anElement = myMesh->AddVolumeWithID(aNodeIds[0]+1,
1223 EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<<iCell);
1225 if((aGrilleInfo->myFamNum).size() > 0){
1226 TInt aFamNum = aGrilleInfo->GetFamNum(iCell);
1227 if ( checkFamilyID ( aFamily, aFamNum )){
1228 aFamily->AddElement(anElement);
1229 aFamily->SetType(anElement->GetType());