Self_intersection_plugin is available for surface_mesh_items. In that case, the output item is anorther Surface_mesh_item instead of a Polyhedron_item.

This commit is contained in:
Maxime Gimeno 2016-11-09 11:23:48 +01:00
parent 502dfc29c1
commit 9ecb5d19bd
2 changed files with 94 additions and 28 deletions

View File

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

View File

@ -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 <CGAL/Three/Polyhedron_demo_plugin_interface.h>
@ -47,7 +48,9 @@ public:
}
bool applicable(QAction*) const {
return qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex()));
return
(qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex())) ||
qobject_cast<Scene_surface_mesh_item*>(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<class Mesh>
bool selfIntersect(Mesh* mesh, std::vector<std::pair<typename boost::graph_traits<Mesh>::face_descriptor,typename boost::graph_traits<Mesh>::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_polyhedron_item*>(scene->item(index));
if(item)
Scene_polyhedron_item* poly_item =
qobject_cast<Scene_polyhedron_item*>(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<std::pair<Facet_handle, Facet_handle> > 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<Polyhedron>::face_descriptor Face_descriptor;
Polyhedron* pMesh = poly_item->polyhedron();
std::vector<std::pair<Face_descriptor, Face_descriptor> > 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<std::pair<Facet_handle, Facet_handle> >::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<std::pair<Face_descriptor, Face_descriptor> >::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<Surface_mesh>::face_descriptor Face_descriptor;
typedef boost::graph_traits<Surface_mesh>::halfedge_descriptor halfedge_descriptor;
typedef Surface_mesh::Vertex_index Vertex_index;
Scene_surface_mesh_item* sm_item =
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
if(sm_item)
{
Surface_mesh* sMesh = sm_item->polyhedron();
std::vector<std::pair<Face_descriptor, Face_descriptor> > 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<std::pair<Face_descriptor, Face_descriptor> >::iterator fb = faces.begin();
fb != faces.end(); ++fb)
{
std::vector<Vertex_index> 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();
}