Merge pull request #8294 from MaelRL/Lab-Add_add_face_from_selection-GF

Lab: Add an operation to create triangle faces from vertex selections
This commit is contained in:
Sébastien Loriot 2024-07-23 17:18:41 +02:00
commit 3a0e644ab7
2 changed files with 83 additions and 7 deletions

View File

@ -232,11 +232,12 @@ public:
"Create Facegraph from Selected Facets" ,
"Erase Selected Facets" ,
"Keep Connected Components of Selected Facets" ,
"Expand Face Selection to Stay Manifold After Removal" ,
"Convert from Edge Selection to Facets Selection" ,
"Convert from Edge Selection to Point Selection" ,
"Convert from Facet Selection to Boundary Edge Selection",
"Convert from Facet Selection to Point Selection"
"Expand Face Selection to Remain Manifold After Removal" ,
"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",
"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
{
@ -555,8 +557,6 @@ public Q_SLOTS:
}
}
void on_Selection_type_combo_box_changed(int index) {
std::cout << "on_Selection_type_combo_box_changed(" << index << ")" << std::endl;
typedef Scene_polyhedron_selection_item::Active_handle Active_handle;
for(Selection_item_map::iterator it = selection_item_map.begin(); it != selection_item_map.end(); ++it) {
it->second->set_active_handle_type(static_cast<Active_handle::Type>(index));
@ -906,6 +906,20 @@ public Q_SLOTS:
selection_item->itemChanged();
break;
}
//Add Triangle Face to FaceGraph
case 10:
{
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
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;
}
@ -1175,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)
{

View File

@ -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<Face_graph>::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<fg_vertex_descriptor, 3> 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);