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::Sqrt3()`
- `CGAL::Subdivision_method_3::CatmullClark_subdivision()` - `CGAL::Subdivision_method_3::CatmullClark_subdivision()`
- `CGAL::Subdivision_method_3::Loop_subdivision()` - `CGAL::Subdivision_method_3::Loop_subdivision()`
- `CGAL::Subdivision_method_3::linear_subdivision()`
- `CGAL::Subdivision_method_3::DooSabin_subdivision()` - `CGAL::Subdivision_method_3::DooSabin_subdivision()`
- `CGAL::Subdivision_method_3::Sqrt3_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 `Polyhedron_3` and `Surface_mesh`, as they are models of the concept
`MutableFaceGraph`, and it aims to be easy to use and to extend. `MutableFaceGraph`, and it aims to be easy to use and to extend.
`Subdivision_method_3` is not a class, but a namespace `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 functions. These include Catmull-Clark, Loop, Doo-Sabin and
\f$ \sqrt{3}\f$ subdivisions. Variations of these methods can be easily \f$ \sqrt{3}\f$ subdivisions. Variations of these methods can be easily
extended by substituting the geometry computation of the refinement 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 `DooSabin_mask_3`, and `Sqrt3_mask_3` are
the best sources of learning these stencil interfaces. 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, `Subdivision_method_3` supports Catmull-Clark, Loop,
Doo-Sabin and \f$ \sqrt{3}\f$ subdivisions by specializing Doo-Sabin and \f$ \sqrt{3}\f$ subdivisions by specializing
their respective refinement hosts. 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` They are designed to work on any model of a `MutableFaceGraph`
such as `Polyhedron_3` and `Surface_mesh`. If your application such as `Polyhedron_3` and `Surface_mesh`. If your application
uses a polygon mesh with a specialized geometry kernel, you need to 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); 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> template <class PolygonMesh, class NamedParameters>
void DooSabin_subdivision(PolygonMesh& pmesh, NamedParameters np) { void DooSabin_subdivision(PolygonMesh& pmesh, NamedParameters np) {
DQQ(pmesh, DooSabin_mask_3<PolygonMesh>(pmesh), 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 \section Subdivision_method_3Other Example: Customizing a Subdivision Method
`Subdivision_method_3` supports four practical subdivision methods on a `Subdivision_method_3` supports four practical subdivision methods on a polyhedral mesh
`Polyhedron_3` with points with %Cartesian coordinates. More subdivision methods can be supported with points with %Cartesian coordinates. More subdivision methods can be supported
through the specialization of refinement hosts with custom geometry masks. through the specialization of refinement hosts with custom geometry masks.
The following example develops a subdivision method The following example develops a subdivision method
generating an improved Loop subdivision surface. 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`. * applies an subdivision several times on the control mesh `pmesh`.
* The geometry of the refined mesh is computed by the geometry policy mask `Upsample_mask_3`. * 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). * 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). * 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. * This function overwrites the control mesh `pmesh` with the subdivided mesh.
* @tparam PolygonMesh a model of `MutableFaceGraph` * @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. * \pre `pmesh` must be a triangle mesh.
**/ **/
template <class PolygonMesh, class NamedParameters = parameters::Default_named_parameters> 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::choose_parameter;
using parameters::get_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)); get_property_map(CGAL::vertex_point, pmesh));
unsigned int step = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 1); 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++) for(unsigned int i = 0; i < step; i++)
internal::PTQ_1step(pmesh, vpm, mask); internal::PTQ_1step(pmesh, vpm, mask);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING

View File

@ -265,6 +265,30 @@ void test_Subdivision_surface_3_SM_NP() {
assert(CGAL::is_valid_polygon_mesh(P)); 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 // test Doo-Sabin subdivision on 'opened' tri mesh
{ {
ifstream mesh(TESTMESH_TRI_OPEN); ifstream mesh(TESTMESH_TRI_OPEN);