1 // SMESH DriverMED : driver to read and write 'med' files
3 // Copyright (C) 2003 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : DriverMED_R_SMESHDS_Mesh.cxx
27 #include "DriverMED_R_SMESHDS_Mesh.h"
28 #include "DriverMED_R_SMDS_Mesh.h"
29 #include "utilities.h"
31 #include "DriverMED_Family.h"
33 #include "SMESHDS_Group.hxx"
35 #include "MEDA_Wrapper.hxx"
36 #include "MED_Utilities.hxx"
40 DriverMED_R_SMESHDS_Mesh::DriverMED_R_SMESHDS_Mesh()
49 DriverMED_R_SMESHDS_Mesh::~DriverMED_R_SMESHDS_Mesh()
51 // map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
52 // for (; aFamsIter != myFamilies.end(); aFamsIter++)
54 // delete (*aFamsIter).second;
58 void DriverMED_R_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
63 void DriverMED_R_SMESHDS_Mesh::SetFile(string aFile)
68 void DriverMED_R_SMESHDS_Mesh::SetFileId(med_idt aFileId)
73 void DriverMED_R_SMESHDS_Mesh::SetMeshId(int aMeshId)
78 void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
80 myMeshName = theMeshName;
83 void DriverMED_R_SMESHDS_Mesh::Read()
86 string myClass = string("SMDS_Mesh");
87 string myExtension = string("MED");
89 DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
91 myReader->SetMesh(myMesh);
92 myReader->SetMeshId(myMeshId);
93 myReader->SetFile(myFile);
94 myReader->SetFileId(-1);
99 void DriverMED_R_SMESHDS_Mesh::Add()
101 string myClass = string("SMDS_Mesh");
102 string myExtension = string("MED");
104 DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
106 myReader->SetMesh(myMesh);
107 myReader->SetMeshId(myMeshId);
110 myReader->SetFileId(myFileId);
116 static const SMDS_MeshNode*
117 FindNode(const SMDS_Mesh* theMesh, med_int theId){
118 const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
119 if(aNode) return aNode;
120 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
124 DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
126 ReadStatus result = DRS_FAIL;
128 using namespace MEDA;
131 MESSAGE("ReadMySelf - myFile : "<<myFile);
132 TWrapper aMed(myFile);
135 if(med_int aNbMeshes = aMed.GetNbMeshes()){
136 for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
137 // Reading the MED mesh
138 //---------------------
139 PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
141 if (myMeshId != -1) {
142 ostringstream aMeshNameStr;
143 aMeshNameStr<<myMeshId;
144 aMeshName = aMeshNameStr.str();
146 aMeshName = myMeshName;
148 MESSAGE("ReadMySelf - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
149 if(aMeshName != aMeshInfo->GetName()) continue;
151 med_int aMeshDim = aMeshInfo->GetDim();
153 // Reading MED families to the temporary structure
154 //------------------------------------------------
155 med_int aNbFams = aMed.GetNbFamilies(aMeshInfo);
156 MESSAGE("Read " << aNbFams << " families");
157 for (med_int iFam = 0; iFam < aNbFams; iFam++) {
158 PFamilyInfo aFamilyInfo = aMed.GetFamilyInfo(aMeshInfo, iFam);
159 med_int aFamId = aFamilyInfo->GetId();
160 MESSAGE("Family " << aFamId << " :");
162 //if (aFamId >= FIRST_VALID_FAMILY) {
163 DriverMED_FamilyPtr aFamily (new DriverMED_Family);
165 med_int aNbGrp = aFamilyInfo->GetNbGroup();
166 MESSAGE("belong to " << aNbGrp << " groups");
167 for (med_int iGr = 0; iGr < aNbGrp; iGr++) {
168 string aGroupName = aFamilyInfo->GetGroupName(iGr);
170 aFamily->AddGroupName(aGroupName);
172 // aFamily->SetId(aFamId);
173 myFamilies[aFamId] = aFamily;
177 // Reading MED nodes to the corresponding SMDS structure
178 //------------------------------------------------------
179 PNodeInfo aNodeInfo = aMed.GetNodeInfo(aMeshInfo);
180 med_booleen anIsNodeNum = aNodeInfo->IsElemNum();
181 med_int aNbElems = aNodeInfo->GetNbElem();
182 MESSAGE("ReadMySelf - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
183 for(med_int iElem = 0; iElem < aNbElems; iElem++){
184 double aCoords[3] = {0.0, 0.0, 0.0};
185 for(med_int iDim = 0; iDim < aMeshDim; iDim++)
186 aCoords[iDim] = aNodeInfo->GetNodeCoord(iElem,iDim);
187 const SMDS_MeshNode* aNode;
189 aNode = myMesh->AddNodeWithID
190 (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
192 aNode = myMesh->AddNode
193 (aCoords[0],aCoords[1],aCoords[2]);
195 //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
197 // Save reference to this node from its family
198 med_int aFamNum = aNodeInfo->GetFamNum(iElem);
199 if (myFamilies.find(aFamNum) != myFamilies.end())
201 myFamilies[aFamNum]->AddElement(aNode);
202 myFamilies[aFamNum]->SetType(SMDSAbs_Node);
206 // Reading pre information about all MED cells
207 //--------------------------------------------
208 bool takeNumbers = true; // initially we trust the numbers from file
209 MED::TEntityInfo aEntityInfo = aMed.GetEntityInfo(aMeshInfo);
210 MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
211 for(; anEntityIter != aEntityInfo.end(); anEntityIter++){
212 const med_entite_maillage& anEntity = anEntityIter->first;
213 if(anEntity == MED_NOEUD) continue;
214 // Reading MED cells to the corresponding SMDS structure
215 //------------------------------------------------------
216 const MED::TGeom& aTGeom = anEntityIter->second;
217 MED::TGeom::const_iterator anTGeomIter = aTGeom.begin();
218 for(; anTGeomIter != aTGeom.end(); anTGeomIter++){
219 const med_geometrie_element& aGeom = anTGeomIter->first;
220 if(aGeom == MED_POINT1) continue;
221 PCellInfo aCellInfo = aMed.GetCellInfo(aMeshInfo,anEntity,aGeom);
222 med_booleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : MED_FAUX;
223 med_int aNbElems = aCellInfo->GetNbElem();
224 MESSAGE("ReadMySelf - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
225 MESSAGE("ReadMySelf - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
227 for(int iElem = 0; iElem < aNbElems; iElem++){
228 med_int aNbNodes = -1;
260 vector<med_int> aNodeIds(aNbNodes);
262 for(int i = 0; i < aNbNodes; i++){
263 aNodeIds.at(i) = aNodeInfo->GetElemNum(aCellInfo->GetConn(iElem,i)-1);
266 for(int i = 0; i < aNbNodes; i++){
267 aNodeIds.at(i) = aCellInfo->GetConn(iElem,i);
271 // cout<<aCellInfo->GetElemNum(iElem)<<": ";
273 // cout<<iElem<<": ";
274 //for(int i = 0; i < aNbNodes; i++){
275 // cout<<aNodeIds.at(i)<<", ";
278 bool isRenum = false;
279 SMDS_MeshElement* anElement = NULL;
280 med_int aFamNum = aCellInfo->GetFamNum(iElem);
286 anElement = myMesh->AddEdgeWithID(aNodeIds.at(0),
288 aCellInfo->GetElemNum(iElem));
290 anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds.at(0)),
291 FindNode(myMesh,aNodeIds.at(1)));
292 isRenum = anIsElemNum;
299 anElement = myMesh->AddFaceWithID(aNodeIds.at(0),
302 aCellInfo->GetElemNum(iElem));
304 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)),
305 FindNode(myMesh,aNodeIds.at(1)),
306 FindNode(myMesh,aNodeIds.at(2)));
307 isRenum = anIsElemNum;
313 // There is some differnce between SMDS and MED
315 anElement = myMesh->AddFaceWithID(aNodeIds.at(0),
319 aCellInfo->GetElemNum(iElem));
321 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)),
322 FindNode(myMesh,aNodeIds.at(1)),
323 FindNode(myMesh,aNodeIds.at(2)),
324 FindNode(myMesh,aNodeIds.at(3)));
325 isRenum = anIsElemNum;
332 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
336 aCellInfo->GetElemNum(iElem));
338 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
339 FindNode(myMesh,aNodeIds.at(1)),
340 FindNode(myMesh,aNodeIds.at(2)),
341 FindNode(myMesh,aNodeIds.at(3)));
342 isRenum = anIsElemNum;
348 // There is some differnce between SMDS and MED
350 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
355 aCellInfo->GetElemNum(iElem));
357 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
358 FindNode(myMesh,aNodeIds.at(1)),
359 FindNode(myMesh,aNodeIds.at(2)),
360 FindNode(myMesh,aNodeIds.at(3)),
361 FindNode(myMesh,aNodeIds.at(4)));
362 isRenum = anIsElemNum;
369 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
375 aCellInfo->GetElemNum(iElem));
377 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
378 FindNode(myMesh,aNodeIds.at(1)),
379 FindNode(myMesh,aNodeIds.at(2)),
380 FindNode(myMesh,aNodeIds.at(3)),
381 FindNode(myMesh,aNodeIds.at(4)),
382 FindNode(myMesh,aNodeIds.at(5)));
383 isRenum = anIsElemNum;
390 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
398 aCellInfo->GetElemNum(iElem));
400 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
401 FindNode(myMesh,aNodeIds.at(1)),
402 FindNode(myMesh,aNodeIds.at(2)),
403 FindNode(myMesh,aNodeIds.at(3)),
404 FindNode(myMesh,aNodeIds.at(4)),
405 FindNode(myMesh,aNodeIds.at(5)),
406 FindNode(myMesh,aNodeIds.at(6)),
407 FindNode(myMesh,aNodeIds.at(7)));
408 isRenum = anIsElemNum;
412 }catch(const std::exception& exc){
413 //INFOS("Follow exception was cought:\n\t"<<exc.what());
416 //INFOS("Unknown exception was cought !!!");
421 result = DRS_WARN_SKIP_ELEM;
425 anIsElemNum = MED_FAUX;
427 if (result < DRS_WARN_RENUMBER)
428 result = DRS_WARN_RENUMBER;
430 if (myFamilies.find(aFamNum) != myFamilies.end()) {
431 // Save reference to this element from its family
432 myFamilies[aFamNum]->AddElement(anElement);
433 myFamilies[aFamNum]->SetType(anElement->GetType());
442 }catch(const std::exception& exc){
443 INFOS("Follow exception was cought:\n\t"<<exc.what());
446 INFOS("Unknown exception was cought !!!");
449 MESSAGE("ReadMySelf - result status = "<<result);
453 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames()
455 list<string> aMeshNames;
458 using namespace MEDA;
460 MESSAGE("GetMeshNames - myFile : " << myFile);
461 TWrapper aMed (myFile);
463 if (med_int aNbMeshes = aMed.GetNbMeshes()) {
464 for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
465 // Reading the MED mesh
466 //---------------------
467 PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
468 aMeshNames.push_back(aMeshInfo->GetName());
471 }catch(const std::exception& exc){
472 INFOS("Follow exception was cought:\n\t"<<exc.what());
474 INFOS("Unknown exception was cought !!!");
480 list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
482 list<string> aResult;
483 set<string> aResGroupNames;
485 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
486 for (; aFamsIter != myFamilies.end(); aFamsIter++)
488 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
489 const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
490 set<string>::iterator aGrNamesIter = aGroupNames.begin();
491 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
493 string aName = *aGrNamesIter;
494 // Check, if this is a Group or SubMesh name
495 //if (aName.substr(0, 5) == string("Group")) {
496 if (aResGroupNames.find(aName) == aResGroupNames.end()) {
497 aResGroupNames.insert(aName);
498 aResult.push_back(aName);
507 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
509 string aGroupName (theGroup->GetStoreName());
510 MESSAGE("Get Group " << aGroupName);
512 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
513 for (; aFamsIter != myFamilies.end(); aFamsIter++)
515 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
516 if (aFamily->MemberOf(aGroupName))
518 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
519 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
520 for (; anElemsIter != anElements.end(); anElemsIter++)
522 theGroup->SMDS_MeshGroup::Add(*anElemsIter);
528 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
531 char submeshGrpName[ 30 ];
532 sprintf( submeshGrpName, "SubMesh %d", theId );
533 string aName (submeshGrpName);
534 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
535 for (; aFamsIter != myFamilies.end(); aFamsIter++)
537 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
538 if (aFamily->MemberOf(aName))
540 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
541 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
542 if (aFamily->GetType() == SMDSAbs_Node)
544 for (; anElemsIter != anElements.end(); anElemsIter++)
546 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
547 theSubMesh->AddNode(node);
552 for (; anElemsIter != anElements.end(); anElemsIter++)
554 theSubMesh->AddElement(*anElemsIter);
561 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
563 SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast<SMESHDS_Mesh*>(myMesh);
565 EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh");
567 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
568 for (; aFamsIter != myFamilies.end(); aFamsIter++)
570 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
571 MED::TStringSet aGroupNames = aFamily->GetGroupNames();
572 set<string>::iterator aGrNamesIter = aGroupNames.begin();
573 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
575 string aName = *aGrNamesIter;
576 // Check, if this is a Group or SubMesh name
577 if (aName.substr(0, 7) == string("SubMesh"))
579 int Id = atoi(string(aName).substr(7).c_str());
580 set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
581 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
582 if (aFamily->GetType() == SMDSAbs_Node)
584 for (; anElemsIter != anElements.end(); anElemsIter++)
586 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
587 aSMESHDSMesh->SetNodeInVolume(node, Id);
588 // aSMESHDSMesh->SetNodeOnFace(node, Id);
589 // aSMESHDSMesh->SetNodeOnEdge(node, Id);
590 // aSMESHDSMesh->SetNodeOnVertex(node, Id);
595 for (; anElemsIter != anElements.end(); anElemsIter++)
597 aSMESHDSMesh->SetMeshElementOnShape(*anElemsIter, Id);