Skip to content

Commit

Permalink
PMP::isotropic_remeshing - add variable sizing field (#4891)
Browse files Browse the repository at this point in the history
## Summary of Changes

This PR introduces the possibility to chose a variable sizing field for
isotropic remeshing.

## Release Management

* Affected package(s): PMP
* Feature/Small Feature (if any):
[Here](https://cgal.geometryfactory.com/CGAL/Members/wiki/Features/Small_Features/Curvature-adaptive_remeshing)
-- **pre-approval on 2023/10/24**
* Link to compiled documentation (obligatory for small feature) [*wrong
link name to be changed*](httpssss://wrong_URL_to_be_changed/Manual/Pkg)
* License and copyright ownership: unchanged
* Depends on #6760

## TODO:
- [x] check branch size (for @sloriot)
- [x] handle the update of the interpolated curvature branch (for
@sloriot)
  • Loading branch information
sloriot authored Nov 19, 2023
2 parents 472fa14 + 38482e8 commit 5c62ae4
Show file tree
Hide file tree
Showing 24 changed files with 1,947 additions and 455 deletions.
10 changes: 10 additions & 0 deletions Documentation/doc/biblio/cgal_manual.bib
Original file line number Diff line number Diff line change
Expand Up @@ -3106,6 +3106,16 @@ @article{ecvp-bhhhk-14
bibsource = {dblp computer science bibliography, https://dblp.org/}
}

@inproceedings {dunyach2013curvRemesh,
booktitle = {Eurographics 2013 - Short Papers},
title = {{Adaptive Remeshing for Real-Time Mesh Deformation}},
author = {Dunyach, Marion and Vanderhaeghe, David and Barthe, Loïc and Botsch, Mario},
year = {2013},
publisher = {The Eurographics Association},
ISSN = {1017-4656},
DOI = {10.2312/conf/EG2013/short/029-032}
}

@book{botsch2010PMP,
title={Polygon mesh processing},
author={M. Botsch and L. Kobbelt and M. Pauly and P. Alliez and B. L{\'e}vy},
Expand Down
2 changes: 1 addition & 1 deletion Documentation/doc/scripts/generate_how_to_cite.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def protect_upper_case(title):
return title.replace("dD","{dD}").replace("2D","{2D}").replace("3D","{3D}").replace("CGAL","{CGAL}").replace("Qt","{Qt}").replace("Boost","{Boost}")

def protect_accentuated_letters(authors):
res=authors.replace("é",r"{\'e}").replace("è",r"{\`e}").replace("É",r"{\'E}").replace("ä",r"{\"a}").replace("ö",r"{\"o}").replace("ñ",r"{\~n}").replace("ã",r"{\~a}").replace("ë",r"{\"e}").replace("ı",r"{\i}").replace("Ş",r"{\c{S}}").replace("ş",r"{\c{s}}").replace("%","")
res=authors.replace("é",r"{\'e}").replace("è",r"{\`e}").replace("É",r"{\'E}").replace("ä",r"{\"a}").replace("ö",r"{\"o}").replace("ñ",r"{\~n}").replace("ã",r"{\~a}").replace("ë",r"{\"e}").replace("ı",r"{\i}").replace("Ş",r"{\c{S}}").replace("ş",r"{\c{s}}").replace("%","").replace("đ",r"{\-d}")
try:
res.encode('ascii')
except UnicodeEncodeError:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/// \ingroup PkgPolygonMeshProcessingConcepts
/// \cgalConcept
///
/// The concept `PMPSizingField` defines the requirements for the sizing field
/// used in `CGAL::Polygon_mesh_processing::isotropic_remeshing()` to define
/// the target length for every individual edge during the remeshing process.
///
/// \cgalHasModelsBegin
/// \cgalHasModels{CGAL::Polygon_mesh_processing::Uniform_sizing_field}
/// \cgalHasModels{CGAL::Polygon_mesh_processing::Adaptive_sizing_field}
/// \cgalHasModelsEnd
///


class PMPSizingField{
public:

/// @name Types
/// @{

/// Vertex descriptor type
typedef boost::graph_traits<PolygonMesh>::vertex_descriptor vertex_descriptor;

/// Halfedge descriptor type
typedef boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;

/// 3D point type matching the value type of the vertex property map passed to `CGAL::Polygon_mesh_processing::isotropic_remeshing()`
typedef unspecified_type Point_3;

/// Polygon mesh type matching the type passed to `CGAL::Polygon_mesh_processing::isotropic_remeshing()`
typedef unspecified_type PolygonMesh;

/// Number type matching the `FT` type of the geometric traits passed to `CGAL::Polygon_mesh_processing::isotropic_remeshing()`
typedef unspecified_type FT;

/// @}

/// @name Functions
/// @{

/// a function that returns the sizing value at `v`.
FT at(const vertex_descriptor v) const;

/// a function controlling edge split and edge collapse,
/// returning the ratio of the current edge length and the local target edge length between
/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise.
std::optional<FT> is_too_long(const vertex_descriptor va,
const vertex_descriptor vb) const;

/// a function controlling edge collapse by returning the ratio of the squared length of `h` and the
/// local target edge length if it is too short, and `std::nullopt` otherwise.
std::optional<FT> is_too_short(const halfedge_descriptor h,
const PolygonMesh& pmesh) const;

/// a function returning the location of the split point of the edge of `h`.
Point_3 split_placement(const halfedge_descriptor h,
const PolygonMesh& pmesh) const;

/// a function that updates the sizing field value at the vertex `v`.
void update(const vertex_descriptor v,
const PolygonMesh& pmesh);

/// @}
};


Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/selfintersections.jpg \
${CGAL_PACKAGE_DOC_DIR}/fig/decimate_cheese.png \
${CGAL_PACKAGE_DOC_DIR}/fig/decimate_colors.png \
${CGAL_PACKAGE_DOC_DIR}/fig/decimate_rg_joint.png

Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
\cgalPkgPicture{hole_filling_ico.png}

\cgalPkgSummaryBegin
\cgalPkgAuthors{David Coeurjolly, Jaques-Olivier Lachaud, Konstantinos Katrioplas, Sébastien Loriot, Mael Rouxel-Labbé, Hossam Saeed, Jane Tournois, and Ilker %O. Yaz}
\cgalPkgAuthors{David Coeurjolly, Jaques-Olivier Lachaud, Konstantinos Katrioplas, Sébastien Loriot, Ivan Pađen, Mael Rouxel-Labbé, Hossam Saeed, Jane Tournois, and Ilker %O. Yaz}
\cgalPkgDesc{This package provides a collection of methods and classes for polygon mesh processing,
ranging from basic operations on simplices, to complex geometry processing algorithms such as
Boolean operations, remeshing, repairing, collision and intersection detection, and more.}
Expand Down Expand Up @@ -115,8 +115,6 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
- `CGAL::Polygon_mesh_processing::split()`

\cgalCRPSection{Meshing Functions}
- \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::isotropic_remeshing()` \endlink
- \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::split_long_edges()` \endlink
- `CGAL::Polygon_mesh_processing::remesh_planar_patches()`
- `CGAL::Polygon_mesh_processing::remesh_almost_planar_patches()`
- `CGAL::Polygon_mesh_processing::refine()`
Expand All @@ -134,6 +132,10 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
- `CGAL::Polygon_mesh_processing::smooth_shape()`
- `CGAL::Polygon_mesh_processing::random_perturbation()`

\cgalCRPSection{Sizing Fields}
- `CGAL::Polygon_mesh_processing::Uniform_sizing_field`
- `CGAL::Polygon_mesh_processing::Adaptive_sizing_field`

\cgalCRPSection{Orientation Functions}
- `CGAL::Polygon_mesh_processing::orient_polygon_soup()`
- `CGAL::Polygon_mesh_processing::orient()`
Expand Down Expand Up @@ -214,6 +216,7 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.

\cgalCRPSection{Corrected Curvatures}
- `CGAL::Polygon_mesh_processing::interpolated_corrected_curvatures()`
- `CGAL::Polygon_mesh_processing::Principal_curvatures_and_directions`

\cgalCRPSection{Normal Computation Functions}
- `CGAL::Polygon_mesh_processing::compute_face_normal()`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace CGAL {
\anchor Chapter_PolygonMeshProcessing

\cgalAutoToc
\authors David Coeurjolly, Jaques-Olivier Lachaud, Konstantinos Katrioplas, Sébastien Loriot, Mael Rouxel-Labbé, Hossam Saeed, Jane Tournois, and Ilker %O. Yaz
\authors David Coeurjolly, Jaques-Olivier Lachaud, Konstantinos Katrioplas, Sébastien Loriot, Ivan Pađen, Mael Rouxel-Labbé, Hossam Saeed, Jane Tournois, and Ilker %O. Yaz

\image html neptun_head.jpg
\image latex neptun_head.jpg
Expand Down Expand Up @@ -116,10 +116,18 @@ to the original surface to keep a good approximation of the input.

A triangulated region of a polygon mesh can be remeshed using the function
`CGAL::Polygon_mesh_processing::isotropic_remeshing()`, as illustrated
by \cgalFigureRef{iso_remeshing}. The algorithm has only two parameters :
the target edge length for the remeshed surface patch, and
the number of iterations of the abovementioned sequence of operations. The bigger
this number, the smoother and closer to target edge length the mesh will be.
by \cgalFigureRef{iso_remeshing}. The algorithm has two parameters:
the sizing field object for the remeshed surface patch, and
the number of iterations of the abovementioned sequence of operations.

The sizing field establishes the local target edge length for the remeshed surface. Two sizing fields are
provided: a uniform and a curvature-adaptive sizing field. With `CGAL::Polygon_mesh_processing::Uniform_sizing_field`,
all triangle edges are targeted to have equal lengths. With `CGAL::Polygon_mesh_processing::Adaptive_sizing_field`, triangle edge lengths depend on the local curvature --
shorter edges appear in regions with a higher curvature and vice versa. The outline of the adaptive sizing
field algorithm is available in \cgalCite{dunyach2013curvRemesh}. The distinction between uniform and adaptive
sizing fields is depicted in figure \cgalFigureRef{uniform_and_adaptive}.

As the number of iterations increases, the mesh tends to be smoother and closer to the target edge length.

An additional option has been added to \e protect (\e i.\e e. not modify) some given polylines.
In some cases, those polylines are too long, and reaching the desired target edge length while protecting them is not
Expand All @@ -134,6 +142,12 @@ Isotropic remeshing. (a) Triangulated input surface mesh.
(d) Surface mesh with the selection uniformly remeshed.
\cgalFigureEnd

\cgalFigureBegin{uniform_and_adaptive, uniform_and_adaptive.png}
Sizing fields in isotropic remeshing.
(a) Uniform sizing field.
(b) Curvature-based adaptive sizing field.
\cgalFigureEnd

\paragraph Delaunay-Based Surface Remeshing
The mesh generation algorithm implemented in the \ref PkgMesh3 package can be used to remesh a given triangulated surface mesh.
The algorithm, based on Delaunay refinement of a restricted Delaunay triangulation,
Expand Down Expand Up @@ -1287,5 +1301,7 @@ supervision of David Coeurjolly, Jaques-Olivier Lachaud, and Sébastien Loriot.
<a href="https://dgtal-team.github.io/doc-nightly/moduleCurvatureMeasures.html">DGtal's implementation</a> was also
used as a reference during the project.

The curvature-based sizing field version of isotropic remeshing was added by Ivan Pađen during GSoC 2023, under the supervision of Sébastien Loriot and Jane Tournois.

*/
} /* namespace CGAL */
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ if(TARGET CGAL::Eigen3_support)
target_link_libraries(hole_filling_example_LCC PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("mesh_smoothing_example.cpp")
target_link_libraries(mesh_smoothing_example PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("isotropic_remeshing_with_sizing_example.cpp")
target_link_libraries(isotropic_remeshing_with_sizing_example PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("delaunay_remeshing_example.cpp")
target_link_libraries(delaunay_remeshing_example PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("remesh_almost_planar_patches.cpp")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h>

#include <fstream>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;

namespace PMP = CGAL::Polygon_mesh_processing;

int main(int argc, char* argv[])
{
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/nefertiti.off");

Mesh mesh;
if (!PMP::IO::read_polygon_mesh(filename, mesh) || !CGAL::is_triangle_mesh(mesh)) {
std::cerr << "Not a valid input file." << std::endl;
return 1;
}

std::cout << "Start remeshing of " << filename
<< " (" << num_faces(mesh) << " faces)..." << std::endl;

const double tol = 0.001;
const std::pair edge_min_max{0.001, 0.5};
PMP::Adaptive_sizing_field<Mesh> sizing_field(tol, edge_min_max, faces(mesh), mesh);
unsigned int nb_iter = 5;

PMP::isotropic_remeshing(
faces(mesh),
sizing_field,
mesh,
CGAL::parameters::number_of_iterations(nb_iter)
.number_of_relaxation_steps(3)
);

CGAL::IO::write_polygon_mesh("out.off", mesh, CGAL::parameters::stream_precision(17));

std::cout << "Remeshing done." << std::endl;

return 0;
}
Loading

0 comments on commit 5c62ae4

Please sign in to comment.