Merge pull request #7801 from janetournois/Tet_remeshing-improve_doc-jtournois

Tetrahedral_remeshing - Doc improvements
This commit is contained in:
Laurent Rineau 2023-11-06 12:40:00 +01:00
commit bf2c798561
4 changed files with 75 additions and 51 deletions

View File

@ -70,6 +70,10 @@ The only required parameter is a given target edge length that drives the remesh
towards a high-quality tetrahedral mesh with improved dihedral angles, and a more
uniform mesh, with edge lengths getting closer to the input parameter value.
By default, the cells with a non-zero `Subdomain_index` are
selected for remeshing. The cells with `Subdomain_index` equal to zero
are ignored by the remeshing algorithm.
\cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_example.cpp }
@ -81,6 +85,10 @@ control on the remeshing process. In this example, a triangulation with two subd
(defined by the `Subdomain_index` 2)
of its subdomains is remeshed.
Only the cells with a non-zero `Subdomain_index` will be remeshed.
The named parameter `cell_is_selected_map` can be used to change this
behavior.
\cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_of_one_subdomain.cpp }

View File

@ -19,7 +19,12 @@ int main(int argc, char* argv[])
const std::size_t nbv = (argc > 2) ? atoi(argv[2]) : 1000;
Remeshing_triangulation tr;
CGAL::Tetrahedral_remeshing::generate_input_one_subdomain(nbv, tr);
CGAL::Tetrahedral_remeshing::insert_random_points_in_cube(nbv, tr);
/// A subdomain index 0 is considered outside and is not remeshed
/// so we set finite cells to a non-zero `Subdomain_index`
for (auto cell : tr.finite_cell_handles())
cell->set_subdomain_index(1);
CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length);

View File

@ -22,40 +22,9 @@ namespace CGAL
namespace Tetrahedral_remeshing
{
template<typename Tr>
void generate_input_two_subdomains(const std::size_t& nbv, Tr& tr)
void insert_random_points_in_cube(const std::size_t& nbv, Tr& tr)
{
CGAL::Random rng;
typedef typename Tr::Point Point;
typedef typename Tr::Cell_handle Cell_handle;
while (tr.number_of_vertices() < nbv)
tr.insert(Point(rng.get_double(-1., 1.), rng.get_double(-1., 1.), rng.get_double(-1., 1.)));
using P = typename Tr::Geom_traits::Point_3;
const typename Tr::Geom_traits::Plane_3
plane(P(0, 0, 0), P(0, 1, 0), P(0, 0, 1));
for (Cell_handle c : tr.finite_cell_handles())
{
if (plane.has_on_positive_side(
CGAL::centroid(P(c->vertex(0)->point()),
P(c->vertex(1)->point()),
P(c->vertex(2)->point()),
P(c->vertex(3)->point()))))
c->set_subdomain_index(1);
else
c->set_subdomain_index(2);
}
assert(tr.is_valid(true));
}
template<typename Tr>
void generate_input_one_subdomain(const std::size_t nbv, Tr& tr)
{
CGAL::Random rng;
typedef typename Tr::Point Point;
std::vector<Point> pts;
while (pts.size() < nbv)
@ -67,11 +36,23 @@ namespace Tetrahedral_remeshing
pts.push_back(Point(x, y, z));
}
tr.insert(pts.begin(), pts.end());
}
for (typename Tr::Cell_handle c : tr.finite_cell_handles())
c->set_subdomain_index(1);
template<typename Plane, typename Tr>
void insert_points_on_plane(const Plane& plane, const std::size_t& nbv, Tr& tr)
{
CGAL::Random rng;
typedef typename Tr::Point Point;
std::vector<Point> pts;
while (pts.size() < nbv)
{
const double x = rng.get_double(-1., 1.);
const double y = rng.get_double(-1., 1.);
const double z = rng.get_double(-1., 1.);
assert(tr.is_valid(true));
pts.push_back(plane.projection(Point(x, y, z)));
}
tr.insert(pts.begin(), pts.end());
}
template<typename Tr>

View File

@ -5,29 +5,22 @@
#include "tetrahedral_remeshing_generate_input.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3<K> Remeshing_triangulation;
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
using Remeshing_triangulation = CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3<K>;
using Subdomain_index = Remeshing_triangulation::Tds::Cell::Subdomain_index;
template<typename Tr>
struct Cells_of_subdomain_pmap
{
private:
using Cell_handle = typename Tr::Cell_handle;
const int m_subdomain;
public:
using key_type = Cell_handle;
using key_type = typename Tr::Cell_handle;
using value_type = bool;
using reference = bool;
using category = boost::read_write_property_map_tag;
Cells_of_subdomain_pmap(const int& subdomain)
: m_subdomain(subdomain)
{}
friend value_type get(const Cells_of_subdomain_pmap& map,
const key_type& c)
{
@ -41,17 +34,54 @@ public:
}
};
Subdomain_index subdomain_on_side_of_plane(const K::Point_3& p,
const K::Plane_3& plane)
{
if (plane.has_on_positive_side(p))
return 1;
else
return 2;
}
K::Point_3 centroid(const Remeshing_triangulation::Cell_handle c)
{
return CGAL::centroid(c->vertex(0)->point(),
c->vertex(1)->point(),
c->vertex(2)->point(),
c->vertex(3)->point());
}
int main(int argc, char* argv[])
{
const double target_edge_length = (argc > 1) ? atof(argv[1]) : 0.1;
const double target_edge_length = (argc > 1) ? atof(argv[1]) : 0.05;
const std::size_t nbv = (argc > 2) ? atoi(argv[2]) : 1000;
const std::size_t nbv_on_plane = (argc > 3) ? atoi(argv[3]) : 100;
/// Create a randomly generated triangulation of a sphere
Remeshing_triangulation tr;
CGAL::Tetrahedral_remeshing::generate_input_two_subdomains(nbv, tr);
CGAL::Tetrahedral_remeshing::insert_random_points_in_cube(nbv, tr);
CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length,
/// Use vertical plane to split the mesh into two subdomains
const K::Plane_3 plane(0, 0, 1, 0);
CGAL::Tetrahedral_remeshing::insert_points_on_plane(plane, nbv_on_plane, tr);
/// A subdomain index 0 is considered outside and is not remeshed
/// so we set finite cells to a non-zero `Subdomain_index`
/// (depending on the side of the plane they are on)
for (auto cell : tr.finite_cell_handles())
{
const K::Point_3 cc = centroid(cell);
cell->set_subdomain_index(subdomain_on_side_of_plane(cc, plane));
}
/// Remesh only the cells of subdomain 2
CGAL::tetrahedral_isotropic_remeshing(tr,
target_edge_length,
CGAL::parameters::cell_is_selected_map(
Cells_of_subdomain_pmap<Remeshing_triangulation>(2)));
Cells_of_subdomain_pmap<Remeshing_triangulation>{2}));
std::ofstream os("out.mesh");
CGAL::IO::write_MEDIT(os, tr);
return EXIT_SUCCESS;
}