From f05a271c37e85153784227c0f238d57edd3b3181 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 17 Jul 2013 11:03:15 +0000 Subject: [PATCH] first pass at CELUM file format --- Common/CreateFile.cpp | 7 +++ Common/GmshDefines.h | 1 + Fltk/graphicWindow.cpp | 4 ++ Geo/CMakeLists.txt | 2 +- Geo/GModel.h | 4 ++ Geo/GModelIO_CELUM.cpp | 120 +++++++++++++++++++++++++++++++++++++++++ Geo/gmshFace.cpp | 2 +- 7 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 Geo/GModelIO_CELUM.cpp diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp index 1345fbe1af..89cf2a95ec 100644 --- a/Common/CreateFile.cpp +++ b/Common/CreateFile.cpp @@ -46,6 +46,7 @@ int GetFileFormatFromExtension(const std::string &ext) else if(ext == ".bdf") return FORMAT_BDF; else if(ext == ".diff") return FORMAT_DIFF; else if(ext == ".inp") return FORMAT_INP; + else if(ext == ".celum")return FORMAT_CELUM; else if(ext == ".nas") return FORMAT_BDF; else if(ext == ".p3d") return FORMAT_P3D; else if(ext == ".wrl") return FORMAT_VRML; @@ -99,6 +100,7 @@ std::string GetDefaultFileName(int format) case FORMAT_BDF: name += ".bdf"; break; case FORMAT_DIFF: name += ".diff"; break; case FORMAT_INP: name += ".inp"; break; + case FORMAT_CELUM:name += ".celum"; break; case FORMAT_P3D: name += ".p3d"; break; case FORMAT_VRML: name += ".wrl"; break; case FORMAT_PLY2: name += ".ply2"; break; @@ -311,6 +313,11 @@ void CreateOutputFile(const std::string &fileName, int format, bool redraw) CTX::instance()->mesh.scalingFactor); break; + case FORMAT_CELUM: + GModel::current()->writeCELUM + (name, CTX::instance()->mesh.saveAll, CTX::instance()->mesh.scalingFactor); + break; + case FORMAT_P3D: GModel::current()->writeP3D (name, CTX::instance()->mesh.saveAll, CTX::instance()->mesh.scalingFactor); diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h index 5217a9215f..0eb368dd1a 100644 --- a/Common/GmshDefines.h +++ b/Common/GmshDefines.h @@ -47,6 +47,7 @@ #define FORMAT_IR3 38 #define FORMAT_INP 39 #define FORMAT_PLY2 40 +#define FORMAT_CELUM 41 // Element types #define TYPE_PNT 1 diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index 9b76308953..26f5d28753 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -270,6 +270,8 @@ static int _save_diff(const char *name){ return genericMeshFileDialog (name, "Diffpack Options", FORMAT_DIFF, true, false); } static int _save_inp(const char *name){ return unvinpFileDialog (name, "Abaqus INP Options", FORMAT_INP); } +static int _save_celum(const char *name){ return genericMeshFileDialog + (name, "CELUM Options", FORMAT_CELUM, false, false); } static int _save_med(const char *name){ return genericMeshFileDialog (name, "MED Options", FORMAT_MED, false, false); } static int _save_mesh(const char *name){ return genericMeshFileDialog @@ -332,6 +334,7 @@ static int _save_auto(const char *name) case FORMAT_BDF : return _save_bdf(name); case FORMAT_DIFF : return _save_diff(name); case FORMAT_INP : return _save_inp(name); + case FORMAT_CELUM: return _save_celum(name); case FORMAT_P3D : return _save_p3d(name); case FORMAT_IR3 : return _save_ir3(name); case FORMAT_STL : return _save_stl(name); @@ -371,6 +374,7 @@ static void file_save_as_cb(Fl_Widget *w, void *data) #endif {"Mesh - Gmsh MSH" TT "*.msh", _save_msh}, {"Mesh - Abaqus INP" TT "*.inp", _save_inp}, + {"Mesh - CELUM" TT "*.celum", _save_celum}, #if defined(HAVE_LIBCGNS) {"Mesh - CGNS (Experimental)" TT "*.cgns", _save_cgns}, #endif diff --git a/Geo/CMakeLists.txt b/Geo/CMakeLists.txt index 07ac19e7eb..2f9474c13c 100644 --- a/Geo/CMakeLists.txt +++ b/Geo/CMakeLists.txt @@ -26,7 +26,7 @@ set(SRC GModelIO_CGNS.cpp GModelIO_MED.cpp GModelIO_MESH.cpp GModelIO_STL.cpp GModelIO_PLY.cpp GModelIO_VRML.cpp GModelIO_UNV.cpp GModelIO_BDF.cpp GModelIO_IR3.cpp GModelIO_DIFF.cpp GModelIO_GEOM.cpp GModelIO_INP.cpp - GModelIO_MAIL.cpp GModelIO_P3D.cpp GModelIO_SGEOM.cpp + GModelIO_MAIL.cpp GModelIO_P3D.cpp GModelIO_SGEOM.cpp GModelIO_CELUM.cpp ExtrudeParams.cpp Geo.cpp GeoStringInterface.cpp GeoInterpolation.cpp diff --git a/Geo/GModel.h b/Geo/GModel.h index d6d8ab132a..98dd7bf120 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -697,6 +697,10 @@ class GModel int writeINP(const std::string &name, bool saveAll=false, bool saveGroupsOfNodes=false, double scalingFactor=1.0); + // CELUM + int writeCELUM(const std::string &name, bool saveAll=false, + double scalingFactor=1.0); + // Geomview mesh int readGEOM(const std::string &name); diff --git a/Geo/GModelIO_CELUM.cpp b/Geo/GModelIO_CELUM.cpp new file mode 100644 index 0000000000..38b7263cc2 --- /dev/null +++ b/Geo/GModelIO_CELUM.cpp @@ -0,0 +1,120 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. + +#include "GModel.h" +#include "OS.h" +#include "MTriangle.h" +#include "MQuadrangle.h" + +class CelumInfo{ +public: + SVector3 normal, dirMax, dirMin; + double curvMax, curvMin; +}; + +int GModel::writeCELUM(const std::string &name, bool saveAll, + double scalingFactor) +{ + std::string namef = name + "_f"; + FILE *fpf = Fopen(namef.c_str(), "w"); + if(!fpf){ + Msg::Error("Unable to open file '%s'", namef.c_str()); + return 0; + } + + std::string names = name + "_s"; + FILE *fps = Fopen(names.c_str(), "w"); + if(!fps){ + Msg::Error("Unable to open file '%s'", names.c_str()); + return 0; + } + + // count faces and vertices; the CELUM format duplicates vertices on the + // boundary of CAD patches + int numf = 0, nums = 0; + for(fiter it = firstFace(); it != lastFace(); it++){ + GFace *f = *it; + if(!saveAll && f->physicals.empty()) continue; + numf += f->triangles.size(); + std::set<MVertex*> vset; + for(unsigned int i = 0; i < f->triangles.size(); i++){ + for(int j = 0; j < 3; j++) + vset.insert(f->triangles[i]->getVertex(j)); + } + nums += vset.size(); + } + + Msg::Info("Writing %d triangles and %d vertices", numf, nums); + + int idf = 1, ids = 1; + /* + * un fichier de facettes + - nombre de facettes + - ligne vide + ... pour chaque facette + - numéro de la facette (commence à 1 : utilisé dans les erreurs de lectures) + - chaîne de caractères (nom de la partie géométrique, matériau,... ) + - la liste des 3 numéros de sommets + - ligne vide + ... + * un fichier de sommets + - nombre de sommets + - facteur de conversion + - ligne vide + ... pour chaque sommet + - numéro du sommet (commence à 1 : utilisé dans les erreurs de lectures) + - coordonnées cartésiennes du sommet + - composantes de la normale extérieure orientée + - valeur de la 1ière courbure principale + - valeur de la 2ième courbure principale + - composantes de la 1ière direction principale + - composantes de la 2ième direction principale + - ligne blanche + ... + */ + fprintf(fpf, "%d\n\n", numf); + fprintf(fps, "%d %g\n\n", nums, 1.0); + for(fiter it = firstFace(); it != lastFace(); it++){ + GFace *f = *it; + if(!saveAll && f->physicals.empty()) continue; + std::vector<MVertex*> vvec; + std::map<MVertex*, CelumInfo> vmap; + for(unsigned int i = 0; i < f->triangles.size(); i++){ + fprintf(fpf, "%d \"face %d\"", idf++, f->tag()); + for(int j = 0; j < 3; j++){ + MVertex *v = f->triangles[i]->getVertex(j); + if(!vmap.count(v)){ + v->setIndex(ids++); + SPoint2 param; + bool ok = reparamMeshVertexOnFace(v, f, param); + if(!ok) + Msg::Warning("Could not reparamtrize vertex %d on face %d", + v->getNum(), f->tag()); + CelumInfo info; + info.normal = f->normal(param); + f->curvatures(param, &info.dirMax, &info.dirMin, + &info.curvMax, &info.curvMin); + vmap[v] = info; + vvec.push_back(v); + } + fprintf(fpf, " %d", v->getIndex()); + } + fprintf(fpf, "\n\n"); + } + for(unsigned int i = 0; i < vvec.size(); i++){ + MVertex *v = vvec[i]; + std::map<MVertex *, CelumInfo>::iterator it = vmap.find(v); + fprintf(fps, "%d %g %g %g %g %g %g %g %g %g %g %g\n\n", + it->first->getIndex(), it->second.normal.x(), it->second.normal.y(), + it->second.normal.z(), it->second.curvMin, it->second.curvMax, + it->second.dirMin.x(), it->second.dirMin.y(), it->second.dirMin.z(), + it->second.dirMax.x(), it->second.dirMax.y(), it->second.dirMax.z()); + } + } + + fclose(fpf); + fclose(fps); + return 1; +} diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp index 026ad19c04..fff57b475e 100644 --- a/Geo/gmshFace.cpp +++ b/Geo/gmshFace.cpp @@ -188,7 +188,7 @@ SVector3 gmshFace::normal(const SPoint2 ¶m) const Msg::Debug("Could not compute normal of surface %d - retrying with %d points", tag(), NP); if(tries > 10){ - Msg::Warning("Could not compute normal of surface %d", tag()); + Msg::Warning("Could not orient normal of surface %d", tag()); return SVector3(n[0], n[1], n[2]); } } -- GitLab