Skip to content

Commit

Permalink
Add remesh_surface utility
Browse files Browse the repository at this point in the history
  • Loading branch information
fdrmrc committed May 22, 2022
1 parent a56c2ee commit 9107a93
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 4 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
97 changes: 97 additions & 0 deletions include/deal.II/cgal/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,19 @@
# include <CGAL/Mesh_criteria_3.h>
# include <CGAL/Mesh_triangulation_3.h>
# include <CGAL/Polygon_mesh_processing/corefinement.h>
# include <CGAL/Polygon_mesh_processing/remesh.h>
# include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
# include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
# include <CGAL/Simple_cartesian.h>
# include <CGAL/Surface_mesh.h>
# include <CGAL/Triangulation_3.h>
# include <CGAL/boost/graph/copy_face_graph.h>
# include <CGAL/boost/graph/selection.h>
# include <CGAL/make_mesh_3.h>
# include <CGAL/make_surface_mesh.h>
//# include <CGAL/tetrahedral_remeshing.h> REQUIRES CGAL_VERSION>=5.1.5

# include <fstream>
# include <type_traits>


Expand Down Expand Up @@ -198,6 +203,56 @@ namespace CGALWrappers
const CGAL::Surface_mesh<CGALPointType> &surface_mesh_2,
const BooleanOperation & boolean_operation,
CGAL::Surface_mesh<CGALPointType> & output_surface_mesh);

/**
* Remesh a CGAL::Surface_mesh.
*
* The optional variable arguments @p cgal_args can be used to pass additional
* arguments to the CGAL::Mesh_criteria_3 class (see
* https://doc.cgal.org/latest/Mesh_3/index.html) for more information.
*
* The arguments allow fine control on the size, quality, and distribution of
* the cells of the final triangulation. CGAL uses named parameters for these
* arguments, i.e., they must be specified with the syntax
* `CGAL::parameters::parameter_name=parameter_value`. Accepted parameters
* are:
*
* - CGAL::parameters::facet_angle,
* - CGAL::parameters::facet_size,
* - CGAL::parameters::facet_distance,
* - CGAL::parameters::cell_radius_edge_ratio,
* - CGAL::parameters::cell_size;
*
* If the domain has 1-dimensional exposed features, the criteria includes a
* sizing field to guide the sampling of 1-dimensional features with
* protecting balls centers.
* - CGAL::parameters::edge_size.
*
* This utility should be exploited to improve the quality of a mesh coming
* from boolean operations. As an example, consider two CGAL::Surface_mesh
* objects describing two hyper_spheres that intersect non-trivially. After
* computing their corefinement and union with compute_boolean_operation(),
* the resulting mesh is the following:
*
* @image html boolean_union_hyper_spheres.png
*
* Clearly, elements (triangles) like the ones arising along the intersection
* of the two spheres should be avoided as they're quite degenerate and would
* decrease the accuracy of the results. A call to the present function will
* try to remesh the surface, according to the given named parameters, to
* improve its quality. In the present case, the result is the following:
*
* @image html boolean_union_hyper_spheres_remeshed.png
*
* @param surface_mesh The input CGAL::Surface_mesh.
* @param out_surface_mesh The output CGAL::Surface_mesh.
* @param cgal_args Optional CGAL named parameters.
*/
template <typename CGALPointType, typename... Args>
void
remesh_surface(const CGAL::Surface_mesh<CGALPointType> &surface_mesh,
CGAL::Surface_mesh<CGALPointType> & out_surface_mesh,
Args... cgal_args);
} // namespace CGALWrappers

# ifndef DOXYGEN
Expand Down Expand Up @@ -330,6 +385,48 @@ namespace CGALWrappers
Assert(res,
ExcMessage("The boolean operation was not successfully computed."));
}



template <typename CGALPointType, typename... Args>
void
remesh_surface(CGAL::Surface_mesh<CGALPointType> &cgal_mesh,
Args... cgal_args)
{
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
using Mesh_domain = CGAL::Polyhedral_mesh_domain_with_features_3<K>;
// Polyhedron type
using Polyhedron = CGAL::Mesh_polyhedron_3<K>::type;
// Triangulation
using Tr = CGAL::Mesh_triangulation_3<Mesh_domain>::type;
using C3t3 =
CGAL::Mesh_complex_3_in_triangulation_3<Tr,
Mesh_domain::Corner_index,
Mesh_domain::Curve_index>;
// Criteria
using Mesh_criteria = CGAL::Mesh_criteria_3<Tr>;

Polyhedron poly;
CGAL::copy_face_graph(cgal_mesh, poly);
// Create a vector with only one element: the pointer to the
// polyhedron.
std::vector<Polyhedron *> poly_ptrs_vector(1, &poly);
// Create a polyhedral domain, with only one polyhedron,
// and no "bounding polyhedron", so the volumetric part of the
// domain will be empty.
Mesh_domain domain(poly_ptrs_vector.begin(), poly_ptrs_vector.end());
// Get sharp features
domain.detect_features(); // includes detection of borders
// Mesh criteria
Mesh_criteria criteria(cgal_args...);
// Mesh generation
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain,
criteria,
CGAL::parameters::no_perturb(),
CGAL::parameters::no_exude());
cgal_mesh.clear();
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, cgal_mesh);
}
} // namespace CGALWrappers
# endif

Expand Down
90 changes: 90 additions & 0 deletions tests/cgal/cgal_remesh_surface.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// ---------------------------------------------------------------------
//
// 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.
//
// ---------------------------------------------------------------------

// Remesh the union of two deal.II hyper_spheres in order to avoid bad
// triangles.

#include <deal.II/base/config.h>

#include <deal.II/base/point.h>

#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/grid/grid_tools.h>
#include <deal.II/grid/tria.h>

#include <deal.II/cgal/surface_mesh.h>
#include <deal.II/cgal/triangulation.h>
#include <deal.II/cgal/utilities.h>
#include <string.h>

#include "../tests.h"

using namespace CGALWrappers;
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
using CGALPoint = CGAL::Point_3<K>;
using CGALMesh = CGAL::Surface_mesh<CGALPoint>;

template <int dim, int spacedim>
void
test()
{
deallog << "dim= " << dim << ",\t spacedim= " << spacedim << std::endl;

Triangulation<spacedim> tria0, tria1;
Triangulation<2, 3> tria_out;
GridOut go;
CGALMesh surface_mesh0, surface_mesh1, out_mesh;

GridGenerator::hyper_ball(tria0, {0., 0., 0.}, 0.4);
GridGenerator::hyper_ball(tria1, {0.3, 0.3, 0.3}, 0.4);
tria0.refine_global(3);
tria1.refine_global(3);

// Move to CGAL surfaces
dealii_tria_to_cgal_surface_mesh(tria0, surface_mesh0);
dealii_tria_to_cgal_surface_mesh(tria1, surface_mesh1);

// close the surfaces
CGAL::Polygon_mesh_processing::stitch_borders(surface_mesh0);
CGAL::Polygon_mesh_processing::stitch_borders(surface_mesh1);

CGAL::Polygon_mesh_processing::triangulate_faces(surface_mesh0);
CGAL::Polygon_mesh_processing::triangulate_faces(surface_mesh1);

compute_boolean_operation(surface_mesh0,
surface_mesh1,
BooleanOperation::compute_union,
out_mesh);

remesh_surface<CGALPoint>(out_mesh,
CGAL::parameters::edge_size = 0.02,
CGAL::parameters::facet_angle = 25,
CGAL::parameters::facet_size = 0.05,
CGAL::parameters::facet_distance = 0.05);

// Now back to deal.II
cgal_surface_mesh_to_dealii_triangulation(out_mesh, tria_out);
std::ofstream out_name_spheres("remeshed_union_spheres.vtk");
go.write_vtk(tria_out, out_name_spheres);
deallog << "OK" << std::endl;
}

int
main()
{
initlog();
test<3, 3>();
}
3 changes: 3 additions & 0 deletions tests/cgal/cgal_remesh_surface.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

DEAL::dim= 3, spacedim= 3
DEAL::OK
8 changes: 4 additions & 4 deletions tests/cgal/cgal_surface_mesh_05.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ test()
out_mesh);
// Now back to deal.II
cgal_surface_mesh_to_dealii_triangulation(out_mesh, tria_out);
std::ofstream out_name_spheres("boolean_triangulation_spheres.vtk");
std::ofstream out_name_spheres("boolean_intersection_hyper_spheres.vtk");
go.write_vtk(tria_out, out_name_spheres);
deallog << "OK" << std::endl;
remove("tria_out.vtk");
remove("boolean_intersection_hyper_spheres.vtk");

// Clear everything
tria0.clear();
Expand Down Expand Up @@ -106,10 +106,10 @@ test()
out_mesh);
// Now back to deal.II
cgal_surface_mesh_to_dealii_triangulation(out_mesh, tria_out);
std::ofstream out_name_cubes("boolean_triangulation_cubes.vtk");
std::ofstream out_name_cubes("boolean_intersection_cubes.vtk");
go.write_vtk(tria_out, out_name_cubes);
remove("tria_out.vtk");
deallog << "OK" << std::endl;
remove("boolean_intersection_cubes.vtk");
}

int
Expand Down

0 comments on commit 9107a93

Please sign in to comment.