Skip to content

Commit

Permalink
Using std::optional for Property_container::get<T> (CGAL#8035)
Browse files Browse the repository at this point in the history
## Summary of Changes
Switching from `std::pair<Property_map<T>, bool>` to `std::optional` in
`Property_container::get<T>`

Introducing `Pair_optional_adaptor` for backward compatibility which
extends `std::optional<T>` to interface of `std::pair`

using `Pair_optional_adaptor` for `Surface_mesh` and `Point_set_3`

## Release Management

* Affected package(s): Point_set_3, Surface_mesh, STL_Extension
  • Loading branch information
lrineau committed May 22, 2024
2 parents 64c6fa7 + 748b1eb commit 8135785
Show file tree
Hide file tree
Showing 49 changed files with 443 additions and 528 deletions.
3 changes: 1 addition & 2 deletions BGL/test/BGL/test_Collapse_edge_with_constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ typedef Mesh::Property_map<Mesh::Edge_index, bool> ECM;

bool test_one_side(Mesh::Halfedge_index h, Mesh m)
{
std::pair<ECM, bool> ecm_and_bool = m.property_map<Mesh::Edge_index, bool>("ecm");
Mesh::Vertex_index vkept=target(h, m);
CGAL::Euler::collapse_edge(edge(h, m), m, ecm_and_bool.first);
CGAL::Euler::collapse_edge(edge(h, m), m, m.property_map<Mesh::Edge_index, bool>("ecm").value());
return (!m.is_removed(vkept) && CGAL::is_valid_polygon_mesh(m));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,23 @@ struct Graphics_scene_options_small_faces:

Graphics_scene_options_small_faces(const SM& sm): Base(), m_sm(sm)
{
typename SM::template Property_map<face_descriptor, FT> faces_size;
boost::tie(faces_size, m_with_size)=sm.template property_map<face_descriptor, FT>("f:size");
std::optional<typename SM::template Property_map<face_descriptor, FT>> faces_size
= sm.template property_map<face_descriptor, FT>("f:size");
m_with_size = faces_size.has_value();
if(!m_with_size)
{ return; }

m_min_size=faces_size[*(sm.faces().begin())];
m_min_size=faces_size.value()[*(sm.faces().begin())];
m_max_size=m_min_size;
FT cur_size;
for (typename SM::Face_range::iterator f=sm.faces().begin(); f!=sm.faces().end(); ++f)
{
cur_size=faces_size[*f];
cur_size=faces_size.value()[*f];
if (cur_size<m_min_size) m_min_size=cur_size;
if (cur_size>m_max_size) m_max_size=cur_size;
}

this->face_color=[=](const SM& sm,
this->face_color=[this](const SM& sm,
typename boost::graph_traits<SM>::face_descriptor fh) -> CGAL::IO::Color
{ return this->get_face_color(sm, fh); };

Expand All @@ -59,13 +60,12 @@ struct Graphics_scene_options_small_faces:
if(!m_with_size) { return c; }

// Compare the size of the face with the % m_threshold
bool exist;
typename SM::template Property_map<face_descriptor, FT> faces_size;
boost::tie(faces_size, exist)=sm.template property_map<face_descriptor, FT>("f:size");
assert(exist);
std::optional<typename SM::template Property_map<face_descriptor, FT>> faces_size
= sm.template property_map<face_descriptor, FT>("f:size");
assert(faces_size.has_value());

// If the face is small, color it in red.
if (get(faces_size, fh)<m_min_size+((m_max_size-m_min_size)/(100-m_threshold)))
if (get(faces_size.value(), fh)<m_min_size + ((m_max_size - m_min_size) / (100 - m_threshold)))
{ return CGAL::IO::Color(255,20,20); }

return c; // Default color
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ int main (int argc, char** argv)
std::cerr << "Reading input" << std::endl;
in >> pts;

Imap label_map;
bool lm_found = false;
std::tie (label_map, lm_found) = pts.property_map<int> ("label");
if (!lm_found)
std::optional<Imap> label_map = pts.property_map<int> ("label");
if (!label_map.has_value())
{
std::cerr << "Error: \"label\" property not found in input file." << std::endl;
return EXIT_FAILURE;
Expand Down Expand Up @@ -78,7 +76,7 @@ int main (int argc, char** argv)
Label_handle roof = labels.add ("roof");

// Check if ground truth is valid for this label set
if (!labels.is_valid_ground_truth (pts.range(label_map), true))
if (!labels.is_valid_ground_truth (pts.range(label_map.value()), true))
return EXIT_FAILURE;

std::vector<int> label_indices(pts.size(), -1);
Expand All @@ -89,7 +87,7 @@ int main (int argc, char** argv)
std::cerr << "Training" << std::endl;
t.reset();
t.start();
classifier.train (pts.range(label_map));
classifier.train (pts.range(label_map.value()));
t.stop();
std::cerr << "Done in " << t.time() << " second(s)" << std::endl;

Expand All @@ -104,7 +102,7 @@ int main (int argc, char** argv)
std::cerr << "Classification with graphcut done in " << t.time() << " second(s)" << std::endl;

std::cerr << "Precision, recall, F1 scores and IoU:" << std::endl;
Classification::Evaluation evaluation (labels, pts.range(label_map), label_indices);
Classification::Evaluation evaluation (labels, pts.range(label_map.value()), label_indices);

for (Label_handle l : labels)
{
Expand All @@ -126,7 +124,7 @@ int main (int argc, char** argv)

for (std::size_t i = 0; i < label_indices.size(); ++ i)
{
label_map[i] = label_indices[i]; // update label map with computed classification
label_map.value()[i] = label_indices[i]; // update label map with computed classification

Label_handle label = labels[label_indices[i]];
const CGAL::IO::Color& color = label->color();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ int main (int argc, char** argv)
std::cerr << "Reading input" << std::endl;
in >> pts;

Imap label_map;
bool lm_found = false;
std::tie (label_map, lm_found) = pts.property_map<int> ("label");
if (!lm_found)
std::optional<Imap> label_map = pts.property_map<int> ("label");
if (!label_map.has_value())
{
std::cerr << "Error: \"label\" property not found in input file." << std::endl;
return EXIT_FAILURE;
Expand Down Expand Up @@ -82,7 +80,7 @@ int main (int argc, char** argv)
std::cerr << "Training" << std::endl;
t.reset();
t.start();
classifier.train<CGAL::Parallel_if_available_tag> (pts.range(label_map), 800);
classifier.train<CGAL::Parallel_if_available_tag> (pts.range(label_map.value()), 800);
t.stop();
std::cerr << "Done in " << t.time() << " second(s)" << std::endl;

Expand All @@ -97,7 +95,7 @@ int main (int argc, char** argv)
std::cerr << "Classification with graphcut done in " << t.time() << " second(s)" << std::endl;

std::cerr << "Precision, recall, F1 scores and IoU:" << std::endl;
Classification::Evaluation evaluation (labels, pts.range(label_map), label_indices);
Classification::Evaluation evaluation (labels, pts.range(label_map.value()), label_indices);

for (Label_handle l : labels)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ int main (int argc, char** argv)
Point_set pts;
in >> pts;

Imap label_map;
bool lm_found = false;
std::tie (label_map, lm_found) = pts.property_map<int> ("label");
if (!lm_found)
std::optional<Imap> label_map = pts.property_map<int> ("label");
if (!label_map.has_value())
{
std::cerr << "Error: \"label\" property not found in input file." << std::endl;
return EXIT_FAILURE;
Expand Down Expand Up @@ -81,7 +79,7 @@ int main (int argc, char** argv)
std::cerr << "Training" << std::endl;
t.reset();
t.start();
classifier.train (pts.range(label_map));
classifier.train (pts.range(label_map.value()));
t.stop();
std::cerr << "Done in " << t.time() << " second(s)" << std::endl;

Expand All @@ -96,7 +94,7 @@ int main (int argc, char** argv)
std::cerr << "Classification with graphcut done in " << t.time() << " second(s)" << std::endl;

std::cerr << "Precision, recall, F1 scores and IoU:" << std::endl;
Classification::Evaluation evaluation (labels, pts.range(label_map), label_indices);
Classification::Evaluation evaluation (labels, pts.range(label_map.value()), label_indices);

for (Label_handle l : labels)
{
Expand All @@ -118,7 +116,7 @@ int main (int argc, char** argv)

for (std::size_t i = 0; i < label_indices.size(); ++ i)
{
label_map[i] = label_indices[i]; // update label map with computed classification
label_map.value()[i] = label_indices[i]; // update label map with computed classification

Label_handle label = labels[label_indices[i]];
const CGAL::IO::Color& color = label->color();
Expand Down
10 changes: 4 additions & 6 deletions Classification/examples/Classification/gis_tutorial_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,11 +691,9 @@ int main (int argc, char** argv)
//! [Classification]

// Get training from input
Point_set::Property_map<int> training_map;
bool training_found;
std::tie (training_map, training_found) = points.property_map<int>("training");
std::optional<Point_set::Property_map<int>> training_map = points.property_map<int>("training");

if (training_found)
if (training_map.has_value())
{
std::cerr << "Classifying ground/vegetation/building" << std::endl;

Expand All @@ -718,7 +716,7 @@ int main (int argc, char** argv)

// Train a random forest classifier
Classification::ETHZ::Random_forest_classifier classifier (labels, features);
classifier.train (points.range(training_map));
classifier.train (points.range(training_map.value()));

// Classify with graphcut regularization
Point_set::Property_map<int> label_map = points.add_property_map<int>("labels").first;
Expand All @@ -732,7 +730,7 @@ int main (int argc, char** argv)
// Evaluate
std::cerr << "Mean IoU on training data = "
<< Classification::Evaluation(labels,
points.range(training_map),
points.range(training_map.value()),
points.range(label_map)).mean_intersection_over_union() << std::endl;

// Save the classified point set
Expand Down
6 changes: 6 additions & 0 deletions Installation/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ Release date: June 2024
`CGAL::Simplicial_mesh_cell_base_3`
have been modified to enable passing a geometric traits and a custom cell base class.

### [Surface Mesh](https://doc.cgal.org/6.0/Manual/packages.html#PkgSurfaceMesh)
- **Breaking change**: The return type of `CGAL::Surface_mesh::property_map()` has been changed to `std::optional`.

### [3D Point Set](https://doc.cgal.org/6.0/Manual/packages.html#PkgPointSet3)
- **Breaking change**: The return type of `CGAL::Point_set_3::property_map()` has been changed to `std::optional`.

### [Surface Mesh Parameterization](https://doc.cgal.org/6.0/Manual/packages.html#PkgSurfaceMeshParameterization)
- **Breaking change**: LSCM_parameterizer_3 needs Eigen

Expand Down
28 changes: 13 additions & 15 deletions Lab/demo/Lab/Plugins/Classification/Cluster_classification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ Cluster_classification::Cluster_classification(Scene_points_with_normal_item* po

backup_existing_colors_and_add_new();

bool cluster_found = false;
boost::tie (m_cluster_id, cluster_found) = m_points->point_set()->property_map<int>("shape");
if (!cluster_found)
std::optional<Point_set::Property_map<int>> cluster_id = m_points->point_set()->property_map<int>("shape");
if (!cluster_id.has_value())
{
std::cerr << "Error! Cluster not found!" << std::endl;
abort();
}
m_cluster_id = cluster_id.value();

CGAL::Classification::create_clusters_from_indices (*(m_points->point_set()),
m_points->point_set()->point_map(),
Expand All @@ -57,20 +57,20 @@ Cluster_classification::Cluster_classification(Scene_points_with_normal_item* po

if (!classif_found)
{
Point_set::Property_map<unsigned char> las_classif;
boost::tie (las_classif, las_found) = m_points->point_set()->property_map<unsigned char>("classification");
std::optional<Point_set::Property_map<unsigned char>> las_classif = m_points->point_set()->property_map<unsigned char>("classification");
las_found = las_classif.has_value();
if (las_found)
{
m_input_is_las = true;
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
{
unsigned char uc = las_classif[*it];
unsigned char uc = las_classif.value()[*it];
m_classif[*it] = int(uc);
if (!training_found)
m_training[*it] = int(uc);
}
m_points->point_set()->remove_property_map (las_classif);
m_points->point_set()->remove_property_map (las_classif.value());
classif_found = true;
training_found = true;
}
Expand Down Expand Up @@ -606,7 +606,7 @@ int Cluster_classification::real_index_color() const
void Cluster_classification::reset_indices ()
{
Point_set::Property_map<Point_set::Index> indices
= m_points->point_set()->property_map<Point_set::Index>("index").first;
= m_points->point_set()->property_map<Point_set::Index>("index").value();

m_points->point_set()->unselect_all();
Point_set::Index idx;
Expand Down Expand Up @@ -636,11 +636,9 @@ void Cluster_classification::compute_features (std::size_t nb_scales, float voxe

bool colors = (m_color != Point_set::Property_map<CGAL::IO::Color>());

Point_set::Property_map<std::uint8_t> echo_map;
bool echo;
boost::tie (echo_map, echo) = m_points->point_set()->template property_map<std::uint8_t>("echo");
if (!echo)
boost::tie (echo_map, echo) = m_points->point_set()->template property_map<std::uint8_t>("number_of_returns");
std::optional<Point_set::Property_map<std::uint8_t>> echo_map = m_points->point_set()->template property_map<std::uint8_t>("echo");
if (!echo_map.has_value())
echo_map = m_points->point_set()->template property_map<std::uint8_t>("number_of_returns");

Feature_set pointwise_features;

Expand All @@ -658,8 +656,8 @@ void Cluster_classification::compute_features (std::size_t nb_scales, float voxe
generator.generate_normal_based_features (pointwise_features, normal_map);
if (colors)
generator.generate_color_based_features (pointwise_features, m_color);
if (echo)
generator.generate_echo_based_features (pointwise_features, echo_map);
if (echo_map.has_value())
generator.generate_echo_based_features (pointwise_features, echo_map.value());

#ifdef CGAL_LINKED_WITH_TBB
pointwise_features.end_parallel_additions();
Expand Down
11 changes: 5 additions & 6 deletions Lab/demo/Lab/Plugins/Classification/Cluster_classification.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,13 @@ class Cluster_classification : public Item_classification_base
bool try_adding_simple_feature (Feature_set& feature_set, const std::string& name)
{
typedef typename Point_set::template Property_map<Type> Pmap;
bool okay = false;
Pmap pmap;
boost::tie (pmap, okay) = m_points->point_set()->template property_map<Type>(name.c_str());
if (okay)

std::optional<Pmap> pmap = m_points->point_set()->template property_map<Type>(name.c_str());
if (pmap.has_value())
feature_set.template add<CGAL::Classification::Feature::Simple_feature <Point_set, Pmap> >
(*(m_points->point_set()), pmap, name.c_str());
(*(m_points->point_set()), pmap.value(), name.c_str());

return okay;
return pmap.has_value();
}

void add_selection_to_training_set (std::size_t label)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ Point_set_item_classification::Point_set_item_classification(Scene_points_with_n

reset_indices();

Point_set::Property_map<int> cluster_id;
bool cluster_found = false;
boost::tie (cluster_id, cluster_found) = m_points->point_set()->property_map<int>("shape");
if (cluster_found)
std::optional<Point_set::Property_map<int>> cluster_id = m_points->point_set()->property_map<int>("shape");
if (cluster_id.has_value())
{
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
{
int c = cluster_id[*it];
int c = cluster_id.value()[*it];
if (c == -1)
continue;
if (std::size_t(c) >= m_clusters.size())
Expand All @@ -54,20 +52,20 @@ Point_set_item_classification::Point_set_item_classification(Scene_points_with_n

if (!classif_found)
{
Point_set::Property_map<unsigned char> las_classif;
boost::tie (las_classif, las_found) = m_points->point_set()->property_map<unsigned char>("classification");
std::optional<Point_set::Property_map<unsigned char>> las_classif = m_points->point_set()->property_map<unsigned char>("classification");
las_found = las_classif.has_value();
if (las_found)
{
m_input_is_las = true;
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
{
unsigned char uc = las_classif[*it];
unsigned char uc = las_classif.value()[*it];
m_classif[*it] = int(uc);
if (!training_found)
m_training[*it] = int(uc);
}
m_points->point_set()->remove_property_map (las_classif);
m_points->point_set()->remove_property_map (las_classif.value());
classif_found = true;
training_found = true;
}
Expand Down Expand Up @@ -498,7 +496,7 @@ int Point_set_item_classification::real_index_color() const
void Point_set_item_classification::reset_indices ()
{
Point_set::Property_map<Point_set::Index> indices
= m_points->point_set()->property_map<Point_set::Index>("index").first;
= m_points->point_set()->property_map<Point_set::Index>("index").value();

m_points->point_set()->unselect_all();
Point_set::Index idx;
Expand Down Expand Up @@ -531,11 +529,9 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales, flo

bool colors = (m_color != Point_set::Property_map<CGAL::IO::Color>());

Point_set::Property_map<std::uint8_t> echo_map;
bool echo;
boost::tie (echo_map, echo) = m_points->point_set()->template property_map<std::uint8_t>("echo");
if (!echo)
boost::tie (echo_map, echo) = m_points->point_set()->template property_map<std::uint8_t>("number_of_returns");
std::optional<Point_set::Property_map<std::uint8_t>> echo_map = m_points->point_set()->template property_map<std::uint8_t>("echo");
if (!echo_map.has_value())
echo_map = m_points->point_set()->template property_map<std::uint8_t>("number_of_returns");

m_generator = new Generator (*(m_points->point_set()), m_points->point_set()->point_map(), nb_scales, voxel_size);

Expand All @@ -551,8 +547,8 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales, flo
m_generator->generate_normal_based_features (m_features, normal_map);
if (colors)
m_generator->generate_color_based_features (m_features, m_color);
if (echo)
m_generator->generate_echo_based_features (m_features, echo_map);
if (echo_map.has_value())
m_generator->generate_echo_based_features (m_features, echo_map.value());

#ifdef CGAL_LINKED_WITH_TBB
m_features.end_parallel_additions();
Expand Down
Loading

0 comments on commit 8135785

Please sign in to comment.