From c751a461ff8657bb2e3911af35d2c203668c8180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 11 Dec 2017 17:51:24 +0100 Subject: [PATCH] copy descriptors as we are looping over them while modifying the mesh done for all but DQQ --- .../internal/subdivision_hosts_impl_3.h | 134 +++++++++--------- 1 file changed, 70 insertions(+), 64 deletions(-) diff --git a/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h b/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h index 1db48935e0d..6b26176615e 100644 --- a/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h +++ b/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h @@ -53,13 +53,19 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { 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 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 boost::graph_traits::face_descriptor face_descriptor; typedef Halfedge_around_face_circulator Halfedge_around_facet_circulator; + //First back up initial vertices/faces/edges + std::vector p_vertices(vertices(p).first, vertices(p).second); + std::vector p_faces(faces(p).first, faces(p).second); + std::vector p_edges(edges(p).first, edges(p).second); + + std::size_t num_v = p_vertices.size(); + std::size_t num_e = p_edges.size(); + std::size_t num_f = p_faces.size(); + // Build a new vertices buffer has the following structure // // 0 1 ... e_begin ... f_begin ... (end_of_buffer) @@ -68,34 +74,29 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { // f_begin ... (end) : store the positions of the face-vertices // The index of the vertices buffer should 1-1 map to the distance // of the corresponding iterator to the begin of the iterator. - typename boost::graph_traits::vertices_size_type num_vertex = num_vertices(p); - typename boost::graph_traits::halfedges_size_type num_edge = num_halfedges(p)/2; - typename boost::graph_traits::faces_size_type num_facet = num_faces(p); // We need to reserve the memory to prevent reallocation. - reserve(p,num_vertex+num_edge+num_facet, 4*2*num_edge, 4*num_edge/2); + reserve(p,num_v+num_e+num_f, 4*2*num_e, 4*num_e/2); typedef typename boost::property_traits::value_type Point; - Point* vertex_point_buffer = new Point[num_vertex + num_edge + num_facet]; - Point* edge_point_buffer = vertex_point_buffer + num_vertex; - Point* face_point_buffer = edge_point_buffer + num_edge; + Point* vertex_point_buffer = new Point[num_v + num_e + num_f]; + Point* edge_point_buffer = vertex_point_buffer + num_v; + Point* face_point_buffer = edge_point_buffer + num_e; int i=0; boost::unordered_map v_index; - BOOST_FOREACH(vertex_descriptor vh, vertices(p)){ + BOOST_FOREACH(vertex_descriptor vh, p_vertices){ v_index[vh]= i++; } - std::vector v_onborder(num_vertex); - face_iterator fitr = faces(p).first; - for (typename boost::graph_traits::faces_size_type i = 0; i < num_facet; i++, ++fitr) + std::vector v_onborder(num_v); + typename std::vector::iterator fitr=p_faces.begin(); + for (std::size_t i = 0; i < num_f; i++, ++fitr) mask.face_node(*fitr, face_point_buffer[i]); - - { std::size_t i = 0; - BOOST_FOREACH(edge_descriptor ed, edges(p)){ + BOOST_FOREACH(edge_descriptor ed, p_edges){ if(is_border(ed,p)){ halfedge_descriptor h=halfedge(ed,p); if (is_border(h,p)) h=opposite(h,p); @@ -110,8 +111,8 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { } } - vertex_iterator vitr = vertices(p).first; - for (typename boost::graph_traits::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) + typename std::vector::iterator vitr = p_vertices.begin(); + for (std::size_t i = 0; i < num_v; i++, ++vitr) if (!v_onborder[v_index[*vitr]]) mask.vertex_node(*vitr, vertex_point_buffer[i]); // Build the connectivity using insert_vertex() and insert_edge() @@ -122,16 +123,16 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { // 4. insert_edge() between all other new inserted vertices of step 1 and // the new inserted vertex of step 3 // Step 1. - edge_iterator eitr = edges(p).first; - for (typename boost::graph_traits::edges_size_type i = 0; i < num_edge; i++, ++eitr) { + typename std::vector::iterator eitr = p_edges.begin(); + for (std::size_t i = 0; i < num_e; i++, ++eitr) { vertex_descriptor vh = insert_vertex(p, halfedge(*eitr,p)); put(vpm, vh, edge_point_buffer[i]); } - fitr = faces(p).first; // TODO: the topoloy modification can be done by a template function // and that gives the user a chance to create new topological masks. - for (typename boost::graph_traits::faces_size_type i = 0; i < num_facet; i++, ++fitr) { + fitr = p_faces.begin(); + for (std::size_t i = 0; i < num_f; i++, ++fitr) { // Step 2. Halfedge_around_facet_circulator hcir_begin(halfedge(*fitr,p),p); Halfedge_around_facet_circulator hcir = hcir_begin; @@ -160,8 +161,8 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { // Update the geometry data of the newly inserted vertices by the // vertices buffer - vitr = vertices(p).first; - for (typename boost::graph_traits::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) + vitr = p_vertices.begin(); + for (std::size_t i = 0; i < num_v; i++, ++vitr) put(vpm, *vitr, vertex_point_buffer[i]); // CGAL_postcondition(p.is_valid()); @@ -174,15 +175,21 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { 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 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 boost::graph_traits::face_descriptor face_descriptor; typedef Halfedge_around_face_circulator Halfedge_around_face_circulator; typedef typename boost::property_traits::value_type Point; + //First back up initial vertices/faces/edges + std::vector p_vertices(vertices(p).first, vertices(p).second); + std::vector p_faces(faces(p).first, faces(p).second); + std::vector p_edges(edges(p).first, edges(p).second); + + std::size_t num_v = p_vertices.size(); + std::size_t num_e = p_edges.size(); + std::size_t num_f = p_faces.size(); + // Build a new vertices buffer has the following structure // // 0 1 ... e_begin ... f_begin ... (end_of_buffer) @@ -190,26 +197,23 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { // 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. - typename boost::graph_traits::vertices_size_type num_vertex = num_vertices(p); - typename boost::graph_traits::halfedges_size_type num_edge = num_halfedges(p)/2; - typename boost::graph_traits::faces_size_type num_facet = num_faces(p); // We need to reserve the memory to prevent reallocation. - reserve(p,num_vertex+num_edge, 2*2*num_edge, 4*num_edge/2); + reserve(p,num_v + num_e, 2*2*num_e, 4*num_e/2); - Point* vertex_point_buffer = new Point[num_vertex + num_edge]; - Point* edge_point_buffer = vertex_point_buffer + num_vertex; + Point* vertex_point_buffer = new Point[num_v + num_e]; + Point* edge_point_buffer = vertex_point_buffer + num_v; int i=0; boost::unordered_map v_index; - BOOST_FOREACH(vertex_descriptor vh, vertices(p)){ + BOOST_FOREACH(vertex_descriptor vh, p_vertices){ v_index[vh]= i++; } - std::vector v_onborder(num_vertex); + std::vector v_onborder(num_v); { std::size_t i = 0; - BOOST_FOREACH(edge_descriptor ed, edges(p)){ + BOOST_FOREACH(edge_descriptor ed, p_edges){ if(! is_border(ed,p)){ mask.edge_node(halfedge(ed,p), edge_point_buffer[i]); } else{ @@ -222,8 +226,8 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { ++i; } } - vertex_iterator vitr = vertices(p).first; - for (typename boost::graph_traits::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) + typename std::vector::iterator vitr = p_vertices.begin(); + for (std::size_t i = 0; i < num_v; i++, ++vitr) if (!v_onborder[i]) mask.vertex_node(*vitr, vertex_point_buffer[i]); // Build the connectivity using insert_vertex() and insert_edge() @@ -234,13 +238,14 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { // 4. insert_edge() between all other new inserted vertices of step 1 and // the new inserted vertex of step 3 // Step 1. - edge_iterator eitr = edges(p).first; - for (typename boost::graph_traits::edges_size_type i = 0; i < num_edge; i++, ++eitr) { - vertex_descriptor vh = insert_vertex(p, halfedge(*eitr,p)); + typename std::vector::iterator eit = p_edges.begin(); + for (std::size_t i = 0; i < num_e; i++, ++eit) { + vertex_descriptor vh = insert_vertex(p, halfedge(*eit,p)); put(vpm,vh, edge_point_buffer[i]); } - face_iterator fitr = faces(p).first; - for (typename boost::graph_traits::faces_size_type i = 0; i < num_facet; i++, ++fitr) { + + typename std::vector::iterator fitr = p_faces.begin(); + for (std::size_t i = 0; i < num_f; i++, ++fitr) { // Step 2. Halfedge_around_face_circulator hcir_begin(halfedge(*fitr,p),p); Halfedge_around_face_circulator hcir = hcir_begin; @@ -260,8 +265,8 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { // Update the geometry data of the newly inserted vertices by the // vertices buffer - vitr = vertices(p).first; - for (typename boost::graph_traits::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) + vitr = p_vertices.begin(); + for (std::size_t i = 0; i < num_v; i++, ++vitr) put(vpm, *vitr, vertex_point_buffer[i]); // CGAL_postcondition(p.is_valid()); @@ -555,19 +560,21 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask, typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename boost::graph_traits::edge_iterator edge_iterator; - typedef typename boost::graph_traits::face_iterator face_iterator; - typedef typename boost::property_traits::value_type Point; - typename boost::graph_traits::vertices_size_type num_v = num_vertices(p); - typename boost::graph_traits::halfedges_size_type num_e = num_halfedges(p)/2; - typename boost::graph_traits::faces_size_type num_f = num_faces(p); + //First back up initial vertices/faces/edges + std::vector p_vertices(vertices(p).first, vertices(p).second); + std::vector p_faces(faces(p).first, faces(p).second); + std::vector p_edges(edges(p).first, edges(p).second); + + std::size_t num_v = p_vertices.size(); + std::size_t num_e = p_edges.size(); + std::size_t num_f = p_faces.size(); // reserve enough size for the new points - typename boost::graph_traits::faces_size_type new_pts_size = num_f; + std::size_t new_pts_size = num_f; if(refine_border) { - BOOST_FOREACH(edge_descriptor ed, edges(p)){ + BOOST_FOREACH(edge_descriptor ed, p_edges){ if(is_border(ed, p)) ++new_pts_size; } @@ -586,7 +593,7 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask, // compute the positions of new points std::size_t i = 0; std::size_t face_id = 0; - BOOST_FOREACH (face_descriptor fd, faces(p)) { + BOOST_FOREACH (face_descriptor fd, p_faces) { //ASSERTION_MSG(circulator_size(fitr->facet_begin())==3, "(ERROR) Non-triangle facet!"); if(refine_border) { BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, p), p)) { @@ -613,7 +620,7 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask, } // smooth the position of existing vertices - BOOST_FOREACH(vertex_descriptor vd, vertices(p)){ + BOOST_FOREACH(vertex_descriptor vd, p_vertices){ Point pt; if(!is_border(vd, p)) { mask.vertex_node(vd, pt); @@ -622,10 +629,9 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask, } // insert the new subdividing points - face_iterator b,e; - boost::tie(b,e) = faces(p); - for(typename boost::graph_traits::faces_size_type i=0, cpt_id=0; i < num_f; ++i, ++b){ - face_descriptor fd = *b; + typename std::vector::iterator fit=p_faces.begin(); + for(std::size_t i=0, cpt_id=0; i < num_f; ++i, ++fit){ + face_descriptor fd = *fit; halfedge_descriptor hd = face_halfedge_border[i]; if(refine_border && hd != boost::graph_traits::null_halfedge()) { halfedge_descriptor hd_next = next(hd, p); @@ -649,8 +655,8 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask, } // flip the old edges (except the border edges) - edge_iterator eitr = edges(p).first; - for (typename boost::graph_traits::edges_size_type i = 0; i < num_e; ++i) { + typename std::vector::iterator eitr = p_edges.begin(); + for (std::size_t i = 0; i < num_e; ++i) { halfedge_descriptor e = halfedge(*eitr,p); ++eitr; // move to next edge before flip since flip destroys current edge if (! is_border(edge(e,p),p)) {