Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions to compute discrete curvatures #6088

Merged
merged 28 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ef8cd29
add functions to compute discrete curvature
sloriot Oct 28, 2021
da3179a
remove debug variable
sloriot Oct 28, 2021
2b7246a
handle border cases
sloriot Oct 28, 2021
8a52d7c
remove unused function
sloriot Oct 29, 2021
80ff6bf
add display for discrete mean and gaussian curvature
sloriot Oct 29, 2021
0fe9405
Fix namespace
MaelRL Dec 7, 2024
693fd25
Use a capital 'G'
MaelRL Dec 7, 2024
f2299f8
Use plural for the all-vertices function
MaelRL Dec 7, 2024
a0e319e
Re-attach convenience overloads to their respective main function
MaelRL Dec 7, 2024
25cd25c
Tiny indentation fix
MaelRL Dec 7, 2024
e8602e1
Use modern typedefs
MaelRL Dec 7, 2024
b24e650
Merge remote-tracking branch 'cgal/master' into PMP-add_discrete_curv…
MaelRL Dec 9, 2024
2838ad2
Delay to_double call
MaelRL Dec 10, 2024
20115d3
Use std::clamp
MaelRL Dec 10, 2024
f7c36ea
Make the bottom and top of the ramp not have same colors
MaelRL Dec 10, 2024
373ad84
Improve discrete curvature implementation
MaelRL Dec 10, 2024
1189356
Add discrete curvatures to display plugin
MaelRL Dec 10, 2024
5ece393
Fix placement of assertion
MaelRL Dec 10, 2024
3814220
Do not use an inexact SQRT if an exact one exists
MaelRL Dec 10, 2024
d779198
Move separator
MaelRL Jan 10, 2025
6d68861
Move PMP/curvature.h outside of 'internal'
MaelRL Jan 10, 2025
26005e5
Fix compilation
MaelRL Jan 10, 2025
db297d7
Handle boundary vertices in angle_sum
MaelRL Jan 10, 2025
c418aea
Document PMP/curvature.h
MaelRL Jan 10, 2025
8e3befc
Add tests for discrete curvatures
MaelRL Jan 10, 2025
76e47d4
Fix header path
MaelRL Jan 10, 2025
07d7615
Require a FaceGraph for boundary checks
MaelRL Feb 6, 2025
4cc3eef
Update CHANGES.md
MaelRL Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Installation/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

## [Release 6.1](https://github.com/CGAL/cgal/releases/tag/v6.1)

### [Polygon Mesh Processing](https://doc.cgal.org/6.1/Manual/packages.html#PkgPolygonMeshProcessing)
- Added the function `CGAL::Polygon_mesh_processing::discrete_mean_curvature` and `CGAL::Polygon_mesh_processing::discrete_Guassian_curvature` to evaluate the discrete curvature at a vertex of a mesh.
- Added the function `CGAL::Polygon_mesh_processing::angle_sum` to compute the sum of the angles around a vertex.

### [Algebraic Kernel](https://doc.cgal.org/6.1/Manual/packages.html#PkgAlgebraicKernelD)

- **Breaking change**: Classes based on the RS Library are no longer provided.
Expand Down
12 changes: 2 additions & 10 deletions Kernel_23/include/CGAL/Kernel/function_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -965,22 +965,14 @@ namespace CommonKernelFunctors {
typename K::Compute_scalar_product_3 scalar_product =
k.compute_scalar_product_3_object();

double product = CGAL::sqrt(to_double(scalar_product(u,u)) * to_double(scalar_product(v,v)));
double product = to_double(approximate_sqrt(scalar_product(u,u) * scalar_product(v,v)));

if(product == 0)
return 0;

// cosine
double dot = to_double(scalar_product(u,v));
double cosine = dot / product;

if(cosine > 1.){
cosine = 1.;
}
if(cosine < -1.){
cosine = -1.;
}

double cosine = std::clamp(dot / product, -1., 1.);
return std::acos(cosine) * 180./CGAL_PI;
}

Expand Down
4 changes: 2 additions & 2 deletions Lab/demo/Lab/Color_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ compute_color_map(QColor base_color,
std::size_t nb_of_colors,
Output_color_iterator out)
{
qreal hue = base_color.hueF();
const qreal step = (static_cast<qreal>(1)) / nb_of_colors;
const qreal step = (static_cast<qreal>(0.85)) / nb_of_colors;

qreal hue = base_color.hueF();
qreal h = (hue == -1) ? 0 : hue;
for(std::size_t i=0; i<nb_of_colors; ++i)
{
Expand Down
74 changes: 63 additions & 11 deletions Lab/demo/Lab/Plugins/Display/Display_property_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <CGAL/Polygon_mesh_processing/measure.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <CGAL/Polygon_mesh_processing/curvature.h>
#include <CGAL/Polygon_mesh_processing/interpolated_corrected_curvatures.h>

#include <QAbstractItemView>
Expand Down Expand Up @@ -350,11 +351,11 @@ private Q_SLOTS:
template<typename ValueType>
void displayMapLegend(const std::vector<ValueType>& values)
{
const std::size_t size = (std::min)(color_map.size(), std::size_t(1024));
const std::size_t size = (std::min)(color_map.size(), std::size_t(4096));

const int text_height = 20;
const int height = text_height * static_cast<int>(size) + text_height;
const int width = 140;
const int width = 200;
const int cell_width = width / 3;
const int top_margin = 15;
const int left_margin = 5;
Expand All @@ -381,13 +382,13 @@ private Q_SLOTS:
tick_height,
color);

QRect text_rect(left_margin + cell_width + 10, drawing_height - top_margin - j, 50, text_height);
painter.drawText(text_rect, Qt::AlignCenter, QObject::tr("%1").arg(values[i], 0, 'f', 3, QLatin1Char(' ')));
QRect text_rect(left_margin + cell_width + 10, drawing_height - top_margin - j, 100, text_height);
painter.drawText(text_rect, Qt::AlignCenter, QObject::tr("%1").arg(values[i], 0, 'f', 6, QLatin1Char(' ')));
}

if(color_map.size() > size)
{
QRect text_rect(left_margin + cell_width + 10, 0, 50, text_height);
QRect text_rect(left_margin + cell_width + 10, 0, 100, text_height);
painter.drawText(text_rect, Qt::AlignCenter, QObject::tr("[...]"));
}

Expand Down Expand Up @@ -463,13 +464,17 @@ private Q_SLOTS:
"Largest Angle Per Face",
"Scaled Jacobian",
"Face Area",
"Discrete Mean Curvature",
"Discrete Gaussian Curvature",
"Interpolated Corrected Mean Curvature",
"Interpolated Corrected Gaussian Curvature"});
property_simplex_types = { Property_simplex_type::FACE,
Property_simplex_type::FACE,
Property_simplex_type::FACE,
Property_simplex_type::FACE,
Property_simplex_type::VERTEX,
Property_simplex_type::VERTEX,
Property_simplex_type::VERTEX,
Property_simplex_type::VERTEX };
detectSMScalarProperties(*(sm_item->face_graph()));
}
Expand Down Expand Up @@ -516,12 +521,12 @@ private Q_SLOTS:

// Curvature property-specific slider
const std::string& property_name = dock_widget->propertyBox->currentText().toStdString();
const bool is_curvature_property = (property_name == "Interpolated Corrected Mean Curvature" ||
property_name == "Interpolated Corrected Gaussian Curvature");
dock_widget->expandingRadiusLabel->setVisible(is_curvature_property);
dock_widget->expandingRadiusSlider->setVisible(is_curvature_property);
dock_widget->expandingRadiusLabel->setEnabled(is_curvature_property);
dock_widget->expandingRadiusSlider->setEnabled(is_curvature_property);
const bool is_interpolated_curvature_property = (property_name == "Interpolated Corrected Mean Curvature" ||
property_name == "Interpolated Corrected Gaussian Curvature");
dock_widget->expandingRadiusLabel->setVisible(is_interpolated_curvature_property);
dock_widget->expandingRadiusSlider->setVisible(is_interpolated_curvature_property);
dock_widget->expandingRadiusLabel->setEnabled(is_interpolated_curvature_property);
dock_widget->expandingRadiusSlider->setEnabled(is_interpolated_curvature_property);
}
else // no or broken property
{
Expand Down Expand Up @@ -570,6 +575,16 @@ private Q_SLOTS:
{
displayArea(sm_item);
}
else if(property_name == "Discrete Mean Curvature")
{
displayDiscreteCurvatureMeasure(sm_item, MEAN_CURVATURE);
sm_item->setRenderingMode(Gouraud);
}
else if(property_name == "Discrete Gaussian Curvature")
{
displayDiscreteCurvatureMeasure(sm_item, GAUSSIAN_CURVATURE);
sm_item->setRenderingMode(Gouraud);
}
else if(property_name == "Interpolated Corrected Mean Curvature")
{
displayInterpolatedCurvatureMeasure(sm_item, MEAN_CURVATURE);
Expand Down Expand Up @@ -682,6 +697,8 @@ private Q_SLOTS:
removeDisplayPluginProperty(item, "f:display_plugin_largest_angle");
removeDisplayPluginProperty(item, "f:display_plugin_scaled_jacobian");
removeDisplayPluginProperty(item, "f:display_plugin_area");
removeDisplayPluginProperty(item, "v:display_plugin_discrete_mean_curvature");
removeDisplayPluginProperty(item, "v:display_plugin_discrete_Gaussian_curvature");
removeDisplayPluginProperty(item, "v:display_plugin_interpolated_corrected_mean_curvature");
removeDisplayPluginProperty(item, "v:display_plugin_interpolated_corrected_Gaussian_curvature");
}
Expand Down Expand Up @@ -864,6 +881,35 @@ private Q_SLOTS:
displaySMProperty<face_descriptor>("f:display_plugin_area", *sm);
}

private:
void displayDiscreteCurvatureMeasure(Scene_surface_mesh_item* sm_item,
CurvatureType mu_index)
{
SMesh* sm = sm_item->face_graph();
if(sm == nullptr)
return;

if(mu_index != MEAN_CURVATURE && mu_index != GAUSSIAN_CURVATURE)
return;

std::string vdc_name = (mu_index == MEAN_CURVATURE) ? "v:display_plugin_discrete_mean_curvature"
: "v:display_plugin_discrete_Gaussian_curvature";

bool not_initialized;
SMesh::Property_map<vertex_descriptor, double> vdc;
std::tie(vdc, not_initialized) = sm->add_property_map<vertex_descriptor, double>(vdc_name, 0);

if(not_initialized)
{
if(mu_index == MEAN_CURVATURE)
PMP::discrete_mean_curvatures(*sm, vdc);
else
PMP::discrete_Gaussian_curvatures(*sm, vdc);
}

displaySMProperty<vertex_descriptor>(vdc_name, *sm);
}

private Q_SLOTS:
void setExpandingRadius()
{
Expand Down Expand Up @@ -1131,6 +1177,10 @@ private Q_SLOTS:
zoomToSimplexWithPropertyExtremum(faces(mesh), mesh, "f:display_plugin_scaled_jacobian", extremum);
else if(property_name == "Face Area")
zoomToSimplexWithPropertyExtremum(faces(mesh), mesh, "f:display_plugin_area", extremum);
else if(property_name == "Discrete Mean Curvature")
zoomToSimplexWithPropertyExtremum(vertices(mesh), mesh, "v:display_plugin_discrete_mean_curvature", extremum);
else if(property_name == "Discrete Gaussian Curvature")
zoomToSimplexWithPropertyExtremum(vertices(mesh), mesh, "v:display_plugin_discrete_Gaussian_curvature", extremum);
else if(property_name == "Interpolated Corrected Mean Curvature")
zoomToSimplexWithPropertyExtremum(vertices(mesh), mesh, "v:display_plugin_interpolated_corrected_mean_curvature", extremum);
else if(property_name == "Interpolated Corrected Gaussian Curvature")
Expand Down Expand Up @@ -1470,6 +1520,8 @@ isSMPropertyScalar(const std::string& name,
name == "f:display_plugin_largest_angle" ||
name == "f:display_plugin_scaled_jacobian" ||
name == "f:display_plugin_area" ||
name == "v:display_plugin_discrete_mean_curvature" ||
name == "v:display_plugin_discrete_Gaussian_curvature" ||
name == "v:display_plugin_interpolated_corrected_mean_curvature" ||
name == "v:display_plugin_interpolated_corrected_Gaussian_curvature")
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/// \ingroup PkgPolygonMeshProcessingRef

/// \defgroup PMP_measure_grp Geometric Measure Functions
/// Functions to compute lengths of edges and borders, areas of faces and patches, as well as volumes of closed meshes.
/// Functions to compute discrete curvatures, lengths of edges and borders, areas of faces and patches, volumes of closed meshes.
/// \ingroup PkgPolygonMeshProcessingRef

/// \defgroup PMP_orientation_grp Orientation Functions
Expand Down Expand Up @@ -239,6 +239,11 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
- `CGAL::Polygon_mesh_processing::sample_triangle_mesh()`

\cgalCRPSection{Geometric Measure Functions}
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::angle_sum()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvatures()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvature()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_mean_curvature()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_mean_curvatures()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::edge_length()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::squared_edge_length()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::face_area()` \endlink
Expand All @@ -248,7 +253,6 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::face_border_length()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::longest_border()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::centroid()` \endlink
- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::match_faces()` \endlink

\cgalCRPSection{Feature Detection Functions}
- `CGAL::Polygon_mesh_processing::sharp_edges_segmentation()`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,17 @@ compute the curvatures on a specific vertex.

\cgalExample{Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp}

\subsection DCurvartures Discrete Curvatures

The package also provides methods to compute the standard, non-interpolated discrete mean and Gaussian
curvatures on triangle meshes, based on the work of Meyer et al. \cgalCite{cgal:mdsb-ddgot-02}.
These curvatures are computed at each vertex of the mesh, and are based on the angles of the incident
triangles. The functions are:
- `CGAL::Polygon_mesh_processing::discrete_mean_curvature()`
- `CGAL::Polygon_mesh_processing::discrete_mean_curvatures()`
- `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvature()`
- `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvatures()`

****************************************
\section PMPSlicer Slicer

Expand Down
Loading