From edc22fceba0f5e85ea5d05f1d339f02253cd1bf0 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 23 Nov 2009 17:00:18 +0000 Subject: [PATCH] The meshing works... almost. --- Polyhedron/demo/Polyhedron/C2t3_type.h | 5 +- Polyhedron/demo/Polyhedron/Nef_type.h | 3 +- ...hedron_demo_remeshing_plugin_cgal_code.cpp | 194 ++++++++++++++---- ..._remeshing_plugin_protection_cgal_code.cpp | 10 +- 4 files changed, 167 insertions(+), 45 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/C2t3_type.h b/Polyhedron/demo/Polyhedron/C2t3_type.h index 256faa48a63..e15f4f93fed 100644 --- a/Polyhedron/demo/Polyhedron/C2t3_type.h +++ b/Polyhedron/demo/Polyhedron/C2t3_type.h @@ -6,12 +6,13 @@ #include #include #include +#include // traits class typedef CGAL::Exact_predicates_inexact_constructions_kernel K2; -typedef CGAL::Robust_circumcenter_traits_3 K; +typedef CGAL::Robust_weighted_circumcenter_filtered_traits_3 Traits; -typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; +// typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; // vertex and cell types typedef CGAL::Surface_mesh_vertex_base_3 Vb; diff --git a/Polyhedron/demo/Polyhedron/Nef_type.h b/Polyhedron/demo/Polyhedron/Nef_type.h index 1d358f5e877..4b99328719d 100644 --- a/Polyhedron/demo/Polyhedron/Nef_type.h +++ b/Polyhedron/demo/Polyhedron/Nef_type.h @@ -13,7 +13,8 @@ // Boolean operations work only with exact kernel #ifdef USE_FORWARD_DECL -struct Exact_Kernel : public CGAL::Exact_predicates_exact_constructions_kernel {}; +// struct Exact_Kernel : public CGAL::Exact_predicates_exact_constructions_kernel {}; +struct Exact_Kernel : public CGAL::Simple_cartesian {}; #else typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_Kernel; #endif 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 f7b57829ac2..74684a6763a 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_cgal_code.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -31,6 +32,79 @@ #include #include #include +#include + +template +class Surface_mesh_modified_criteria_3 +{ +public: + typedef Tr Triangulation; + typedef typename Tr::Geom_traits::FT FT; + + typedef typename CGAL::array Quality; + typedef typename Tr::Facet Facet; + + Surface_mesh_modified_criteria_3(const FT angle_bound, + const FT radius_bound, + const FT distance_bound) + : curvature_size_criterion(distance_bound), + uniform_size_criterion(radius_bound), + aspect_ratio_criterion(angle_bound) + + { + } + + bool is_bad (const Facet& f, Quality& q) const + { + const typename Tr::Point& pa = f.first->vertex((f.second+1)%4)->point(); + const typename Tr::Point& pb = f.first->vertex((f.second+2)%4)->point(); + const typename Tr::Point& pc = f.first->vertex((f.second+3)%4)->point(); + 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; + } + } + } + else { + q[0] = 1; + if(nb_protecting_balls == 3) + return false; + else 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; + } + } + return false; + } +private: + CGAL::Surface_mesher::Curvature_size_criterion curvature_size_criterion; + // bound on Hausdorff distance does not play any role if bigger than + // the square of the Uniform_size_criterion + + CGAL::Surface_mesher::Uniform_size_criterion uniform_size_criterion; + // bound on radii of surface Delaunay balls + + CGAL::Surface_mesher::Aspect_ratio_criterion aspect_ratio_criterion; + // lower bound on minimum angle in degrees + +}; // end class Surface_mesh_default_criteria_3 + namespace { void CGALglcolor(QColor c) @@ -108,7 +182,25 @@ public: } void draw() const { - // draw_sphere(c2t3().triangulation().finite_vertices_begin()->point()); + ::glBegin(GL_TRIANGLES); + for(C2t3::Facet_iterator + fit = c2t3().facets_begin(), + end = c2t3().facets_end(); + fit != end; ++fit) + { + const Tr::Cell_handle& cell = fit->first; + const int& index = fit->second; + const Tr::Geom_traits::Point_3& pa = cell->vertex((index+1)&3)->point(); + const Tr::Geom_traits::Point_3& pb = cell->vertex((index+2)&3)->point(); + const Tr::Geom_traits::Point_3& pc = cell->vertex((index+3)&3)->point(); + draw_triangle(pa, pb, pc); + } + ::glEnd(); + + // 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(); @@ -116,6 +208,8 @@ public: { draw_sphere(vit->point()); } + ::glPolygonMode(GL_FRONT, polygon_mode[0]); + ::glPolygonMode(GL_BACK, polygon_mode[1]); } void draw_sphere(const Tr::Point p) const @@ -146,6 +240,20 @@ public: } } +private: + static void draw_triangle(const Tr::Point& pa, + const Tr::Point& pb, + const Tr::Point& pc) { + Tr::Geom_traits::Vector_3 n = cross_product(pb - pa, pc -pa); + n = n / CGAL::sqrt(n*n); + + ::glNormal3d(n.x(),n.y(),n.z()); + + ::glVertex3d(pa.x(),pa.y(),pa.z()); + ::glVertex3d(pb.x(),pb.y(),pb.z()); + ::glVertex3d(pc.x(),pc.y(),pc.z()); + } + private: mutable GLuint sphere_display_list; mutable GLUquadric* quadric; @@ -172,7 +280,9 @@ Scene_item* cgal_code_remesh(Polyhedron* pMesh, // C2t3 c2t3(triangulation); // 2D-complex in 3D-Delaunay triangulation // meshing parameters - CGAL::Surface_mesh_default_criteria_3 facets_criteria(angle,sizing,approx); + const Surface_mesh_modified_criteria_3 facets_criteria(angle,sizing,approx); + + // const Criteria new_facets_criteria(facets_criteria); // AABB tree CGAL::Timer timer; @@ -180,13 +290,14 @@ Scene_item* cgal_code_remesh(Polyhedron* pMesh, std::cerr << "Build AABB tree..."; typedef CGAL::Simple_cartesian Simple_cartesian_kernel; // input surface - typedef CGAL::AABB_polyhedral_oracle Input_surface; + typedef CGAL::Mesh_3::Robust_intersection_traits_3 IGT; + typedef CGAL::AABB_polyhedral_oracle Input_surface; Input_surface input(*pMesh); std::cerr << "done (" << timer.time() << " ms)" << std::endl; // initial point set timer.reset(); - std::cerr << "Insert initial point set..."; + std::cerr << "Insert initial point set... "; typedef CGAL::Cartesian_converter Converter; Converter convert; @@ -215,9 +326,12 @@ Scene_item* cgal_code_remesh(Polyhedron* pMesh, std::cerr << "done (" << timer.time() << " ms)" << std::endl; - insert_spheres(c2t3, pMesh, sizing); - std::cerr << c2t3.number_of_facets() << std::endl; - return new Scene_c2t3_item(c2t3); + std::cerr << "Insert protecting balls... "; + timer.reset(); + insert_spheres(c2t3, pMesh, sizing/1.5); + std::cerr << "done (" << timer.time() << " ms)" << std::endl; + + // return new Scene_c2t3_item(c2t3); // remesh timer.reset(); std::cerr << "Remesh..."; @@ -236,37 +350,43 @@ Scene_item* cgal_code_remesh(Polyhedron* pMesh, 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); - try { - CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); - pRemesh->delegate(builder); - } catch(CGAL::Failure_exception) - { - } - CGAL::set_error_behaviour(CGAL::ABORT); + // // 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); - 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); - } + // 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); + // } } 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 index fd7b836b1a3..1c78088f1c6 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_remeshing_plugin_protection_cgal_code.cpp @@ -178,10 +178,10 @@ struct Insert_spheres { while(it != end2) { const Point& a = *it; const Point& b = *++it; - std::cerr << "segment( " << a << ", " << b << ")\n"; - std::cerr << "small_distance_to_go=" << small_distance_to_go << std::endl; + // std::cerr << "segment( " << a << ", " << b << ")\n"; + // std::cerr << "small_distance_to_go=" << small_distance_to_go << std::endl; const FT d = CGAL_NTS sqrt(squared_distance(a, b)); - std::cerr << "d=" << d << std::endl; + // std::cerr << "d=" << d << std::endl; FT pos = small_distance_to_go; if(pos < d) { for(; pos < d; @@ -190,7 +190,7 @@ struct Insert_spheres { const Point p = a + pos * ( b - a ) / d; c2t3.triangulation().insert(Point_3(p, r2)); - std::cerr << "."; + // std::cerr << "."; } // pos -= local_size; small_distance_to_go = pos - d; @@ -198,7 +198,7 @@ struct Insert_spheres { else { small_distance_to_go -= d; } - std::cerr << "\n"; + // std::cerr << "\n"; } c2t3.triangulation().insert(b); std::cerr << "One polyline is protected!\n";