From 3eace192a7b17f5db2ca03c4dcd77ba9c8ccfca9 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 8 Jan 2010 16:42:02 +0000 Subject: [PATCH] - Remove in trunk/Polyhedron/demo/Polyhedron/ the bits about protecting spheres. The experimental code will now be in branches/experimental-packages/Mesh_3-protecting_balls-branch/. --- Polyhedron/demo/Polyhedron/C2t3_type.h | 52 +- Polyhedron/demo/Polyhedron/CMakeLists.txt | 2 +- .../Polyhedron_demo_remeshing_plugin.cpp | 33 +- ...hedron_demo_remeshing_plugin_cgal_code.cpp | 115 +-- ..._remeshing_plugin_protection_cgal_code.cpp | 778 ------------------ ...mo_remeshing_plugin_protection_cgal_code.h | 2 - .../demo/Polyhedron/Remeshing_dialog.ui | 35 +- Polyhedron/demo/Polyhedron/Scene_c2t3_item.h | 70 +- 8 files changed, 46 insertions(+), 1041 deletions(-) delete mode 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp delete mode 100755 Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.h diff --git a/Polyhedron/demo/Polyhedron/C2t3_type.h b/Polyhedron/demo/Polyhedron/C2t3_type.h index 6a40f3bf5c2..d0fc441d49c 100644 --- a/Polyhedron/demo/Polyhedron/C2t3_type.h +++ b/Polyhedron/demo/Polyhedron/C2t3_type.h @@ -3,61 +3,11 @@ #include "Polyhedron_type.h" -#include -#include #include #include -#include -#include -#include -#include -#include - -// traits class -typedef CGAL::Exact_predicates_inexact_constructions_kernel K2; -typedef CGAL::Robust_weighted_circumcenter_filtered_traits_3 Traits; - -// typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; - -struct Ball_context; - -class Vertex_info { - Ball_context* context_; - -public: - Vertex_info(); - ~Vertex_info(); - - Ball_context* context(); -}; - -class Cell_info { - std::bitset<32> marks; - -public: - bool mark(int i) const - { - return marks[i]; - } - - void set_mark(int i, bool b) - { - marks[i] = b; - } -}; - -// vertex and cell types -typedef CGAL::Triangulation_vertex_base_with_info_3 Vb1; -typedef CGAL::Surface_mesh_vertex_base_3 Vb; -typedef CGAL::Triangulation_cell_base_with_info_3 Cb1; -typedef CGAL::Surface_mesh_cell_base_3 Cb; -typedef CGAL::Triangulation_cell_base_with_circumcenter_3 Cb_with_circumcenter; - -// triangulation -typedef CGAL::Triangulation_data_structure_3 Tds; -typedef CGAL::Regular_triangulation_3 Tr; +typedef CGAL::Surface_mesh_default_triangulation_3 Tr; typedef CGAL::Complex_2_in_triangulation_3 C2t3; #endif diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index dee4bcde65d..c51eccc16eb 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -209,7 +209,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) endmacro(polyhedron_demo_plugin) - polyhedron_demo_plugin(remeshing_plugin Polyhedron_demo_remeshing_plugin Polyhedron_demo_remeshing_plugin_cgal_code.cpp Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp Polyhedron_demo_remeshing_plugin_cgal_code.moc ${remeshingUI_FILES}) + polyhedron_demo_plugin(remeshing_plugin Polyhedron_demo_remeshing_plugin Polyhedron_demo_remeshing_plugin_cgal_code.cpp Polyhedron_demo_remeshing_plugin_cgal_code.moc ${remeshingUI_FILES}) target_link_libraries(remeshing_plugin scene_polyhedron_item polygon_soup scene_c2t3_item) qt4_generate_moc("${CMAKE_CURRENT_SOURCE_DIR}/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp" Scene_c3t3_item.moc ) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp index f891131fea6..a593195f779 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin.cpp @@ -20,9 +20,7 @@ Scene_item* cgal_code_remesh(QWidget* parent, const double angle, const double sizing, const double approx, - int tag, - bool protect, - bool refine_balls); + int tag); class Polyhedron_demo_remeshing_plugin : public QObject, @@ -39,18 +37,6 @@ public: connect(actionRemeshing, SIGNAL(triggered()), this, SLOT(remesh())); } - actionShowSpheres = new QAction("Show protecting spheres", mw); - actionShowSpheres->setCheckable(true); - actionShowSpheres->setChecked(false); - QMenu* menuView = mw->findChild("menuView"); - if(menuView) - { - menuView->addAction(actionShowSpheres); - } - else { - std::cerr << "Error: cannot find menu \"menuView\" in QMainWindow \"" - << qPrintable(mw->objectName()) << "\"!\n"; - } } QList actions() const { @@ -61,7 +47,6 @@ public slots: private: QAction* actionRemeshing; - QAction* actionShowSpheres; }; // end class Polyhedron_demo_remeshing_plugin void Polyhedron_demo_remeshing_plugin::remesh() @@ -109,8 +94,6 @@ void Polyhedron_demo_remeshing_plugin::remesh() const double approx = ui.approx->value(); const double sizing = ui.sizing->value(); const int tag_index = ui.tags->currentIndex(); - const bool protect = ui.protect->isChecked(); - const bool refine_balls = ui.refine_balls->isChecked(); if(tag_index < 0) return; QApplication::setOverrideCursor(Qt::WaitCursor); @@ -121,17 +104,13 @@ void Polyhedron_demo_remeshing_plugin::remesh() << "\n approx=" << approx << "\n tag=" << tag_index << std::boolalpha - << "\n protect=" << protect - << "\n refine_balls=" << refine_balls << std::endl; Scene_item* new_item = cgal_code_remesh(mw, pMesh, angle, sizing, approx, - tag_index, - protect, - refine_balls); + tag_index); if(new_item) { @@ -144,14 +123,6 @@ void Polyhedron_demo_remeshing_plugin::remesh() new_item->setRenderingMode(item->renderingMode()); item->setVisible(false); scene->itemChanged(index); - QObject::connect(actionShowSpheres, SIGNAL(toggled(bool)), - new_item, SLOT(show_spheres(bool))); - // meta-call, to avoid the inclusing of the CGAL headers - QMetaObject::invokeMethod(new_item, - "show_spheres", - Qt::DirectConnection, - Q_ARG(bool, actionShowSpheres->isChecked())); - scene->addItem(new_item); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_cgal_code.cpp index b35a7e26d8e..40d4ccf1a5b 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_cgal_code.cpp @@ -72,36 +72,17 @@ public: return false; if( squared_distance(pa, pc) < sq_distance_bound ) return false; - int nb_protecting_balls = 0; - if(pa.weight() != FT(0)) ++nb_protecting_balls; - if(pb.weight() != FT(0)) ++nb_protecting_balls; - if(pc.weight() != FT(0)) ++nb_protecting_balls; - if(nb_protecting_balls == 0) - { - if(aspect_ratio_criterion.is_bad(f, q[0])) - return true; - else { - q[0] = 1; - if(uniform_size_criterion.is_bad(f, q[1])) - return true; - else { - q[1] = 1; - if(curvature_size_criterion.is_bad(f, q[2])) - return true; - } - } - } + if(aspect_ratio_criterion.is_bad(f, q[0])) + return true; else { q[0] = 1; - if(false && nb_protecting_balls == 3) - return false; - else if(uniform_size_criterion.is_bad(f, q[1])) + if(uniform_size_criterion.is_bad(f, q[1])) return true; - // else { - // q[1] = 1; - // if(nb_protecting_balls == 1 && curvature_size_criterion.is_bad(f, q[2])) - // return true; - // } + else { + q[1] = 1; + if(curvature_size_criterion.is_bad(f, q[2])) + return true; + } } return false; } @@ -131,8 +112,8 @@ namespace { // typedef CGAL::Simple_cartesian Simple_cartesian_kernel; // input surface -typedef CGAL::Mesh_3::Robust_intersection_traits_3 IGT; -typedef CGAL::AABB_polyhedral_oracle Input_surface; +// typedef CGAL::Mesh_3::Robust_intersection_traits_3 IGT; +typedef CGAL::AABB_polyhedral_oracle Input_surface; // A base non-templated class, to allow @@ -249,16 +230,12 @@ struct Meshing_thread : QThread typedef Tr::Geom_traits GT; typedef Tr::Geom_traits::FT FT; -#include "Polyhedron_demo_remeshing_plugin_protection_cgal_code.h" - Scene_item* cgal_code_remesh(QWidget* parent, Polyhedron* pMesh, const double angle, const double sizing, const double approx, - int tag, - bool protect, - bool refine_balls) { + int tag) { // }; // class Mesh_process : public QObject { @@ -312,18 +289,9 @@ Scene_item* cgal_code_remesh(QWidget* parent, Input_surface input(*pMesh); std::cerr << "done (" << timer.time() << " ms)" << std::endl; - if(protect) { - std::cerr << "Insert protecting balls... "; - timer.reset(); - insert_spheres(c2t3, pMesh, sizing/1.5, refine_balls); - std::cerr << "done (" << timer.time() << " ms)" << std::endl; - } - // initial point set timer.reset(); std::cerr << "Insert initial point set... "; - typedef CGAL::Cartesian_converter Converter; - Converter convert; { // new scope for the initialization, so that the vector // polyhedron_points is destroyed as soon as the initialization is @@ -394,43 +362,30 @@ Scene_item* cgal_code_remesh(QWidget* parent, if(triangulation.number_of_vertices() > 0) { - // // add remesh as new polyhedron - // Polyhedron *pRemesh = new Polyhedron; - // CGAL::Complex_2_in_triangulation_3_polyhedron_builder builder(c2t3); - return new Scene_c2t3_item(c2t3); - - // try { - // CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); - // pRemesh->delegate(builder); - // } catch(CGAL::Failure_exception) - // { - // } - // CGAL::set_error_behaviour(CGAL::ABORT); - - // if(c2t3.number_of_facets() != pRemesh->size_of_facets()) - // { - // delete pRemesh; - // std::stringstream temp_file; - // namespace sm = CGAL::Surface_mesher; - // if(!CGAL::output_surface_facets_to_off(temp_file, c2t3, - // sm::NO_OPTION | sm::IO_VERBOSE)) - // { - // std::cerr << "Cannot write the mesh to an off file!\n"; - // std::cerr << temp_file.str() << std::endl; - // return 0; - // } - // Scene_polygon_soup* soup = new Scene_polygon_soup(); - // if(!soup->load(temp_file)) - // { - // std::cerr << "Cannot reload the mesh from an off file!\n"; - // return 0; - // } - // else - // return soup; - // } else { - // return new Scene_polyhedron_item(pRemesh); - // } + // add remesh as new polyhedron + Polyhedron *pRemesh = new Polyhedron; + CGAL::Complex_2_in_triangulation_3_polyhedron_builder builder(c2t3); + pRemesh->delegate(builder); + if(c2t3.number_of_facets() != pRemesh->size_of_facets()) + { + delete pRemesh; + std::stringstream temp_file; + if(!CGAL::output_surface_facets_to_off(temp_file, c2t3)) + { + std::cerr << "Cannot write the mesh to an off file!\n"; + return 0; + } + Scene_polygon_soup* soup = new Scene_polygon_soup(); + if(!soup->load(temp_file)) + { + std::cerr << "Cannot reload the mesh from an off file!\n"; + return 0; + } + else + return soup; + } else { + return new Scene_polyhedron_item(pRemesh); + } } else return 0; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp deleted file mode 100644 index 2507239387a..00000000000 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp +++ /dev/null @@ -1,778 +0,0 @@ -#include "config.h" // defines *_DEBUG_* macro for the demo -#include -#include "Polyhedron_type.h" -#include "C2t3_type.h" -#include -#include -#include -#include - -typedef Tr::Geom_traits::FT FT; - -struct Less { - template - bool operator()(const Handle& va, const Handle& vb) const { - return &*va < &*vb; - } -}; - -typedef std::vector Polyline; -typedef unsigned Polyline_id; - -struct Ball_context { - typedef Tr::Vertex_handle Tr_vertex_handle; - - Tr_vertex_handle pred; // predecessor of the current non-corner ball on a - // polyline - Tr_vertex_handle succ; // successor.. - Polyline_id id; // polyline id - Polyline::const_iterator iterator; // in the polyline, iterator to the - // point that precedes the ball - // (*it, *(it+1)) is the segment. - FT position; // distance between the center of the current ball, and - // halfedge->opposite()->vertex()->point() - bool is_corner; -}; - -Vertex_info::Vertex_info() : context_(0) { -} - -Vertex_info::~Vertex_info() { - if(context_) - { - delete context_; - context_ = 0; - } -} - -Ball_context* Vertex_info::context() { - if(!context_) { - context_ = new Ball_context; - } - return context_; -} - -struct Insert_spheres { - typedef Polyhedron::Halfedge_const_handle Halfedge_const_handle; - typedef Polyhedron::Vertex_const_handle Vertex_const_handle; - typedef Polyhedron::size_type size_type; - - typedef Tr::Geom_traits::Point_3 Point_3; - typedef Tr::Vertex_handle Tr_vertex_handle; - - typedef std::set Vertices_set; - typedef std::map Vertices_counter; - - typedef std::set Border_edges_set; - - Border_edges_set edges_to_consider; - Vertices_counter border_vertices; - Vertices_set corner_vertices; - - typedef std::vector Polylines; - - typedef std::vector Polyline_is_a_cycle; - typedef std::set Hidden_balls; - typedef CGAL::cpp0x::tuple Corner_context; - typedef std::multimap Tr_corner_vertices; - - Polylines polylines; - Polyline_is_a_cycle polyline_is_a_cycle; - Tr_corner_vertices tr_corner_vertices; - Hidden_balls hidden_balls; - - C2t3& c2t3; - Polyhedron* pMesh; - const FT size; - - Halfedge_const_handle canonical(Halfedge_const_handle he) - { - const Halfedge_const_handle& op = he->opposite(); - if(Less()(he, op)) - return he; - else - return op; - } - - /** Follow a polyline or a polygon, from the halfedge he. */ - void follow_half_edge(const Halfedge_const_handle he, const bool is_cycle) - { - Border_edges_set::iterator it = edges_to_consider.find(canonical(he)); - if(it == edges_to_consider.end()) { - return; - } - - Polyline polyline; - polyline.push_back(he->opposite()->vertex()->point()); - // std::cerr << "Start: " << he->opposite()->vertex()->point() << std::endl; - - Halfedge_const_handle current_he = he; - do { - CGAL_assertion(current_he->is_border() || - current_he->opposite()->is_border()); - CGAL_assertion_code(const size_type n = )edges_to_consider.erase(canonical(current_he)); - CGAL_assertion(n > 0); - Vertex_const_handle v = current_he->vertex(); - polyline.push_back(v->point()); - // std::cerr << v->point() << std::endl; - if(corner_vertices.count(v) > 0) break; - Polyhedron::Halfedge_around_vertex_const_circulator - loop_he = v->vertex_begin(), end(loop_he); - ++loop_he; - // CGAL_assertion((&*loop_he) != (&*current_he) ); - while((&*loop_he) == (&*current_he) || - (!loop_he->is_border() && !loop_he->opposite()->is_border()) ) { - ++loop_he; - // CGAL_assertion((&*loop_he) != (&*current_he) ); - } - current_he = loop_he->opposite(); - } while(current_he != he ); - - // if(current_he == he) - // std::cerr << "New polyline, of size " << polyline.size() << std::endl; - // else - // std::cerr << "New polygon (cycle), of size " << polyline.size() << std::endl; - - polyline_is_a_cycle.push_back(is_cycle); - polylines.push_back(polyline); - } - - /** Loop around a corner vertex, and try to follow a polyline of border - edges, from each incident edge. */ - void loop_around_corner(const Vertex_const_handle v) - { - Polyhedron::Halfedge_around_vertex_const_circulator - he = v->vertex_begin(), end(he); - do { - CGAL_assertion(he->vertex() == v); - follow_half_edge(he->opposite(), false); - ++he; - } while(he != end); - } - - /** For a non-corner vertex v (that is incident to two border edges), - mesure the angle between the two edges, and mark the vertex as corner - edge, if the angle is < 120°. **/ - void mesure_angle(const Vertex_const_handle v) - { - Halfedge_const_handle e1; - Halfedge_const_handle e2; - Polyhedron::Halfedge_around_vertex_const_circulator he = v->vertex_begin(), end(he); - // std::cerr << "mesure_handle(" << (void*)(&*v) - // << " = " << v->point() << ")"; - bool first = true; - do { - CGAL_assertion(he->vertex() == v); - // std::cerr << he->opposite()->vertex()->point() << std::endl; - if(he->is_border() || he->opposite()->is_border()) { - if(first) { - e1 = he; - first = false; - } - else { - CGAL_assertion(e2 == Halfedge_const_handle()); - e2 = he; - } - // std::cerr << "x"; - } - // else - // std::cerr << "."; - ++he; - } while(he != end); - // std::cerr << "\n"; - const Point_3 pv = v->point(); - const Point_3 pa = e1->opposite()->vertex()->point(); - const Point_3 pb = e2->opposite()->vertex()->point(); - const Tr::Geom_traits::Vector_3 av = pv - pa; - const Tr::Geom_traits::Vector_3 bv = pv - pb; - const FT sc_prod = av * bv; - if( sc_prod >= 0 || - (sc_prod < 0 && - CGAL::square(sc_prod) < (av * av) * (bv * bv) / 4 ) ) - { - // std::cerr << "Corner (" << pa << ", " << pv - // << ", " << pb << ")\n"; - corner_vertices.insert(v); - } - } - - const Tr_vertex_handle insert(const Point_3& p, const Polyline_id polyline_id) - { - Tr::Vertex_handle v = c2t3.triangulation().insert(p); - if(v == Tr_vertex_handle()) { - v = c2t3.triangulation().nearest_power_vertex(p); - hidden_balls.insert(p); -#ifdef PROTECTION_DEBUG - std::cerr << "Hidden ball " << p << " (id=" - << polyline_id << "), hidden by the ball " - << v->point() - << " (" - << print_context(v) - << ")\n"; -#endif - } - v->info().context()->id = polyline_id; - return v; - } - - void cover(Polyline::const_iterator begin, - Polyline::const_iterator end2, - const Polyline_id polyline_id, - FT alpha, // alpha is the desired radius of covering ball - // the real radius must be lower. - Tr_vertex_handle va, - Tr_vertex_handle vb, - const FT position_begin, - const FT position_end) - { -#ifdef PROTECTION_DEBUG - std::cerr << "cover(" << va->point() << ", " - << vb->point() << ", " << polyline_id << ")\n"; -#endif - FT radius_begin = CGAL_NTS sqrt(va->point().weight()); - FT radius_end = CGAL_NTS sqrt(vb->point().weight()); - - if(begin == end2 && position_begin >= position_end) - return; - - FT distance = 0; - for(Polyline::const_iterator it = begin; - it != end2; /*'it' is incremented in the body*/ ) { - const Point& a = *it; - const Point& b = *++it; - distance += CGAL_NTS sqrt( CGAL::squared_distance(a, b) ); - } - distance -= radius_begin; - distance -= radius_end; - distance -= position_begin; - distance += position_end; - if(distance < 0) return; - // distance -= (alpha * 2) / 3; - // std::cerr << "Distance: " << distance << std::endl; - // std::cerr << "Size: " << size << std::endl; - - // The desired radius is alpha. The desired inter-distance (between - // balls centers) is 4*alpha/3 - // const FT desired_inter_distance = 4 * alpha / 3; - - // Let r be the real radius (r <= alpha). - // Let inter_distance be the real inter-distance: - // inter_distance = 4 * r / 3 <= desired_inter_distance - // Let n be the number of steps: the number of inserted balls is n+1. - // Then : - // distance = r / 3 + n * (4 * r /3 ) + r / 3 - // - // 3* distance = (4 * n + 2 ) * r - // - // 1 3 * distance - // n = - * ( ------------ - 2 ) - // 4 r - // - // n >= 1 then r <= distance / 2 - const int n = (std::max) - (1, - static_cast(std::ceil(((3 * distance / alpha) - 2) / 4) + 0.5)); - - const FT r = (3 * distance ) / ( 4 * n + 2) ; - // std::cerr << n << std::endl; - // std::cerr << "Local size: " << local_size << std::endl; - // CGAL_assertion(local_size < size); - const FT inter_distance = 4 * r / 3; - const FT r2 = CGAL::square(r); - -#ifdef PROTECTION_DEBUG - std::cerr << "distance = " << distance - << "\nalpha = " << alpha - << "\nn = " << n - << "\nr = " << r - << std::endl; -#endif - - Point_3 a(begin->point(), r2); - Point_3 b(end2->point(), r2); - FT small_distance_to_go = position_begin + radius_begin + (r / 3); - Polyline::const_iterator it = begin; - bool first = true; - Tr_vertex_handle first_non_corner; - Tr_vertex_handle last_non_corner; - Tr_vertex_handle previous = va; - int counter = 0; - while(it <= end2 && counter <= n)//small_distance_to_go < (position_end - radius_end))) - { - const Point& a = *it; - const Point& b = *(it+1); -#ifdef PROTECTION_DEBUG - std::cerr << "segment( " << a << ", " << b << ")\n"; - std::cerr << "small_distance_to_go=" << small_distance_to_go << std::endl; -#endif - const FT d = CGAL_NTS sqrt(squared_distance(a, b)); -#ifdef PROTECTION_DEBUG - std::cerr << "d=" << d << std::endl; -#endif - FT pos = small_distance_to_go; - if(pos < d && counter <= n) { - for(; pos < d && counter <= n; - pos += inter_distance) - { -#ifdef PROTECTION_DEBUG - std::cerr << "pos=" << pos << "" << std::endl; -#endif - const Point p = a + - pos * ( b - a ) / d; - ++counter; - Tr_vertex_handle current = insert(Point_3(p, r2), polyline_id); - if(current != Tr_vertex_handle()) { - current->info().context()->pred = previous; - current->info().context()->iterator = it; - current->info().context()->position = pos; - current->info().context()->is_corner = false; - previous->info().context()->succ = current; - - // at the end of the loop, last_non_corner is the last non-corner - // ball on the polyline - last_non_corner = current; - if(first) { - // and first_non_corner is the first non-corner ball on the - // polyline - first_non_corner = current; - first = false; - } - previous = current; - } - } - // pos -= inter_distance; - small_distance_to_go = pos - d; - } - else { - small_distance_to_go -= d; - } - ++it; - // std::cerr << "\n"; - } - if(!polyline_is_a_cycle[polyline_id]) - { - // CGAL_assertion(va == Tr_vertex_handle() || - // vb == Tr_vertex_handle() || - // va != vb); - // if(va != Tr_vertex_handle()) - if(va->info().context()->is_corner) { -#ifdef PROTECTION_DEBUG - std::cerr << "Corner vertex va " << va->point() - << ", neighbor " << *first_non_corner << std::endl; -#endif - tr_corner_vertices.insert(std::make_pair(va, - Corner_context(polyline_id, begin, first_non_corner))); - // CGAL_assertion(first_non_corner->info().context()->pred == va); - } - if(vb->info().context()->is_corner) { -#ifdef PROTECTION_DEBUG - std::cerr << "Corner vertex vb " << vb->point() - << ", neighbor " << *last_non_corner << std::endl; -#endif - tr_corner_vertices.insert(std::make_pair(vb, - Corner_context(polyline_id, end2, last_non_corner))); - } - } - else - { - vb = va; - } - if(last_non_corner != Tr_vertex_handle()) { - last_non_corner->info().context()->succ = vb; - } - // if(vb != Tr_vertex_handle()) - vb->info().context()->pred = last_non_corner; - - // std::cerr << "One polyline is protected!\n"; - } - - void separate_balls() { - Tr& tr = c2t3.triangulation(); - bool restart = false; - do { - restart = false; - for(Tr::Finite_edges_iterator eit = tr.finite_edges_begin(), - end = tr.finite_edges_end(); eit != end; ++eit) - { - const Tr_vertex_handle& va = eit->first->vertex(eit->second); - const Tr_vertex_handle& vb = eit->first->vertex(eit->third); - if(non_adjacent_but_intersect(va, vb)) - { -#ifdef PROTECTION_DEBUG - std::cerr << "Balls " << va->point() << " (" - << print_context(va) - << ") and " << vb->point() << " (" - << print_context(vb) - << ") intersect.\n"; -#endif - - if(// !va->info().context()->is_corner && - va->point().weight() > vb->point().weight()) { - restart = true; - refine_ball(va); - break; - } - else // if(!vb->info().context()->is_corner) - { - restart = true; - refine_ball(vb); - break; - } - } - } - } - while(restart); - } - - std::string print_context(Tr_vertex_handle va) { - std::stringstream s; - using CGAL::cpp0x::get; - if(!va->info().context()->is_corner) - s << "on polyline " << va->info().context()->id; - else { - typedef Tr_corner_vertices::const_iterator const_iterator; - typedef std::pair Range; - Range range_a = tr_corner_vertices.equal_range(va); - s << "on polylines"; - for(const_iterator it = range_a.first; it != range_a.second; ++it) - s << " " << get<0>(it->second); - } - return s.str(); - } - - bool non_adjacent_but_intersect(const Tr_vertex_handle& va, - const Tr_vertex_handle& vb) const - { - using CGAL::cpp0x::get; - - typedef Tr_corner_vertices::const_iterator const_iterator; - typedef std::pair Range; - typedef std::set P_id_set; - bool non_adjacent; - - if(!va->info().context()->is_corner && //range_a.first == range_a.second && - !vb->info().context()->is_corner) // range_b.first == range_b.second) - { - non_adjacent = ( va->info().context()->id != vb->info().context()->id ); - } - else { - Range range_a = tr_corner_vertices.equal_range(va); - Range range_b = tr_corner_vertices.equal_range(vb); - - P_id_set s_a; - P_id_set s_b; - for(const_iterator it = range_a.first; it != range_a.second; ++it) - { - s_a.insert(get<0>(it->second)); - } - s_a.insert(va->info().context()->id); - for(const_iterator it = range_b.first; it != range_b.second; ++it) - { - s_b.insert(get<0>(it->second)); - } - s_b.insert(va->info().context()->id); - P_id_set intersection; - std::set_intersection(s_a.begin(), s_a.end(), - s_b.begin(), s_b.end(), - std::inserter(intersection, intersection.begin())); - non_adjacent = intersection.empty(); - } - if(non_adjacent) - { - const Point_3& a = va->point(); - const Point_3& b = vb->point(); - if( CGAL_NTS sqrt( CGAL::squared_distance(a, b) ) < - CGAL_NTS sqrt( a.weight() ) + CGAL_NTS sqrt( b.weight() ) ) - { - return true; - } - } - return false; - } - - void refine_ball(Tr_vertex_handle v) { - typedef Tr_corner_vertices::const_iterator const_iterator; - typedef Tr_corner_vertices::iterator iterator; - typedef std::pair Range; - using CGAL::cpp0x::get; - if(v->info().context()->is_corner) //r.first != r.second) - { - Range r = tr_corner_vertices.equal_range(v); -#ifdef PROTECTION_DEBUG - std::cerr << "Refine vertex ball " << v->point() << "\n" - << "Number of adjacent balls: " << distance(r.first, r.second) - << std::endl; -#endif - Point_3 new_point(v->point().point(), v->point().weight() / 4); - Polyline_id id = v->info().context()->id; - c2t3.triangulation().remove(v); - Tr_vertex_handle new_v = insert(new_point, id); - new_v->info().context()->is_corner = true; - for(iterator it = r.first; it != r.second; ++it) { - Tr_vertex_handle neighbor = get<2>(it->second); - Ball_context* context = neighbor->info().context(); -#ifdef PROTECTION_DEBUG - std::cerr << " adjacent ball: " << neighbor->point() - << ", id=" << context->id << std::endl; -#endif - if(v == context->pred) - { - context->pred = new_v; - } - else { - CGAL_assertion(v == context->succ); - context->succ = new_v; - } - } - - iterator hint = tr_corner_vertices.begin(); - for(iterator it = r.first; it != r.second; ++it) { - hint = tr_corner_vertices.insert(hint, - std::make_pair(new_v, it->second)); - } - for(iterator it = r.first; it != r.second; ++it) { - refine_ball(get<2>(it->second)); - } - tr_corner_vertices.erase(r.first, r.second); - } - else { -#ifdef PROTECTION_DEBUG - std::cerr << "Refine ball " << v->point(); -#endif - Point_3 new_point(v->point().point(), v->point().weight() / 16); - Ball_context* context = v->info().context(); - const Polyline_id id = context->id; -#ifdef PROTECTION_DEBUG - std::cerr << ", id= " << id << "\n"; -#endif - const Tr_vertex_handle pred = context->pred; - const Tr_vertex_handle succ = context->succ; - const Polyline::const_iterator it = context->iterator; - // const FT position = context->position; - - c2t3.triangulation().remove(v); - // Tr_vertex_handle new_v = insert(new_point, id); - // Ball_context* new_context = new_v->info().context(); - // new_context->is_corner = false; - // new_context->pred = pred; - // new_context->succ = succ; - // new_context->iterator = it; - // new_context->position = position; - - Polyline::const_iterator pred_it, succ_it; - FT pred_pos, succ_pos; - boost::tie(pred_it, pred_pos) = get_it_and_pos(pred, id); - boost::tie(succ_it, succ_pos) = get_it_and_pos(succ, id); - if(pred_it != Polyline::const_iterator() && - succ_it != Polyline::const_iterator()) - { -#ifdef PROTECTION_DEBUG - std::cerr << "OK!\n"; -#endif - if(pred_it > succ_it) { - std::swap(pred_it, succ_it); - std::swap(pred_pos, succ_pos); - } - cover(pred_it, succ_it, - id, - CGAL_NTS sqrt(new_point.weight()), - pred, succ, - pred_pos, succ_pos); - } - else { - std::cerr << "ERROR!\n"; - } - } - } - - std::pair - get_it_and_pos(Tr_vertex_handle v, Polyline_id id) - { - Ball_context* context = v->info().context(); - if(!context->is_corner) { - if(context->id == id) - return std::make_pair(context->iterator, context->position); - } - else { - typedef Tr_corner_vertices::const_iterator const_iterator; - typedef std::pair Range; - Range range_a = tr_corner_vertices.equal_range(v); - for(const_iterator it = range_a.first; it != range_a.second; ++it) - { - using CGAL::cpp0x::get; - if(get<0>(it->second) == id) - return std::make_pair(get<1>(it->second), 0); - } - } - return std::make_pair(Polyline::const_iterator(), 0); - } - - Insert_spheres(C2t3& c2t3, Polyhedron* pMesh, const FT size, - bool refine_balls) - : c2t3(c2t3), pMesh(pMesh), size(size) - { - Tr& tr = c2t3.triangulation(); - - // That call orders the set of edges of the polyhedron, so that the - // border edges are at the end of the sequence of edges. - pMesh->normalize_border(); - - // Iterate over border edges, and find out which vertices are corner - // vertices (more than two incident border edges). - for(Polyhedron::Edge_const_iterator - eit = pMesh->border_edges_begin (), - end = pMesh->edges_end(); - eit != end; ++eit) - { - edges_to_consider.insert(canonical(eit)); - Polyhedron::Vertex_const_handle v = eit->vertex(); - for(Polyline_id i = 0; i < 2; ++i) { - if(++border_vertices[v] == 3) - corner_vertices.insert(v); - v = eit->opposite()->vertex(); - } - - } - std::cerr << "Corner vertices: " << corner_vertices.size() << std::endl; - std::cerr << "Border vertices: " << border_vertices.size() << std::endl; - - // Iterate over non-corner border vertices, and mesure the angle. - for(Vertices_counter::iterator it = border_vertices.begin(), - end = border_vertices.end(); it != end; ++it) - { - const Vertex_const_handle v = it->first; - if(corner_vertices.count(v) == 0) { - CGAL_assertion(it->second == 2); - mesure_angle(v); - } - } - std::cerr << "New corner vertices: " << corner_vertices.size() << std::endl; - - // Follow the polylines... - for(Vertices_set::iterator it = corner_vertices.begin(), - end = corner_vertices.end(); it != end; ++it) - { - loop_around_corner(*it); - } - - // ... and the cycles. - while(! edges_to_consider.empty() ) { - follow_half_edge(*edges_to_consider.begin(), true); - } - - typedef std::vector > Polylines_endpoints; - Polylines_endpoints polylines_endpoints; - - // Then insert the protecting balls. - for(Polyline_id i = 0; i < polylines.size(); ++i) - { - Tr_vertex_handle va = insert(Point_3(*polylines[i].begin(), 0), i); - Tr_vertex_handle vb = insert(Point_3(*(--polylines[i].end()), 0), i); - polylines_endpoints.push_back(std::make_pair(va, vb)); - CGAL_assertion(!polyline_is_a_cycle[i] || - va == vb); - } - - typedef std::vector > Polylines_endpoints_sq_radii; - std::map sq_radii; - Polylines_endpoints_sq_radii polylines_endpoints_sq_radii; - - FT size2 = CGAL::square(size); - for(Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(), - end = tr.finite_vertices_end(); vit != end; ++vit) - { - const Point_3& a = vit->point(); - std::vector incident_vertices; - incident_vertices.reserve(32); - tr.incident_vertices(vit, std::back_inserter(incident_vertices)); - std::vector::const_iterator vit2 = incident_vertices.begin(); - FT min_sq_distance = CGAL::squared_distance(a, (*vit2)->point()); - for(std::vector::const_iterator end = incident_vertices.end(); - vit2 != end; ++vit2) - { - FT sq_distance = CGAL::squared_distance(a, (*vit2)->point()); - if(sq_distance < min_sq_distance) { - min_sq_distance = sq_distance; - } - } - sq_radii[vit] = (std::min)(min_sq_distance, size2); - } - - for(Polyline_id i = 0; i < polylines.size(); ++i) { - polylines_endpoints_sq_radii.push_back(std::make_pair(sq_radii[polylines_endpoints[i].first], - sq_radii[polylines_endpoints[i].second])); - } - - polylines_endpoints.clear(); - tr.clear(); - - // Then insert the protecting balls. - for(Polyline_id i = 0; i < polylines.size(); ++i) - { - Tr_vertex_handle va = insert(Point_3(*polylines[i].begin(), - polylines_endpoints_sq_radii[i].first), i); - Tr_vertex_handle vb = insert(Point_3(*(polylines[i].end()-1), - polylines_endpoints_sq_radii[i].second), i); - if(!polyline_is_a_cycle[i]) { - va->info().context()->is_corner = true; - vb->info().context()->is_corner = true; - } - else { - CGAL_assertion(va == vb); - } - - cover(polylines[i].begin(), - polylines[i].end()-1, - i, - CGAL_NTS sqrt((std::min)(va->point().weight(), - vb->point().weight())), - va, - vb, - 0, - 0); - } - polylines_endpoints_sq_radii.clear(); - - unsigned counter = 0; - for(unsigned i = 0; i < polyline_is_a_cycle.size(); ++i) - if(polyline_is_a_cycle[i]) ++counter; - std::cerr << "Number of cycles: " << counter << std::endl; - std::cerr << "Number of polylines: " << polylines.size() - counter << "\n"; - std::cerr << "Number of protecting balls: " - << c2t3.triangulation().number_of_vertices() << std::endl; - - counter = 0; - for(Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(), - end = tr.finite_vertices_end(); vit != end; ++vit) { - if(vit->info().context()->is_corner) - ++counter; - } - std::cerr << "Number of vertex balls: " << counter << std::endl; - - std::cerr << "Number of hidden balls: " << hidden_balls.size() << "\n"; - for(Hidden_balls::const_iterator it = hidden_balls.begin(), - end = hidden_balls.end(); it != end; ++it) - { - std::cerr << "Hidden ball " << *it << ", hidden by the ball " - << c2t3.triangulation().nearest_power_vertex(*it)->point() - << "\n"; - } - if(refine_balls) { - separate_balls(); - } - } -}; - -#include "Polyhedron_demo_remeshing_plugin_protection_cgal_code.h" - -void insert_spheres(C2t3& c2t3, Polyhedron* pMesh, const FT size, - bool refine_balls) { - - Insert_spheres go(c2t3, pMesh, size, refine_balls); -} - - diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.h deleted file mode 100755 index cf7ccf8e093..00000000000 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.h +++ /dev/null @@ -1,2 +0,0 @@ -void insert_spheres(C2t3& c2t3, Polyhedron* pMesh, const FT size, - bool refine_balls); diff --git a/Polyhedron/demo/Polyhedron/Remeshing_dialog.ui b/Polyhedron/demo/Polyhedron/Remeshing_dialog.ui index 1ef0787faab..ec54b1bbfcc 100644 --- a/Polyhedron/demo/Polyhedron/Remeshing_dialog.ui +++ b/Polyhedron/demo/Polyhedron/Remeshing_dialog.ui @@ -7,7 +7,7 @@ 0 0 389 - 227 + 173 @@ -112,23 +112,6 @@ - - - - &Protect borders with spheres - - - - - - - false - - - &Refine protecting balls - - - @@ -188,21 +171,5 @@ - - protect - toggled(bool) - refine_balls - setEnabled(bool) - - - 237 - 119 - - - 241 - 143 - - - diff --git a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h index 8417747ca25..de5dd3072d3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h @@ -15,16 +15,12 @@ class SCENE_C2T3_ITEM_EXPORT Scene_c2t3_item : public Scene_item Q_OBJECT public: Scene_c2t3_item(const C2t3& c2t3) - : sphere_display_list(0), quadric(0), c2t3_(c2t3) + : c2t3_(c2t3) { } ~Scene_c2t3_item() { - if(quadric != 0) - gluDeleteQuadric(quadric); - if(sphere_display_list != 0) - glDeleteLists(sphere_display_list, 1); } C2t3& c2t3() { @@ -50,13 +46,11 @@ public: end = c2t3().triangulation().finite_vertices_end(); vit != end; ++vit) { - if(vit->point().weight() > 0) { - if(first) { - result = vit->point().bbox(); - first = false; - } else { - result = result + vit->point().bbox(); - } + if(first) { + result = vit->point().bbox(); + first = false; + } else { + result = result + vit->point().bbox(); } } return Bbox(result.xmin(), result.ymin(), result.zmin(), @@ -101,55 +95,6 @@ public: GLenum gl_error = ::glGetError(); if(gl_error != GL_NO_ERROR) std::cerr << "GL error: " << gluErrorString(gl_error) << std::endl; - - if(!draw_spheres) - return; - - // force wireframe for protecting spheres - GLint polygon_mode[2]; - ::glGetIntegerv(GL_POLYGON_MODE, &polygon_mode[0]); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - for(Tr::Finite_vertices_iterator - vit = c2t3().triangulation().finite_vertices_begin(), - end = c2t3().triangulation().finite_vertices_end(); - vit != end; ++vit) - { - draw_sphere(vit->point()); - } - ::glPolygonMode(GL_FRONT_AND_BACK, polygon_mode[0]); - } - - void draw_sphere(const Tr::Point p) const - { - if(p.weight() > 0) { - if(sphere_display_list == 0) { - sphere_display_list = glGenLists(1); - if(sphere_display_list == 0) - std::cerr << "ERROR: Cannot create display list!\n"; - if(quadric == 0) - quadric = gluNewQuadric(); - if(quadric == 0) - std::cerr << "ERROR: Cannot create GLU quadric!\n"; - glNewList(sphere_display_list, GL_COMPILE); - gluSphere(quadric, 1., 10, 10); - glEndList(); - if(glGetError() != GL_NO_ERROR) - std::cerr << gluErrorString(glGetError()); - } - glPushMatrix(); - glTranslated(CGAL::to_double(p.point().x()), - CGAL::to_double(p.point().y()), - CGAL::to_double(p.point().z())); - const GLdouble r = CGAL::to_double(CGAL_NTS sqrt(p.weight())); - glScaled(r, r, r); - glCallList(sphere_display_list); - glPopMatrix(); - } - } - -public slots: - void show_spheres(bool b) { - draw_spheres = b; } private: @@ -167,10 +112,7 @@ private: } private: - mutable GLuint sphere_display_list; - mutable GLUquadric* quadric; C2t3 c2t3_; - bool draw_spheres; }; #endif // SCENE_C2T3_ITEM