Add an operation to add triangle faces from vertex selection

This commit is contained in:
Mael Rouxel-Labbé 2024-06-19 16:00:23 +02:00
parent 4b71b12443
commit 363df4c424
2 changed files with 79 additions and 1 deletions

View File

@ -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<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;
}
@ -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)
{

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);