From 299d748adf5964cae1eaf8bb52ceb39cd219e3d4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 2 Jan 2017 22:31:27 +0100 Subject: [PATCH] Loop subdivision now works for Surface_mesh --- .../Subdivision_method_3/Loop_subdivision.cpp | 8 +- .../include/CGAL/Polyhedron_decorator_3.h | 1 + .../include/CGAL/Subdivision_mask_3.h | 56 ++++++----- .../include/CGAL/Subdivision_method_3.h | 2 +- .../include/CGAL/Subdivision_method_impl_3.h | 99 +++++++++---------- 5 files changed, 87 insertions(+), 79 deletions(-) diff --git a/Subdivision_method_3/examples/Subdivision_method_3/Loop_subdivision.cpp b/Subdivision_method_3/examples/Subdivision_method_3/Loop_subdivision.cpp index 380af8bca96..8f3fdf21904 100644 --- a/Subdivision_method_3/examples/Subdivision_method_3/Loop_subdivision.cpp +++ b/Subdivision_method_3/examples/Subdivision_method_3/Loop_subdivision.cpp @@ -1,13 +1,17 @@ #include -#include #include #include +#include #include +#include + +#include typedef CGAL::Simple_cartesian Kernel; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Surface_mesh Polyhedron; +//typedef CGAL::Polyhedron_3 Polyhedron; using namespace std; using namespace CGAL; diff --git a/Subdivision_method_3/include/CGAL/Polyhedron_decorator_3.h b/Subdivision_method_3/include/CGAL/Polyhedron_decorator_3.h index 74e205c2b15..b72e6cc2c30 100644 --- a/Subdivision_method_3/include/CGAL/Polyhedron_decorator_3.h +++ b/Subdivision_method_3/include/CGAL/Polyhedron_decorator_3.h @@ -25,6 +25,7 @@ #define CGAL_POLYHEDRON_DECORATOR_H_01282002 #include +#include namespace CGAL { diff --git a/Subdivision_method_3/include/CGAL/Subdivision_mask_3.h b/Subdivision_method_3/include/CGAL/Subdivision_mask_3.h index 5eacf2596f5..e4a9ac272e9 100644 --- a/Subdivision_method_3/include/CGAL/Subdivision_mask_3.h +++ b/Subdivision_method_3/include/CGAL/Subdivision_mask_3.h @@ -200,32 +200,39 @@ public: /// The geometry mask of Loop subdivision template class Loop_mask_3 : public PQQ_stencil_3 { + typedef PQQ_stencil_3 Base; public: typedef Poly Polyhedron; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename Base::vertex_descriptor vertex_descriptor; + typedef typename Base::halfedge_descriptor halfedge_descriptor; + typedef typename Base::face_descriptor face_descriptor; - typedef typename Polyhedron::Halfedge_around_facet_circulator + typedef typename Base::Kernel Kernel; + + typedef typename Base::FT FT; + typedef typename Base::Point Point; + typedef typename Base::Vector Vector; + + typedef Halfedge_around_face_circulator Halfedge_around_facet_circulator; - typedef typename Polyhedron::Halfedge_around_vertex_circulator + typedef typename Halfedge_around_target_circulator Halfedge_around_vertex_circulator; - typedef typename Polyhedron::Traits Traits; - typedef typename Traits::Kernel Kernel; - - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; + public: + + Loop_mask_3(Polyhedron& poly) + : Base(poly) + {} + // void edge_node(halfedge_descriptor edge, Point& pt) { - Point& p1 = edge->vertex()->point(); - Point& p2 = edge->opposite()->vertex()->point(); - Point& f1 = edge->next()->vertex()->point(); - Point& f2 = edge->opposite()->next()->vertex()->point(); + Point& p1 = get(this->vpmap,target(edge, this->polyhedron)); + Point& p2 = get(this->vpmap,target(opposite(edge, this->polyhedron), this->polyhedron)); + Point& f1 = get(this->vpmap,target(next(edge, this->polyhedron), this->polyhedron)); + Point& f2 = get(this->vpmap,target(next(opposite(edge, this->polyhedron), this->polyhedron), this->polyhedron)); pt = Point((3*(p1[0]+p2[0])+f1[0]+f2[0])/8, (3*(p1[1]+p2[1])+f1[1]+f2[1])/8, @@ -233,14 +240,14 @@ public: } // void vertex_node(vertex_descriptor vertex, Point& pt) { - Halfedge_around_vertex_circulator vcir = vertex->vertex_begin(); + Halfedge_around_vertex_circulator vcir(vertex, this->polyhedron); size_t n = circulator_size(vcir); FT R[] = {0.0, 0.0, 0.0}; - Point& S = vertex->point(); + Point& S = get(this->vpmap,vertex); for (size_t i = 0; i < n; i++, ++vcir) { - Point& p = vcir->opposite()->vertex()->point(); + Point& p = get(this->vpmap,target(opposite(*vcir, this->polyhedron), this->polyhedron)); R[0] += p[0]; R[1] += p[1]; R[2] += p[2]; } if (n == 6) { @@ -256,14 +263,15 @@ public: //void facet_node(face_descriptor facet, Point& pt) {}; // void border_node(halfedge_descriptor edge, Point& ept, Point& vpt) { - Point& ep1 = edge->vertex()->point(); - Point& ep2 = edge->opposite()->vertex()->point(); + Point& ep1 = get(this->vpmap,target(edge, this->polyhedron)); + Point& ep2 = get(this->vpmap,target(opposite(edge, this->polyhedron), this->polyhedron)); ept = Point((ep1[0]+ep2[0])/2, (ep1[1]+ep2[1])/2, (ep1[2]+ep2[2])/2); - Halfedge_around_vertex_circulator vcir = edge->vertex_begin(); - Point& vp1 = vcir->opposite()->vertex()->point(); - Point& vp0 = vcir->vertex()->point(); - Point& vp_1 = (--vcir)->opposite()->vertex()->point(); + Halfedge_around_vertex_circulator vcir(edge,this->polyhedron); + Point& vp1 = get(this->vpmap,target(opposite(*vcir,this->polyhedron ),this->polyhedron)); + Point& vp0 = get(this->vpmap,target(*vcir,this->polyhedron)); + --vcir; + Point& vp_1 = get(this->vpmap,target(opposite(*vcir,this->polyhedron),this->polyhedron)); vpt = Point((vp_1[0] + 6*vp0[0] + vp1[0])/8, (vp_1[1] + 6*vp0[1] + vp1[1])/8, (vp_1[2] + 6*vp0[2] + vp1[2])/8 ); diff --git a/Subdivision_method_3/include/CGAL/Subdivision_method_3.h b/Subdivision_method_3/include/CGAL/Subdivision_method_3.h index cf36f228269..6aaea5ad424 100644 --- a/Subdivision_method_3/include/CGAL/Subdivision_method_3.h +++ b/Subdivision_method_3/include/CGAL/Subdivision_method_3.h @@ -66,7 +66,7 @@ namespace Subdivision_method_3 { // template void Loop_subdivision(Polyhedron& p, int step = 1) { - PTQ(p, Loop_mask_3() , step); + PTQ(p, Loop_mask_3(p) , step); } // template diff --git a/Subdivision_method_3/include/CGAL/Subdivision_method_impl_3.h b/Subdivision_method_3/include/CGAL/Subdivision_method_impl_3.h index 70a67573e14..93ec22f42c7 100644 --- a/Subdivision_method_3/include/CGAL/Subdivision_method_impl_3.h +++ b/Subdivision_method_3/include/CGAL/Subdivision_method_impl_3.h @@ -60,8 +60,6 @@ namespace Subdivision_method_3 { Vertex_pmap vpm = get(CGAL::vertex_point, p); - // AF p.normalize_border(); - // Build a new vertices buffer has the following structure // // 0 1 ... e_begin ... f_begin ... (end_of_buffer) @@ -94,17 +92,7 @@ namespace Subdivision_method_3 { for (size_t i = 0; i < num_facet; i++, ++fitr) mask.facet_node(*fitr, face_point_buffer[i]); -#if 0 - size_t sb = 0; // AF p.size_of_border_edges(); - edge_iterator eitr = edges(p).first; - for (size_t i = 0; i < num_edge-sb; i++, ++eitr) - mask.edge_node(halfedge(*eitr,p), edge_point_buffer[i]); - for (size_t i = num_edge-sb; i < num_edge; i++, ++eitr) { - int v = v_index[target(*eitr,p)]; - v_onborder[v] = true; - mask.border_node(halfedge(*eitr,p), edge_point_buffer[i], vertex_point_buffer[v]); - } -#else + { std::size_t i = 0; BOOST_FOREACH(edge_descriptor ed, edges(p)){ @@ -119,7 +107,7 @@ namespace Subdivision_method_3 { ++i; } } -#endif + vertex_iterator vitr = vertices(p).first; for (size_t i = 0; i < num_vertex; i++, ++vitr) if (!v_onborder[v_index[*vitr]]) mask.vertex_node(*vitr, vertex_point_buffer[i]); @@ -183,21 +171,20 @@ namespace Subdivision_method_3 { typedef Polyhedron_decorator_3 PD; - typedef typename Poly::Vertex_handle Vertex_handle; - typedef typename Poly::Halfedge_handle Halfedge_handle; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - typedef typename Poly::Vertex_iterator Vertex_iterator; - typedef typename Poly::Edge_iterator Edge_iterator; - typedef typename Poly::Facet_iterator Facet_iterator; + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::edge_iterator edge_iterator; + typedef typename boost::graph_traits::face_iterator face_iterator; - typedef typename Poly::Halfedge_around_facet_circulator - Halfedge_around_facet_circulator; + typedef Halfedge_around_face_circulator Halfedge_around_face_circulator; - typedef typename Poly::Traits Traits; - typedef typename Traits::Kernel Kernel; - typedef typename Kernel::Point_3 Point; + typedef typename boost::property_map::type Vertex_pmap; + typedef typename boost::property_traits::value_type Point; - p.normalize_border(); + Vertex_pmap vpm = get(CGAL::vertex_point, p); // Build a new vertices buffer has the following structure // @@ -206,9 +193,9 @@ namespace Subdivision_method_3 { // e_begin ... (end) : store the positions of the edge-vertices // The index of the vertices buffer should 1-1 map to the distance // of the corresponding iterator to the begin of the iterator. - size_t num_vertex = p.size_of_vertices(); - size_t num_edge = p.size_of_halfedges()/2; - size_t num_facet = p.size_of_facets(); + size_t num_vertex = num_vertices(p); + size_t num_edge = num_halfedges(p)/2; + size_t num_facet = num_faces(p); // If Polyhedron is using vector, we need to reserve the memory to prevent // the CGAL_assertion. @@ -218,21 +205,29 @@ namespace Subdivision_method_3 { Point* vertex_point_buffer = new Point[num_vertex + num_edge]; Point* edge_point_buffer = vertex_point_buffer + num_vertex; - std::vector v_onborder(num_vertex); - size_t sb = p.size_of_border_edges(); - - Edge_iterator eitr = p.edges_begin(); - for (size_t i = 0; i < num_edge-sb; i++, ++eitr) - mask.edge_node(eitr, edge_point_buffer[i]); - for (size_t i = num_edge-sb; i < num_edge; i++, ++eitr) { - int v = (int) std::distance(p.vertices_begin(), eitr->vertex()); - v_onborder[v] = true; - mask.border_node(eitr, edge_point_buffer[i], vertex_point_buffer[v]); + int i=0; + boost::unordered_map v_index; + BOOST_FOREACH(vertex_descriptor vh, vertices(p)){ + v_index[vh]= i++; } + std::vector v_onborder(num_vertex); - Vertex_iterator vitr = p.vertices_begin(); + { + std::size_t i = 0; + BOOST_FOREACH(edge_descriptor ed, edges(p)){ + if(! is_border(ed,p)){ + mask.edge_node(halfedge(ed,p), edge_point_buffer[i]); + } else{ + int v = v_index[target(ed,p)]; + v_onborder[v] = true; + mask.border_node(halfedge(ed,p), edge_point_buffer[i], vertex_point_buffer[v]); + } + ++i; + } + } + vertex_iterator vitr = vertices(p).first; for (size_t i = 0; i < num_vertex; i++, ++vitr) - if (!v_onborder[i]) mask.vertex_node(vitr, vertex_point_buffer[i]); + if (!v_onborder[i]) mask.vertex_node(*vitr, vertex_point_buffer[i]); // Build the connectivity using insert_vertex() and insert_edge() // 1. insert_vertex() to all edges and set them to new positions @@ -242,25 +237,25 @@ namespace Subdivision_method_3 { // 4. insert_edge() between all other new inserted vertices of step 1 and // the new inserted vertex of step 3 // Step 1. - eitr = p.edges_begin(); + edge_iterator eitr = edges(p).first; for (size_t i = 0; i < num_edge; i++, ++eitr) { - Vertex_handle vh = PD::insert_vertex(p, eitr); - vh->point() = edge_point_buffer[i]; + vertex_descriptor vh = PD::insert_vertex(p, halfedge(*eitr,p)); + put(vpm,vh, edge_point_buffer[i]); } - Facet_iterator fitr = p.facets_begin(); + face_iterator fitr = faces(p).first; for (size_t i = 0; i < num_facet; i++, ++fitr) { // Step 2. - Halfedge_around_facet_circulator hcir_begin = fitr->facet_begin(); - Halfedge_around_facet_circulator hcir = hcir_begin; + Halfedge_around_face_circulator hcir_begin(halfedge(*fitr,p),p); + Halfedge_around_face_circulator hcir = hcir_begin; // After linsub, the facet valence = 6 CGAL_assertion(circulator_size(hcir)==6); - Halfedge_handle e1 = ++hcir; + halfedge_descriptor e1 = *(++hcir); ++hcir; - Halfedge_handle e2 = ++hcir; + halfedge_descriptor e2 = *(++hcir); ++hcir; - Halfedge_handle e3 = ++hcir; + halfedge_descriptor e3 = *(++hcir); e2 = PD::insert_edge(p, e1, e2); e3 = PD::insert_edge(p, e2, e3); PD::insert_edge(p, e3, e1); @@ -268,12 +263,12 @@ namespace Subdivision_method_3 { // Update the geometry data of the newly inserted vertices by the // vertices buffer - vitr = p.vertices_begin(); + vitr = vertices(p).first; for (size_t i = 0; i < num_vertex; i++, ++vitr) - vitr->point() = vertex_point_buffer[i]; + put(vpm, *vitr, vertex_point_buffer[i]); delete []vertex_point_buffer; - } + } // ======================================================================