Skip to content

Commit

Permalink
Merge pull request #6088 from sloriot/PMP-add_discrete_curvature
Browse files Browse the repository at this point in the history
Add functions to compute discrete curvatures
  • Loading branch information
sloriot committed Feb 12, 2025
2 parents de1fb95 + 4cc3eef commit 06b511c
Show file tree
Hide file tree
Showing 12 changed files with 717 additions and 30 deletions.
5 changes: 5 additions & 0 deletions Installation/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
### General Changes
- The minimal supported version of Boost is now 1.74.0.

### [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

0 comments on commit 06b511c

Please sign in to comment.