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;
261 // cout<<aCellInfo->GetElemNum(iElem)<<": ";
263 // cout<<iElem<<": ";
264 vector<med_int> aNodeIds(aNbNodes);
265 for(int i = 0; i < aNbNodes; i++){
266 aNodeIds.at(i) = aCellInfo->GetConn(iElem,i);
267 //cout<<aNodeIds.at(i)<<", ";
271 bool isRenum = false;
272 SMDS_MeshElement* anElement = NULL;
273 med_int aFamNum = aCellInfo->GetFamNum(iElem);
279 anElement = myMesh->AddEdgeWithID(aNodeIds.at(0),
281 aCellInfo->GetElemNum(iElem));
283 anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds.at(0)),
284 FindNode(myMesh,aNodeIds.at(1)));
285 isRenum = anIsElemNum;
292 anElement = myMesh->AddFaceWithID(aNodeIds.at(0),
295 aCellInfo->GetElemNum(iElem));
297 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)),
298 FindNode(myMesh,aNodeIds.at(1)),
299 FindNode(myMesh,aNodeIds.at(2)));
300 isRenum = anIsElemNum;
306 // There is some differnce between SMDS and MED
308 anElement = myMesh->AddFaceWithID(aNodeIds.at(0),
312 aCellInfo->GetElemNum(iElem));
314 anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds.at(0)),
315 FindNode(myMesh,aNodeIds.at(1)),
316 FindNode(myMesh,aNodeIds.at(2)),
317 FindNode(myMesh,aNodeIds.at(3)));
318 isRenum = anIsElemNum;
325 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
329 aCellInfo->GetElemNum(iElem));
331 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
332 FindNode(myMesh,aNodeIds.at(1)),
333 FindNode(myMesh,aNodeIds.at(2)),
334 FindNode(myMesh,aNodeIds.at(3)));
335 isRenum = anIsElemNum;
341 // There is some differnce between SMDS and MED
343 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
348 aCellInfo->GetElemNum(iElem));
350 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
351 FindNode(myMesh,aNodeIds.at(1)),
352 FindNode(myMesh,aNodeIds.at(2)),
353 FindNode(myMesh,aNodeIds.at(3)),
354 FindNode(myMesh,aNodeIds.at(4)));
355 isRenum = anIsElemNum;
362 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
368 aCellInfo->GetElemNum(iElem));
370 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
371 FindNode(myMesh,aNodeIds.at(1)),
372 FindNode(myMesh,aNodeIds.at(2)),
373 FindNode(myMesh,aNodeIds.at(3)),
374 FindNode(myMesh,aNodeIds.at(4)),
375 FindNode(myMesh,aNodeIds.at(5)));
376 isRenum = anIsElemNum;
383 anElement = myMesh->AddVolumeWithID(aNodeIds.at(0),
391 aCellInfo->GetElemNum(iElem));
393 anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds.at(0)),
394 FindNode(myMesh,aNodeIds.at(1)),
395 FindNode(myMesh,aNodeIds.at(2)),
396 FindNode(myMesh,aNodeIds.at(3)),
397 FindNode(myMesh,aNodeIds.at(4)),
398 FindNode(myMesh,aNodeIds.at(5)),
399 FindNode(myMesh,aNodeIds.at(6)),
400 FindNode(myMesh,aNodeIds.at(7)));
401 isRenum = anIsElemNum;
405 }catch(const std::exception& exc){
406 //INFOS("Follow exception was cought:\n\t"<<exc.what());
409 //INFOS("Unknown exception was cought !!!");
414 result = DRS_WARN_SKIP_ELEM;
418 anIsElemNum = MED_FAUX;
420 if (result < DRS_WARN_RENUMBER)
421 result = DRS_WARN_RENUMBER;
423 if (myFamilies.find(aFamNum) != myFamilies.end()) {
424 // Save reference to this element from its family
425 myFamilies[aFamNum]->AddElement(anElement);
426 myFamilies[aFamNum]->SetType(anElement->GetType());
435 }catch(const std::exception& exc){
436 INFOS("Follow exception was cought:\n\t"<<exc.what());
439 INFOS("Unknown exception was cought !!!");
442 MESSAGE("ReadMySelf - result status = "<<result);
446 list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames()
448 list<string> aMeshNames;
451 using namespace MEDA;
453 MESSAGE("GetMeshNames - myFile : " << myFile);
454 TWrapper aMed (myFile);
456 if (med_int aNbMeshes = aMed.GetNbMeshes()) {
457 for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
458 // Reading the MED mesh
459 //---------------------
460 PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
461 aMeshNames.push_back(aMeshInfo->GetName());
464 }catch(const std::exception& exc){
465 INFOS("Follow exception was cought:\n\t"<<exc.what());
467 INFOS("Unknown exception was cought !!!");
473 list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
475 list<string> aResult;
476 set<string> aResGroupNames;
478 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
479 for (; aFamsIter != myFamilies.end(); aFamsIter++)
481 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
482 const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
483 set<string>::iterator aGrNamesIter = aGroupNames.begin();
484 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
486 string aName = *aGrNamesIter;
487 // Check, if this is a Group or SubMesh name
488 //if (aName.substr(0, 5) == string("Group")) {
489 if (aResGroupNames.find(aName) == aResGroupNames.end()) {
490 aResGroupNames.insert(aName);
491 aResult.push_back(aName);
500 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
502 string aGroupName (theGroup->GetStoreName());
503 MESSAGE("Get Group " << aGroupName);
505 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
506 for (; aFamsIter != myFamilies.end(); aFamsIter++)
508 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
509 if (aFamily->MemberOf(aGroupName))
511 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
512 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
513 for (; anElemsIter != anElements.end(); anElemsIter++)
515 theGroup->SMDS_MeshGroup::Add(*anElemsIter);
521 void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
524 char submeshGrpName[ 30 ];
525 sprintf( submeshGrpName, "SubMesh %d", theId );
526 string aName (submeshGrpName);
527 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
528 for (; aFamsIter != myFamilies.end(); aFamsIter++)
530 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
531 if (aFamily->MemberOf(aName))
533 const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
534 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
535 if (aFamily->GetType() == SMDSAbs_Node)
537 for (; anElemsIter != anElements.end(); anElemsIter++)
539 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
540 theSubMesh->AddNode(node);
545 for (; anElemsIter != anElements.end(); anElemsIter++)
547 theSubMesh->AddElement(*anElemsIter);
554 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
556 SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast<SMESHDS_Mesh*>(myMesh);
558 EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh");
560 map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
561 for (; aFamsIter != myFamilies.end(); aFamsIter++)
563 DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
564 MED::TStringSet aGroupNames = aFamily->GetGroupNames();
565 set<string>::iterator aGrNamesIter = aGroupNames.begin();
566 for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
568 string aName = *aGrNamesIter;
569 // Check, if this is a Group or SubMesh name
570 if (aName.substr(0, 7) == string("SubMesh"))
572 int Id = atoi(string(aName).substr(7).c_str());
573 set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
574 set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
575 if (aFamily->GetType() == SMDSAbs_Node)
577 for (; anElemsIter != anElements.end(); anElemsIter++)
579 const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
580 aSMESHDSMesh->SetNodeInVolume(node, Id);
581 // aSMESHDSMesh->SetNodeOnFace(node, Id);
582 // aSMESHDSMesh->SetNodeOnEdge(node, Id);
583 // aSMESHDSMesh->SetNodeOnVertex(node, Id);
588 for (; anElemsIter != anElements.end(); anElemsIter++)
590 aSMESHDSMesh->SetMeshElementOnShape(*anElemsIter, Id);