mirror of https://github.com/CGAL/cgal
Merge hole_filling and hole_filling_polylines plugins
This commit is contained in:
parent
b8d5c5e89a
commit
d44c38644e
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@
|
|||
#include "ui_Hole_filling_widget.h"
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/triangulate_hole.h>
|
||||
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
|
||||
#include <CGAL/Polygon_mesh_processing/refine.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_function_params.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/iterator.h>
|
||||
|
||||
|
|
@ -23,6 +27,7 @@
|
|||
#include <QMainWindow>
|
||||
#include <QApplication>
|
||||
#include <QDockWidget>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
|
|
@ -33,7 +38,6 @@
|
|||
|
||||
#include <CGAL/Qt/qglviewer.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#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<int,3>
|
||||
{
|
||||
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> 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_face_graph_item*>(scene->item(scene->mainSelectionIndex())) ||
|
||||
qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex())); }
|
||||
bool applicable(QAction* action) const
|
||||
{
|
||||
if(action == actionHoleFilling)
|
||||
{
|
||||
return qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex())) ||
|
||||
qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return qobject_cast<Scene_polylines_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
}
|
||||
}
|
||||
void print_message(QString message) { CGAL::Three::Three::information(message); }
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << actionHoleFilling; }
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << actionHoleFilling
|
||||
<<actionHoleFillingPolyline; }
|
||||
|
||||
|
||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m);
|
||||
|
|
@ -352,6 +379,7 @@ public Q_SLOTS:
|
|||
}
|
||||
void on_Select_all_holes_button();
|
||||
void on_Fill_from_selection_button();
|
||||
void hole_filling_polyline_action();
|
||||
void on_Deselect_all_holes_button();
|
||||
void on_Visualize_holes_button();
|
||||
void on_Fill_selected_holes_button();
|
||||
|
|
@ -380,9 +408,15 @@ protected:
|
|||
private:
|
||||
Messages_interface* messages;
|
||||
QAction* actionHoleFilling;
|
||||
QAction* actionHoleFillingPolyline;
|
||||
|
||||
QDockWidget* dock_widget;
|
||||
Ui::HoleFilling ui_widget;
|
||||
struct Nop_functor {
|
||||
template<class T>
|
||||
void operator()(const T & /*t*/) const {}
|
||||
};
|
||||
typedef boost::function_output_iterator<Nop_functor> 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_polylines_item*>(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<Face> 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"
|
||||
|
|
|
|||
|
|
@ -1,150 +0,0 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include "Messages_interface.h"
|
||||
#include "Scene_surface_mesh_item.h"
|
||||
#include "Scene_polylines_item.h"
|
||||
#include <CGAL/Three/Scene_interface.h>
|
||||
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/triangulate_hole.h>
|
||||
#include <CGAL/Polygon_mesh_processing/refine.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_function_params.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/array.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QMainWindow>
|
||||
#include <QApplication>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
#include <CGAL/boost/iterator/transform_iterator.hpp>
|
||||
#include <CGAL/Three/Three.h>
|
||||
|
||||
|
||||
struct Face : public std::array<int,3>
|
||||
{
|
||||
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_polylines_item*>(scene->item(scene->mainSelectionIndex())); }
|
||||
void print_message(QString message) { CGAL::Three::Three::information(message); }
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << 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<class T>
|
||||
void operator()(const T & /*t*/) const {}
|
||||
};
|
||||
typedef boost::function_output_iterator<Nop_functor> Nop_out;
|
||||
|
||||
public Q_SLOTS:
|
||||
void hole_filling_polyline_action() {
|
||||
Scene_polylines_item* polylines_item = qobject_cast<Scene_polylines_item*>(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<Face> 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"
|
||||
Loading…
Reference in New Issue