]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add boolean operations between surface_meshes
authorMarco Feder <marco.feder@sissa.it>
Tue, 10 May 2022 16:50:04 +0000 (18:50 +0200)
committerMarco Feder <marco.feder@sissa.it>
Sun, 15 May 2022 09:23:27 +0000 (11:23 +0200)
doc/doxygen/images/boolean_difference.png [new file with mode: 0644]
doc/doxygen/images/boolean_intersection.png [new file with mode: 0644]
doc/doxygen/images/boolean_union.png [new file with mode: 0644]
doc/doxygen/images/corefinement.png [new file with mode: 0644]
doc/doxygen/images/hedra_cube.png [new file with mode: 0644]
include/deal.II/cgal/utilities.h
tests/cgal/cgal_surface_mesh_02.cc
tests/cgal/cgal_surface_mesh_03.cc [new file with mode: 0644]
tests/cgal/cgal_surface_mesh_03.output [new file with mode: 0644]
tests/cgal/input_grids/hedra.off [new file with mode: 0644]

diff --git a/doc/doxygen/images/boolean_difference.png b/doc/doxygen/images/boolean_difference.png
new file mode 100644 (file)
index 0000000..e9bd5b4
Binary files /dev/null and b/doc/doxygen/images/boolean_difference.png differ
diff --git a/doc/doxygen/images/boolean_intersection.png b/doc/doxygen/images/boolean_intersection.png
new file mode 100644 (file)
index 0000000..ee1d50d
Binary files /dev/null and b/doc/doxygen/images/boolean_intersection.png differ
diff --git a/doc/doxygen/images/boolean_union.png b/doc/doxygen/images/boolean_union.png
new file mode 100644 (file)
index 0000000..2830483
Binary files /dev/null and b/doc/doxygen/images/boolean_union.png differ
diff --git a/doc/doxygen/images/corefinement.png b/doc/doxygen/images/corefinement.png
new file mode 100644 (file)
index 0000000..a222954
Binary files /dev/null and b/doc/doxygen/images/corefinement.png differ
diff --git a/doc/doxygen/images/hedra_cube.png b/doc/doxygen/images/hedra_cube.png
new file mode 100644 (file)
index 0000000..1b14580
Binary files /dev/null and b/doc/doxygen/images/hedra_cube.png differ
index b26cb3245431bd445d659fd41383d3ad0ffe1a2d..e485ecc6302943b4006c623e5441154f69554dcb 100644 (file)
@@ -27,6 +27,7 @@
 #  include <CGAL/Mesh_complex_3_in_triangulation_3.h>
 #  include <CGAL/Mesh_criteria_3.h>
 #  include <CGAL/Mesh_triangulation_3.h>
+#  include <CGAL/Polygon_mesh_processing/corefinement.h>
 #  include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
 #  include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
 #  include <CGAL/Simple_cartesian.h>
@@ -60,6 +61,16 @@ namespace CGALWrappers
   using ConcurrencyTag = CGAL::Sequential_tag;
 #  endif
 
+  enum class BooleanOperation
+  {
+    compute_corefinement = 1 << 0, ///< Corefine the two surfaces
+    compute_difference   = 1 << 1, ///< Compute the boolean difference of the
+                                   ///< first input argument minus the second
+    compute_intersection =
+      1 << 2,               ///< Compute the intersection of the input arguments
+    compute_union = 1 << 3, ///< Compute the union of the input arguments
+  };
+
   /**
    * Convert from deal.II Point to any compatible CGAL point.
    *
@@ -103,6 +114,45 @@ namespace CGALWrappers
   cgal_surface_mesh_to_cgal_coarse_triangulation(
     CGAL::Surface_mesh<typename C3t3::Point::Point> &surface_mesh,
     C3t3 &                                           triangulation);
+
+  /**
+   * Given two triangulated surface meshes, execute a boolean operation on them,
+   * and store the result in another surface mesh.
+   *
+   * The corefinement of two triangulated surface meshes can naturally be used
+   * for computing Boolean operations on the volumes bounded by surfaces,
+   * according to the chosen BooleanOperation. See BooleanOperation for a list
+   * of available operations. As an example consider the following case with a
+   * cube and the green polyhedron.
+   *
+   * @image html hedra_cube.png
+   *
+   * The shaded regions in the following show the results of the intersection,
+   * union, difference and corefinement between a cube and the green polyhedron.
+   *
+   * @image html boolean_intersection.png
+   * @image html boolean_union.png
+   * @image html boolean_difference.png
+   * @image html corefinement.png
+   *
+   * See the CGAL documentation for an extended discussion and several examples:
+   * https://doc.cgal.org/latest/Polygon_mesh_processing/index.html#title14
+   *
+   * @param[in] surface_mesh_1 The first surface mesh.
+   * @param[in] surface_mesh_2 The second surface mesh.
+   * @param[in] boolean_operation See BooleanOperation for the list of the
+   * allowed operations.
+   * @param[out] output_surface_mesh The surface mesh with the result of
+   * the boolean operation. Notice that in case of corefinement only, the
+   * corefined mesh will be the first one.
+   */
+  template <typename CGALPointType>
+  void
+  compute_boolean_operation(
+    const CGAL::Surface_mesh<CGALPointType> &surface_mesh_1,
+    const CGAL::Surface_mesh<CGALPointType> &surface_mesh_2,
+    const BooleanOperation &                 boolean_operation,
+    CGAL::Surface_mesh<CGALPointType> &      output_surface_mesh);
 } // namespace CGALWrappers
 
 #  ifndef DOXYGEN
@@ -176,6 +226,56 @@ namespace CGALWrappers
                                             CGAL::parameters::no_perturb(),
                                             CGAL::parameters::no_exude());
   }
+
+
+
+  template <typename CGALPointType>
+  void
+  compute_boolean_operation(
+    const CGAL::Surface_mesh<CGALPointType> &surface_mesh_1,
+    const CGAL::Surface_mesh<CGALPointType> &surface_mesh_2,
+    const BooleanOperation &                 boolean_operation,
+    CGAL::Surface_mesh<CGALPointType> &      output_surface_mesh)
+  {
+    Assert(
+      output_surface_mesh.is_empty() && CGAL::is_closed(surface_mesh_1) &&
+        CGAL::is_closed(surface_mesh_2),
+      ExcMessage(
+        "The output surface_mesh must be empty upon calling this function"));
+    bool res      = false;
+    auto surf_1   = surface_mesh_1;
+    auto surf_2   = surface_mesh_2;
+    namespace PMP = CGAL::Polygon_mesh_processing;
+    switch (boolean_operation)
+      {
+        case BooleanOperation::compute_union:
+          res = PMP::corefine_and_compute_union(surf_1,
+                                                surf_2,
+                                                output_surface_mesh);
+          break;
+        case BooleanOperation::compute_intersection:
+          res = PMP::corefine_and_compute_intersection(surf_1,
+                                                       surf_2,
+                                                       output_surface_mesh);
+          break;
+        case BooleanOperation::compute_difference:
+          res = PMP::corefine_and_compute_difference(surf_1,
+                                                     surf_2,
+                                                     output_surface_mesh);
+          break;
+        case BooleanOperation::compute_corefinement:
+          PMP::corefine(surf_1,
+                        surf_2); // both surfaces are corefined
+          output_surface_mesh = std::move(surf_1);
+          res                 = true;
+          break;
+        default:
+          output_surface_mesh.clear();
+          break;
+      }
+    Assert(res,
+           ExcMessage("The boolean operation was not succesfully computed."));
+  }
 } // namespace CGALWrappers
 #  endif
 
index f9a1d228d1bf27efbf6a65b3042ab2dce67f5732..9ed9935628006117f45ca4b7d9336598a849baba 100644 (file)
@@ -43,6 +43,7 @@ using C3t3          = CGAL::Mesh_complex_3_in_triangulation_3<Tr,
                                                      Mesh_domain::Corner_index,
                                                      Mesh_domain::Curve_index>;
 
+
 void
 test()
 {
@@ -50,6 +51,7 @@ test()
                                         "input_grids/tetrahedron.off"};
   CGAL::Surface_mesh<CGALPoint>  sm;
   C3t3                           tria;
+
   for (const auto &name : fnames)
     {
       std::ifstream input(name);
diff --git a/tests/cgal/cgal_surface_mesh_03.cc b/tests/cgal/cgal_surface_mesh_03.cc
new file mode 100644 (file)
index 0000000..7bd0125
--- /dev/null
@@ -0,0 +1,67 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2022 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+// Perform corefinement and boolean operations between surface_meshes.
+
+#include <deal.II/base/config.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria.h>
+
+#include <CGAL/IO/io.h>
+#include <deal.II/cgal/utilities.h>
+
+#include "../tests.h"
+
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+using CGALPoint = CGAL::Point_3<K>;
+using namespace CGALWrappers;
+void
+test()
+{
+  const std::vector<std::string> fnames{"input_grids/cube.off",
+                                        "input_grids/hedra.off"};
+  CGAL::Surface_mesh<CGALPoint>  sm0, sm1, outsm;
+  std::ifstream                  input0(fnames[0]);
+  std::ifstream                  input1(fnames[1]);
+  input0 >> sm0;
+  input1 >> sm1;
+  CGAL::Polygon_mesh_processing::triangulate_faces(sm0);
+  CGAL::Polygon_mesh_processing::triangulate_faces(sm1);
+  const std::vector<BooleanOperation> bool_operations{
+    BooleanOperation::compute_union,
+    BooleanOperation::compute_intersection,
+    BooleanOperation::compute_difference,
+    BooleanOperation::compute_corefinement};
+
+  for (const auto &bool_op : bool_operations)
+    {
+      compute_boolean_operation(sm0, sm1, bool_op, outsm);
+      Assert((outsm.is_valid() && sm0.is_valid() && sm1.is_valid()),
+             ExcMessage("Result is not valid."));
+      // Uncomment the following to have print the meshes
+      deallog << outsm << std::endl;
+      // Clear surface
+      outsm.clear();
+    }
+}
+
+int
+main()
+{
+  initlog();
+  test();
+}
diff --git a/tests/cgal/cgal_surface_mesh_03.output b/tests/cgal/cgal_surface_mesh_03.output
new file mode 100644 (file)
index 0000000..ee1f419
--- /dev/null
@@ -0,0 +1,379 @@
+
+DEAL::OFF
+38 72 0
+1.00000 -0.271570 1.00000
+1.00000 -0.271570 0.271570
+1.00000 -0.271570 -1.00000
+0.271570 -0.271570 -1.00000
+-1.00000 -0.271570 -1.00000
+-1.00000 -0.271570 0.271570
+-1.00000 -0.271570 1.00000
+-0.271570 -0.271570 1.00000
+1.00000 0.271570 1.00000
+1.00000 0.271570 -0.271570
+1.00000 0.271570 -1.00000
+-0.271570 0.271570 -1.00000
+-1.00000 0.271570 -1.00000
+-1.00000 0.271570 -0.271570
+-1.00000 0.271570 1.00000
+0.271570 0.271570 1.00000
+-0.485001 1.00000 -0.485001
+0.485001 1.00000 -0.485001
+0.485001 1.00000 0.485001
+-0.485001 1.00000 0.485001
+0.485001 -1.00000 -0.485001
+0.485001 -1.00000 0.485001
+-0.485001 -1.00000 0.485001
+-0.485001 -1.00000 -0.485001
+-1.00000 1.00000 1.00000
+-1.00000 1.00000 -1.00000
+1.00000 1.00000 -1.00000
+1.00000 1.00000 1.00000
+-1.00000 -1.00000 1.00000
+-1.00000 -1.00000 -1.00000
+1.00000 -1.00000 1.00000
+1.00000 -1.00000 -1.00000
+-1.19200 0.00000 1.19200
+1.19200 0.00000 1.19200
+-1.19200 0.00000 -1.19200
+1.19200 0.00000 -1.19200
+0.00000 -1.68600 0.00000
+0.00000 1.68600 0.00000
+3 13 24 25
+3 18 24 27
+3 16 17 25
+3 9 10 26
+3 10 11 26
+3 11 25 26
+3 14 24 13
+3 24 14 15
+3 24 15 27
+3 27 15 8
+3 27 8 9
+3 27 9 26
+3 11 12 25
+3 24 18 19
+3 24 19 25
+3 25 19 16
+3 25 12 13
+3 26 25 17
+3 26 17 27
+3 27 17 18
+3 20 23 31
+3 22 30 28
+3 2 1 31
+3 1 30 31
+3 3 2 31
+3 6 5 28
+3 28 7 6
+3 30 0 7
+3 30 7 28
+3 30 1 0
+3 4 3 29
+3 3 31 29
+3 29 31 23
+3 29 23 28
+3 28 23 22
+3 29 5 4
+3 28 5 29
+3 30 22 21
+3 30 21 31
+3 31 21 20
+3 10 9 35
+3 4 5 34
+3 7 33 32
+3 7 0 33
+3 6 7 32
+3 34 32 13
+3 32 14 13
+3 34 13 12
+3 6 32 5
+3 5 32 34
+3 32 33 15
+3 33 8 15
+3 32 15 14
+3 8 33 9
+3 9 33 35
+3 35 33 1
+3 33 0 1
+3 35 1 2
+3 35 2 3
+3 35 3 34
+3 34 3 4
+3 35 34 11
+3 34 12 11
+3 35 11 10
+3 21 22 36
+3 22 23 36
+3 36 20 21
+3 36 23 20
+3 37 16 19
+3 37 19 18
+3 18 17 37
+3 37 17 16
+
+DEAL::OFF
+24 44 0
+1.00000 -0.271570 1.00000
+1.00000 -0.271570 0.271570
+1.00000 -0.271570 -1.00000
+0.271570 -0.271570 -1.00000
+-1.00000 -0.271570 -1.00000
+-1.00000 -0.271570 0.271570
+-1.00000 -0.271570 1.00000
+-0.271570 -0.271570 1.00000
+1.00000 0.271570 1.00000
+1.00000 0.271570 -0.271570
+1.00000 0.271570 -1.00000
+-0.271570 0.271570 -1.00000
+-1.00000 0.271570 -1.00000
+-1.00000 0.271570 -0.271570
+-1.00000 0.271570 1.00000
+0.271570 0.271570 1.00000
+-0.485001 1.00000 -0.485001
+0.485001 1.00000 -0.485001
+0.485001 1.00000 0.485001
+-0.485001 1.00000 0.485001
+0.485001 -1.00000 -0.485001
+0.485001 -1.00000 0.485001
+-0.485001 -1.00000 0.485001
+-0.485001 -1.00000 -0.485001
+3 4 11 3
+3 10 3 11
+3 13 4 5
+3 2 9 1
+3 1 9 8
+3 15 7 0
+3 7 15 14
+3 9 2 10
+3 3 10 2
+3 14 13 5
+3 6 14 5
+3 6 7 14
+3 8 15 0
+3 0 1 8
+3 11 4 12
+3 13 12 4
+3 23 20 22
+3 21 22 20
+3 19 18 16
+3 17 16 18
+3 23 4 3
+3 6 22 7
+3 21 20 1
+3 21 7 22
+3 21 0 7
+3 22 6 5
+3 23 22 5
+3 23 5 4
+3 1 20 2
+3 1 0 21
+3 20 23 3
+3 3 2 20
+3 19 16 13
+3 16 17 11
+3 18 19 15
+3 13 16 12
+3 13 14 19
+3 15 19 14
+3 15 8 18
+3 18 8 9
+3 17 18 9
+3 17 9 10
+3 11 17 10
+3 11 12 16
+
+DEAL::OFF
+32 64 0
+1.00000 -0.271570 1.00000
+1.00000 -0.271570 0.271570
+1.00000 -0.271570 -1.00000
+0.271570 -0.271570 -1.00000
+-1.00000 -0.271570 -1.00000
+-1.00000 -0.271570 0.271570
+-1.00000 -0.271570 1.00000
+-0.271570 -0.271570 1.00000
+1.00000 0.271570 1.00000
+1.00000 0.271570 -0.271570
+1.00000 0.271570 -1.00000
+-0.271570 0.271570 -1.00000
+-1.00000 0.271570 -1.00000
+-1.00000 0.271570 -0.271570
+-1.00000 0.271570 1.00000
+0.271570 0.271570 1.00000
+-0.485001 1.00000 -0.485001
+0.485001 1.00000 -0.485001
+0.485001 1.00000 0.485001
+-0.485001 1.00000 0.485001
+0.485001 -1.00000 -0.485001
+0.485001 -1.00000 0.485001
+-0.485001 -1.00000 0.485001
+-0.485001 -1.00000 -0.485001
+-1.00000 1.00000 1.00000
+-1.00000 1.00000 -1.00000
+1.00000 1.00000 -1.00000
+1.00000 1.00000 1.00000
+-1.00000 -1.00000 1.00000
+-1.00000 -1.00000 -1.00000
+1.00000 -1.00000 1.00000
+1.00000 -1.00000 -1.00000
+3 13 24 25
+3 18 24 27
+3 16 17 25
+3 9 10 26
+3 10 11 26
+3 11 25 26
+3 14 24 13
+3 24 14 15
+3 24 15 27
+3 27 15 8
+3 27 8 9
+3 27 9 26
+3 11 12 25
+3 24 18 19
+3 24 19 25
+3 25 19 16
+3 25 12 13
+3 26 25 17
+3 26 17 27
+3 27 17 18
+3 20 23 31
+3 22 30 28
+3 2 1 31
+3 1 30 31
+3 3 2 31
+3 6 5 28
+3 28 7 6
+3 30 0 7
+3 30 7 28
+3 30 1 0
+3 4 3 29
+3 3 31 29
+3 29 31 23
+3 29 23 28
+3 28 23 22
+3 29 5 4
+3 28 5 29
+3 30 22 21
+3 30 21 31
+3 31 21 20
+3 3 4 23
+3 7 22 6
+3 1 20 21
+3 22 7 21
+3 7 0 21
+3 5 6 22
+3 5 22 23
+3 4 5 23
+3 2 20 1
+3 21 0 1
+3 3 23 20
+3 20 2 3
+3 13 16 19
+3 11 17 16
+3 15 19 18
+3 12 16 13
+3 19 14 13
+3 14 19 15
+3 18 8 15
+3 9 8 18
+3 9 18 17
+3 10 9 17
+3 10 17 11
+3 16 12 11
+
+DEAL::OFF
+32 60 0
+-1.00000 -1.00000 -1.00000
+-1.00000 1.00000 -1.00000
+1.00000 1.00000 -1.00000
+1.00000 -1.00000 -1.00000
+-1.00000 -1.00000 1.00000
+-1.00000 1.00000 1.00000
+1.00000 1.00000 1.00000
+1.00000 -1.00000 1.00000
+-1.00000 -0.271570 -1.00000
+-1.00000 0.271570 -1.00000
+0.271570 0.271570 1.00000
+-0.271570 -0.271570 1.00000
+-1.00000 -0.271570 0.271570
+-1.00000 0.271570 -0.271570
+1.00000 0.271570 -1.00000
+1.00000 -0.271570 -1.00000
+0.485001 -1.00000 -0.485001
+-0.485001 -1.00000 0.485001
+1.00000 0.271570 -0.271570
+1.00000 -0.271570 0.271570
+0.485001 1.00000 0.485001
+-0.485001 1.00000 -0.485001
+-0.271570 0.271570 -1.00000
+0.271570 -0.271570 -1.00000
+-1.00000 -0.271570 1.00000
+-1.00000 0.271570 1.00000
+1.00000 0.271570 1.00000
+1.00000 -0.271570 1.00000
+-0.485001 -1.00000 -0.485001
+-0.485001 1.00000 0.485001
+0.485001 1.00000 -0.485001
+0.485001 -1.00000 0.485001
+3 8 22 23
+3 14 23 22
+3 13 8 12
+3 13 5 1
+3 15 18 19
+3 19 18 26
+3 16 28 3
+3 17 7 4
+3 10 11 27
+3 11 10 25
+3 20 5 6
+3 21 30 1
+3 18 15 14
+3 18 14 2
+3 15 19 3
+3 19 7 3
+3 23 14 15
+3 23 15 3
+3 14 22 2
+3 22 1 2
+3 25 13 12
+3 24 12 4
+3 24 25 12
+3 25 5 13
+3 5 25 10
+3 24 11 25
+3 5 10 6
+3 4 11 24
+3 7 27 11
+3 26 10 27
+3 7 11 4
+3 6 10 26
+3 6 26 18
+3 27 19 26
+3 6 18 2
+3 7 19 27
+3 22 8 9
+3 22 9 1
+3 8 23 0
+3 23 3 0
+3 0 3 28
+3 0 28 4
+3 28 16 17
+3 4 28 17
+3 5 20 29
+3 5 29 1
+3 29 20 21
+3 1 29 21
+3 0 12 8
+3 13 9 8
+3 4 12 0
+3 1 9 13
+3 2 1 30
+3 2 30 6
+3 30 21 20
+3 6 30 20
+3 7 17 31
+3 7 31 3
+3 31 17 16
+3 3 31 16
+
diff --git a/tests/cgal/input_grids/hedra.off b/tests/cgal/input_grids/hedra.off
new file mode 100644 (file)
index 0000000..597be0e
--- /dev/null
@@ -0,0 +1,16 @@
+OFF
+6 8 0
+0.000000 1.686000 0.000000
+1.192000 0.000000 -1.192000
+-1.192000 0.000000 -1.192000
+-1.192000 0.000000 1.192000
+1.192000 0.000000 1.192000
+0.000000 -1.686000 0.000000
+3 0 4 1 
+3 1 5 2 
+3 2 3 0 
+3 3 5 4 
+3 1 2 0 
+3 3 4 0 
+3 4 5 1 
+3 3 2 5 
\ No newline at end of file

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.