From 6ac45f820a306a389203ffae6ddf6ab1bd0e9703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 11 Jan 2017 15:16:03 +0100 Subject: [PATCH] use PMP for corefinement and intersection plugins --- .../Polygon_mesh_processing/corefinement.h | 4 +- Polyhedron/demo/Polyhedron/CMakeLists.txt | 4 - .../Operations_on_polyhedra/CMakeLists.txt | 4 - .../Corefinement_plugin.cpp | 181 ------ .../Intersection_plugin.cpp | 223 ------- .../Scene_combinatorial_map_item.cpp | 579 ------------------ .../Scene_combinatorial_map_item.h | 83 --- .../Scene_combinatorial_map_item_config.h | 10 - .../Polyhedron/Plugins/PMP/CMakeLists.txt | 6 + .../Plugins/PMP/Corefinement_plugin.cpp | 228 +++++++ .../PMP/Surface_intersection_plugin.cpp | 122 ++++ 11 files changed, 358 insertions(+), 1086 deletions(-) delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Corefinement_plugin.cpp delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Intersection_plugin.cpp delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.cpp delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.h delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item_config.h create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp create mode 100644 Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h index 94f90fac182..2612ce4e520 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -336,9 +336,9 @@ boolean_operation( TriangleMesh& tm1, Corefinement::No_mark//default > ::type Ecm2; - Ecm1 ecm1 = boost::choose_param( get_param(np1, edge_is_constrained), + Ecm1 ecm1 = boost::choose_param( boost::get_param(np1, edge_is_constrained), Corefinement::No_mark() ); - Ecm2 ecm2 = boost::choose_param( get_param(np2, edge_is_constrained), + Ecm2 ecm2 = boost::choose_param( boost::get_param(np2, edge_is_constrained), Corefinement::No_mark() ); typedef Corefinement::Ecm_bind Ecm_in; diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index beccd80aa77..c98a2a62ace 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -237,10 +237,6 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) # special target_link_libraries(scene_polyhedron_transform_item scene_polyhedron_item) - add_item(scene_combinatorial_map_item Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.cpp) - # special - target_link_libraries(scene_combinatorial_map_item scene_polyhedron_item) - add_item(scene_polylines_item Scene_polylines_item.cpp) target_link_libraries(scene_polylines_item scene_basic_objects) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt index fe820f46d8d..637575ddcf8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt @@ -2,9 +2,5 @@ include( polyhedron_demo_macros ) qt5_wrap_ui( clip_polyhedronUI_FILES Clip_polyhedron_plugin.ui ) polyhedron_demo_plugin(clip_polyhedron_plugin Clip_polyhedron_plugin ${clip_polyhedronUI_FILES}) target_link_libraries(clip_polyhedron_plugin scene_polyhedron_item scene_basic_objects) - polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin) - target_link_libraries(corefinement_plugin scene_polyhedron_item scene_combinatorial_map_item scene_polylines_item) - polyhedron_demo_plugin(intersection_plugin Intersection_plugin) - target_link_libraries(intersection_plugin scene_polyhedron_item scene_polylines_item) polyhedron_demo_plugin(point_set_from_vertices_plugin Point_set_from_vertices_plugin) target_link_libraries(point_set_from_vertices_plugin scene_polyhedron_item scene_polygon_soup_item scene_points_with_normal_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Corefinement_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Corefinement_plugin.cpp deleted file mode 100644 index 51fd0b79d1a..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Corefinement_plugin.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#define CGAL_COREFINEMENT_DO_REPORT_SELF_INTERSECTIONS -#include -#include -#include -#include "Scene_polyhedron_item.h" -#include "Scene_combinatorial_map_item.h" -#include "Polyhedron_type.h" -#include - -#include "Scene_polylines_item.h" - -#include -#include -#include -#include -#include -#include -#include - -//#define PRINT_EACH_VOLUME -using namespace CGAL::Three; -class Polyhedron_demo_corefinement_plugin : - public QObject, - public Polyhedron_demo_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") - -public: - - bool applicable(QAction*) const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); - } - - QList actions() const { - return QList() << actionPolyhedronCorefinement_3; - } - - void init(QMainWindow* mw, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) { - this->scene = scene_interface; - actionPolyhedronCorefinement_3 = new QAction("Polyhedra Corefinement (A/B)", mw); - actionPolyhedronCorefinement_3->setProperty("subMenuName", "Operations on Polyhedra"); - if(actionPolyhedronCorefinement_3) { - connect(actionPolyhedronCorefinement_3, SIGNAL(triggered()), - this, SLOT(corefinement())); - } - } - -private: - - QAction* actionPolyhedronCorefinement_3; - Scene_interface *scene; - -public Q_SLOTS: - void corefinement(); - -}; // end class Polyhedron_demo_corefinement_plugin - - -struct Is_on_polyline{ - bool operator()(Polyhedron::Halfedge_handle he) const { - return he->is_feature_edge(); - } -}; - -struct Set_vertex_corner{ - template - void add_info_to_node(int, Polyhedron*,const Info&) { - } - - void operator()(Polyhedron::Vertex_handle v, int, Polyhedron*) { - ++v->nb_of_feature_edges; - } -}; - -void Polyhedron_demo_corefinement_plugin::corefinement() -{ - int indexA = scene->selectionAindex(); - int indexB = scene->selectionBindex(); - - Scene_polyhedron_item* itemA = - qobject_cast(scene->item(indexA)); - Scene_polyhedron_item* itemB = - qobject_cast(scene->item(indexB)); - if(!itemA || !itemB || itemA == itemB) - { - Q_FOREACH(int index, scene->selectionIndices()) { - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - if(!item) - return; - } - if(scene->selectionIndices().size() == 2) { - indexA = scene->selectionIndices()[0]; - indexB = scene->selectionIndices()[1]; - itemA = - qobject_cast(scene->item(indexA)); - itemB = - qobject_cast(scene->item(indexB)); - } - } - std::vector poly_ptrs; - Q_FOREACH(int index, scene->selectionIndices()) { - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - if(!item) - return; - else if(item != itemA) { - poly_ptrs.push_back(item->polyhedron()); - if(poly_ptrs.back() == 0) return; - } - } - - QApplication::setOverrideCursor(Qt::WaitCursor); - - if(itemA && itemB && itemA != itemB) { - - // perform Boolean operation - QTime time; - time.start(); - - //since the visitor modify input polyhedra, we make copies. - Polyhedron A( *itemA->polyhedron() ); - Polyhedron B( *itemB->polyhedron() ); - - itemA->setVisible(false); - itemB->setVisible(false); - - Scene_polylines_item* new_item = new Scene_polylines_item(); - - #ifdef _COREFINEMENT_OUTPUT_IS_POLYHEDRON - typedef CGAL::Polyhedron_corefinement Corefinement; - Corefinement corefinement; - - typedef std::list > Decomposition; - Decomposition decomposition; - - #ifndef PRINT_EACH_VOLUME - int features=Corefinement::Join_tag+Corefinement::Intersection_tag+Corefinement::P_minus_Q_tag+Corefinement::Q_minus_P_tag; - #else - int features=Corefinement::Decomposition_tag; - #endif - corefinement(A, B, std::back_inserter(new_item->polylines),std::back_inserter(decomposition),features); - - - for (Decomposition::iterator it=decomposition.begin();it!=decomposition.end();++it) - { - Polyhedron* new_poly=it->first; - Scene_polyhedron_item* new_item_bool= new Scene_polyhedron_item(new_poly); - new_item_bool->setName( - QString::fromStdString( - corefinement.get_type_str(itemA->name().toStdString(),itemB->name().toStdString(),it->second) - ) - ); - scene->addItem(new_item_bool); - } - #else - Scene_combinatorial_map_item* cmap_item = new Scene_combinatorial_map_item(scene,static_cast(&A)); - typedef CGAL::Corefinement::Combinatorial_map_output_builder Output_builder; - typedef CGAL::Node_visitor_refine_polyhedra Split_visitor; - cmap_item->m_combinatorial_map=boost::shared_ptr( new Combinatorial_map_3() ); - Split_visitor visitor( Output_builder(cmap_item->m_combinatorial_map) ); - CGAL::Intersection_of_Polyhedra_3 polyline_intersections(visitor); - polyline_intersections(A, B, std::back_inserter(new_item->polylines)); - cmap_item->setName(QString("%1_and_%2_corefined").arg(itemA->name()).arg(itemB->name())); - scene->addItem(cmap_item); - #endif - new_item->setName(tr("boundary intersection")); - new_item->setColor(Qt::green); - new_item->setRenderingMode(Wireframe); - scene->addItem(new_item); - new_item->invalidateOpenGLBuffers(); - std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; - - } - - QApplication::restoreOverrideCursor(); -} - -#include "Corefinement_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Intersection_plugin.cpp deleted file mode 100644 index 2d8080c8ba6..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Intersection_plugin.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#define CGAL_COREFINEMENT_DO_REPORT_SELF_INTERSECTIONS -#define CGAL_USE_SEGMENT_APPROACH -#include -#ifdef CGAL_USE_SEGMENT_APPROACH -#include -#else -#include -#endif -#include -#include -#include "Scene_polyhedron_item.h" -#include "Polyhedron_type.h" -#include - -#include "Scene_polylines_item.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -using namespace CGAL::Three; -class Polyhedron_demo_intersection_plugin : - public QObject, - public Polyhedron_demo_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") - -public: - - bool applicable(QAction*) const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); - } - - QList actions() const { - return QList() << actionPolyhedronIntersection_3; - } - - void init(QMainWindow* mw, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) { - this->scene = scene_interface; - actionPolyhedronIntersection_3 = new QAction("Intersect Polyhedra (A/B)", mw); - actionPolyhedronIntersection_3->setProperty("subMenuName", "Operations on Polyhedra"); - if(actionPolyhedronIntersection_3) { - connect(actionPolyhedronIntersection_3, SIGNAL(triggered()), - this, SLOT(intersection())); - } - } - -private: - - QAction* actionPolyhedronIntersection_3; - Scene_interface *scene; - -public Q_SLOTS: - void intersection(); - -}; // end class Polyhedron_demo_intersection_plugin - - -#ifdef CGAL_USE_SEGMENT_APPROACH -struct Is_on_polyline{ - bool operator()(Polyhedron::Halfedge_handle he) const { - return he->is_feature_edge(); - } -}; - -struct Set_vertex_corner{ - template - void add_info_to_node(int, Polyhedron*,const Info&) { - } - - void operator()(Polyhedron::Vertex_handle v, int, Polyhedron*) { - ++v->nb_of_feature_edges; - } -}; -#endif - -void Polyhedron_demo_intersection_plugin::intersection() -{ - int indexA = scene->selectionAindex(); - int indexB = scene->selectionBindex(); - - Scene_polyhedron_item* itemA = - qobject_cast(scene->item(indexA)); - Scene_polyhedron_item* itemB = - qobject_cast(scene->item(indexB)); - if(!itemA || !itemB || itemA == itemB) - { - Q_FOREACH(int index, scene->selectionIndices()) { - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - if(!item) - return; - } - if(scene->selectionIndices().size() == 2) { - indexA = scene->selectionIndices()[0]; - indexB = scene->selectionIndices()[1]; - itemA = - qobject_cast(scene->item(indexA)); - itemB = - qobject_cast(scene->item(indexB)); - } - } -#ifndef CGAL_USE_SEGMENT_APPROACH - if(!itemA || !itemB || itemA == itemB) - return; -#else - std::vector poly_ptrs; - Q_FOREACH(int index, scene->selectionIndices()) { - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - if(!item) - return; - else if(item != itemA) { - poly_ptrs.push_back(item->polyhedron()); - if(poly_ptrs.back() == 0) return; - } - } -#endif - - QApplication::setOverrideCursor(Qt::WaitCursor); - - Scene_polylines_item* new_item = new Scene_polylines_item(); - // perform Boolean operation - QTime time; - time.start(); - -#ifdef CGAL_USE_SEGMENT_APPROACH - typedef CGAL::Node_visitor_for_polyline_split Split_visitor; - - CGAL::Intersection_of_Polyhedra_3 polyline_intersections; - - typedef std::pair Pair_of_facet_handles; - typedef std::vector Polyline_info; - typedef std::vector Polylines_infos; - Polylines_infos polylines_infos; - - typedef Scene_polylines_item::Polylines_container Polylines_container; - typedef std::back_insert_iterator To_container; - typedef std::back_insert_iterator To_infos; - To_container to_container(new_item->polylines); - To_infos to_infos(polylines_infos); - CGAL::Dispatch_output_iterator< - CGAL::cpp11::tuple, - CGAL::cpp11::tuple > out_iterator(to_container, - to_infos); - - if(itemA && itemB && itemA != itemB) { - Polyhedron* A = itemA->polyhedron(); - Polyhedron* B = itemB->polyhedron(); - polyline_intersections(*A, *B, out_iterator); - } else { - if(itemA) { - Polyhedron* A = itemA->polyhedron(); - polyline_intersections(*A, - poly_ptrs.begin(), - poly_ptrs.end(), - out_iterator, - 0); - } else { - polyline_intersections(poly_ptrs.begin(), - poly_ptrs.end(), - out_iterator, - 0); - } - } - QStringList polylines_metadata; - BOOST_FOREACH(Polyline_info& info, polylines_infos) { - std::set indices; - BOOST_FOREACH(Pair_of_facet_handles p, info) - { - indices.insert(p.first->patch_id()); - indices.insert(p.second->patch_id()); - } - QString metadata; - BOOST_FOREACH(int index, indices) { - metadata = metadata + QString(" %1").arg(index); - } - std::cerr << "new polyline metadata: " << qPrintable(metadata) << "\n"; - polylines_metadata << metadata; - } - new_item->setProperty("polylines metadata", polylines_metadata); - new_item->setName(tr("intersection")); -#else - Polyhedron* A = itemA->polyhedron(); - Polyhedron* B = itemB->polyhedron(); - CGAL::intersection_Polyhedron_3_Polyhedron_3(*A, *B, std::back_inserter(new_item->polylines)); - - QString name = tr("%1 intersection %2"); - - new_item->setName(name.arg(itemA->name(), itemB->name())); - itemA->setRenderingMode(Wireframe); - itemB->setRenderingMode(Wireframe); - scene->itemChanged(indexA); - scene->itemChanged(indexB); -#endif - std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; - - if (new_item->polylines.empty()) - delete new_item; - else{ - new_item->setColor(Qt::green); - new_item->setRenderingMode(Wireframe); - scene->addItem(new_item); - new_item->invalidateOpenGLBuffers(); - } - - QApplication::restoreOverrideCursor(); -} - -#include "Intersection_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.cpp deleted file mode 100644 index a9285733a37..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.cpp +++ /dev/null @@ -1,579 +0,0 @@ -#include "Scene_combinatorial_map_item.h" -#include "Scene_polyhedron_item.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -struct Scene_combinatorial_map_item_priv -{ - Scene_combinatorial_map_item_priv(CGAL::Three::Scene_interface* scene, void* ad_A, Scene_combinatorial_map_item* parent) - :last_known_scene(scene),volume_to_display(0),exportSelectedVolume(NULL),address_of_A(ad_A) - { - item = parent; - item->are_buffers_filled = false; - nb_points = 0; - nb_lines =0; - nb_facets =0; - } - - Kernel::Vector_3 compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const; - - template - void export_as_polyhedron(Predicate,const QString&) const; - void initialize_buffers(CGAL::Three::Viewer_interface *viewer) const; - void compute_elements(void) const; - - Scene_combinatorial_map_item *item; - enum VAOs { - Edges = 0, - Points, - Facets, - NbOfVaos - }; - enum VBOs { - Edges_vertices = 0, - Points_vertices, - Facets_vertices, - Facets_normals, - NbOfVbos - }; - - CGAL::Three::Scene_interface* last_known_scene; - std::size_t volume_to_display; - QAction* exportSelectedVolume; - void* address_of_A; - - mutable QOpenGLShaderProgram *program; - mutable std::vector positions_lines; - mutable std::vector positions_points; - mutable std::vector positions_facets; - mutable std::vector normals; - mutable std::size_t nb_lines; - mutable std::size_t nb_points; - mutable std::size_t nb_facets; -}; -Scene_combinatorial_map_item::Scene_combinatorial_map_item(CGAL::Three::Scene_interface* scene,void* address){d = new Scene_combinatorial_map_item_priv(scene, address, this);} -Scene_combinatorial_map_item::~Scene_combinatorial_map_item(){delete d;} - -Scene_combinatorial_map_item* Scene_combinatorial_map_item::clone() const{return NULL;} - -Kernel::Vector_3 Scene_combinatorial_map_item_priv::compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const -{ - typedef Combinatorial_map_3::Dart_of_orbit_const_range<1> Dart_in_facet_range; - typedef Kernel::Vector_3 Vector_3; - Vector_3 normal = CGAL::NULL_VECTOR; - - Dart_in_facet_range vertices=item->combinatorial_map().darts_of_orbit<1>(adart); - Kernel::Point_3 points[3]; - int index=0; - Dart_in_facet_range::const_iterator pit=vertices.begin(); - for (;pit!=vertices.end() && index!=3;++pit,++index ){ - points[index]=item->combinatorial_map().attribute<0>(pit)->point(); - } - - if (index!=3) return normal; - - do{ - Vector_3 n = CGAL::cross_product(points[2]-points[1],points[0]-points[1]); - if (n != Vector_3(0,0,0) ) - normal = normal + (n / std::sqrt(n*n)); - points[0]=points[1]; - points[1]=points[2]; - if ( pit==vertices.end() ) break; - - points[2]=item->combinatorial_map().attribute<0>(pit)->point(); - ++pit; - }while(true); - - return normal == Vector_3(0,0,0)? normal : normal / std::sqrt(normal * normal); -} - -void Scene_combinatorial_map_item::set_next_volume(){ - //Update des vectors faits ici - ++d->volume_to_display; - d->volume_to_display=d->volume_to_display%(combinatorial_map().attributes<3>().size()+1); - are_buffers_filled = false; - invalidateOpenGLBuffers(); - Q_EMIT itemChanged(); - - if (d->exportSelectedVolume!=NULL && ( d->volume_to_display==1 || d->volume_to_display==0 ) ) - d->exportSelectedVolume->setEnabled(!d->exportSelectedVolume->isEnabled()); -} - - -template -void Scene_combinatorial_map_item_priv::export_as_polyhedron(Predicate pred,const QString& name) const { - typedef Combinatorial_map_3::Dart_const_handle Dart_handle; - typedef Combinatorial_map_3::One_dart_per_cell_range<3> One_dart_per_vol_range; - typedef CGAL::internal::Import_volume_as_polyhedron Volume_import_modifier; - - std::vector darts; - One_dart_per_vol_range cell_range=item->combinatorial_map().template one_dart_per_cell<3>(); - - - for (One_dart_per_vol_range::const_iterator it = cell_range.begin();it!= cell_range.end() ; ++it ) - if ( pred(it) ){ - darts.push_back(it); - if (Predicate::only_one_run) break; - } - - if (!darts.empty()) - { - Volume_import_modifier modifier=Predicate::swap_orientation? - Volume_import_modifier(item->combinatorial_map(),darts.begin(),darts.end(),Predicate::swap_orientation): - Volume_import_modifier(item->combinatorial_map(),darts.begin(),darts.end()); - - Polyhedron* new_poly=new Polyhedron(); - new_poly->delegate(modifier); - Scene_polyhedron_item* new_item = new Scene_polyhedron_item(new_poly); - new_item->setName(name); - last_known_scene->addItem(new_item); - } -} - -struct Select_volume{ - static const bool only_one_run=true; - static const bool swap_orientation=false; - Select_volume(std::size_t i):volume_to_select(i),index(0){} - template - bool operator() (Dart_handle){ - return ++index==volume_to_select; - } -private: - std::size_t volume_to_select; - std::size_t index; -}; - -void Scene_combinatorial_map_item::export_current_volume_as_polyhedron() const { - if (d->volume_to_display==0) return; //no volume selected - - Select_volume predicate(d->volume_to_display); - d->export_as_polyhedron(predicate,QString("%1_%2").arg(this->name()).arg(d->volume_to_display-1)); -} - -struct Select_union{ - const Combinatorial_map_3& map; - Select_union(const Combinatorial_map_3& m) : map(m) {} - static const bool only_one_run=false; - static const bool swap_orientation=true; - template - bool operator() (Dart_handle d){ return map.template attribute<3>(d)->info().outside.size()==2; } -}; - -struct Select_inter{ - const Combinatorial_map_3& map; - Select_inter(const Combinatorial_map_3& m) : map(m) {} - static const bool only_one_run=false; - static const bool swap_orientation=false; - template - bool operator() (Dart_handle d){ return map.template attribute<3>(d)->info().inside.size()==2; } -}; - -struct Select_A_minus_B{ - const Combinatorial_map_3& map; - static const bool only_one_run=false; - static const bool swap_orientation=false; - Select_A_minus_B(const Combinatorial_map_3& m, void* address):map(m), address_of_A(address){} - template - bool operator() (Dart_handle d){ - return map.template attribute<3>(d)->info().inside.size()==1 && - static_cast(*map.template attribute<3>(d)->info().inside.begin())==address_of_A; - } -private: - void* address_of_A; -}; - -struct Select_B_minus_A{ - const Combinatorial_map_3& map; - static const bool only_one_run=false; - static const bool swap_orientation=false; - Select_B_minus_A(const Combinatorial_map_3& m, void* address):map(m), address_of_A(address){} - template - bool operator() (Dart_handle d){ - return map.template attribute<3>(d)->info().inside.size()==1 && - static_cast(*map.template attribute<3>(d)->info().inside.begin())!=address_of_A; - } -private: - void* address_of_A; -}; - -void Scene_combinatorial_map_item::export_union_as_polyhedron() const { - d->export_as_polyhedron(Select_union(this->combinatorial_map()),QString("%1_union_%2").arg("A").arg("B")); -} -void Scene_combinatorial_map_item::export_intersection_as_polyhedron() const{ - d->export_as_polyhedron(Select_inter(this->combinatorial_map()),QString("%1_inter_%2").arg("A").arg("B")); -} -void Scene_combinatorial_map_item::export_A_minus_B_as_polyhedron() const{ - Select_A_minus_B predicate(this->combinatorial_map(),d->address_of_A); - d->export_as_polyhedron(predicate,QString("%1_minus_%2").arg("A").arg("B")); -} -void Scene_combinatorial_map_item::export_B_minus_A_as_polyhedron() const{ - Select_B_minus_A predicate(this->combinatorial_map(),d->address_of_A); - d->export_as_polyhedron(predicate,QString("%1_minus_%2").arg("B").arg("A")); -} - -QMenu* Scene_combinatorial_map_item::contextMenu() -{ - const char* prop_name = "Menu modified by Scene_combinatorial_map_item."; - - QMenu* menu = Scene_item::contextMenu(); - - // Use dynamic properties: - // http://doc.qt.io/qt-5/qobject.html#property - bool menuChanged = menu->property(prop_name).toBool(); - - if(!menuChanged) { - QAction* actionSelectNextVolume = - menu->addAction(tr("Iterate over volumes")); - actionSelectNextVolume->setObjectName("actionSelectNextVolume"); - connect(actionSelectNextVolume, SIGNAL(triggered()),this, SLOT(set_next_volume())); - - d->exportSelectedVolume = - menu->addAction(tr("Export current volume as polyhedron")); - d->exportSelectedVolume->setObjectName("exportSelectedVolume"); - connect(d->exportSelectedVolume, SIGNAL(triggered()),this, SLOT(export_current_volume_as_polyhedron())); - d->exportSelectedVolume->setEnabled(d->volume_to_display!=0); - menu->setProperty(prop_name, true); - - if(is_from_corefinement()){ - //Export union as polyhedron - QAction* exportUnion = - menu->addAction(tr("Export union as polyhedron")); - exportUnion->setObjectName("exportUnion"); - connect(exportUnion, SIGNAL(triggered()),this, SLOT(export_union_as_polyhedron())); - - //Export intersection as polyhedron - QAction* exportIntersection = - menu->addAction(tr("Export intersection as polyhedron")); - exportIntersection->setObjectName("exportIntersection"); - connect(exportIntersection, SIGNAL(triggered()),this, SLOT(export_intersection_as_polyhedron())); - - //Export A minus B as polyhedron - QAction* exportAMinusB = - menu->addAction(tr("Export A minus B as polyhedron")); - exportAMinusB->setObjectName("exportAMinusB"); - connect(exportAMinusB, SIGNAL(triggered()),this, SLOT(export_A_minus_B_as_polyhedron())); - - //Export B minus A as polyhedron - QAction* exportBMinusA = - menu->addAction(tr("Export B minus A as polyhedron")); - exportBMinusA->setObjectName("exportBMinusA"); - connect(exportBMinusA, SIGNAL(triggered()),this, SLOT(export_B_minus_A_as_polyhedron())); - - } - } - return menu; -} - -bool Scene_combinatorial_map_item::keyPressEvent(QKeyEvent* e){ - if (e->key()==Qt::Key_N){ - set_next_volume(); - return true; - } - return false; -} - -void Scene_combinatorial_map_item_priv::compute_elements(void) const{ - QApplication::setOverrideCursor(Qt::WaitCursor); - - positions_facets.resize(0); - normals.resize(0); - positions_lines.resize(0); - positions_points.resize(0); - - //Facets - { - std::size_t index = 0; - Combinatorial_map_3::size_type voltreated - = item->combinatorial_map().get_new_mark(); - Combinatorial_map_3::size_type facetreated - = item->combinatorial_map().get_new_mark(); - Combinatorial_map_3::Dart_const_range::const_iterator - darts_it=item->combinatorial_map().darts().begin(), darts_end=item->combinatorial_map().darts().end(); - for( ; darts_it!=darts_end; ++darts_it) - { - if ( !item->combinatorial_map().is_marked(darts_it,voltreated) ) - { - ++index; - //iterate over all the darts of the volume - Combinatorial_map_3::Dart_of_cell_const_range<3>::const_iterator - vol_it=item->combinatorial_map().darts_of_cell<3>(darts_it).begin(), - vol_end=item->combinatorial_map().darts_of_cell<3>(darts_it).end(); - if ( volume_to_display!=0 && index!=volume_to_display ) - { - //only mark darts if the volume is not the one to display - for ( ;vol_it!=vol_end; ++vol_it ) - { - item->combinatorial_map().mark(vol_it,facetreated); - item->combinatorial_map().mark(vol_it, voltreated); - } - } - else - { - for ( ;vol_it!=vol_end; ++vol_it ) - { - if ( !item->combinatorial_map().is_marked(vol_it,facetreated) ) - { - Kernel::Vector_3 normal = compute_face_normal(vol_it); - for(int i=0; i<3; i++) - { - normals.push_back(normal.x()); - normals.push_back(normal.y()); - normals.push_back(normal.z()); - } - - //iterate over all darts of facets - for ( Combinatorial_map_3::Dart_of_orbit_const_range<1>::const_iterator - face_it=item->combinatorial_map().darts_of_orbit<1>(vol_it).begin(), - face_end=item->combinatorial_map().darts_of_orbit<1>(vol_it).end(); - face_it!=face_end; ++face_it) - { - const Kernel::Point_3& p= item->combinatorial_map().attribute<0>(face_it)->point(); - positions_facets.push_back(p.x()); - positions_facets.push_back(p.y()); - positions_facets.push_back(p.z()); - item->combinatorial_map().mark(face_it,facetreated); - item->combinatorial_map().mark(face_it, voltreated); - } - } - } - } - if ( index==volume_to_display ) break; - } - } - //mark remaining darts to have an O(1) free_mark - for( ; darts_it!=darts_end; ++darts_it) - { - item->combinatorial_map().mark(darts_it, facetreated); - item->combinatorial_map().mark(darts_it, voltreated); - } - - item->combinatorial_map().free_mark(facetreated); - item->combinatorial_map().free_mark(voltreated); - } - - //edges - { - - typedef Combinatorial_map_3::One_dart_per_cell_range<1,3> Edge_darts; - Edge_darts darts=item->combinatorial_map().one_dart_per_cell<1>(); - for (Edge_darts::const_iterator dit=darts.begin();dit!=darts.end();++dit){ - CGAL_assertion(!item->combinatorial_map().is_free(dit,1)); - const Kernel::Point_3& a = item->combinatorial_map().attribute<0>(dit)->point(); - const Kernel::Point_3& b = item->combinatorial_map().attribute<0>(item->combinatorial_map().beta(dit,1))->point(); - positions_lines.push_back(a.x()); - positions_lines.push_back(a.y()); - positions_lines.push_back(a.z()); - - positions_lines.push_back(b.x()); - positions_lines.push_back(b.y()); - positions_lines.push_back(b.z()); - - } - } - - //points - { - typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range; - const Point_range& points=item->combinatorial_map().attributes<0>(); - for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit){ - const Kernel::Point_3& p=pit->point(); - positions_points.push_back(p.x()); - positions_points.push_back(p.y()); - positions_points.push_back(p.z()); - } - - } - QApplication::restoreOverrideCursor(); -} - - -void Scene_combinatorial_map_item_priv::initialize_buffers(CGAL::Three::Viewer_interface *viewer) const -{ - //vao for the edges - { - program = item->getShaderProgram(Scene_combinatorial_map_item::PROGRAM_WITHOUT_LIGHT, viewer); - program->bind(); - - item->vaos[Scene_combinatorial_map_item_priv::Edges]->bind(); - item->buffers[Scene_combinatorial_map_item_priv::Edges_vertices].bind(); - item->buffers[Scene_combinatorial_map_item_priv::Edges_vertices].allocate(positions_lines.data(), - static_cast(positions_lines.size()*sizeof(double))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - item->buffers[Scene_combinatorial_map_item_priv::Edges_vertices].release(); - nb_lines = positions_lines.size(); - positions_lines.resize(0); - std::vector(positions_lines).swap(positions_lines); - item->vaos[Scene_combinatorial_map_item_priv::Edges]->release(); - program->release(); - } - //vao for the points - { - program = item->getShaderProgram(Scene_combinatorial_map_item::PROGRAM_WITHOUT_LIGHT, viewer); - program->bind(); - - item->vaos[Scene_combinatorial_map_item_priv::Points]->bind(); - item->buffers[Scene_combinatorial_map_item_priv::Points_vertices].bind(); - item->buffers[Scene_combinatorial_map_item_priv::Points_vertices].allocate(positions_points.data(), - static_cast(positions_points.size()*sizeof(double))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - item->buffers[Scene_combinatorial_map_item_priv::Points_vertices].release(); - item->vaos[Scene_combinatorial_map_item_priv::Points]->release(); - nb_points = positions_points.size(); - positions_points.resize(0); - std::vector(positions_points).swap(positions_points); - program->release(); - } - //vao for the facets - { - program = item->getShaderProgram(Scene_combinatorial_map_item::PROGRAM_WITH_LIGHT, viewer); - program->bind(); - - item->vaos[Scene_combinatorial_map_item_priv::Facets]->bind(); - item->buffers[Scene_combinatorial_map_item_priv::Facets_vertices].bind(); - item->buffers[Scene_combinatorial_map_item_priv::Facets_vertices].allocate(positions_facets.data(), - static_cast(positions_facets.size()*sizeof(double))); - program->enableAttributeArray("vertex"); - program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); - item->buffers[Scene_combinatorial_map_item_priv::Facets_vertices].release(); - - item->buffers[Scene_combinatorial_map_item_priv::Facets_normals].bind(); - item->buffers[Scene_combinatorial_map_item_priv::Facets_normals].allocate(normals.data(), - static_cast(normals.size()*sizeof(double))); - program->enableAttributeArray("normals"); - program->setAttributeBuffer("normals",GL_DOUBLE,0,3); - item->buffers[Scene_combinatorial_map_item_priv::Facets_normals].release(); - nb_facets = positions_facets.size(); - positions_facets.resize(0); - std::vector(positions_facets).swap(positions_facets); - normals.resize(0); - std::vector(normals).swap(normals); - item->vaos[Scene_combinatorial_map_item_priv::Facets]->release(); - program->release(); - } - item->are_buffers_filled = true; - - -} - -bool Scene_combinatorial_map_item::isEmpty() const {return combinatorial_map().number_of_darts()==0;} - -void -Scene_combinatorial_map_item::compute_bbox() const { - typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range; - const Point_range& points=combinatorial_map().attributes<0>(); - CGAL::Bbox_3 bbox=points.begin()->point().bbox(); - for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit) - bbox=bbox+pit->point().bbox(); - _bbox = Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); -} - - -QString Scene_combinatorial_map_item::toolTip() const{ - if(!m_combinatorial_map) - return QString(); - - std::vector cells(5); - for (unsigned int i=0; i<=4; ++i) - cells[i]=i; - std::vector res = combinatorial_map().count_cells(cells); - if (d->volume_to_display==0) - return QObject::tr("

Combinatorial_map_3 %1 (mode: %8, color: %9)

" - "

Number of darts: %2
" - "Number of vertices: %3
" - "Number of edges: %4
" - "Number of facets: %5
" - "Number of volumes: %6
" - "Number of connected components: %7

") - .arg(this->name()) - .arg(combinatorial_map().number_of_darts()) - .arg(res[0]) - .arg(res[1]) - .arg(res[2]) - .arg(res[3]) - .arg(res[4]) - .arg(this->renderingModeName()) - .arg(this->color().name()); - return QObject::tr("

Combinatorial_map_3 %1 (mode: %8, color: %9)

" - "

Number of darts: %2
" - "Number of vertices: %3
" - "Number of edges: %4
" - "Number of facets: %5
" - "Number of volumes: %6
" - "Number of connected components: %7
" - "Currently Displaying facets of volume: %10

") - .arg(this->name()) - .arg(combinatorial_map().number_of_darts()) - .arg(res[0]) - .arg(res[1]) - .arg(res[2]) - .arg(res[3]) - .arg(res[4]) - .arg(this->renderingModeName()) - .arg(this->color().name()) - .arg(d->volume_to_display-1); -} - - -void Scene_combinatorial_map_item::draw(CGAL::Three::Viewer_interface* viewer) const -{ - if(!are_buffers_filled) - { - d->compute_elements(); - d->initialize_buffers(viewer); - } - vaos[Scene_combinatorial_map_item_priv::Facets]->bind(); - d->program=getShaderProgram(PROGRAM_WITH_LIGHT); - attribBuffers(viewer,PROGRAM_WITH_LIGHT); - d->program->bind(); - d->program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(d->nb_facets/3)); - vaos[Scene_combinatorial_map_item_priv::Facets]->release(); - d->program->release(); -} - void Scene_combinatorial_map_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const -{ - if(!are_buffers_filled) - { - d->compute_elements(); - d->initialize_buffers(viewer); - } - vaos[Scene_combinatorial_map_item_priv::Edges]->bind(); - d->program=getShaderProgram(PROGRAM_WITHOUT_LIGHT); - attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT); - d->program->bind(); - d->program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_LINES, 0, static_cast(d->nb_lines/3)); - vaos[Scene_combinatorial_map_item_priv::Edges]->release(); - d->program->release(); - -} - void Scene_combinatorial_map_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const -{ - if(!are_buffers_filled) - { - d->compute_elements(); - d->initialize_buffers(viewer); - } - vaos[Scene_combinatorial_map_item_priv::Points]->bind(); - d->program=getShaderProgram(PROGRAM_WITHOUT_LIGHT); - attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT); - d->program->bind(); - d->program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(d->nb_points/3)); - vaos[Scene_combinatorial_map_item_priv::Points]->release(); - d->program->release(); -} - - bool Scene_combinatorial_map_item::is_from_corefinement() const{return d->address_of_A!=NULL;} diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.h b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.h deleted file mode 100644 index 64610438522..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef SCENE_COMBINATORIAL_MAP_ITEM_H -#define SCENE_COMBINATORIAL_MAP_ITEM_H - -//========= -#include -#include "Scene_combinatorial_map_item_config.h" -#include -#include -#include -#include -#include "Polyhedron_type.h" -#include -typedef CGAL::internal_IOP::Item_with_points_and_volume_info Items; -typedef CGAL::Combinatorial_map<3,Items> Combinatorial_map_3; -//========= -struct Scene_combinatorial_map_item_priv; -class QMenu; -class QAction; -namespace CGAL { namespace Three{ -class Scene_interface; -}} -class Scene_polyhedron_item; -class Viewer_interface; - -class SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Scene_combinatorial_map_item - : public CGAL::Three::Scene_item -{ - Q_OBJECT -public: - Scene_combinatorial_map_item(CGAL::Three::Scene_interface*,void* ad_A=NULL); - ~Scene_combinatorial_map_item(); - - Scene_combinatorial_map_item* clone() const; - // Function to override the context menu - QMenu* contextMenu(); - - // bool load(std::istream& in); - // void load(Scene_polyhedron_item*); - // bool save(std::ostream& out) const; - - QString toolTip() const; - - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting && m!=ShadedPoints); } // CHECK THIS! - //Event handling - virtual bool keyPressEvent(QKeyEvent*); - //drawing of the scene - virtual void drawEdges(CGAL::Three::Viewer_interface* viewer) const; - virtual void drawPoints(CGAL::Three::Viewer_interface*) const; - virtual void draw(CGAL::Three::Viewer_interface*) const; - - bool isFinite() const { return true; } - bool is_from_corefinement() const; - bool isEmpty() const; - void compute_bbox() const; - - const Combinatorial_map_3& combinatorial_map() const - { - return *m_combinatorial_map; - } - - Combinatorial_map_3& combinatorial_map() - { - return *m_combinatorial_map; - } - - boost::shared_ptr m_combinatorial_map; - - -public Q_SLOTS: - void set_next_volume(); - void export_current_volume_as_polyhedron() const; - void export_union_as_polyhedron() const; - void export_intersection_as_polyhedron() const; - void export_A_minus_B_as_polyhedron() const; - void export_B_minus_A_as_polyhedron() const; -protected: - friend struct Scene_combinatorial_map_item_priv; - Scene_combinatorial_map_item_priv* d; - -}; // end class Scene_combinatorial_map_item - -#endif // SCENE_COMBINATORIAL_MAP_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item_config.h b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item_config.h deleted file mode 100644 index fbe1df44652..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item_config.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SCENE_COMBINATORIAL_MAP_ITEM_CONFIG_H -#define SCENE_COMBINATORIAL_MAP_ITEM_CONFIG_H - -#ifdef scene_combinatorial_map_item_EXPORTS -# define SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Q_DECL_EXPORT -#else -# define SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Q_DECL_IMPORT -#endif - -#endif // SCENE_COMBINATORIAL_MAP_ITEM_CONFIG_H diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 2aee9ba72f4..6dd3a47fc83 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -69,6 +69,12 @@ target_link_libraries(self_intersection_plugin scene_polyhedron_item scene_polyh polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin) target_link_libraries(triangulate_facets_plugin scene_polyhedron_item) +polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin) +target_link_libraries(corefinement_plugin scene_polyhedron_item) + +polyhedron_demo_plugin(surface_intersection_plugin Surface_intersection_plugin) +target_link_libraries(surface_intersection_plugin scene_polyhedron_item scene_polylines_item) + polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin) target_link_libraries(repair_polyhedron_plugin scene_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp new file mode 100644 index 00000000000..15e2a4fada2 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Corefinement_plugin.cpp @@ -0,0 +1,228 @@ +#include +#include +#include +#include "Messages_interface.h" +#include +#include "Scene_polyhedron_item.h" +#include "Polyhedron_type.h" + +#include + +using namespace CGAL::Three; +namespace PMP = CGAL::Polygon_mesh_processing; +class Polyhedron_demo_corefinement_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + + enum bool_op {CRF_UNION, CRF_INTER, CRF_MINUS, CRF_MINUS_OP}; + +public: + + void init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, + Messages_interface* m) { + this->scene = scene_interface; + this->mw = mainWindow; + this->messages = m; + actionCorefine = new QAction("Corefine", mw); + actionCorefine->setProperty("subMenuName","Polygon Mesh Processing/Corefinement"); + if(actionCorefine) + connect(actionCorefine, SIGNAL(triggered()), this, SLOT(corefine())); + + actionUnion = new QAction("Compute Union", mw); + actionUnion->setProperty("subMenuName","Polygon Mesh Processing/Corefinement"); + if(actionUnion) + connect(actionUnion, SIGNAL(triggered()), this, SLOT(corefine_and_union())); + + actionInter = new QAction("Compute Intersection", mw); + actionInter->setProperty("subMenuName","Polygon Mesh Processing/Corefinement"); + if(actionInter) + connect(actionInter, SIGNAL(triggered()), this, SLOT(corefine_and_inter())); + + actionDiff = new QAction("Compute Difference", mw); + actionDiff->setProperty("subMenuName","Polygon Mesh Processing/Corefinement"); + if(actionDiff) + connect(actionDiff, SIGNAL(triggered()), this, SLOT(corefine_and_diff())); + + actionDiffRev = new QAction("Compute Opposite Difference", mw); + actionDiffRev->setProperty("subMenuName","Polygon Mesh Processing/Corefinement"); + if(actionDiffRev) + connect(actionDiffRev, SIGNAL(triggered()), this, SLOT(corefine_and_diff_rev())); + }; + + QList actions() const { + return QList() << actionCorefine + << actionUnion + << actionInter + << actionDiff + << actionDiffRev; + } + + bool applicable(QAction*) const { + int nb_selected=0; + Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices()) + if ( qobject_cast(scene->item(index)) ) + ++nb_selected; + return nb_selected==2; + } + +public Q_SLOTS: + void corefine() { + Scene_polyhedron_item* first_item = NULL; + Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices()) + { + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + if (first_item==NULL) + { + first_item = item; + continue; + } + + if(!first_item->polyhedron()->is_pure_triangle()) { + messages->warning(tr("The polyhedron \"%1\" is not triangulated.") + .arg(first_item->name())); + return; + } + if(!item->polyhedron()->is_pure_triangle()) { + messages->warning(tr("The polyhedron \"%1\" is not triangulated.") + .arg(item->name())); + return; + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + PMP::corefine(*first_item->polyhedron(), *item->polyhedron()); + first_item->invalidateOpenGLBuffers(); + item->invalidateOpenGLBuffers(); + scene->itemChanged(item); + scene->itemChanged(first_item); + // default cursor + QApplication::restoreOverrideCursor(); + break; + } // end of if(item) + } // end of the loop on the selected items + } + + + void corefine_and_bool_op(bool_op op) + { + Scene_polyhedron_item* first_item = NULL; + Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices()) + { + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + if (first_item==NULL) + { + first_item = item; + continue; + } + + if(!first_item->polyhedron()->is_pure_triangle()) { + messages->warning(tr("The polyhedron \"%1\" is not triangulated.") + .arg(first_item->name())); + return; + } + if(!item->polyhedron()->is_pure_triangle()) { + messages->warning(tr("The polyhedron \"%1\" is not triangulated.") + .arg(item->name())); + return; + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + Polyhedron* new_poly = new Polyhedron(); + QString str_op; + Polyhedron P, Q; + switch(op) + { + case CRF_UNION: + P = *first_item->polyhedron(), Q = *item->polyhedron(); + if (! PMP::corefine_and_compute_union(P, Q, *new_poly) ) + { + delete new_poly; + messages->warning(tr("The result of the requested operation is not manifold and has not been computed.")); + return; + } + str_op = "Union"; + break; + case CRF_INTER: + P = *first_item->polyhedron(), Q = *item->polyhedron(); + if (! PMP::corefine_and_compute_intersection(P, Q, *new_poly) ) + { + delete new_poly; + messages->warning(tr("The result of the requested operation is not manifold and has not been computed.")); + return; + } + str_op = "Intersection"; + break; + case CRF_MINUS_OP: + std::swap(first_item, item); + case CRF_MINUS: + P = *first_item->polyhedron(), Q = *item->polyhedron(); + if (! PMP::corefine_and_compute_difference(P, Q, *new_poly) ) + { + delete new_poly; + messages->warning(tr("The result of the requested operation is not manifold and has not been computed.")); + return; + } + str_op = "Difference"; + break; + } + + first_item->invalidateOpenGLBuffers(); + item->invalidateOpenGLBuffers(); + scene->itemChanged(item); + scene->itemChanged(first_item); + + Scene_polyhedron_item* new_item = new Scene_polyhedron_item(new_poly); + new_item->setName(QString("%1 of %2 and %3").arg(str_op).arg(first_item->name()).arg(item->name())); + new_item->setColor(first_item->color()); + new_item->setRenderingMode(first_item->renderingMode()); + new_item->setVisible(first_item->visible()); + scene->addItem(new_item); + new_item->invalidateOpenGLBuffers(); + + // default cursor + QApplication::restoreOverrideCursor(); + break; + } // end of if(item) + } // end of the loop on the selected items + } + + void corefine_and_union() + { + corefine_and_bool_op(CRF_UNION); + } + void corefine_and_inter() + { + corefine_and_bool_op(CRF_INTER); + } + void corefine_and_diff() + { + corefine_and_bool_op(CRF_MINUS); + } + void corefine_and_diff_rev() + { + corefine_and_bool_op(CRF_MINUS_OP); + } + + +private: + QAction* actionCorefine; + QAction* actionUnion; + QAction* actionInter; + QAction* actionDiff; + QAction* actionDiffRev; + Messages_interface* messages; +}; + +#include "Corefinement_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp new file mode 100644 index 00000000000..ea3e20e3db0 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Surface_intersection_plugin.cpp @@ -0,0 +1,122 @@ +#include +#include +#include "Scene_polyhedron_item.h" +#include "Polyhedron_type.h" +#include + +#include "Scene_polylines_item.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace CGAL::Three; +namespace PMP = CGAL::Polygon_mesh_processing; + +class Polyhedron_demo_intersection_plugin : + public QObject, + public Polyhedron_demo_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + +public: + + bool applicable(QAction*) const { + int nb_selected=0; + Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices()) + if ( qobject_cast(scene->item(index)) ) + ++nb_selected; + return nb_selected==2; + } + + QList actions() const { + return QList() << actionPolyhedronIntersection_3; + } + + void init(QMainWindow* mw, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) { + this->scene = scene_interface; + actionPolyhedronIntersection_3 = new QAction("Surface Intersection", mw); + actionPolyhedronIntersection_3->setProperty("subMenuName", "Polygon Mesh Processing"); + if(actionPolyhedronIntersection_3) { + connect(actionPolyhedronIntersection_3, SIGNAL(triggered()), + this, SLOT(intersection())); + } + } + +private: + + QAction* actionPolyhedronIntersection_3; + Scene_interface *scene; + +public Q_SLOTS: + void intersection(); + +}; // end class Polyhedron_demo_intersection_plugin + +void Polyhedron_demo_intersection_plugin::intersection() +{ + Scene_polyhedron_item* itemA = NULL; + Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices()) + { + Scene_polyhedron_item* itemB = + qobject_cast(scene->item(index)); + + if(itemB) + { + if (itemA==NULL) + { + itemA = itemB; + continue; + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + + Scene_polylines_item* new_item = new Scene_polylines_item(); + // perform Boolean operation + QTime time; + time.start(); + + try{ + PMP::surface_intersection(*itemA->polyhedron(), + *itemB->polyhedron(), + std::back_inserter(new_item->polylines), + true); + } + catch(CGAL::Corefinement::Self_intersection_exception) + { + QMessageBox::warning((QWidget*)NULL, + tr("Self-intersections Found"), + tr("Some self-intersections were found amongst intersecting facets")); + delete new_item; + QApplication::restoreOverrideCursor(); + return; + } + + QString name = tr("%1 intersection %2"); + + new_item->setName(name.arg(itemA->name(), itemB->name())); + std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; + + if (new_item->polylines.empty()) + delete new_item; + else{ + new_item->setColor(Qt::green); + new_item->setRenderingMode(Wireframe); + scene->addItem(new_item); + new_item->invalidateOpenGLBuffers(); + } + + QApplication::restoreOverrideCursor(); + } + } +} + +#include "Surface_intersection_plugin.moc"