From d44c38644e97546cc08b386eeccf320fbcca498a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 9 Oct 2020 14:04:27 +0200 Subject: [PATCH] Merge hole_filling and hole_filling_polylines plugins --- .../Polyhedron/Plugins/PMP/CMakeLists.txt | 3 - .../Plugins/PMP/Hole_filling_plugin.cpp | 115 +++++++++++++- .../PMP/Hole_filling_polyline_plugin.cpp | 150 ------------------ 3 files changed, 111 insertions(+), 157 deletions(-) delete mode 100644 Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_polyline_plugin.cpp diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index a7d9eac607b..5f38b486e16 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -22,9 +22,6 @@ if(TARGET CGAL::Eigen_support) polyhedron_demo_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES} KEYWORDS PMP) target_link_libraries(fairing_plugin PUBLIC scene_selection_item CGAL::Eigen_support) - polyhedron_demo_plugin(hole_filling_polyline_plugin Hole_filling_polyline_plugin ) - target_link_libraries(hole_filling_polyline_plugin PUBLIC scene_surface_mesh_item scene_polylines_item CGAL::Eigen_support) - qt5_wrap_ui( Mean_curvature_flow_skeleton_pluginUI_FILES Mean_curvature_flow_skeleton_plugin.ui) polyhedron_demo_plugin(mean_curvature_flow_skeleton_plugin Mean_curvature_flow_skeleton_plugin ${Mean_curvature_flow_skeleton_pluginUI_FILES}) target_link_libraries(mean_curvature_flow_skeleton_plugin diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index 8e20942414e..b9a532a67d9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -15,6 +15,10 @@ #include "ui_Hole_filling_widget.h" #include +#include +#include +#include +#include #include #include @@ -23,6 +27,7 @@ #include #include #include +#include #include #include @@ -33,7 +38,6 @@ #include -#include #include #include "Kernel_type.h" @@ -47,6 +51,17 @@ using namespace CGAL::Three; typedef Scene_surface_mesh_item Scene_face_graph_item; + +struct Face : public std::array +{ + Face(int i, int j, int k) + { + (*this)[0] = i; + (*this)[1] = j; + (*this)[2] = k; + } +}; + void normalize_border(Scene_face_graph_item::Face_graph&) {} @@ -77,6 +92,7 @@ public: }; public: typedef std::list Polyline_data_list; private: + struct List_iterator_comparator { bool operator()(Polyline_data_list::const_iterator it_1, Polyline_data_list::const_iterator it_2) const { return (&*it_1) < (&*it_2); } @@ -328,10 +344,21 @@ class Polyhedron_demo_hole_filling_plugin : Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "hole_filling_plugin.json") public: - bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) || - qobject_cast(scene->item(scene->mainSelectionIndex())); } + bool applicable(QAction* action) const + { + if(action == actionHoleFilling) + { + return qobject_cast(scene->item(scene->mainSelectionIndex())) || + qobject_cast(scene->item(scene->mainSelectionIndex())); + } + else + { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } + } void print_message(QString message) { CGAL::Three::Three::information(message); } - QList actions() const { return QList() << actionHoleFilling; } + QList actions() const { return QList() << actionHoleFilling + < + void operator()(const T & /*t*/) const {} + }; + typedef boost::function_output_iterator Nop_out; //Maintains a reference between all the visualizers and their poly_item // to ease the management of the visualizers @@ -435,6 +469,10 @@ void Polyhedron_demo_hole_filling_plugin::init(QMainWindow* mainWindow, ), mw); actionHoleFilling->setProperty("subMenuName", "Polygon Mesh Processing"); connect(actionHoleFilling, SIGNAL(triggered()), this, SLOT(hole_filling_action())); + actionHoleFillingPolyline = new QAction(tr("Polyline Hole Filling"), mw); + actionHoleFillingPolyline->setProperty("subMenuName", "Polygon Mesh Processing"); + connect(actionHoleFillingPolyline, SIGNAL(triggered()), + this, SLOT(hole_filling_polyline_action())); dock_widget = new QDockWidget( "Hole Filling" @@ -873,6 +911,75 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() { edge_selection->polyhedron_item()->itemChanged(); } +void Polyhedron_demo_hole_filling_plugin::hole_filling_polyline_action() { + Scene_polylines_item* polylines_item = qobject_cast(scene->item(scene->mainSelectionIndex())); + if(!polylines_item) { + print_message("Error: there is no selected polyline item!"); + return; + } + + bool also_refine; + const double density_control_factor = + QInputDialog::getDouble(mw, tr("Density Control Factor"), + tr("Density Control Factor (Cancel for not Refine): "), 1.41, 0.0, 100.0, 2, &also_refine); + + bool use_DT = + QMessageBox::Yes == QMessageBox::question( + NULL, "Use Delaunay Triangulation", "Use Delaunay Triangulation ?", QMessageBox::Yes|QMessageBox::No); + + QApplication::setOverrideCursor(Qt::WaitCursor); + QApplication::processEvents(); + std::size_t counter = 0; + for(Scene_polylines_item::Polylines_container::iterator it = polylines_item->polylines.begin(); + it != polylines_item->polylines.end(); ++it, ++counter) + { + if(it->front() != it->back()) { //not closed, skip it + print_message("Warning: skipping not closed polyline!"); + continue; + } + if(it->size() < 4) { // no triangle, skip it (needs at least 3 + 1 repeat) + print_message("Warning: skipping polyline which has less than 4 points!"); + continue; + } + + CGAL::Timer timer; timer.start(); + std::vector patch; + CGAL::Polygon_mesh_processing::triangulate_hole_polyline(*it, + std::back_inserter(patch), + PMP::parameters::use_delaunay_triangulation(use_DT)); + print_message(QString("Triangulated in %1 sec.").arg(timer.time())); + + if(patch.empty()) { + if(use_DT){ + print_message("Warning: generating patch is not successful, please try it without 'Delaunay Triangulation'!"); + continue; + } + else{ + print_message("Warning: generating patch is not successful, skipping."); + continue; + } + } + SMesh* poly = new SMesh; + CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(*it, + patch, + *poly); + + if(also_refine) { + timer.reset(); + CGAL::Polygon_mesh_processing::refine(*poly, faces(*poly), + Nop_out(), Nop_out(), + CGAL::Polygon_mesh_processing::parameters::density_control_factor(density_control_factor)); + print_message(QString("Refined in %1 sec.").arg(timer.time())); + } + + Scene_surface_mesh_item* poly_item = new Scene_surface_mesh_item(poly); + poly_item->setName(tr("%1-filled-%2").arg(polylines_item->name()).arg(counter)); + poly_item->setRenderingMode(FlatPlusEdges); + scene->setSelectedItem(scene->addItem(poly_item)); + } + QApplication::restoreOverrideCursor(); +} + // Q_EXPORT_PLUGIN2(Polyhedron_demo_hole_filling_plugin, Polyhedron_demo_hole_filling_plugin) #include "Hole_filling_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_polyline_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_polyline_plugin.cpp deleted file mode 100644 index 175ad8e9c5d..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_polyline_plugin.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include - -#include "Messages_interface.h" -#include "Scene_surface_mesh_item.h" -#include "Scene_polylines_item.h" -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - - -struct Face : public std::array -{ - Face(int i, int j, int k) - { - (*this)[0] = i; - (*this)[1] = j; - (*this)[2] = k; - } -}; -namespace PMP = CGAL::Polygon_mesh_processing; - -using namespace CGAL::Three; -class Polyhedron_demo_hole_filling_polyline_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())); } - void print_message(QString message) { CGAL::Three::Three::information(message); } - QList actions() const { return QList() << actionHoleFillingPolyline; } - - void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m){ - mw = mainWindow; - scene = scene_interface; - messages = m; - actionHoleFillingPolyline = new QAction(tr("Polyline Hole Filling"), mw); - connect(actionHoleFillingPolyline, SIGNAL(triggered()), - this, SLOT(hole_filling_polyline_action())); - } -private: - struct Nop_functor { - template - void operator()(const T & /*t*/) const {} - }; - typedef boost::function_output_iterator Nop_out; - -public Q_SLOTS: - void hole_filling_polyline_action() { - Scene_polylines_item* polylines_item = qobject_cast(scene->item(scene->mainSelectionIndex())); - if(!polylines_item) { - print_message("Error: there is no selected polyline item!"); - return; - } - - bool also_refine; - const double density_control_factor = - QInputDialog::getDouble(mw, tr("Density Control Factor"), - tr("Density Control Factor (Cancel for not Refine): "), 1.41, 0.0, 100.0, 2, &also_refine); - - bool use_DT = - QMessageBox::Yes == QMessageBox::question( - NULL, "Use Delaunay Triangulation", "Use Delaunay Triangulation ?", QMessageBox::Yes|QMessageBox::No); - - QApplication::setOverrideCursor(Qt::WaitCursor); - QApplication::processEvents(); - std::size_t counter = 0; - for(Scene_polylines_item::Polylines_container::iterator it = polylines_item->polylines.begin(); - it != polylines_item->polylines.end(); ++it, ++counter) - { - if(it->front() != it->back()) { //not closed, skip it - print_message("Warning: skipping not closed polyline!"); - continue; - } - if(it->size() < 4) { // no triangle, skip it (needs at least 3 + 1 repeat) - print_message("Warning: skipping polyline which has less than 4 points!"); - continue; - } - - CGAL::Timer timer; timer.start(); - std::vector patch; - CGAL::Polygon_mesh_processing::triangulate_hole_polyline(*it, - std::back_inserter(patch), - PMP::parameters::use_delaunay_triangulation(use_DT)); - print_message(QString("Triangulated in %1 sec.").arg(timer.time())); - - if(patch.empty()) { - if(use_DT){ - print_message("Warning: generating patch is not successful, please try it without 'Delaunay Triangulation'!"); - continue; - } - else{ - print_message("Warning: generating patch is not successful, skipping."); - continue; - } - } - SMesh* poly = new SMesh; - CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(*it, - patch, - *poly); - - if(also_refine) { - timer.reset(); - CGAL::Polygon_mesh_processing::refine(*poly, faces(*poly), - Nop_out(), Nop_out(), - CGAL::Polygon_mesh_processing::parameters::density_control_factor(density_control_factor)); - print_message(QString("Refined in %1 sec.").arg(timer.time())); - } - - Scene_surface_mesh_item* poly_item = new Scene_surface_mesh_item(poly); - poly_item->setName(tr("%1-filled-%2").arg(polylines_item->name()).arg(counter)); - poly_item->setRenderingMode(FlatPlusEdges); - scene->setSelectedItem(scene->addItem(poly_item)); - } - QApplication::restoreOverrideCursor(); - } - -private: - QMainWindow* mw; - CGAL::Three::Scene_interface* scene; - Messages_interface* messages; - QAction* actionHoleFillingPolyline; - -}; // end Polyhedron_demo_hole_filling_polyline_plugin - -// Q_EXPORT_PLUGIN2(Polyhedron_demo_hole_filling_polyline_plugin, Polyhedron_demo_hole_filling_polyline_plugin) - -#include "Hole_filling_polyline_plugin.moc"