1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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"
29 #include "DriverMED_Family.h"
30 #include "SMESHDS_Group.hxx"
31 #include "SMESHDS_Mesh.hxx"
32 #include "SMESH_Comment.hxx"
34 #include "MED_CoordUtils.hxx"
35 #include "MED_Factory.hxx"
36 #include "MED_Utilities.hxx"
38 #include <NCollection_Map.hxx>
40 #include "utilities.h"
45 static int MYDEBUG = 1;
48 static int MYDEBUG = 0;
51 #define _EDF_NODE_IDS_
56 typedef std::map<int, DriverMED_FamilyPtr> TID2FamilyMap;
60 bool buildMeshGrille(const MED::PWrapper& theWrapper,
61 const MED::PMeshInfo& theMeshInfo,
62 SMESHDS_Mesh* theMesh,
63 const TID2FamilyMap& myFamilies);
65 * \brief Ensure aFamily has a required ID
66 * \param aFamily - a family to check
67 * \param anID - an ID aFamily should have
68 * \param myFamilies - a map of the family ID to the Family
69 * \retval bool - true if successful
71 bool checkFamilyID(DriverMED_FamilyPtr & aFamily,
73 const TID2FamilyMap& myFamilies);
76 const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, TInt theId)
78 const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
79 if(aNode) return aNode;
80 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
85 //================================================================================
87 * \brief Stores a mesh name
89 //================================================================================
91 void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
93 myMeshName = theMeshName;
96 //================================================================================
98 * \brief Reads a med file
100 //================================================================================
102 Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
104 using namespace DriverMED;
106 Status aResult = DRS_FAIL;
107 bool isDescConn = false; // Mantis issue 0020483
112 if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
113 PWrapper aMed = CrWrapper(myFile,true);
116 TInt aNbMeshes = aMed->GetNbMeshes();
117 for (int iMesh = 0; iMesh < aNbMeshes; iMesh++)
119 // Reading the MED mesh
120 //---------------------
121 PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
124 if (myMeshId != -1) aMeshName = SMESH_Comment( myMeshId );
125 else aMeshName = myMeshName;
127 if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
128 if ( aMeshName != aMeshInfo->GetName() ) continue;
131 // Reading MED families to the temporary structure
132 //------------------------------------------------
134 TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
135 if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
136 for (TInt iFam = 0; iFam < aNbFams; iFam++)
138 PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
140 TInt aFamId = aFamilyInfo->GetId();
141 if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
143 DriverMED_FamilyPtr aFamily (new DriverMED_Family);
145 TInt aNbGrp = aFamilyInfo->GetNbGroup();
146 if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
147 bool isAttrOk = false;
148 if(aFamilyInfo->GetNbAttr() == aNbGrp)
150 for (TInt iGr = 0; iGr < aNbGrp; iGr++)
152 string aGroupName = aFamilyInfo->GetGroupName(iGr);
154 TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
155 aFamily->SetGroupAttributVal(anAttrVal);
157 if(MYDEBUG) MESSAGE(aGroupName);
158 aFamily->AddGroupName(aGroupName);
160 aFamily->SetId( aFamId );
161 myFamilies[aFamId] = aFamily;
165 if (aMeshInfo->GetType() == MED::eSTRUCTURE)
167 /*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies);
171 // Reading MED nodes to the corresponding SMDS structure
172 //------------------------------------------------------
173 PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
178 aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
179 PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
181 EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
182 TInt aNbElems = aNodeInfo->GetNbElem();
183 if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
184 DriverMED_FamilyPtr aFamily;
185 for ( TInt iElem = 0; iElem < aNbElems; iElem++ )
187 TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
188 double aCoords[3] = {0.0, 0.0, 0.0};
189 for(TInt iDim = 0; iDim < 3; iDim++)
190 aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
191 const SMDS_MeshNode* aNode;
193 aNode = myMesh->AddNodeWithID
194 (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
197 aNode = myMesh->AddNodeWithID
198 (aCoords[0],aCoords[1],aCoords[2], iElem+1);
201 // Save reference to this node from its family
202 TInt aFamNum = aNodeInfo->GetFamNum(iElem);
203 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
205 aFamily->AddElement(aNode);
206 aFamily->SetType(SMDSAbs_Node);
210 // Are there any MED cells in descending connectivity
211 // Mantis issue 0020483
212 //---------------------------------------------------
213 NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
215 MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
216 MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
217 //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
218 for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
219 const EEntiteMaillage& anEntity = anEntityIterDesc->first;
220 aDescendingEntitiesMap.Add(anEntity);
221 //if (anEntity != eNOEUD) isDescConn = true;
225 // Reading pre information about all MED cells
226 //--------------------------------------------
227 typedef MED::TVector<int> TNodeIds;
228 bool takeNumbers = true; // initially we trust the numbers from file
229 MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo, eNOD);
230 MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
232 for (; anEntityIter != aEntityInfo.end(); anEntityIter++)
234 const EEntiteMaillage& anEntity = anEntityIter->first;
235 aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
236 if (anEntity == eNOEUD) continue;
238 // Reading MED cells to the corresponding SMDS structure
239 //------------------------------------------------------
240 const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
241 MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
242 for ( ; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++)
244 const EGeometrieElement& aGeom = aGeom2SizeIter->first;
246 if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
248 PBallInfo aBallInfo = aMed->GetPBallInfo(aMeshInfo);
249 TInt aNbBalls = aBallInfo->GetNbElem();
251 EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
252 if ( anIsElemNum && aBallInfo->myElemNum->empty() )
255 // get supporting nodes
257 #ifdef _EDF_NODE_IDS_
259 aNodeIds.resize( aNbBalls );
260 for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
262 aNodeIds[iBall] = aNodeInfo->GetElemNum( (*aBallInfo->myConn)[ iBall ]-1 );
263 anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
268 aNodeIds.swap( *(aBallInfo->myConn ));
270 // allocate array of diameters
271 vtkIdType maxID = myMesh->MaxElementID() + aNbBalls;
272 if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
273 maxID = *std::max_element( aBallInfo->myElemNum->begin(),
274 aBallInfo->myElemNum->end() );
275 myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
278 SMDS_MeshElement* anElement;
279 DriverMED_FamilyPtr aFamily;
280 for ( TInt iBall = 0; iBall < aNbBalls; iBall++)
284 if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
285 aBallInfo->myDiameters[iBall],
286 aBallInfo->GetElemNum(iBall))))
290 myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
291 aBallInfo->myDiameters[iBall] );
293 // Save reference to this element from its family
294 TInt aFamNum = aBallInfo->GetFamNum(iBall);
295 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
297 aFamily->AddElement(anElement);
298 aFamily->SetType( SMDSAbs_Ball );
303 ( takeNumbers && aBallInfo->IsElemNum() && !aBallInfo->myElemNum->empty() ))
304 if ( aResult < DRS_WARN_RENUMBER )
305 aResult = DRS_WARN_RENUMBER;
311 // case ePOINT1: ## PAL16410
316 PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
317 EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
319 typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolyWithID)
320 (const std::vector<int> & nodes_ids, const int ID);
321 typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolygon)
322 (const std::vector<const SMDS_MeshNode*> & nodes);
324 FAddPolyWithID addPolyWithID = & SMESHDS_Mesh::AddPolygonalFaceWithID;
325 FAddPolygon addPolygon = & SMESHDS_Mesh::AddPolygonalFace;
326 if ( aGeom == ePOLYGON2 ) {
327 addPolyWithID = & SMESHDS_Mesh::AddQuadPolygonalFaceWithID;
328 addPolygon = & SMESHDS_Mesh::AddQuadPolygonalFace;
331 vector<const SMDS_MeshNode*> aNodes;
332 const TInt aNbElem = aPolygoneInfo->GetNbElem();
333 for ( TInt iElem = 0; iElem < aNbElem; iElem++ )
335 MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
336 TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
337 aNodeIds.resize( aNbConn );
338 #ifdef _EDF_NODE_IDS_
340 for(TInt iConn = 0; iConn < aNbConn; iConn++)
341 aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
343 for(TInt iConn = 0; iConn < aNbConn; iConn++)
344 aNodeIds[iConn] = aConnSlice[iConn];
346 for(TInt iConn = 0; iConn < aNbConn; iConn++)
347 aNodeIds[iConn] = aConnSlice[iConn];
349 bool isRenum = false;
350 SMDS_MeshElement* anElement = NULL;
351 TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
356 TInt anElemId = aPolygoneInfo->GetElemNum( iElem );
357 anElement = (myMesh->*addPolyWithID)( aNodeIds, anElemId );
360 aNodes.resize( aNbConn );
361 for ( TInt iConn = 0; iConn < aNbConn; iConn++ )
362 aNodes[iConn] = FindNode( myMesh, aNodeIds[iConn] );
363 anElement = (myMesh->*addPolygon)( aNodes );
364 isRenum = anIsElemNum;
367 } catch(const std::exception& exc) {
374 aResult = DRS_WARN_SKIP_ELEM;
380 if(aResult < DRS_WARN_RENUMBER)
381 aResult = DRS_WARN_RENUMBER;
383 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
385 // Save reference to this element from its family
386 aFamily->AddElement(anElement);
387 aFamily->SetType(anElement->GetType());
394 PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
395 EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
397 TInt aNbElem = aPolyedreInfo->GetNbElem();
398 for(TInt iElem = 0; iElem < aNbElem; iElem++){
399 MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
400 TInt aNbFaces = aConnSliceArr.size();
401 typedef MED::TVector<int> TQuantities;
402 TQuantities aQuantities(aNbFaces);
403 TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
404 TNodeIds aNodeIds(aNbNodes);
405 for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
406 MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
407 TInt aNbConn = aConnSlice.size();
408 aQuantities[iFace] = aNbConn;
409 #ifdef _EDF_NODE_IDS_
411 for(TInt iConn = 0; iConn < aNbConn; iConn++)
413 aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
417 for(TInt iConn = 0; iConn < aNbConn; iConn++)
419 aNodeIds[iNode++] = aConnSlice[iConn];
422 for(TInt iConn = 0; iConn < aNbConn; iConn++)
424 aNodeIds[iNode++] = aConnSlice[iConn];
429 bool isRenum = false;
430 SMDS_MeshElement* anElement = NULL;
431 TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
437 TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
438 anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
441 vector<const SMDS_MeshNode*> aNodes(aNbNodes);
442 for(TInt iConn = 0; iConn < aNbNodes; iConn++)
443 aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
444 anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
445 isRenum = anIsElemNum;
448 }catch(const std::exception& exc){
455 aResult = DRS_WARN_SKIP_ELEM;
460 if (aResult < DRS_WARN_RENUMBER)
461 aResult = DRS_WARN_RENUMBER;
463 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
464 // Save reference to this element from its family
465 aFamily->AddElement(anElement);
466 aFamily->SetType(anElement->GetType());
473 PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
474 EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
475 TInt aNbElems = aCellInfo->GetNbElem();
476 if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
477 if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
481 case eSEG2: aNbNodes = 2; break;
482 case eSEG3: aNbNodes = 3; break;
483 case eTRIA3: aNbNodes = 3; break;
484 case eTRIA6: aNbNodes = 6; break;
485 case eTRIA7: aNbNodes = 7; break;
486 case eQUAD4: aNbNodes = 4; break;
487 case eQUAD8: aNbNodes = 8; break;
488 case eQUAD9: aNbNodes = 9; break;
489 case eTETRA4: aNbNodes = 4; break;
490 case eTETRA10: aNbNodes = 10; break;
491 case ePYRA5: aNbNodes = 5; break;
492 case ePYRA13: aNbNodes = 13; break;
493 case ePENTA6: aNbNodes = 6; break;
494 case ePENTA15: aNbNodes = 15; break;
495 case eHEXA8: aNbNodes = 8; break;
496 case eHEXA20: aNbNodes = 20; break;
497 case eHEXA27: aNbNodes = 27; break;
498 case eOCTA12: aNbNodes = 12; break;
499 case ePOINT1: aNbNodes = 1; break;
502 vector<TInt> aNodeIds(aNbNodes);
503 for ( int iElem = 0; iElem < aNbElems; iElem++ )
505 bool anIsValidConnect = false;
506 TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
510 #ifdef _EDF_NODE_IDS_
512 for(int iNode = 0; iNode < aNbNodes; iNode++)
513 aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
515 for(int iNode = 0; iNode < aNbNodes; iNode++)
516 aNodeIds[iNode] = aConnSlice[iNode];
518 for(int iNode = 0; iNode < aNbNodes; iNode++)
519 aNodeIds[iNode] = aConnSlice[iNode];
521 anIsValidConnect = true;
523 }catch(const std::exception& exc){
524 INFOS("Following exception was caught:\n\t"<<exc.what());
527 INFOS("Unknown exception was caught !!!");
531 if(!anIsValidConnect)
534 bool isRenum = false;
535 const SMDS_MeshElement* anElement = NULL;
536 TInt aFamNum = aCellInfo->GetFamNum(iElem);
540 //MESSAGE("Try to create element # " << iElem << " with id = "
541 // << aCellInfo->GetElemNum(iElem));
544 //anElement = FindNode(myMesh,aNodeIds[0]);
546 anElement = myMesh->Add0DElementWithID
547 (aNodeIds[0], aCellInfo->GetElemNum(iElem));
549 anElement = myMesh->Add0DElement(FindNode(myMesh,aNodeIds[0]));
550 isRenum = anIsElemNum;
555 anElement = myMesh->AddEdgeWithID(aNodeIds[0],
557 aCellInfo->GetElemNum(iElem));
559 anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
560 FindNode(myMesh,aNodeIds[1]));
561 isRenum = anIsElemNum;
566 anElement = myMesh->AddEdgeWithID(aNodeIds[0],
569 aCellInfo->GetElemNum(iElem));
571 anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
572 FindNode(myMesh,aNodeIds[1]),
573 FindNode(myMesh,aNodeIds[2]));
574 isRenum = anIsElemNum;
580 anElement = myMesh->AddFaceWithID(aNodeIds[0],
583 aCellInfo->GetElemNum(iElem));
585 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
586 FindNode(myMesh,aNodeIds[1]),
587 FindNode(myMesh,aNodeIds[2]));
588 isRenum = anIsElemNum;
594 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
595 aNodeIds[2], aNodeIds[3],
596 aNodeIds[4], aNodeIds[5],
597 aCellInfo->GetElemNum(iElem));
599 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
600 FindNode(myMesh,aNodeIds[1]),
601 FindNode(myMesh,aNodeIds[2]),
602 FindNode(myMesh,aNodeIds[3]),
603 FindNode(myMesh,aNodeIds[4]),
604 FindNode(myMesh,aNodeIds[5]));
605 isRenum = anIsElemNum;
611 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
612 aNodeIds[2], aNodeIds[3],
613 aNodeIds[4], aNodeIds[5], aNodeIds[6],
614 aCellInfo->GetElemNum(iElem));
616 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
617 FindNode(myMesh,aNodeIds[1]),
618 FindNode(myMesh,aNodeIds[2]),
619 FindNode(myMesh,aNodeIds[3]),
620 FindNode(myMesh,aNodeIds[4]),
621 FindNode(myMesh,aNodeIds[5]),
622 FindNode(myMesh,aNodeIds[6]));
623 isRenum = anIsElemNum;
629 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
630 aNodeIds[2], aNodeIds[3],
631 aCellInfo->GetElemNum(iElem));
633 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
634 FindNode(myMesh,aNodeIds[1]),
635 FindNode(myMesh,aNodeIds[2]),
636 FindNode(myMesh,aNodeIds[3]));
637 isRenum = anIsElemNum;
643 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
644 aNodeIds[2], aNodeIds[3],
645 aNodeIds[4], aNodeIds[5],
646 aNodeIds[6], aNodeIds[7],
647 aCellInfo->GetElemNum(iElem));
649 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
650 FindNode(myMesh,aNodeIds[1]),
651 FindNode(myMesh,aNodeIds[2]),
652 FindNode(myMesh,aNodeIds[3]),
653 FindNode(myMesh,aNodeIds[4]),
654 FindNode(myMesh,aNodeIds[5]),
655 FindNode(myMesh,aNodeIds[6]),
656 FindNode(myMesh,aNodeIds[7]));
657 isRenum = anIsElemNum;
663 anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
664 aNodeIds[2], aNodeIds[3],
665 aNodeIds[4], aNodeIds[5],
666 aNodeIds[6], aNodeIds[7], aNodeIds[8],
667 aCellInfo->GetElemNum(iElem));
669 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
670 FindNode(myMesh,aNodeIds[1]),
671 FindNode(myMesh,aNodeIds[2]),
672 FindNode(myMesh,aNodeIds[3]),
673 FindNode(myMesh,aNodeIds[4]),
674 FindNode(myMesh,aNodeIds[5]),
675 FindNode(myMesh,aNodeIds[6]),
676 FindNode(myMesh,aNodeIds[7]),
677 FindNode(myMesh,aNodeIds[8]));
678 isRenum = anIsElemNum;
684 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
685 aNodeIds[2], aNodeIds[3],
686 aCellInfo->GetElemNum(iElem));
688 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
689 FindNode(myMesh,aNodeIds[1]),
690 FindNode(myMesh,aNodeIds[2]),
691 FindNode(myMesh,aNodeIds[3]));
692 isRenum = anIsElemNum;
698 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
699 aNodeIds[2], aNodeIds[3],
700 aNodeIds[4], aNodeIds[5],
701 aNodeIds[6], aNodeIds[7],
702 aNodeIds[8], aNodeIds[9],
703 aCellInfo->GetElemNum(iElem));
705 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
706 FindNode(myMesh,aNodeIds[1]),
707 FindNode(myMesh,aNodeIds[2]),
708 FindNode(myMesh,aNodeIds[3]),
709 FindNode(myMesh,aNodeIds[4]),
710 FindNode(myMesh,aNodeIds[5]),
711 FindNode(myMesh,aNodeIds[6]),
712 FindNode(myMesh,aNodeIds[7]),
713 FindNode(myMesh,aNodeIds[8]),
714 FindNode(myMesh,aNodeIds[9]));
715 isRenum = anIsElemNum;
721 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
722 aNodeIds[2], aNodeIds[3],
724 aCellInfo->GetElemNum(iElem));
726 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
727 FindNode(myMesh,aNodeIds[1]),
728 FindNode(myMesh,aNodeIds[2]),
729 FindNode(myMesh,aNodeIds[3]),
730 FindNode(myMesh,aNodeIds[4]));
731 isRenum = anIsElemNum;
737 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
738 aNodeIds[2], aNodeIds[3],
739 aNodeIds[4], aNodeIds[5],
740 aNodeIds[6], aNodeIds[7],
741 aNodeIds[8], aNodeIds[9],
742 aNodeIds[10], aNodeIds[11],
744 aCellInfo->GetElemNum(iElem));
746 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
747 FindNode(myMesh,aNodeIds[1]),
748 FindNode(myMesh,aNodeIds[2]),
749 FindNode(myMesh,aNodeIds[3]),
750 FindNode(myMesh,aNodeIds[4]),
751 FindNode(myMesh,aNodeIds[5]),
752 FindNode(myMesh,aNodeIds[6]),
753 FindNode(myMesh,aNodeIds[7]),
754 FindNode(myMesh,aNodeIds[8]),
755 FindNode(myMesh,aNodeIds[9]),
756 FindNode(myMesh,aNodeIds[10]),
757 FindNode(myMesh,aNodeIds[11]),
758 FindNode(myMesh,aNodeIds[12]));
759 isRenum = anIsElemNum;
765 anElement = myMesh->AddVolumeWithID(aNodeIds[0],
771 aCellInfo->GetElemNum(iElem));
773 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
774 FindNode(myMesh,aNodeIds[1]),
775 FindNode(myMesh,aNodeIds[2]),
776 FindNode(myMesh,aNodeIds[3]),
777 FindNode(myMesh,aNodeIds[4]),
778 FindNode(myMesh,aNodeIds[5]));
779 isRenum = anIsElemNum;
785 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
786 aNodeIds[2], aNodeIds[3],
787 aNodeIds[4], aNodeIds[5],
788 aNodeIds[6], aNodeIds[7],
789 aNodeIds[8], aNodeIds[9],
790 aNodeIds[10], aNodeIds[11],
791 aNodeIds[12], aNodeIds[13],
793 aCellInfo->GetElemNum(iElem));
795 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
796 FindNode(myMesh,aNodeIds[1]),
797 FindNode(myMesh,aNodeIds[2]),
798 FindNode(myMesh,aNodeIds[3]),
799 FindNode(myMesh,aNodeIds[4]),
800 FindNode(myMesh,aNodeIds[5]),
801 FindNode(myMesh,aNodeIds[6]),
802 FindNode(myMesh,aNodeIds[7]),
803 FindNode(myMesh,aNodeIds[8]),
804 FindNode(myMesh,aNodeIds[9]),
805 FindNode(myMesh,aNodeIds[10]),
806 FindNode(myMesh,aNodeIds[11]),
807 FindNode(myMesh,aNodeIds[12]),
808 FindNode(myMesh,aNodeIds[13]),
809 FindNode(myMesh,aNodeIds[14]));
810 isRenum = anIsElemNum;
816 anElement = myMesh->AddVolumeWithID(aNodeIds[0],
824 aCellInfo->GetElemNum(iElem));
826 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
827 FindNode(myMesh,aNodeIds[1]),
828 FindNode(myMesh,aNodeIds[2]),
829 FindNode(myMesh,aNodeIds[3]),
830 FindNode(myMesh,aNodeIds[4]),
831 FindNode(myMesh,aNodeIds[5]),
832 FindNode(myMesh,aNodeIds[6]),
833 FindNode(myMesh,aNodeIds[7]));
834 isRenum = anIsElemNum;
841 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
842 aNodeIds[2], aNodeIds[3],
843 aNodeIds[4], aNodeIds[5],
844 aNodeIds[6], aNodeIds[7],
845 aNodeIds[8], aNodeIds[9],
846 aNodeIds[10], aNodeIds[11],
847 aNodeIds[12], aNodeIds[13],
848 aNodeIds[14], aNodeIds[15],
849 aNodeIds[16], aNodeIds[17],
850 aNodeIds[18], aNodeIds[19],
851 aCellInfo->GetElemNum(iElem));
853 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
854 FindNode(myMesh,aNodeIds[1]),
855 FindNode(myMesh,aNodeIds[2]),
856 FindNode(myMesh,aNodeIds[3]),
857 FindNode(myMesh,aNodeIds[4]),
858 FindNode(myMesh,aNodeIds[5]),
859 FindNode(myMesh,aNodeIds[6]),
860 FindNode(myMesh,aNodeIds[7]),
861 FindNode(myMesh,aNodeIds[8]),
862 FindNode(myMesh,aNodeIds[9]),
863 FindNode(myMesh,aNodeIds[10]),
864 FindNode(myMesh,aNodeIds[11]),
865 FindNode(myMesh,aNodeIds[12]),
866 FindNode(myMesh,aNodeIds[13]),
867 FindNode(myMesh,aNodeIds[14]),
868 FindNode(myMesh,aNodeIds[15]),
869 FindNode(myMesh,aNodeIds[16]),
870 FindNode(myMesh,aNodeIds[17]),
871 FindNode(myMesh,aNodeIds[18]),
872 FindNode(myMesh,aNodeIds[19]));
873 isRenum = anIsElemNum;
880 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
881 aNodeIds[2], aNodeIds[3],
882 aNodeIds[4], aNodeIds[5],
883 aNodeIds[6], aNodeIds[7],
884 aNodeIds[8], aNodeIds[9],
885 aNodeIds[10], aNodeIds[11],
886 aNodeIds[12], aNodeIds[13],
887 aNodeIds[14], aNodeIds[15],
888 aNodeIds[16], aNodeIds[17],
889 aNodeIds[18], aNodeIds[19],
890 aNodeIds[20], aNodeIds[21],
891 aNodeIds[22], aNodeIds[23],
892 aNodeIds[24], aNodeIds[25],
894 aCellInfo->GetElemNum(iElem));
896 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
897 FindNode(myMesh,aNodeIds[1]),
898 FindNode(myMesh,aNodeIds[2]),
899 FindNode(myMesh,aNodeIds[3]),
900 FindNode(myMesh,aNodeIds[4]),
901 FindNode(myMesh,aNodeIds[5]),
902 FindNode(myMesh,aNodeIds[6]),
903 FindNode(myMesh,aNodeIds[7]),
904 FindNode(myMesh,aNodeIds[8]),
905 FindNode(myMesh,aNodeIds[9]),
906 FindNode(myMesh,aNodeIds[10]),
907 FindNode(myMesh,aNodeIds[11]),
908 FindNode(myMesh,aNodeIds[12]),
909 FindNode(myMesh,aNodeIds[13]),
910 FindNode(myMesh,aNodeIds[14]),
911 FindNode(myMesh,aNodeIds[15]),
912 FindNode(myMesh,aNodeIds[16]),
913 FindNode(myMesh,aNodeIds[17]),
914 FindNode(myMesh,aNodeIds[18]),
915 FindNode(myMesh,aNodeIds[19]),
916 FindNode(myMesh,aNodeIds[20]),
917 FindNode(myMesh,aNodeIds[21]),
918 FindNode(myMesh,aNodeIds[22]),
919 FindNode(myMesh,aNodeIds[23]),
920 FindNode(myMesh,aNodeIds[24]),
921 FindNode(myMesh,aNodeIds[25]),
922 FindNode(myMesh,aNodeIds[26]));
923 isRenum = anIsElemNum;
930 anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
931 aNodeIds[2], aNodeIds[3],
932 aNodeIds[4], aNodeIds[5],
933 aNodeIds[6], aNodeIds[7],
934 aNodeIds[8], aNodeIds[9],
935 aNodeIds[10], aNodeIds[11],
936 aCellInfo->GetElemNum(iElem));
938 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
939 FindNode(myMesh,aNodeIds[1]),
940 FindNode(myMesh,aNodeIds[2]),
941 FindNode(myMesh,aNodeIds[3]),
942 FindNode(myMesh,aNodeIds[4]),
943 FindNode(myMesh,aNodeIds[5]),
944 FindNode(myMesh,aNodeIds[6]),
945 FindNode(myMesh,aNodeIds[7]),
946 FindNode(myMesh,aNodeIds[8]),
947 FindNode(myMesh,aNodeIds[9]),
948 FindNode(myMesh,aNodeIds[10]),
949 FindNode(myMesh,aNodeIds[11]));
950 isRenum = anIsElemNum;
959 } catch(const std::exception& exc) {
960 INFOS("The following exception was caught:\n\t"<<exc.what());
963 INFOS("Unknown exception was caught !!!");
968 aResult = DRS_WARN_SKIP_ELEM;
974 if (aResult < DRS_WARN_RENUMBER)
975 aResult = DRS_WARN_RENUMBER;
977 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
978 // Save reference to this element from its family
979 myFamilies[aFamNum]->AddElement(anElement);
980 myFamilies[aFamNum]->SetType(anElement->GetType());
983 } // loop on aNbElems
985 } // loop on aGeom2Size
986 } // loop on aEntityInfo
988 if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
990 } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
993 catch(const std::exception& exc)
995 INFOS("The following exception was caught:\n\t"<<exc.what());
1000 INFOS("Unknown exception was caught !!!");
1005 myMesh->compactMesh();
1007 // Mantis issue 0020483
1008 if (aResult == DRS_OK && isDescConn) {
1009 INFOS("There are some elements in descending connectivity in med file. They were not read !!!");
1010 aResult = DRS_WARN_DESCENDING;
1013 if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
1017 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
1019 list<string> aMeshNames;
1022 if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
1024 PWrapper aMed = CrWrapper(myFile);
1026 if (TInt aNbMeshes = aMed->GetNbMeshes()) {
1027 for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
1028 // Reading the MED mesh
1029 //---------------------
1030 PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
1031 aMeshNames.push_back(aMeshInfo->GetName());
1034 } catch(const std::exception& exc) {
1035 INFOS("Following exception was caught:\n\t"<<exc.what());
1036 theStatus = DRS_FAIL;
1038 INFOS("Unknown exception was caught !!!");
1039 theStatus = DRS_FAIL;
1045 list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
1047 list<TNameAndType> aResult;
1048 set<TNameAndType> aResGroupNames;
1050 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1051 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1053 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1054 const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
1055 set<string>::const_iterator aGrNamesIter = aGroupNames.begin();
1056 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
1058 const set< SMDSAbs_ElementType >& types = aFamily->GetTypes();
1059 set< SMDSAbs_ElementType >::const_iterator type = types.begin();
1060 for ( ; type != types.end(); ++type )
1062 TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type );
1063 if ( aResGroupNames.insert( aNameAndType ).second ) {
1064 aResult.push_back( aNameAndType );
1073 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
1075 string aGroupName (theGroup->GetStoreName());
1076 if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
1078 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1079 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1081 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1082 if (aFamily->GetTypes().count( theGroup->GetType() ) && aFamily->MemberOf(aGroupName))
1084 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
1085 set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
1086 for (; anElemsIter != anElements.end(); anElemsIter++)
1088 const SMDS_MeshElement * element = *anElemsIter;
1089 if ( element->GetType() == theGroup->GetType() ) // Issue 0020576
1090 theGroup->SMDSGroup().Add(element);
1092 int aGroupAttrVal = aFamily->GetGroupAttributVal();
1093 if( aGroupAttrVal != 0)
1094 theGroup->SetColorGroup(aGroupAttrVal);
1095 // if ( element ) -- Issue 0020576
1096 // theGroup->SetType( theGroup->SMDSGroup().GetType() );
1101 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
1104 char submeshGrpName[ 30 ];
1105 sprintf( submeshGrpName, "SubMesh %d", theId );
1106 string aName (submeshGrpName);
1107 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1108 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1110 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1111 if (aFamily->MemberOf(aName))
1113 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
1114 set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
1115 if (aFamily->GetType() == SMDSAbs_Node)
1117 for (; anElemsIter != anElements.end(); anElemsIter++)
1119 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
1120 theSubMesh->AddNode(node);
1125 for (; anElemsIter != anElements.end(); anElemsIter++)
1127 theSubMesh->AddElement(*anElemsIter);
1134 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
1136 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
1137 for (; aFamsIter != myFamilies.end(); aFamsIter++)
1139 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
1140 MED::TStringSet aGroupNames = aFamily->GetGroupNames();
1141 set<string>::iterator aGrNamesIter = aGroupNames.begin();
1142 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
1144 string aName = *aGrNamesIter;
1145 // Check, if this is a Group or SubMesh name
1146 if (aName.substr(0, 7) == string("SubMesh"))
1148 int Id = atoi(string(aName).substr(7).c_str());
1149 set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
1150 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
1151 if (aFamily->GetType() == SMDSAbs_Node)
1153 for (; anElemsIter != anElements.end(); anElemsIter++)
1155 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
1156 ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
1157 // find out a shape type
1158 TopoDS_Shape aShape = myMesh->IndexToShape( Id );
1159 int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
1160 switch ( aShapeType ) {
1162 myMesh->SetNodeOnFace(node, Id); break;
1164 myMesh->SetNodeOnEdge(node, Id); break;
1166 myMesh->SetNodeOnVertex(node, Id); break;
1168 myMesh->SetNodeInVolume(node, Id);
1174 for (; anElemsIter != anElements.end(); anElemsIter++)
1176 myMesh->SetMeshElementOnShape(*anElemsIter, Id);
1184 * \brief Ensure aFamily to have required ID
1185 * \param aFamily - a family to check and update
1186 * \param anID - an ID aFamily should have
1187 * \retval bool - true if successful
1189 bool DriverMED::checkFamilyID(DriverMED_FamilyPtr & aFamily,
1191 const TID2FamilyMap& myFamilies)
1193 if ( !aFamily || aFamily->GetId() != anID ) {
1194 map<int, DriverMED_FamilyPtr>::const_iterator i_fam = myFamilies.find(anID);
1195 if ( i_fam == myFamilies.end() )
1197 aFamily = i_fam->second;
1199 return ( aFamily->GetId() == anID );
1203 * \brief Reading the structured mesh and convert to non structured
1204 * (by filling of smesh structure for non structured mesh)
1205 * \param theWrapper - PWrapper const pointer
1206 * \param theMeshInfo - PMeshInfo const pointer
1207 * \param myFamilies - a map of the family ID to the Family
1208 * \return TRUE, if successfully. Else FALSE
1210 bool DriverMED::buildMeshGrille(const MED::PWrapper& theWrapper,
1211 const MED::PMeshInfo& theMeshInfo,
1212 SMESHDS_Mesh* myMesh,
1213 const TID2FamilyMap& myFamilies)
1217 MED::PGrilleInfo aGrilleInfo = theWrapper->GetPGrilleInfo(theMeshInfo);
1218 MED::TInt aNbNodes = aGrilleInfo->GetNbNodes();
1219 MED::TInt aNbCells = aGrilleInfo->GetNbCells();
1220 MED::TInt aMeshDim = theMeshInfo->GetDim();
1221 DriverMED_FamilyPtr aFamily;
1222 for(MED::TInt iNode=0;iNode < aNbNodes; iNode++){
1223 double aCoords[3] = {0.0, 0.0, 0.0};
1224 const SMDS_MeshNode* aNode;
1225 MED::TNodeCoord aMEDNodeCoord = aGrilleInfo->GetCoord(iNode);
1226 for(MED::TInt iDim=0;iDim<aMeshDim;iDim++)
1227 aCoords[(int)iDim] = aMEDNodeCoord[(int)iDim];
1228 aNode = myMesh->AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],iNode+1);
1230 EXCEPTION(runtime_error,"buildMeshGrille Error. Node not created! "<<(int)iNode);
1233 if((aGrilleInfo->myFamNumNode).size() > 0){
1234 TInt aFamNum = aGrilleInfo->GetFamNumNode(iNode);
1235 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
1237 aFamily->AddElement(aNode);
1238 aFamily->SetType(SMDSAbs_Node);
1244 SMDS_MeshElement* anElement = NULL;
1245 MED::TIntVector aNodeIds;
1246 for(MED::TInt iCell=0;iCell < aNbCells; iCell++){
1247 aNodeIds = aGrilleInfo->GetConn(iCell);
1248 switch(aGrilleInfo->GetGeom()){
1250 if(aNodeIds.size() != 2){
1252 EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 2!="<<aNodeIds.size());
1254 anElement = myMesh->AddEdgeWithID(aNodeIds[0]+1,
1259 if(aNodeIds.size() != 4){
1261 EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 4!="<<aNodeIds.size());
1263 anElement = myMesh->AddFaceWithID(aNodeIds[0]+1,
1270 if(aNodeIds.size() != 8){
1272 EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 8!="<<aNodeIds.size());
1274 anElement = myMesh->AddVolumeWithID(aNodeIds[0]+1,
1288 EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<<iCell);
1290 if((aGrilleInfo->myFamNum).size() > 0){
1291 TInt aFamNum = aGrilleInfo->GetFamNum(iCell);
1292 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )){
1293 aFamily->AddElement(anElement);
1294 aFamily->SetType(anElement->GetType());