From: Marco Feder Date: Tue, 10 May 2022 16:50:04 +0000 (+0200) Subject: Add boolean operations between surface_meshes X-Git-Tag: v9.4.0-rc1~212^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d737e77ea7e33ddc51162d1157b5409a7ab95ad8;p=dealii.git Add boolean operations between surface_meshes --- diff --git a/doc/doxygen/images/boolean_difference.png b/doc/doxygen/images/boolean_difference.png new file mode 100644 index 0000000000..e9bd5b4932 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 index 0000000000..ee1d50d361 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 index 0000000000..283048372a 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 index 0000000000..a22295492a 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 index 0000000000..1b14580096 Binary files /dev/null and b/doc/doxygen/images/hedra_cube.png differ diff --git a/include/deal.II/cgal/utilities.h b/include/deal.II/cgal/utilities.h index b26cb32454..e485ecc630 100644 --- a/include/deal.II/cgal/utilities.h +++ b/include/deal.II/cgal/utilities.h @@ -27,6 +27,7 @@ # include # include # include +# include # include # include # include @@ -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 &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 + void + compute_boolean_operation( + const CGAL::Surface_mesh &surface_mesh_1, + const CGAL::Surface_mesh &surface_mesh_2, + const BooleanOperation & boolean_operation, + CGAL::Surface_mesh & output_surface_mesh); } // namespace CGALWrappers # ifndef DOXYGEN @@ -176,6 +226,56 @@ namespace CGALWrappers CGAL::parameters::no_perturb(), CGAL::parameters::no_exude()); } + + + + template + void + compute_boolean_operation( + const CGAL::Surface_mesh &surface_mesh_1, + const CGAL::Surface_mesh &surface_mesh_2, + const BooleanOperation & boolean_operation, + CGAL::Surface_mesh & 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 diff --git a/tests/cgal/cgal_surface_mesh_02.cc b/tests/cgal/cgal_surface_mesh_02.cc index f9a1d228d1..9ed9935628 100644 --- a/tests/cgal/cgal_surface_mesh_02.cc +++ b/tests/cgal/cgal_surface_mesh_02.cc @@ -43,6 +43,7 @@ using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; + void test() { @@ -50,6 +51,7 @@ test() "input_grids/tetrahedron.off"}; CGAL::Surface_mesh 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 index 0000000000..7bd01256c8 --- /dev/null +++ b/tests/cgal/cgal_surface_mesh_03.cc @@ -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 + +#include +#include + +#include +#include + +#include "../tests.h" + + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +using CGALPoint = CGAL::Point_3; +using namespace CGALWrappers; +void +test() +{ + const std::vector fnames{"input_grids/cube.off", + "input_grids/hedra.off"}; + CGAL::Surface_mesh 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 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 index 0000000000..ee1f419842 --- /dev/null +++ b/tests/cgal/cgal_surface_mesh_03.output @@ -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 index 0000000000..597be0e2f3 --- /dev/null +++ b/tests/cgal/input_grids/hedra.off @@ -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