From 96fc2c5c140c39edc1dade8d9ff5583bf3509a7b Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 24 Mar 2008 20:51:04 +0000 Subject: [PATCH] fine-tune MED mesh I/O (saveAll, read points, etc.) --- Fltk/Callbacks.cpp | 4 +- Geo/GModel.h | 3 +- Geo/GModelIO_MED.cpp | 118 ++++++++++++++++++++++++++---------------- Parser/CreateFile.cpp | 4 +- 4 files changed, 80 insertions(+), 49 deletions(-) diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 9259a39df7..337d58dd83 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.573 2008-03-23 21:42:56 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.574 2008-03-24 20:51:04 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -664,7 +664,7 @@ int _save_options(const char *name){ return options_dialog(name); } int _save_geo(const char *name){ return geo_dialog(name); } int _save_cgns(const char *name){ CreateOutputFile(name, FORMAT_CGNS); return 1; } int _save_unv(const char *name){ return unv_dialog(name); } -int _save_med(const char *name){ CreateOutputFile(name, FORMAT_MED); return 1; } +int _save_med(const char *name){ return generic_mesh_dialog(name, "MED Options", FORMAT_MED); } int _save_mesh(const char *name){ return generic_mesh_dialog(name, "MESH Options", FORMAT_MESH); } int _save_bdf(const char *name){ return bdf_dialog(name); } int _save_p3d(const char *name){ return generic_mesh_dialog(name, "P3D Options", FORMAT_P3D); } diff --git a/Geo/GModel.h b/Geo/GModel.h index f075f0e7f9..94702b258a 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -261,7 +261,8 @@ class GModel // Med interface ("Modele d'Echange de Donnees") int readMED(const std::string &name); - int writeMED(const std::string &name, double scalingFactor=1.0); + int writeMED(const std::string &name, + bool saveAll=false, double scalingFactor=1.0); }; #endif diff --git a/Geo/GModelIO_MED.cpp b/Geo/GModelIO_MED.cpp index 788cc6d385..9a85f4c48e 100644 --- a/Geo/GModelIO_MED.cpp +++ b/Geo/GModelIO_MED.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO_MED.cpp,v 1.13 2008-03-24 06:39:13 geuzaine Exp $ +// $Id: GModelIO_MED.cpp,v 1.14 2008-03-24 20:51:04 geuzaine Exp $ // // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle // @@ -31,6 +31,7 @@ #include <cstring> #include "MElement.h" #include "MVertex.h" +#include "discreteVertex.h" extern "C" { #include <med.h> @@ -83,7 +84,7 @@ static void writeElementsMED(med_idt &fid, char *meshName, Msg(GERROR, "Could not write elements"); } -int GModel::writeMED(const std::string &name, double scalingFactor) +int GModel::writeMED(const std::string &name, bool saveAll, double scalingFactor) { med_idt fid = MEDouvrir((char*)name.c_str(), MED_CREATION); if(fid < 0) { @@ -106,9 +107,12 @@ int GModel::writeMED(const std::string &name, double scalingFactor) return 0; } - // renumber all the vertices in a continuous sequence (MED + // if there are no physicals we save all the elements + if(noPhysicalGroups()) saveAll = true; + + // renumber the vertices we will save in a continuous sequence (MED // connectivity is given in terms of vertex indices) - renumberMeshVertices(true); + renumberMeshVertices(saveAll); // fill a vector containing all the geometrical entities in the model std::vector<GEntity*> entities; @@ -128,24 +132,26 @@ int GModel::writeMED(const std::string &name, double scalingFactor) // create one family per elementary entity, with one group per // physical entity and no attributes for(unsigned int i = 0; i < entities.size(); i++){ - int num = - (families.size() + 1); - families[entities[i]] = num; - std::ostringstream fs; - fs << entities[i]->dim() << "D_" << entities[i]->tag(); - std::string familyName = "F_" + fs.str(); - std::string groupName; - for(unsigned j = 0; j < entities[i]->physicals.size(); j++){ - std::string tmp = getPhysicalName(entities[i]->physicals[j]); - std::ostringstream gs; - gs << entities[i]->dim() << "D_" << tmp; - if(tmp.empty()) gs << entities[i]->physicals[j]; - groupName += "G_" + gs.str(); - groupName.resize((j + 1) * 80, ' '); + if(saveAll || entities[i]->physicals.size()){ + int num = - (families.size() + 1); + families[entities[i]] = num; + std::ostringstream fs; + fs << entities[i]->dim() << "D_" << entities[i]->tag(); + std::string familyName = "F_" + fs.str(); + std::string groupName; + for(unsigned j = 0; j < entities[i]->physicals.size(); j++){ + std::string tmp = getPhysicalName(entities[i]->physicals[j]); + std::ostringstream gs; + gs << entities[i]->dim() << "D_" << tmp; + if(tmp.empty()) gs << entities[i]->physicals[j]; + groupName += "G_" + gs.str(); + groupName.resize((j + 1) * 80, ' '); + } + if(MEDfamCr(fid, meshName, (char*)familyName.c_str(), + (med_int)num, 0, 0, 0, 0, (char*)groupName.c_str(), + (med_int)entities[i]->physicals.size()) < 0) + Msg(GERROR, "Could not create MED family %d", num); } - if(MEDfamCr(fid, meshName, (char*)familyName.c_str(), - (med_int)num, 0, 0, 0, 0, (char*)groupName.c_str(), - (med_int)entities[i]->physicals.size()) < 0) - Msg(GERROR, "Could not create MED family %d", num); } } @@ -165,6 +171,10 @@ int GModel::writeMED(const std::string &name, double scalingFactor) } } } + if(num.empty()){ + Msg(GERROR, "No nodes to write in MED mesh"); + return 0; + } char coordName[3 * MED_TAILLE_PNOM + 1] = "x y z "; char coordUnit[3 * MED_TAILLE_PNOM + 1] = @@ -183,52 +193,61 @@ int GModel::writeMED(const std::string &name, double scalingFactor) { // points std::vector<med_int> num, conn, fam; for(viter it = firstVertex(); it != lastVertex(); it++){ - num.push_back(++ele); - conn.push_back((*it)->mesh_vertices[0]->getNum()); - fam.push_back(families[*it]); + if(saveAll || (*it)->physicals.size()){ + num.push_back(++ele); + conn.push_back((*it)->mesh_vertices[0]->getNum()); + fam.push_back(families[*it]); + } } writeElementsMED(fid, meshName, num, conn, fam, MED_POINT1); } { // lines std::vector<med_int> num, conn, fam; for(eiter it = firstEdge(); it != lastEdge(); it++) - fillElementsMED(families[*it], (*it)->lines, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->lines, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } { // triangles std::vector<med_int> num, conn, fam; for(fiter it = firstFace(); it != lastFace(); it++) - fillElementsMED(families[*it], (*it)->triangles, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->triangles, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } { // quads std::vector<med_int> num, conn, fam; for(fiter it = firstFace(); it != lastFace(); it++) - fillElementsMED(families[*it], (*it)->quadrangles, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->quadrangles, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } { // tets std::vector<med_int> num, conn, fam; for(riter it = firstRegion(); it != lastRegion(); it++) - fillElementsMED(families[*it], (*it)->tetrahedra, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->tetrahedra, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } { // hexas std::vector<med_int> num, conn, fam; for(riter it = firstRegion(); it != lastRegion(); it++) - fillElementsMED(families[*it], (*it)->hexahedra, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->hexahedra, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } { // prisms std::vector<med_int> num, conn, fam; for(riter it = firstRegion(); it != lastRegion(); it++) - fillElementsMED(families[*it], (*it)->prisms, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->prisms, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } { // pyramids std::vector<med_int> num, conn, fam; for(riter it = firstRegion(); it != lastRegion(); it++) - fillElementsMED(families[*it], (*it)->pyramids, ele, num, conn, fam, typ); + if(saveAll || (*it)->physicals.size()) + fillElementsMED(families[*it], (*it)->pyramids, ele, num, conn, fam, typ); writeElementsMED(fid, meshName, num, conn, fam, typ); } } @@ -255,8 +274,7 @@ int GModel::readMED(const std::string &name) return 0; } if(numMeshes > 1) - Msg(WARNING, "There are %d meshes in the MED file: reading only the first", - numMeshes); + Msg(WARNING, "Reading mesh 1 of %d (ignoring the other)", numMeshes); // read mesh info char meshName[MED_TAILLE_NOM + 1], meshDesc[MED_TAILLE_DESC + 1]; @@ -327,22 +345,34 @@ int GModel::readMED(const std::string &name) std::vector<med_int> eleTags(numEle); if(MEDnumLire(fid, meshName, &eleTags[0], numEle, MED_MAILLE, type) < 0) eleTags.clear(); - std::map<int, std::vector<MElement*> > elements; - MElementFactory factory; - for(int j = 0; j < numEle; j++){ - std::vector<MVertex*> v(numNodPerEle); - for(int k = 0; k < numNodPerEle; k++) - v[k] = verts[conn[numNodPerEle * j + k] - 1]; - MElement *e = factory.create(mshType, v, eleTags.empty() ? 0 : eleTags[j]); - if(e) elements[-fam[j]].push_back(e); + if(numNodPerEle == 1){ // special case for points + for(int j = 0; j < numEle; j++){ + GVertex *v = getVertexByTag(-fam[j]); + if(!v){ + v = new discreteVertex(this, -fam[j]); + add(v); + } + v->mesh_vertices.push_back(verts[conn[j] - 1]); + } + } + else{ + std::map<int, std::vector<MElement*> > elements; + MElementFactory factory; + for(int j = 0; j < numEle; j++){ + std::vector<MVertex*> v(numNodPerEle); + for(int k = 0; k < numNodPerEle; k++) + v[k] = verts[conn[numNodPerEle * j + k] - 1]; + MElement *e = factory.create(mshType, v, eleTags.empty() ? 0 : eleTags[j]); + if(e) elements[-fam[j]].push_back(e); + } + _storeElementsInEntities(elements); } - _storeElementsInEntities(elements); } _associateEntityWithMeshVertices(); for(unsigned int i = 0; i < verts.size(); i++){ GEntity *ge = verts[i]->onWhat(); - if(ge) ge->mesh_vertices.push_back(verts[i]); - else delete verts[i]; // delete all unused vertices + if(ge && ge->dim()) ge->mesh_vertices.push_back(verts[i]); + if(!ge) delete verts[i]; // delete unused vertices } // read family info diff --git a/Parser/CreateFile.cpp b/Parser/CreateFile.cpp index 6891fb0d38..0e5e709be9 100644 --- a/Parser/CreateFile.cpp +++ b/Parser/CreateFile.cpp @@ -1,4 +1,4 @@ -// $Id: CreateFile.cpp,v 1.27 2008-03-23 21:42:57 geuzaine Exp $ +// $Id: CreateFile.cpp,v 1.28 2008-03-24 20:51:04 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -186,7 +186,7 @@ void CreateOutputFile(const char *filename, int format) break; case FORMAT_MED: - GModel::current()->writeMED(name, CTX.mesh.scaling_factor); + GModel::current()->writeMED(name, CTX.mesh.save_all, CTX.mesh.scaling_factor); break; case FORMAT_POS: -- GitLab