mirror of https://github.com/CGAL/cgal
bglize hole_filling_plugin ; Does not yet work with Surface_mesh as there is also a selection
This commit is contained in:
parent
00f35fc70e
commit
97990e001f
|
|
@ -15,6 +15,11 @@ if(EIGEN3_FOUND)
|
|||
polyhedron_demo_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES})
|
||||
target_link_libraries(hole_filling_plugin scene_polyhedron_item scene_polylines_item scene_polyhedron_selection_item)
|
||||
|
||||
qt5_wrap_ui( hole_fillingUI_FILES Hole_filling_widget.ui)
|
||||
polyhedron_demo_plugin(hole_filling_sm_plugin Hole_filling_plugin ${hole_fillingUI_FILES})
|
||||
target_link_libraries(hole_filling_sm_plugin scene_surface_mesh_item scene_polylines_item scene_polyhedron_selection_item)
|
||||
target_compile_definitions(hole_filling_sm_plugin PUBLIC "-DUSE_SURFACE_MESH" )
|
||||
|
||||
qt5_wrap_ui( fairingUI_FILES Fairing_widget.ui)
|
||||
polyhedron_demo_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES})
|
||||
target_link_libraries(fairing_plugin scene_polyhedron_selection_item)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "Messages_interface.h"
|
||||
#include "Scene_polyhedron_item.h"
|
||||
#include "Scene_surface_mesh_item.h"
|
||||
#include "Scene_polylines_item.h"
|
||||
#include "Scene_polyhedron_selection_item.h"
|
||||
#include "Scene.h"
|
||||
|
|
@ -35,11 +36,35 @@
|
|||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include "Kernel_type.h"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <QMap>
|
||||
#include <QVector>
|
||||
|
||||
#ifdef USE_SURFACE_MESH
|
||||
typedef Scene_surface_mesh_item Scene_face_graph_item;
|
||||
|
||||
void normalize_border(Scene_face_graph_item::FaceGraph&)
|
||||
{}
|
||||
|
||||
#else
|
||||
typedef Scene_polyhedron_item Scene_face_graph_item;
|
||||
|
||||
void normalize_border(Scene_face_graph_item::FaceGraph& polyhedron)
|
||||
{
|
||||
polyhedron.normalize_border();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
typedef Scene_face_graph_item::FaceGraph Face_graph;
|
||||
|
||||
typedef boost::graph_traits<Face_graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef boost::graph_traits<Face_graph>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef boost::graph_traits<Face_graph>::face_descriptor face_descriptor;
|
||||
typedef Kernel::Point_3 Point_3;
|
||||
|
||||
// Class for visualizing holes in a polyhedron
|
||||
// provides mouse selection functionality
|
||||
class Q_DECL_EXPORT Scene_hole_visualizer : public CGAL::Three::Scene_item
|
||||
|
|
@ -49,7 +74,7 @@ public:
|
|||
// structs
|
||||
struct Polyline_data {
|
||||
Scene_polylines_item* polyline;
|
||||
Polyhedron::Halfedge_handle halfedge;
|
||||
halfedge_descriptor halfedge;
|
||||
qglviewer::Vec position;
|
||||
};
|
||||
struct Mouse_keyboard_state
|
||||
|
|
@ -66,7 +91,7 @@ private:
|
|||
public:
|
||||
typedef std::set<Polyline_data_list::const_iterator, List_iterator_comparator> Selected_holes_set;
|
||||
|
||||
Scene_hole_visualizer(Scene_polyhedron_item* poly_item, QMainWindow* mainWindow)
|
||||
Scene_hole_visualizer(Scene_face_graph_item* poly_item, QMainWindow* mainWindow)
|
||||
: poly_item(poly_item), block_poly_item_changed(false)
|
||||
{
|
||||
get_holes();
|
||||
|
|
@ -78,9 +103,11 @@ public:
|
|||
|
||||
connect(poly_item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed()));
|
||||
}
|
||||
|
||||
~Scene_hole_visualizer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
bool isFinite() const { return true; }
|
||||
bool isEmpty() const { return polyline_data_list.empty(); }
|
||||
void compute_bbox() const {
|
||||
|
|
@ -91,6 +118,7 @@ public:
|
|||
}
|
||||
_bbox = bbox;
|
||||
}
|
||||
|
||||
Scene_hole_visualizer* clone() const {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -175,8 +203,6 @@ public:
|
|||
private:
|
||||
// find holes in polyhedron and construct a internal polyline for each
|
||||
void get_holes() {
|
||||
typedef Polyhedron::Halfedge_iterator Halfedge_iterator;
|
||||
typedef Polyhedron::Halfedge_around_facet_circulator Halfedge_around_facet_circulator;
|
||||
// save selected hole positions to keep selected holes selected
|
||||
// we just use center position of holes for identification which might not work good for advanced cases...
|
||||
std::vector<qglviewer::Vec> selected_hole_positions;
|
||||
|
|
@ -185,31 +211,33 @@ private:
|
|||
}
|
||||
|
||||
clear();
|
||||
|
||||
Face_graph& poly = *poly_item->polyhedron();
|
||||
|
||||
Polyhedron& poly = *poly_item->polyhedron();
|
||||
for(Halfedge_iterator it = poly.halfedges_begin(); it != poly.halfedges_end(); ++it)
|
||||
{ it->id() = 0; }
|
||||
boost::unordered_set<halfedge_descriptor> visited;
|
||||
boost::property_map<Face_graph,CGAL::vertex_point_t>::type vpm = get(CGAL::vertex_point,poly);
|
||||
|
||||
for(Halfedge_iterator it = poly.halfedges_begin(); it != poly.halfedges_end(); ++it){
|
||||
if(it->is_border() && it->id() == 0){
|
||||
BOOST_FOREACH(halfedge_descriptor hd, halfedges(poly)){
|
||||
if(hd->is_border() && visited.find(hd) == visited.end()){
|
||||
polyline_data_list.push_back(Polyline_data());
|
||||
Polyline_data& polyline_data = polyline_data_list.back();
|
||||
polyline_data.polyline = new Scene_polylines_item();
|
||||
polyline_data.polyline->polylines.push_back(Scene_polylines_item::Polyline());
|
||||
polyline_data.halfedge = it;
|
||||
polyline_data.halfedge = hd;
|
||||
|
||||
qglviewer::Vec center;
|
||||
int counter = 0;
|
||||
Halfedge_around_facet_circulator hf_around_facet = it->facet_begin();
|
||||
do {
|
||||
CGAL_assertion(hf_around_facet->id() == 0);
|
||||
hf_around_facet->id() = 1;
|
||||
const Polyhedron::Traits::Point_3& p = hf_around_facet->vertex()->point();
|
||||
halfedge_descriptor hf_around_facet;
|
||||
BOOST_FOREACH(hf_around_facet, halfedges_around_face(hd,poly)){
|
||||
CGAL_assertion(visited.find(hf_around_facet) == visited.end());
|
||||
visited.insert(hf_around_facet);
|
||||
const Point_3& p = get(vpm,target(hf_around_facet, poly));
|
||||
polyline_data.polyline->polylines.front().push_back(p);
|
||||
center += qglviewer::Vec(p.x(), p.y(), p.z());
|
||||
++counter;
|
||||
} while(++hf_around_facet != it->facet_begin());
|
||||
polyline_data.polyline->polylines.front().push_back(hf_around_facet->vertex()->point());
|
||||
}
|
||||
hf_around_facet = *halfedges_around_face(hd,poly).first;
|
||||
polyline_data.polyline->polylines.front().push_back(get(vpm,target(hf_around_facet,poly)));
|
||||
polyline_data.position = center / counter;
|
||||
}
|
||||
}
|
||||
|
|
@ -220,11 +248,14 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// finds closest polyline from polyline_data_list and makes it active_hole
|
||||
bool activate_closest_hole(int x, int y) {
|
||||
typedef Polyhedron::Halfedge_around_facet_circulator Halfedge_around_facet_circulator;
|
||||
if(polyline_data_list.empty()) { return false; }
|
||||
|
||||
Face_graph& poly = *poly_item->polyhedron();
|
||||
|
||||
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
||||
qglviewer::Camera* camera = viewer->camera();
|
||||
|
||||
|
|
@ -242,13 +273,12 @@ private:
|
|||
min_it = it;
|
||||
}
|
||||
#else
|
||||
boost::property_map<Face_graph,CGAL::vertex_point_t>::type vpm = get(CGAL::vertex_point,poly);
|
||||
/* use polyline points to measure distance - might hurt performance for large holes */
|
||||
Halfedge_around_facet_circulator hf_around_facet = it->halfedge->facet_begin();
|
||||
do {
|
||||
|
||||
const Polyhedron::Traits::Point_3& p_1 = hf_around_facet->vertex()->point();
|
||||
BOOST_FOREACH(halfedge_descriptor hf_around_facet, halfedges_around_face(it->halfedge,poly)){
|
||||
const Point_3& p_1 = get(vpm,target(hf_around_facet,poly));
|
||||
const qglviewer::Vec& pos_it_1 = camera->projectedCoordinatesOf(qglviewer::Vec(p_1.x(), p_1.y(), p_1.z()));
|
||||
const Polyhedron::Traits::Point_3& p_2 = hf_around_facet->opposite()->vertex()->point();
|
||||
const Point_3& p_2 = get(vpm,target(opposite(hf_around_facet,poly),poly));
|
||||
const qglviewer::Vec& pos_it_2 = camera->projectedCoordinatesOf(qglviewer::Vec(p_2.x(), p_2.y(), p_2.z()));
|
||||
Kernel::Segment_2 s(Kernel::Point_2(pos_it_1.x, pos_it_1.y), Kernel::Point_2(pos_it_2.x, pos_it_2.y));
|
||||
|
||||
|
|
@ -257,7 +287,7 @@ private:
|
|||
min_dist = dist;
|
||||
min_it = it;
|
||||
}
|
||||
} while(++hf_around_facet != it->halfedge->facet_begin());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +311,7 @@ private:
|
|||
Mouse_keyboard_state state;
|
||||
public:
|
||||
Selected_holes_set selected_holes;
|
||||
Scene_polyhedron_item* poly_item;
|
||||
Scene_face_graph_item* poly_item;
|
||||
Polyline_data_list polyline_data_list;
|
||||
bool block_poly_item_changed;
|
||||
|
||||
|
|
@ -303,7 +333,7 @@ class Polyhedron_demo_hole_filling_plugin :
|
|||
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_polyhedron_item*>(scene->item(scene->mainSelectionIndex())) ||
|
||||
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())); }
|
||||
void print_message(QString message) { messages->information(message); }
|
||||
QList<QAction*> actions() const { return QList<QAction*>() << actionHoleFilling; }
|
||||
|
|
@ -315,7 +345,7 @@ public:
|
|||
{
|
||||
dock_widget->hide();
|
||||
}
|
||||
Scene_hole_visualizer* get_hole_visualizer(Scene_polyhedron_item* poly_item) {
|
||||
Scene_hole_visualizer* get_hole_visualizer(Scene_face_graph_item* poly_item) {
|
||||
return visualizers[poly_item];
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +375,7 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
void change_poly_item_by_blocking(Scene_polyhedron_item* poly_item, Scene_hole_visualizer* collection) {
|
||||
void change_poly_item_by_blocking(Scene_face_graph_item* poly_item, Scene_hole_visualizer* collection) {
|
||||
if(collection) collection->block_poly_item_changed = true;
|
||||
poly_item->invalidateOpenGLBuffers();
|
||||
scene->itemChanged(poly_item);
|
||||
|
|
@ -360,13 +390,13 @@ private:
|
|||
|
||||
//Maintains a reference between all the visualizers and their poly_item
|
||||
// to ease the management of the visualizers
|
||||
QMap<Scene_polyhedron_item*, Scene_hole_visualizer*> visualizers;
|
||||
QMap<Scene_face_graph_item*, Scene_hole_visualizer*> visualizers;
|
||||
// hold created facet for accept reject functionality
|
||||
std::vector<Polyhedron::Facet_handle> new_facets;
|
||||
Scene_polyhedron_item* last_active_item; // always keep it NULL while not active-reject state
|
||||
std::vector<face_descriptor> new_facets;
|
||||
Scene_face_graph_item* last_active_item; // always keep it NULL while not active-reject state
|
||||
|
||||
bool fill(Polyhedron& polyhedron, Polyhedron::Halfedge_handle halfedge);
|
||||
bool self_intersecting(Polyhedron& polyhedron);
|
||||
bool fill(Face_graph& polyhedron, halfedge_descriptor halfedge);
|
||||
bool self_intersecting(Face_graph& polyhedron);
|
||||
void accept_reject_toggle(bool activate_accept_reject) {
|
||||
if(activate_accept_reject) {
|
||||
ui_widget.Accept_button->setVisible(true);
|
||||
|
|
@ -433,7 +463,7 @@ void Polyhedron_demo_hole_filling_plugin::init(QMainWindow* mainWindow,
|
|||
}
|
||||
|
||||
void Polyhedron_demo_hole_filling_plugin::item_about_to_be_destroyed(CGAL::Three::Scene_item* scene_item) {
|
||||
Scene_polyhedron_item* poly_item = qobject_cast<Scene_polyhedron_item*>(scene_item);
|
||||
Scene_face_graph_item* poly_item = qobject_cast<Scene_face_graph_item*>(scene_item);
|
||||
if(poly_item) {
|
||||
// erase assoc polylines item
|
||||
if(Scene_hole_visualizer* hole_visualizer = get_hole_visualizer(poly_item))
|
||||
|
|
@ -464,9 +494,9 @@ void Polyhedron_demo_hole_filling_plugin::dock_widget_closed() {
|
|||
}
|
||||
on_Accept_button();
|
||||
}
|
||||
// creates a Scene_hole_visualizer and associate it with active Scene_polyhedron_item
|
||||
// creates a Scene_hole_visualizer and associate it with active Scene_face_graph_item
|
||||
void Polyhedron_demo_hole_filling_plugin::on_Visualize_holes_button() {
|
||||
Scene_polyhedron_item* poly_item = getSelectedItem<Scene_polyhedron_item>();
|
||||
Scene_face_graph_item* poly_item = getSelectedItem<Scene_face_graph_item>();
|
||||
if(!poly_item) {
|
||||
print_message("Error: please select a polyhedron item from Geometric Objects list!");
|
||||
return;
|
||||
|
|
@ -597,7 +627,7 @@ void Polyhedron_demo_hole_filling_plugin::on_Reject_button() {
|
|||
if(last_active_item == NULL) { return; }
|
||||
|
||||
accept_reject_toggle(false);
|
||||
for(std::vector<Polyhedron::Facet_handle>::iterator it = new_facets.begin(); it != new_facets.end(); ++it) {
|
||||
for(std::vector<face_descriptor>::iterator it = new_facets.begin(); it != new_facets.end(); ++it) {
|
||||
last_active_item->polyhedron()->erase_facet((*it)->halfedge());
|
||||
}
|
||||
change_poly_item_by_blocking(last_active_item, get_hole_visualizer(last_active_item));
|
||||
|
|
@ -615,7 +645,7 @@ void Polyhedron_demo_hole_filling_plugin::hole_visualizer_changed() {
|
|||
}
|
||||
// helper function for filling holes
|
||||
bool Polyhedron_demo_hole_filling_plugin::fill
|
||||
(Polyhedron& poly, Polyhedron::Halfedge_handle it) {
|
||||
(Face_graph& poly, halfedge_descriptor it) {
|
||||
|
||||
int action_index = ui_widget.action_combo_box->currentIndex();
|
||||
double alpha = ui_widget.Density_control_factor_spin_box->value();
|
||||
|
|
@ -623,7 +653,7 @@ bool Polyhedron_demo_hole_filling_plugin::fill
|
|||
unsigned int continuity = ui_widget.Continuity_spin_box->value();
|
||||
|
||||
CGAL::Timer timer; timer.start();
|
||||
std::vector<Polyhedron::Facet_handle> patch;
|
||||
std::vector<face_descriptor> patch;
|
||||
if(action_index == 0) {
|
||||
CGAL::Polygon_mesh_processing::triangulate_hole(poly,
|
||||
it, std::back_inserter(patch),
|
||||
|
|
@ -643,7 +673,7 @@ bool Polyhedron_demo_hole_filling_plugin::fill
|
|||
success = CGAL::cpp11::get<0>(CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(poly,
|
||||
it, std::back_inserter(patch), CGAL::Emptyset_iterator(),
|
||||
CGAL::Polygon_mesh_processing::parameters::weight_calculator
|
||||
(CGAL::internal::Uniform_weight_fairing<Polyhedron>(poly)).
|
||||
(CGAL::internal::Uniform_weight_fairing<Face_graph>(poly)).
|
||||
density_control_factor(alpha).
|
||||
fairing_continuity(continuity).
|
||||
use_delaunay_triangulation(use_DT)));
|
||||
|
|
@ -651,7 +681,7 @@ bool Polyhedron_demo_hole_filling_plugin::fill
|
|||
else {
|
||||
success = CGAL::cpp11::get<0>(CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(poly,
|
||||
it, std::back_inserter(patch), CGAL::Emptyset_iterator(),
|
||||
CGAL::Polygon_mesh_processing::parameters::weight_calculator(CGAL::internal::Cotangent_weight_with_voronoi_area_fairing<Polyhedron>(poly)).
|
||||
CGAL::Polygon_mesh_processing::parameters::weight_calculator(CGAL::internal::Cotangent_weight_with_voronoi_area_fairing<Face_graph>(poly)).
|
||||
density_control_factor(alpha).
|
||||
fairing_continuity(continuity).
|
||||
use_delaunay_triangulation(use_DT)));
|
||||
|
|
@ -671,7 +701,7 @@ bool Polyhedron_demo_hole_filling_plugin::fill
|
|||
if(ui_widget.Skip_self_intersection_check_box->checkState() == Qt::Checked) {
|
||||
timer.reset();
|
||||
|
||||
typedef std::vector<std::pair<Polyhedron::Facet_const_handle, Polyhedron::Facet_const_handle> > Intersected_facets;
|
||||
typedef std::vector<std::pair<face_descriptor, face_descriptor> > Intersected_facets;
|
||||
Intersected_facets intersected_facets;
|
||||
CGAL::Polygon_mesh_processing::self_intersections(poly,
|
||||
std::back_inserter(intersected_facets),
|
||||
|
|
@ -683,7 +713,7 @@ bool Polyhedron_demo_hole_filling_plugin::fill
|
|||
bool intersected = false;
|
||||
for(Intersected_facets::iterator it = intersected_facets.begin();
|
||||
it != intersected_facets.end() && !intersected; ++it) {
|
||||
for(std::vector<Polyhedron::Facet_handle>::iterator it_patch = patch.begin();
|
||||
for(std::vector<face_descriptor>::iterator it_patch = patch.begin();
|
||||
it_patch != patch.end() && !intersected; ++it_patch) {
|
||||
if(it->first == (*it_patch) || it->second == (*it_patch)) {
|
||||
intersected = true;
|
||||
|
|
@ -692,7 +722,7 @@ bool Polyhedron_demo_hole_filling_plugin::fill
|
|||
}
|
||||
print_message(QString("Self intersecting test: iterate on patch in %1 sec.").arg(timer.time()));
|
||||
if(intersected) {
|
||||
for(std::vector<Polyhedron::Facet_handle>::iterator it = patch.begin(); it != patch.end(); ++it) {
|
||||
for(std::vector<face_descriptor>::iterator it = patch.begin(); it != patch.end(); ++it) {
|
||||
poly.erase_facet((*it)->halfedge());
|
||||
}
|
||||
print_message("Self intersecting patch is generated, and it is removed.");
|
||||
|
|
@ -715,23 +745,23 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() {
|
|||
print_message("No edge selection found in the current item selection.");
|
||||
return;
|
||||
}
|
||||
Polyhedron *poly = edge_selection->polyhedron();
|
||||
QVector<Polyhedron::Vertex_handle> vertices;
|
||||
std::vector<Polyhedron::Point_3> points;
|
||||
Face_graph *poly = edge_selection->polyhedron();
|
||||
QVector<vertex_descriptor> vertices;
|
||||
std::vector<Point_3> points;
|
||||
bool use_DT = ui_widget.Use_delaunay_triangulation_check_box->isChecked();
|
||||
poly->normalize_border();
|
||||
normalize_border(*poly);
|
||||
|
||||
// fill hole
|
||||
boost::unordered_set<Polyhedron::Halfedge_handle, CGAL::Handle_hash_function> buffer;
|
||||
boost::unordered_set<halfedge_descriptor> buffer;
|
||||
//check if all selected edges are boder
|
||||
//to do check that the seection is closed
|
||||
BOOST_FOREACH(boost::graph_traits<Polyhedron>::edge_descriptor ed, edge_selection->selected_edges)
|
||||
BOOST_FOREACH(edge_descriptor ed, edge_selection->selected_edges)
|
||||
{
|
||||
Polyhedron::Halfedge_handle h(halfedge(ed, *poly));
|
||||
if(!h->is_border())
|
||||
halfedge_descriptor h(halfedge(ed, *poly));
|
||||
if(! is_border(h,*poly))
|
||||
{
|
||||
h = h->opposite();
|
||||
if(!h->is_border())
|
||||
h = opposite(h,*poly);
|
||||
if(! is_border(h,*poly))
|
||||
{
|
||||
print_message("A selected_border is not a border edge. Cannot fill something that is not a hole.");
|
||||
return;
|
||||
|
|
@ -741,21 +771,21 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() {
|
|||
}
|
||||
//fill the points
|
||||
//order edges
|
||||
QVector<Polyhedron::Halfedge_handle> b_edges;
|
||||
Polyhedron::Halfedge_handle c_e = *buffer.begin();
|
||||
QVector<halfedge_descriptor> b_edges;
|
||||
halfedge_descriptor c_e = *buffer.begin();
|
||||
b_edges.reserve(static_cast<int>(buffer.size()));
|
||||
b_edges.push_back(c_e);
|
||||
buffer.erase(c_e);
|
||||
while(!buffer.empty())
|
||||
{
|
||||
bool found = false;
|
||||
BOOST_FOREACH(Polyhedron::Halfedge_handle h, buffer)
|
||||
BOOST_FOREACH(halfedge_descriptor h, buffer)
|
||||
{
|
||||
//if h and c_e share a point
|
||||
if(h->vertex() == c_e->vertex() ||
|
||||
h->vertex() == c_e->opposite()->vertex() ||
|
||||
h->opposite()->vertex() == c_e->vertex() ||
|
||||
h->opposite()->vertex() == c_e->opposite()->vertex())
|
||||
if(target(h, *poly) == target(c_e,*poly) ||
|
||||
target(h, *poly) == target(opposite(c_e,*poly), *poly) ||
|
||||
target(opposite(h, *poly), *poly) == target(c_e,*poly) ||
|
||||
target(opposite(h, *poly),*poly) == target(opposite(c_e,*poly),*poly))
|
||||
{
|
||||
c_e = h;
|
||||
b_edges.push_back(c_e);
|
||||
|
|
@ -775,19 +805,19 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() {
|
|||
// else add the shared point.
|
||||
for(int i=0; i<b_edges.size()-1; ++i)
|
||||
{
|
||||
Polyhedron::Vertex_handle shared_vertex;
|
||||
Polyhedron::Vertex_handle other_vertex;
|
||||
if(b_edges[i]->vertex() == b_edges[i+1]->vertex() ||
|
||||
b_edges[i]->vertex() == b_edges[i+1]->opposite()->vertex()
|
||||
vertex_descriptor shared_vertex;
|
||||
vertex_descriptor other_vertex;
|
||||
if(target(b_edges[i], *poly) == target(b_edges[i+1], *poly) ||
|
||||
target(b_edges[i], *poly) == target(b_edges[i+1]->opposite(), *poly)
|
||||
)
|
||||
{
|
||||
shared_vertex = b_edges[i]->vertex();
|
||||
other_vertex = b_edges[i]->opposite()->vertex();
|
||||
shared_vertex = target(b_edges[i], *poly);
|
||||
other_vertex = target(opposite(b_edges[i],*poly), *poly);
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_vertex = b_edges[i]->opposite()->vertex();
|
||||
other_vertex = b_edges[i]->vertex();
|
||||
shared_vertex = target(opposite(b_edges[i],*poly), *poly);
|
||||
other_vertex = target(b_edges[i], *poly);
|
||||
}
|
||||
if(!vertices.contains(shared_vertex))
|
||||
vertices.push_back(shared_vertex);
|
||||
|
|
@ -795,14 +825,15 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() {
|
|||
vertices.push_back(other_vertex);
|
||||
}
|
||||
//close the loop
|
||||
if(!vertices.contains(b_edges.back()->vertex()))
|
||||
vertices.push_back(b_edges.back()->vertex());
|
||||
if(!vertices.contains(target(b_edges.back(), *poly)))
|
||||
vertices.push_back(target(b_edges.back(), *poly));
|
||||
else
|
||||
vertices.push_back(b_edges.back()->opposite()->vertex());
|
||||
vertices.push_back(target(opposite(b_edges.back(),*poly), *poly));
|
||||
|
||||
Q_FOREACH(Polyhedron::Vertex_handle vh, vertices)
|
||||
boost::property_map<Face_graph,CGAL::vertex_point_t>::type vpm = get(CGAL::vertex_point,*poly);
|
||||
Q_FOREACH(vertex_descriptor vh, vertices)
|
||||
{
|
||||
points.push_back(vh->point());
|
||||
points.push_back(get(vpm,vh));
|
||||
}
|
||||
|
||||
std::vector<CGAL::Triple<int, int, int> > patch;
|
||||
|
|
@ -814,14 +845,14 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() {
|
|||
for(std::size_t i=0; i<patch.size(); ++i)
|
||||
{
|
||||
CGAL::Triple<int, int, int> indices = patch[i];
|
||||
std::vector<Polyhedron::Vertex_handle> face;
|
||||
std::vector<vertex_descriptor> face;
|
||||
face.push_back(vertices[indices.first]);
|
||||
face.push_back(vertices[indices.second]);
|
||||
face.push_back(vertices[indices.third]);
|
||||
Polyhedron::Facet_handle new_fh = CGAL::Euler::add_face(face, *poly);
|
||||
face_descriptor new_fh = CGAL::Euler::add_face(face, *poly);
|
||||
if(new_fh == boost::graph_traits<Polyhedron>::null_face())
|
||||
{
|
||||
new_fh = CGAL::Euler::add_face(std::vector<Polyhedron::Vertex_handle>(face.rbegin(), face.rend()), *poly);
|
||||
new_fh = CGAL::Euler::add_face(std::vector<vertex_descriptor>(face.rbegin(), face.rend()), *poly);
|
||||
if( new_fh == boost::graph_traits<Polyhedron>::null_face())
|
||||
print_message("The facet could not be added. Please try again.");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue