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

Using std::optional for Property_container::get<T> #8035

Merged
merged 11 commits into from
May 22, 2024
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,17 +27,18 @@ 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;
}
Expand All @@ -60,12 +61,12 @@ struct Graphics_scene_options_small_faces:

// 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 @@ -101,6 +101,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
27 changes: 13 additions & 14 deletions Lab/demo/Lab/Plugins/Classification/Cluster_classification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,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 +58,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 +607,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 +637,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 +657,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