From 363df4c42432ed2a3433a9c1b3d75a4228d84114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 19 Jun 2024 16:00:23 +0200 Subject: [PATCH] Add an operation to add triangle faces from vertex selection --- Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp | 20 ++++++- .../Lab/Scene_polyhedron_selection_item.h | 60 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp b/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp index a3424d44163..eaf633c7cf5 100644 --- a/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp @@ -236,7 +236,8 @@ public: "Select Edges Incident to Selected Facets" , "Select Vertices Incident to Selected Edges" , "Select Edges on the Boundary of Regions of Selected Facets", - "Select Vertices of Selected Facets" + "Select Vertices of Selected Facets", + "Add Triangle Face from Selected Vertices" }; operations_map[operations_strings[0]] = 0; @@ -249,6 +250,7 @@ public: operations_map[operations_strings[7]] = 7; operations_map[operations_strings[8]] = 8; operations_map[operations_strings[9]] = 9; + operations_map[operations_strings[10]] = 10; } virtual void closure() override { @@ -904,6 +906,20 @@ public Q_SLOTS: selection_item->itemChanged(); break; } + //Add Triangle Face to FaceGraph + case 10: + { + Scene_polyhedron_selection_item* selection_item = getSelectedItem(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + if(selection_item->selected_vertices.size() != 3) { + print_message("Error: there is not exactly 3 vertices selected!"); + return; + } + selection_item->add_facet_from_selected_vertices(); + } default : break; } @@ -1173,6 +1189,8 @@ void filter_operations() if(has_v) { ui_widget.operationsBox->addItem(operations_strings[0]); + if(selection_item->selected_vertices.size() == 3) + ui_widget.operationsBox->addItem(operations_strings[10]); } if(has_e) { diff --git a/Lab/demo/Lab/Scene_polyhedron_selection_item.h b/Lab/demo/Lab/Scene_polyhedron_selection_item.h index c74837396e4..7a2cc2f16bd 100644 --- a/Lab/demo/Lab/Scene_polyhedron_selection_item.h +++ b/Lab/demo/Lab/Scene_polyhedron_selection_item.h @@ -781,6 +781,66 @@ public: return num_vertices(*out) > 0; } + fg_face_descriptor add_facet_from_selected_vertices() + { + fg_face_descriptor null_face = boost::graph_traits::null_face(); + + if(selected_vertices.size() != 3) // NYI + return null_face; + + // since the selected vertices are a set, we lost order in the process, + // so find back the correct orientation + std::array vs; + for(std::size_t i=0; i<3; ++i) + vs[i] = *(std::next(selected_vertices.begin(), i)); + + int pos_counter = 0, neg_counter = 0; + for(std::size_t i=0; i<3; ++i) + { + auto res = halfedge(vs[i], vs[(i+1)%3], *polyhedron()); + if(res.second && !is_border(res.first, *polyhedron())) + { + // the halfedge 'vs[i] - vs[i+1]' already exists in the graph and is not border, + // so vote for orienting the facet the other way + ++neg_counter; + } + + res = halfedge(vs[(i+1)%3], vs[i], *polyhedron()); + if(res.second && !is_border(res.first, *polyhedron())) + { + // the halfedge 'vs[i+1] - vs[i]' already exists in the graph and is not border, + // so vote for keeping the current orientationorientation + ++pos_counter; + } + } + + if(pos_counter > 0 && neg_counter > 0) + { + // disagreement, can't insert the face (@todo duplicate and insert?) + std::cerr << "Failed to find a valid orientation (" << pos_counter << " VS " << neg_counter << ")!" << std::endl; + return null_face; + } + else if(neg_counter > 0) + { + std::swap(vs[0], vs[1]); + } + + fg_face_descriptor new_f = CGAL::Euler::add_face(vs, *polyhedron()); + const bool successful_insertion = (new_f != null_face); + if(successful_insertion) + { + selected_vertices.clear(); + invalidateOpenGLBuffers(); + changed_with_poly_item(); + } + else + { + std::cerr << "Failed to insert face!" << std::endl; + } + + return new_f; + } + void select_sharp_edges(const double angle) { CGAL::detect_sharp_edges(polyhedron(), angle);