Add linear_subdivision

This commit is contained in:
Mael Rouxel-Labbé 2025-02-20 11:09:29 +01:00
parent afcd45e39b
commit 3547db7787
4 changed files with 43 additions and 10 deletions

View File

@ -46,6 +46,7 @@ The page \ref bgl_namedparameters describes their usage.
- `CGAL::Subdivision_method_3::Sqrt3()`
- `CGAL::Subdivision_method_3::CatmullClark_subdivision()`
- `CGAL::Subdivision_method_3::Loop_subdivision()`
- `CGAL::Subdivision_method_3::linear_subdivision()`
- `CGAL::Subdivision_method_3::DooSabin_subdivision()`
- `CGAL::Subdivision_method_3::Sqrt3_subdivision()`

View File

@ -25,7 +25,7 @@ subdivision methods.
`Polyhedron_3` and `Surface_mesh`, as they are models of the concept
`MutableFaceGraph`, and it aims to be easy to use and to extend.
`Subdivision_method_3` is not a class, but a namespace
which contains four popular subdivision methods and their refinement
which contains popular subdivision methods and their refinement
functions. These include Catmull-Clark, Loop, Doo-Sabin and
\f$ \sqrt{3}\f$ subdivisions. Variations of these methods can be easily
extended by substituting the geometry computation of the refinement
@ -512,11 +512,13 @@ The source codes of `CatmullClark_mask_3`, `Loop_mask_3`,
`DooSabin_mask_3`, and `Sqrt3_mask_3` are
the best sources of learning these stencil interfaces.
\section Subdivision_method_3The The Four Subdivision Methods
\section Subdivision_method_3The Subdivision Methods
`Subdivision_method_3` supports Catmull-Clark, Loop,
Doo-Sabin and \f$ \sqrt{3}\f$ subdivisions by specializing
their respective refinement hosts.
In addition, a linear subdivision host is provided which
enable the user to perform an upsampling of a triangle mesh.
They are designed to work on any model of a `MutableFaceGraph`
such as `Polyhedron_3` and `Surface_mesh`. If your application
uses a polygon mesh with a specialized geometry kernel, you need to
@ -536,6 +538,11 @@ namespace Subdivision_method_3 {
PTQ(pmesh, Loop_mask_3<PolygonMesh>(pmesh) , np);
}
template <class PolygonMesh, class NamedParameters>
void linear_subdivision(PolygonMesh& pmesh, NamedParameters np) {
PTQ(pmesh, Linear_mask_3<PolygonMesh>(pmesh), np);
}
template <class PolygonMesh, class NamedParameters>
void DooSabin_subdivision(PolygonMesh& pmesh, NamedParameters np) {
DQQ(pmesh, DooSabin_mask_3<PolygonMesh>(pmesh), np);
@ -552,8 +559,8 @@ namespace Subdivision_method_3 {
\section Subdivision_method_3Other Example: Customizing a Subdivision Method
`Subdivision_method_3` supports four practical subdivision methods on a
`Polyhedron_3` with points with %Cartesian coordinates. More subdivision methods can be supported
`Subdivision_method_3` supports four practical subdivision methods on a polyhedral mesh
with points with %Cartesian coordinates. More subdivision methods can be supported
through the specialization of refinement hosts with custom geometry masks.
The following example develops a subdivision method
generating an improved Loop subdivision surface.

View File

@ -201,10 +201,10 @@ void Loop_subdivision(PolygonMesh& pmesh, const NamedParameters& np = parameters
/*!
*
* applies Upsample subdivision several times on the control mesh `pmesh`.
* The geometry of the refined mesh is computed by the geometry policy mask `Upsample_mask_3`.
* Which is similar to Loop subdivision but does not change the shape of the mesh (only the connectivity).
* The new vertices are trivially computed as the average of the incident vertices (midpoint of edge).
* applies an subdivision several times on the control mesh `pmesh`.
* The geometry of the refined mesh is computed by the geometry policy mask `Linear_mask_3`,
* which is similar to Loop subdivision but does not change the shape of the mesh (only the connectivity).
* The new vertices are trivially computed as the average of the incident vertices (e.g., midpoint of an edge).
* This function overwrites the control mesh `pmesh` with the subdivided mesh.
* @tparam PolygonMesh a model of `MutableFaceGraph`
@ -233,7 +233,7 @@ void Loop_subdivision(PolygonMesh& pmesh, const NamedParameters& np = parameters
* \pre `pmesh` must be a triangle mesh.
**/
template <class PolygonMesh, class NamedParameters = parameters::Default_named_parameters>
void Upsample_subdivision(PolygonMesh& pmesh, const NamedParameters& np = parameters::default_values()) {
void linear_subdivision(PolygonMesh& pmesh, const NamedParameters& np = parameters::default_values()) {
using parameters::choose_parameter;
using parameters::get_parameter;
@ -242,11 +242,12 @@ void Upsample_subdivision(PolygonMesh& pmesh, const NamedParameters& np = parame
get_property_map(CGAL::vertex_point, pmesh));
unsigned int step = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 1);
Upsample_mask_3<PolygonMesh,Vpm> mask(&pmesh, vpm);
Linear_mask_3<PolygonMesh,Vpm> mask(&pmesh, vpm);
for(unsigned int i = 0; i < step; i++)
internal::PTQ_1step(pmesh, vpm, mask);
}
// -----------------------------------------------------------------------------
#ifndef DOXYGEN_RUNNING

View File

@ -265,6 +265,30 @@ void test_Subdivision_surface_3_SM_NP() {
assert(CGAL::is_valid_polygon_mesh(P));
}
// test linear subdivision on tri mesh
{
ifstream mesh(TESTMESH_TRI);
Polyhedron P;
mesh >> P;
Subdivision_method_3::linear_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P))
.number_of_iterations(TEST_DEPTH));
assert(CGAL::is_valid_polygon_mesh(P));
}
// test linear subdivision on 'opened' tri mesh
{
ifstream mesh(TESTMESH_TRI_OPEN);
Polyhedron P;
mesh >> P;
Subdivision_method_3::linear_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P))
.number_of_iterations(TEST_DEPTH));
assert(CGAL::is_valid_polygon_mesh(P));
}
// test Doo-Sabin subdivision on 'opened' tri mesh
{
ifstream mesh(TESTMESH_TRI_OPEN);