diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 136b6eac9544ea173c489c9457836940059551e8..62e3530df28a3385b2211c1671cf76630262675b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,9 +1,9 @@ -4.9.3 (Work-in-progress): improved handling of degenerate curves in periodic +4.9.3 (January 4, 2022): improved handling of degenerate curves in periodic surfaces and boundary layer extrusion; extended Mesh.SaveGroupsOfElements capabilities for INP export; extended Mesh.MeshSizeExtendFromBoundary + new "Extend" mesh size field to enable alternative mesh size extensions from -boundary; moved all kernel sources to src/ subdirectory; renamed demos/ as -examples/ and tutorial/ as tutorials/; small bug fixes. +boundary; enhanced X3D output; moved all kernel sources to src/ subdirectory; +renamed demos/ as examples/ and tutorial/ as tutorials/; small bug fixes. 4.9.2 (December 23, 2021): faster projection on OCC entities; extended Mesh.SaveGroupsOfNodes capabilities for INP export; improved transfinite meshing diff --git a/CREDITS.txt b/CREDITS.txt index 35e1584685d650bc8d7e8b5a0ef4b39e59042fa3..29ae579657e3785b3179e5a935b13df053efb63f 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -32,9 +32,9 @@ Pierre-Alexandre Beaufort (HXT/reparam), Zhidong Han (LSDYNA export), Ismail Badia (hierarchical basis functions), Jeremy Theler (X3D export), Thomas Toulorge (high order mesh optimizer, new CGNS IO), Max Orok (binary PLY), Marek Wojciechowski (PyPi packaging), Maxence Reberol (automatic transfinite, quad -meshing tools), Michael Ermakov (Gambit export, Fortran API). See comments in -the sources for more information. If we forgot to list your contributions please -send us an email! +meshing tools), Michael Ermakov (Gambit export, Fortran API), Alex Krasner (X3D +export). See comments in the sources for more information. If we forgot to list +your contributions please send us an email! Thanks to the following folks who have contributed by providing fresh ideas on theoretical or programming topics, who have sent patches, requests for changes diff --git a/doc/gmsh.html b/doc/gmsh.html index 1fda50989915dce18f36871f23820f30c2f6c0f8..5506d0694dc7b40c54c3c59513042f30afd60e8d 100644 --- a/doc/gmsh.html +++ b/doc/gmsh.html @@ -98,17 +98,17 @@ Public License (GPL)</a>: <ul> <li> <div class="highlight"> - Current stable release (version 4.9.2, 23 December 2021): + Current stable release (version 4.9.3, 4 January 2022): <ul> <li>Download Gmsh for - <a href="bin/Windows/gmsh-4.9.2-Windows64.zip">Windows</a>, - <a href="bin/Linux/gmsh-4.9.2-Linux64.tgz">Linux</a> or - <a href="bin/MacOSX/gmsh-4.9.2-MacOSX.dmg">macOS</a> <a href="#1"><sup>*</sup></a> - <li>Download the <a href="src/gmsh-4.9.2-source.tgz">source code</a> + <a href="bin/Windows/gmsh-4.9.3-Windows64.zip">Windows</a>, + <a href="bin/Linux/gmsh-4.9.3-Linux64.tgz">Linux</a> or + <a href="bin/MacOSX/gmsh-4.9.3-MacOSX.dmg">macOS</a> <a href="#1"><sup>*</sup></a> + <li>Download the <a href="src/gmsh-4.9.3-source.tgz">source code</a> <li>Download the Software Development Kit (SDK) for - <a href="bin/Windows/gmsh-4.9.2-Windows64-sdk.zip">Windows</a>, - <a href="bin/Linux/gmsh-4.9.2-Linux64-sdk.tgz">Linux</a> or - <a href="bin/MacOSX/gmsh-4.9.2-MacOSX-sdk.tgz">macOS</a> <a href="#1"><sup>*</sup></a> + <a href="bin/Windows/gmsh-4.9.3-Windows64-sdk.zip">Windows</a>, + <a href="bin/Linux/gmsh-4.9.3-Linux64-sdk.tgz">Linux</a> or + <a href="bin/MacOSX/gmsh-4.9.3-MacOSX-sdk.tgz">macOS</a> <a href="#1"><sup>*</sup></a> <li>Download both Gmsh and the SDK with pip: '<code>pip install --upgrade <a href="https://pypi.org/project/gmsh/">gmsh</a></code>' </ul> diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi index eac705ed3be0c86139875f169267eb6aa8b02e9a..2a4bb9930afd77ec5ad8906a3cad1a9c9f03d82e 100644 --- a/doc/texinfo/opt_general.texi +++ b/doc/texinfo/opt_general.texi @@ -38,7 +38,7 @@ Saved in: @code{General.OptionsFileName} @item General.BuildInfo Gmsh build information (read-only)@* -Default value: @code{"Version: 4.9.3-git-0776dfa97; License: GNU General Public License; Build OS: MacOSX-sdk; Build date: 20211229; Build host: MacBook-Pro-Christophe.local; Build options: 64Bit ALGLIB[contrib] ANN[contrib] Bamg Blossom Cairo Cgns DIntegration Dlopen DomHex Eigen[contrib] Fltk GMP Gmm[contrib] Hxt Jpeg Kbipack MathEx[contrib] Med Mesh Metis[contrib] Mmg Mpeg Netgen ONELAB ONELABMetamodel OpenCASCADE OpenCASCADE-CAF OpenGL OpenMP OptHom Parasolid ParasolidSTEP Parser Plugins Png Post QuadMeshingTools QuadTri Solver TetGen/BR TouchBar Voro++[contrib] WinslowUntangler Zlib; FLTK version: 1.4.0; OCC version: 7.7.0; MED version: 4.1.0; Packaged by: geuzaine; Web site: https://gmsh.info; Issue tracker: https://gitlab.onelab.info/gmsh/gmsh/issues"}@* +Default value: @code{"Version: 4.9.3-git-6d50eb0d5; License: GNU General Public License; Build OS: MacOSX-sdk; Build date: 20220104; Build host: MacBook-Pro-Christophe.local; Build options: 64Bit ALGLIB[contrib] ANN[contrib] Bamg Blossom Cairo Cgns DIntegration Dlopen DomHex Eigen[contrib] Fltk GMP Gmm[contrib] Hxt Jpeg Kbipack MathEx[contrib] Med Mesh Metis[contrib] Mmg Mpeg Netgen ONELAB ONELABMetamodel OpenCASCADE OpenCASCADE-CAF OpenGL OpenMP OptHom Parasolid ParasolidSTEP Parser Plugins Png Post QuadMeshingTools QuadTri Solver TetGen/BR TouchBar Voro++[contrib] WinslowUntangler Zlib; FLTK version: 1.4.0; OCC version: 7.7.0; MED version: 4.1.0; Packaged by: geuzaine; Web site: https://gmsh.info; Issue tracker: https://gitlab.onelab.info/gmsh/gmsh/issues"}@* Saved in: @code{-} @item General.BuildOptions @@ -168,7 +168,7 @@ Saved in: @code{General.SessionFileName} @item General.Version Gmsh version (read-only)@* -Default value: @code{"4.9.3-git-0776dfa97"}@* +Default value: @code{"4.9.3-git-6d50eb0d5"}@* Saved in: @code{-} @item General.WatchFilePattern diff --git a/doc/texinfo/opt_print.texi b/doc/texinfo/opt_print.texi index 599885489e503aaae95c09925fd937d535a7d1b4..3e60bfc28490bbe74973b309e4c2ccbb56a18f43 100644 --- a/doc/texinfo/opt_print.texi +++ b/doc/texinfo/opt_print.texi @@ -232,12 +232,12 @@ Default value: @code{0}@* Saved in: @code{General.OptionsFileName} @item Print.X3dVolumes -Save surfaces in CAD X3D output (0: no, 1: create separate x3d file for each volume in model)@* +Save separate volumes in CAD X3D output (0: no, 1: yes)@* Default value: @code{0}@* Saved in: @code{General.OptionsFileName} @item Print.X3dColorize -Save surfaces in CAD X3D output (0: no, 1: apply color to faces)@* +Apply colors to faces (0: no, 1: yes)@* Default value: @code{0}@* Saved in: @code{General.OptionsFileName} diff --git a/src/fltk/graphicWindow.cpp b/src/fltk/graphicWindow.cpp index c68b2ac2dd8f5aa572d7af66214e80d80f0cf34d..66aa95472355d1c13699764fc434a8c1f51bbca4 100644 --- a/src/fltk/graphicWindow.cpp +++ b/src/fltk/graphicWindow.cpp @@ -442,17 +442,28 @@ static int _save_view_txt(const char *name) { return genericViewFileDialog(name, "TXT Options", 4); } +static int _save_mesh_x3d(const char *name) +{ + return genericMeshFileDialog(name, "X3D Options", FORMAT_X3D, false, false); +} static int _save_view_x3d(const char *name) { return x3dViewFileDialog(name, "X3D Options", 7); } +static int _save_x3d(const char *name) +{ + if(PView::list.empty()) + return _save_mesh_x3d(name); + else + return _save_view_x3d(name); +} static int _save_auto(const char *name) { switch(GuessFileFormatFromFileName(name)) { case FORMAT_MSH: return _save_msh(name); case FORMAT_POS: return _save_view_pos(name); - case FORMAT_X3D: return _save_view_x3d(name); + case FORMAT_X3D: return _save_x3d(name); case FORMAT_PVTU: return _save_view_adapt_pvtu(name); case FORMAT_TXT: return _save_view_txt(name); case FORMAT_OPT: return _save_options(name); @@ -545,8 +556,9 @@ static void file_export_cb(Fl_Widget *w, void *data) {"Mesh - PLY2 Surface\t*.ply2", _save_ply2}, {"Mesh - SU2\t*.su2", _save_su2}, {"Mesh - GAMBIT Neutral File\t*.neu", _save_neu}, + {"Mesh - X3D\t*.x3d", _save_mesh_x3d}, {"Post-processing - Gmsh POS\t*.pos", _save_view_pos}, - {"Post-processing - X3D (X3D)\t*.x3d", _save_view_x3d}, + {"Post-processing - X3D\t*.x3d", _save_view_x3d}, #if defined(HAVE_MED) {"Post-processing - MED\t*.rmed", _save_view_med}, #endif diff --git a/src/geo/GModel.h b/src/geo/GModel.h index 2ae35eb382cbb439a635e989f3d90d4e284dd4c1..b6767fda4ae4ecbc0319c46980772a6029993823 100644 --- a/src/geo/GModel.h +++ b/src/geo/GModel.h @@ -80,8 +80,9 @@ private: bool binary, bool saveAll, bool saveParametric, double scalingFactor); int _writeX3dFile(FILE* fp, bool saveAll, - double scalingFactor, int x3dsurfaces, int x3dedges, - int x3dvertices, int x3dcolorize, std::vector<GFace *>& customFaces); + double scalingFactor, int x3dsurfaces, int x3dedges, + int x3dvertices, int x3dcolorize, + std::vector<GFace *> &customFaces); protected: // the name of the model @@ -772,7 +773,8 @@ public: // X3D (only output from OCCT's triangulation) int writeX3D(const std::string &name, bool saveAll = false, double scalingFactor = 1.0, int x3dsurfaces = 1, - int x3dedges = 0, int x3dvertices = 0, int x3dvolumes = 0, int x3dcolorize = 0); + int x3dedges = 0, int x3dvertices = 0, int x3dvolumes = 0, + int x3dcolorize = 0); // PLY(2) format (ascii text format) int readPLY(const std::string &name); diff --git a/src/geo/GModelIO_X3D.cpp b/src/geo/GModelIO_X3D.cpp index d518a08fc73923255496f54fd005f54de4e6ae66..5d249d28772f6da9182914db826e3bb3f7546a47 100644 --- a/src/geo/GModelIO_X3D.cpp +++ b/src/geo/GModelIO_X3D.cpp @@ -29,7 +29,7 @@ static void writeX3dHeader(FILE *fp, std::vector<std::string> &metadata) "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' >\n"); fprintf(fp, " <head>\n"); fprintf(fp, " <meta name='creator' content='gmsh'/> \n"); - for(auto it = metadata.begin(); it != metadata.end(); ++it){ + for(auto it = metadata.begin(); it != metadata.end(); ++it) { fprintf(fp, " <meta name='metadata_%s' content='%s'/> \n", std::to_string(std::distance(metadata.begin(), it)).c_str(), (*it).c_str()); @@ -38,19 +38,23 @@ static void writeX3dHeader(FILE *fp, std::vector<std::string> &metadata) fprintf(fp, " <Scene>\n"); } -static void writeX3dTrailer(FILE *fp){ +static void writeX3dTrailer(FILE *fp) +{ fprintf(fp, " </Scene>\n"); fprintf(fp, "</X3D>\n"); } -static void writeHTMLHeader(FILE *fp){ +static void writeHTMLHeader(FILE *fp) +{ fprintf(fp, "<!DOCTYPE HTML\n>"); fprintf(fp, "<html lang=\"en\"> \n"); fprintf(fp, "<head>\n"); fprintf(fp, " <title> gmsh x3d render</title>\n"); fprintf(fp, " <meta charset=\"utf-8\">\n"); - fprintf(fp, " <link rel=\"stylesheet\" type=\"text/css\" href=\"https://x3dom.org/release/x3dom.css\">\n"); - fprintf(fp, " <script src=\"https://x3dom.org/release/x3dom.js\"></script>\n"); + fprintf(fp, " <link rel=\"stylesheet\" type=\"text/css\" " + "href=\"https://x3dom.org/release/x3dom.css\">\n"); + fprintf(fp, + " <script src=\"https://x3dom.org/release/x3dom.js\"></script>\n"); fprintf(fp, " <style>\n"); fprintf(fp, " body {\n"); fprintf(fp, " background: #ced7de;\n"); @@ -68,23 +72,43 @@ static void writeHTMLHeader(FILE *fp){ fprintf(fp, "</head>\n"); } -static void writeHTMLBody(FILE *fp, std::vector<std::string> &x3dfiles){ +static void writeHTMLBody(FILE *fp, std::vector<std::string> &x3dfiles) +{ fprintf(fp, "<body>\n"); - fprintf(fp, " <x3d id=\"gmsh-scene\" style=\"width: 100%%; height: 100%%;border: none\" >\n"); + fprintf(fp, " <x3d id=\"gmsh-scene\" style=\"width: 100%%; height: " + "100%%;border: none\" >\n"); fprintf(fp, " <Scene>\n"); fprintf(fp, " <transform scale=\"1,1,1\">\n"); - fprintf(fp, " <transform id=\"plane_axis\" rotation=\"1 0 0 -1.57079632679\">\n"); - fprintf(fp, " <inline url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/plane.x3d\" mapDEFToID=\"true\" namespaceName=\"plane\"></inline>\n"); - fprintf(fp, " <inline url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/axesSmall.x3d\" mapDEFToID=\"true\" namespaceName=\"axesSmall\"></inline>\n"); + fprintf( + fp, + " <transform id=\"plane_axis\" rotation=\"1 0 0 -1.57079632679\">\n"); + fprintf( + fp, + " <inline " + "url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/" + "plane.x3d\" mapDEFToID=\"true\" namespaceName=\"plane\"></inline>\n"); + fprintf(fp, " <inline " + "url=\"https://rawcdn.githack.com/x3dom/component-editor/master/" + "static/x3d/axesSmall.x3d\" mapDEFToID=\"true\" " + "namespaceName=\"axesSmall\"></inline>\n"); fprintf(fp, " </transform>\n"); - fprintf(fp, " <inline url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/axes.x3d\" mapDEFToID=\"true\" namespaceName=\"axes\"></inline>\n"); + fprintf( + fp, + " <inline " + "url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/" + "axes.x3d\" mapDEFToID=\"true\" namespaceName=\"axes\"></inline>\n"); fprintf(fp, " </transform>\n"); - fprintf(fp, " <transform id=\"components\" rotation=\"1 0 0 -1.57079632679\">\n"); - for(auto it = x3dfiles.begin(); it != x3dfiles.end(); ++it){ - //drop path on x3d since it will be in the same folder as html + fprintf( + fp, + " <transform id=\"components\" rotation=\"1 0 0 -1.57079632679\">\n"); + for(auto it = x3dfiles.begin(); it != x3dfiles.end(); ++it) { + // drop path on x3d since it will be in the same folder as html std::vector<std::string> split = SplitFileName(*it); std::string x3dname = split[1] + split[2]; - fprintf(fp, " <inline onload=\"fit()\" mapDEFToID=\"true\" url=%s></inline>\n", x3dname.c_str()); + fprintf( + fp, + " <inline onload=\"fit()\" mapDEFToID=\"true\" url=%s></inline>\n", + x3dname.c_str()); } fprintf(fp, " </transform>\n"); fprintf(fp, " </Scene>\n"); @@ -102,8 +126,7 @@ static void writeHTMLBody(FILE *fp, std::vector<std::string> &x3dfiles){ static void writeX3dFaces(FILE *fp, std::vector<GFace *> &faces, bool useIndexedSet, double scalingFactor, - const std::string &name, - bool useColor, + const std::string &name, bool useColor, std::vector<unsigned int> &colors) { bool useGeoSTL = false; @@ -120,27 +143,28 @@ static void writeX3dFaces(FILE *fp, std::vector<GFace *> &faces, } } - if(!useColor){ + if(!useColor) { fprintf(fp, " <Shape DEF=\"%s\">\n", name.c_str()); - fprintf(fp, - " <Appearance><Material DEF=\"mat%s\"></Material></Appearance>\n", - name.c_str()); + fprintf( + fp, " <Appearance><Material DEF=\"mat%s\"></Material></Appearance>\n", + name.c_str()); } - else{ - if(colors.size()==1){ + else { + if(colors.size() == 1) { unsigned int cvalue = colors[0]; float r = static_cast<float>(CTX::instance()->unpackRed(cvalue)) / 255.0; - float g = static_cast<float>(CTX::instance()->unpackGreen(cvalue)) / 255.0; + float g = + static_cast<float>(CTX::instance()->unpackGreen(cvalue)) / 255.0; float b = static_cast<float>(CTX::instance()->unpackBlue(cvalue)) / 255.0; fprintf(fp, " <Shape DEF=\"%s\">\n", name.c_str()); fprintf(fp, - " <Appearance><Material DEF=\"mat%s\" diffuseColor=\"%s %s %s\" shininess=\"0.9\" specularColor=\"0.2 0.2 0.2\" transparency=\"0\"></Material></Appearance>\n", - name.c_str(), - std::to_string(r).c_str(), - std::to_string(g).c_str(), - std::to_string(b).c_str()); + " <Appearance><Material DEF=\"mat%s\" diffuseColor=\"%s %s " + "%s\" shininess=\"0.9\" specularColor=\"0.2 0.2 0.2\" " + "transparency=\"0\"></Material></Appearance>\n", + name.c_str(), std::to_string(r).c_str(), + std::to_string(g).c_str(), std::to_string(b).c_str()); } - else{ + else { Msg::Error("Error in x3d coloring"); } } @@ -288,21 +312,20 @@ static void writeX3dEdges(FILE *fp, std::vector<GEdge *> &edges, } } -int GModel::_writeX3dFile(FILE* fp, bool saveAll, - double scalingFactor, int x3dsurfaces, int x3dedges, - int x3dvertices, int x3dcolorize, std::vector<GFace *>& customFaces) +int GModel::_writeX3dFile(FILE *fp, bool saveAll, double scalingFactor, + int x3dsurfaces, int x3dedges, int x3dvertices, + int x3dcolorize, std::vector<GFace *> &customFaces) { if(noPhysicalGroups()) saveAll = true; std::vector<GFace *> modelFaces; - if(customFaces.size() > 0) - { - for(auto it = customFaces.begin(); it != customFaces.end(); ++it){ + if(customFaces.size() > 0) { + for(auto it = customFaces.begin(); it != customFaces.end(); ++it) { modelFaces.push_back(*it); } } - else{ - for(auto it = firstFace(); it != lastFace(); ++it){ + else { + for(auto it = firstFace(); it != lastFace(); ++it) { modelFaces.push_back(*it); } } @@ -313,7 +336,7 @@ int GModel::_writeX3dFile(FILE* fp, bool saveAll, // all surfaces in a single x3d object std::vector<GFace *> faces; std::vector<unsigned int> colors; - //for(auto it = first_face; it != last_face; ++it) { + // for(auto it = first_face; it != last_face; ++it) { for(auto it = modelFaces.begin(); it != modelFaces.end(); ++it) { if(saveAll || (*it)->physicals.size()) { faces.push_back(*it); } } @@ -322,7 +345,7 @@ int GModel::_writeX3dFile(FILE* fp, bool saveAll, } else if(x3dsurfaces == 2) { // one x3d object for each geometrical surface - //for(auto it = first_face; it != last_face; ++it) { + // for(auto it = first_face; it != last_face; ++it) { for(auto it = modelFaces.begin(); it != modelFaces.end(); ++it) { if(saveAll || (*it)->physicals.size()) { std::vector<GFace *> faces(1, *it); @@ -433,14 +456,14 @@ int GModel::_writeX3dFile(FILE* fp, bool saveAll, return 1; } -static std::string TagFileName(std::string const & name, int tag) +static std::string TagFileName(std::string const &name, int tag) { std::vector<std::string> split = SplitFileName(name); //<path>/<name>.<ext> std::string new_name = split[1] + "_" + std::to_string(tag); return split[0] + new_name + split[2]; } -static std::string HtmlFileName(std::string const & name) +static std::string HtmlFileName(std::string const &name) { std::vector<std::string> split = SplitFileName(name); //<path>/<name>.<ext> return split[0] + "index.html"; @@ -464,10 +487,10 @@ int GModel::writeX3D(const std::string &name, bool saveAll, Msg::Info("separating volumes into separate files"); std::vector<GEntity *> volumes; getEntities(volumes, 3); - + // if volumes present in model, else continue to single file mode - if(volumes.size() > 0){ - for(auto it = volumes.begin(); it != volumes.end(); ++it){ + if(volumes.size() > 0) { + for(auto it = volumes.begin(); it != volumes.end(); ++it) { faces = (*it)->bindingsGetFaces(); std::string _vol_name = getElementaryName((*it)->dim(), (*it)->tag()); metadata.push_back(_vol_name); @@ -478,13 +501,14 @@ int GModel::writeX3D(const std::string &name, bool saveAll, Msg::Warning("Unable to open file '%s'", name.c_str()); return 0; } - writeX3dHeader(fp,metadata); - _writeX3dFile(fp, saveAll, scalingFactor, x3dsurfaces, x3dedges, x3dvertices, x3dcolorize, faces); + writeX3dHeader(fp, metadata); + _writeX3dFile(fp, saveAll, scalingFactor, x3dsurfaces, x3dedges, + x3dvertices, x3dcolorize, faces); writeX3dTrailer(fp); fclose(fp); metadata.clear(); } - //collate x3d files to html + // collate x3d files to html std::string _htmlname = HtmlFileName(name); fp = Fopen(_htmlname.c_str(), "w"); writeHTMLHeader(fp); @@ -501,9 +525,10 @@ int GModel::writeX3D(const std::string &name, bool saveAll, Msg::Warning("Unable to open file '%s'", name.c_str()); return 0; } - writeX3dHeader(fp,metadata); + writeX3dHeader(fp, metadata); // main write function - _writeX3dFile(fp, saveAll, scalingFactor, x3dsurfaces, x3dedges, x3dvertices, x3dcolorize, faces); + _writeX3dFile(fp, saveAll, scalingFactor, x3dsurfaces, x3dedges, x3dvertices, + x3dcolorize, faces); writeX3dTrailer(fp); fclose(fp);