diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 663d099b5db..2aee9ba72f4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -64,7 +64,7 @@ polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES}) target_link_libraries(selection_plugin scene_polyhedron_selection_item scene_points_with_normal_item scene_polylines_item) polyhedron_demo_plugin(self_intersection_plugin Self_intersection_plugin) -target_link_libraries(self_intersection_plugin scene_polyhedron_item scene_polyhedron_selection_item) +target_link_libraries(self_intersection_plugin scene_polyhedron_item scene_polyhedron_selection_item scene_surface_mesh_item) polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin) target_link_libraries(triangulate_facets_plugin scene_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp index 262bf70edf7..01683783044 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Self_intersection_plugin.cpp @@ -6,6 +6,7 @@ #include "Kernel_type.h" #include "Polyhedron_type.h" #include "Scene_polyhedron_item.h" +#include "Scene_surface_mesh_item.h" #include "Scene_polyhedron_selection_item.h" #include @@ -47,7 +48,9 @@ public: } bool applicable(QAction*) const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); + return + (qobject_cast(scene->item(scene->mainSelectionIndex())) || + qobject_cast(scene->item(scene->mainSelectionIndex()))); } public Q_SLOTS: @@ -59,34 +62,40 @@ private: }; // end Polyhedron_demo_self_intersection_plugin +//pretty useless for now but could allow a huge factorization when a selection_item is +// available for SM_items +template +bool selfIntersect(Mesh* mesh, std::vector::face_descriptor,typename boost::graph_traits::face_descriptor> > &faces) +{ + + // compute self-intersections + CGAL::Polygon_mesh_processing::self_intersections + (*mesh, std::back_inserter(faces), + CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, *mesh))); + + std::cout << "ok (" << faces.size() << " triangle pair(s))" << std::endl; + return !faces.empty(); +} + void Polyhedron_demo_self_intersection_plugin::on_actionSelfIntersection_triggered() { + QApplication::setOverrideCursor(Qt::WaitCursor); CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - - if(item) + Scene_polyhedron_item* poly_item = + qobject_cast(scene->item(index)); + //if the selected item is a polyhedron_item + if(poly_item) { - QApplication::setOverrideCursor(Qt::WaitCursor); - Polyhedron* pMesh = item->polyhedron(); - - // compute self-intersections - - typedef Polyhedron::Facet_handle Facet_handle; - std::vector > facets; - CGAL::Polygon_mesh_processing::self_intersections - (*pMesh, std::back_inserter(facets), - CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, *pMesh))); - - std::cout << "ok (" << facets.size() << " triangle pair(s))" << std::endl; - - // add intersecting triangles as a new polyhedron, i.e., a triangle soup. - if(!facets.empty()) + typedef typename boost::graph_traits::face_descriptor Face_descriptor; + Polyhedron* pMesh = poly_item->polyhedron(); + std::vector > facets; + // add intersecting triangles to a selection_item. + if(selfIntersect(pMesh, facets)) { - Scene_polyhedron_selection_item* selection_item = new Scene_polyhedron_selection_item(item, mw); - for(std::vector >::iterator fb = facets.begin(); - fb != facets.end(); ++fb) { + Scene_polyhedron_selection_item* selection_item = new Scene_polyhedron_selection_item(poly_item, mw); + for(std::vector >::iterator fb = facets.begin(); + fb != facets.end(); ++fb) { selection_item->selected_facets.insert(fb->first); selection_item->selected_facets.insert(fb->second); @@ -101,16 +110,73 @@ void Polyhedron_demo_self_intersection_plugin::on_actionSelfIntersection_trigger } } selection_item->invalidateOpenGLBuffers(); - selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(item->name())); - item->setRenderingMode(Wireframe); + selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(poly_item->name())); + poly_item->setRenderingMode(Wireframe); scene->addItem(selection_item); - scene->itemChanged(item); + scene->itemChanged(poly_item); scene->itemChanged(selection_item); } else QMessageBox::information(mw, tr("No self intersection"), tr("The polyhedron \"%1\" does not self-intersect."). - arg(item->name())); + arg(poly_item->name())); + } + //else if the selected item is a Surface_mesh_item + else + { + typedef Scene_surface_mesh_item::SMesh Surface_mesh; + typedef boost::graph_traits::face_descriptor Face_descriptor; + typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef Surface_mesh::Vertex_index Vertex_index; + Scene_surface_mesh_item* sm_item = + qobject_cast(scene->item(index)); + if(sm_item) + { + Surface_mesh* sMesh = sm_item->polyhedron(); + std::vector > faces; + // add intersecting triangles to a new Surface_mesh. + if(selfIntersect(sMesh, faces)) + { + //add the faces + Surface_mesh* new_mesh = new Surface_mesh(); + for(std::vector >::iterator fb = faces.begin(); + fb != faces.end(); ++fb) + { + std::vector face_vertices; + BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fb->first, *sMesh), *sMesh)) + { + face_vertices.push_back(new_mesh->add_vertex(get(sMesh->points(), target(he_circ, *sMesh)))); + } + new_mesh->add_face(face_vertices); + face_vertices.clear(); + BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fb->second, *sMesh), *sMesh)) + { + face_vertices.push_back(new_mesh->add_vertex(get(sMesh->points(), target(he_circ, *sMesh)))); + } + new_mesh->add_face(face_vertices); + } + //add the edges + BOOST_FOREACH(Face_descriptor fd, new_mesh->faces()) + { + BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fd, *new_mesh), *new_mesh)) + { + new_mesh->add_edge(source(he_circ, *new_mesh), target(he_circ, *new_mesh)); + } + } + Scene_surface_mesh_item* ism_item = new Scene_surface_mesh_item(new_mesh); + ism_item->invalidateOpenGLBuffers(); + ism_item->setName(tr("%1(intersecting triangles)").arg(sm_item->name())); + ism_item->setColor(QColor(Qt::gray).darker(200)); + sm_item->setRenderingMode(Wireframe); + scene->addItem(ism_item); + scene->itemChanged(sm_item); + scene->itemChanged(ism_item); + } + else + QMessageBox::information(mw, tr("No self intersection"), + tr("The surface_mesh \"%1\" does not self-intersect."). + arg(sm_item->name())); + } } QApplication::restoreOverrideCursor(); }