From 79c2ec906c72dbf3eb721f7c4fdc13c9093d5422 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@uliege.be>
Date: Fri, 4 Feb 2022 17:26:49 +0100
Subject: [PATCH] new options in Plugin(Invisible) to mark as invisible
 elements outside a bounding box

---
 doc/texinfo/opt_general.texi |  4 +--
 doc/texinfo/opt_plugin.texi  | 14 ++++++++++-
 src/plugin/Invisible.cpp     | 47 +++++++++++++++++++++++++++++++++---
 3 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi
index 376a9e3a27..be1adcff71 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.4-git-1b82f12da; License: GNU General Public License; Build OS: MacOSX-sdk; Build date: 20220202; 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.5-git-f511f1b2c; License: GNU General Public License; Build OS: MacOSX-sdk; Build date: 20220204; 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.1; 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.4-git-1b82f12da"}@*
+Default value: @code{"4.9.5-git-f511f1b2c"}@*
 Saved in: @code{-}
 
 @item General.WatchFilePattern
diff --git a/doc/texinfo/opt_plugin.texi b/doc/texinfo/opt_plugin.texi
index 1172a6ae43..4b30eeb2e4 100644
--- a/doc/texinfo/opt_plugin.texi
+++ b/doc/texinfo/opt_plugin.texi
@@ -636,13 +636,25 @@ Default value: @code{1}
 @end table
 
 @item Plugin(Invisible)
-Plugin(Invisible) deletes (if `DeleteElements' is set) or reverses (if `ReverseElements' is set) all the invisible elements in the current model.
+Plugin(Invisible) deletes (if `DeleteElements' is set) or reverses (if `ReverseElements' is set) all the invisible elements in the current model. If the bounding box defined by `XMin' < x < `XMax, `YMin' < y < `YMax and `ZMin' < z < `ZMax' is not empty, mark all elements outside the bounding box as invisible prior to deleting or inverting the elements.
 Numeric options:
 @table @code
 @item DeleteElements
 Default value: @code{1}
 @item ReverseElements
 Default value: @code{0}
+@item XMin
+Default value: @code{0}
+@item YMin
+Default value: @code{0}
+@item ZMin
+Default value: @code{0}
+@item XMax
+Default value: @code{0}
+@item YMax
+Default value: @code{0}
+@item ZMax
+Default value: @code{0}
 @end table
 
 @item Plugin(Isosurface)
diff --git a/src/plugin/Invisible.cpp b/src/plugin/Invisible.cpp
index ed2007cd2b..185421d36e 100644
--- a/src/plugin/Invisible.cpp
+++ b/src/plugin/Invisible.cpp
@@ -9,6 +9,12 @@
 StringXNumber InvisibleOptions_Number[] = {
   {GMSH_FULLRC, "DeleteElements", nullptr, 1.},
   {GMSH_FULLRC, "ReverseElements", nullptr, 0.},
+  {GMSH_FULLRC, "XMin", nullptr, 0.},
+  {GMSH_FULLRC, "YMin", nullptr, 0.},
+  {GMSH_FULLRC, "ZMin", nullptr, 0.},
+  {GMSH_FULLRC, "XMax", nullptr, 0.},
+  {GMSH_FULLRC, "YMax", nullptr, 0.},
+  {GMSH_FULLRC, "ZMax", nullptr, 0.}
 };
 
 extern "C" {
@@ -22,7 +28,10 @@ std::string GMSH_InvisiblePlugin::getHelp() const
 {
   return "Plugin(Invisible) deletes (if `DeleteElements' is set) or "
          "reverses (if `ReverseElements' is set) all the invisible elements in "
-         "the current model.";
+         "the current model. If the bounding box defined by `XMin' < x < `XMax, "
+         "`YMin' < y < `YMax and `ZMin' < z < `ZMax' is not empty, mark all "
+         "elements outside the bounding box as invisible prior to deleting or "
+         "inverting the elements.";
 }
 
 int GMSH_InvisiblePlugin::getNbOptions() const
@@ -37,10 +46,42 @@ StringXNumber *GMSH_InvisiblePlugin::getOption(int iopt)
 
 PView *GMSH_InvisiblePlugin::execute(PView *v)
 {
+  double xmin = InvisibleOptions_Number[2].def;
+  double ymin = InvisibleOptions_Number[3].def;
+  double zmin = InvisibleOptions_Number[4].def;
+  double xmax = InvisibleOptions_Number[5].def;
+  double ymax = InvisibleOptions_Number[6].def;
+  double zmax = InvisibleOptions_Number[7].def;
+
+  GModel *m = GModel::current();
+
+  if((xmax - xmin) > 0. || (ymax - ymin) > 0. || (zmax - zmin) > 0.) {
+    std::vector<GEntity *> entities;
+    m->getEntities(entities);
+    for(std::size_t i = 0; i < entities.size(); i++) {
+      for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
+        MElement *e = entities[i]->getMeshElement(j);
+        bool visible = false;
+        for(std::size_t k = 0; k < e->getNumVertices(); k++) {
+          MVertex *v = e->getVertex(k);
+          if(v->x() >= xmin && v->x() <= xmax &&
+             v->y() >= ymin && v->y() <= ymax &&
+             v->z() >= zmin && v->z() <= zmax) {
+            visible = true;
+            break;
+          }
+        }
+        if(!visible) {
+          e->setVisibility(0);
+        }
+      }
+    }
+  }
+
   if(InvisibleOptions_Number[0].def)
-    GModel::current()->removeInvisibleElements();
+    m->removeInvisibleElements();
   if(InvisibleOptions_Number[1].def)
-    GModel::current()->reverseInvisibleElements();
+    m->reverseInvisibleElements();
 
   return nullptr;
 }
-- 
GitLab