copy descriptors as we are looping over them while modifying the mesh

done for all but DQQ
This commit is contained in:
Sébastien Loriot 2017-12-11 17:51:24 +01:00
parent 25491714ba
commit c751a461ff
1 changed files with 70 additions and 64 deletions

View File

@ -53,13 +53,19 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) {
typedef typename boost::graph_traits<Poly>::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits<Poly>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Poly>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Poly>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Poly>::edge_descriptor edge_descriptor; typedef typename boost::graph_traits<Poly>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Poly>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Poly>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<Poly>::edge_iterator edge_iterator;
typedef typename boost::graph_traits<Poly>::face_iterator face_iterator;
typedef Halfedge_around_face_circulator<Poly> Halfedge_around_facet_circulator; typedef Halfedge_around_face_circulator<Poly> Halfedge_around_facet_circulator;
//First back up initial vertices/faces/edges
std::vector<vertex_descriptor> p_vertices(vertices(p).first, vertices(p).second);
std::vector<face_descriptor> p_faces(faces(p).first, faces(p).second);
std::vector<edge_descriptor> 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 // Build a new vertices buffer has the following structure
// //
// 0 1 ... e_begin ... f_begin ... (end_of_buffer) // 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 // f_begin ... (end) : store the positions of the face-vertices
// The index of the vertices buffer should 1-1 map to the distance // The index of the vertices buffer should 1-1 map to the distance
// of the corresponding iterator to the begin of the iterator. // of the corresponding iterator to the begin of the iterator.
typename boost::graph_traits<Poly>::vertices_size_type num_vertex = num_vertices(p);
typename boost::graph_traits<Poly>::halfedges_size_type num_edge = num_halfedges(p)/2;
typename boost::graph_traits<Poly>::faces_size_type num_facet = num_faces(p);
// We need to reserve the memory to prevent reallocation. // 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<VertexPointMap>::value_type Point; typedef typename boost::property_traits<VertexPointMap>::value_type Point;
Point* vertex_point_buffer = new Point[num_vertex + num_edge + num_facet]; Point* vertex_point_buffer = new Point[num_v + num_e + num_f];
Point* edge_point_buffer = vertex_point_buffer + num_vertex; Point* edge_point_buffer = vertex_point_buffer + num_v;
Point* face_point_buffer = edge_point_buffer + num_edge; Point* face_point_buffer = edge_point_buffer + num_e;
int i=0; int i=0;
boost::unordered_map<vertex_descriptor,int> v_index; boost::unordered_map<vertex_descriptor,int> v_index;
BOOST_FOREACH(vertex_descriptor vh, vertices(p)){ BOOST_FOREACH(vertex_descriptor vh, p_vertices){
v_index[vh]= i++; v_index[vh]= i++;
} }
std::vector<bool> v_onborder(num_vertex); std::vector<bool> v_onborder(num_v);
face_iterator fitr = faces(p).first; typename std::vector<face_descriptor>::iterator fitr=p_faces.begin();
for (typename boost::graph_traits<Poly>::faces_size_type i = 0; i < num_facet; i++, ++fitr) for (std::size_t i = 0; i < num_f; i++, ++fitr)
mask.face_node(*fitr, face_point_buffer[i]); mask.face_node(*fitr, face_point_buffer[i]);
{ {
std::size_t i = 0; std::size_t i = 0;
BOOST_FOREACH(edge_descriptor ed, edges(p)){ BOOST_FOREACH(edge_descriptor ed, p_edges){
if(is_border(ed,p)){ if(is_border(ed,p)){
halfedge_descriptor h=halfedge(ed,p); halfedge_descriptor h=halfedge(ed,p);
if (is_border(h,p)) h=opposite(h,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; typename std::vector<vertex_descriptor>::iterator vitr = p_vertices.begin();
for (typename boost::graph_traits<Poly>::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) 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]); if (!v_onborder[v_index[*vitr]]) mask.vertex_node(*vitr, vertex_point_buffer[i]);
// Build the connectivity using insert_vertex() and insert_edge() // 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 // 4. insert_edge() between all other new inserted vertices of step 1 and
// the new inserted vertex of step 3 // the new inserted vertex of step 3
// Step 1. // Step 1.
edge_iterator eitr = edges(p).first; typename std::vector<edge_descriptor>::iterator eitr = p_edges.begin();
for (typename boost::graph_traits<Poly>::edges_size_type i = 0; i < num_edge; i++, ++eitr) { for (std::size_t i = 0; i < num_e; i++, ++eitr) {
vertex_descriptor vh = insert_vertex(p, halfedge(*eitr,p)); vertex_descriptor vh = insert_vertex(p, halfedge(*eitr,p));
put(vpm, vh, edge_point_buffer[i]); put(vpm, vh, edge_point_buffer[i]);
} }
fitr = faces(p).first;
// TODO: the topoloy modification can be done by a template function // TODO: the topoloy modification can be done by a template function
// and that gives the user a chance to create new topological masks. // and that gives the user a chance to create new topological masks.
for (typename boost::graph_traits<Poly>::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. // Step 2.
Halfedge_around_facet_circulator hcir_begin(halfedge(*fitr,p),p); Halfedge_around_facet_circulator hcir_begin(halfedge(*fitr,p),p);
Halfedge_around_facet_circulator hcir = hcir_begin; 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 // Update the geometry data of the newly inserted vertices by the
// vertices buffer // vertices buffer
vitr = vertices(p).first; vitr = p_vertices.begin();
for (typename boost::graph_traits<Poly>::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) for (std::size_t i = 0; i < num_v; i++, ++vitr)
put(vpm, *vitr, vertex_point_buffer[i]); put(vpm, *vitr, vertex_point_buffer[i]);
// CGAL_postcondition(p.is_valid()); // CGAL_postcondition(p.is_valid());
@ -174,15 +175,21 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) {
typedef typename boost::graph_traits<Poly>::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits<Poly>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Poly>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Poly>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Poly>::edge_descriptor edge_descriptor; typedef typename boost::graph_traits<Poly>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Poly>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Poly>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<Poly>::edge_iterator edge_iterator;
typedef typename boost::graph_traits<Poly>::face_iterator face_iterator;
typedef Halfedge_around_face_circulator<Poly> Halfedge_around_face_circulator; typedef Halfedge_around_face_circulator<Poly> Halfedge_around_face_circulator;
typedef typename boost::property_traits<VertexPointMap>::value_type Point; typedef typename boost::property_traits<VertexPointMap>::value_type Point;
//First back up initial vertices/faces/edges
std::vector<vertex_descriptor> p_vertices(vertices(p).first, vertices(p).second);
std::vector<face_descriptor> p_faces(faces(p).first, faces(p).second);
std::vector<edge_descriptor> 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 // Build a new vertices buffer has the following structure
// //
// 0 1 ... e_begin ... f_begin ... (end_of_buffer) // 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 // e_begin ... (end) : store the positions of the edge-vertices
// The index of the vertices buffer should 1-1 map to the distance // The index of the vertices buffer should 1-1 map to the distance
// of the corresponding iterator to the begin of the iterator. // of the corresponding iterator to the begin of the iterator.
typename boost::graph_traits<Poly>::vertices_size_type num_vertex = num_vertices(p);
typename boost::graph_traits<Poly>::halfedges_size_type num_edge = num_halfedges(p)/2;
typename boost::graph_traits<Poly>::faces_size_type num_facet = num_faces(p);
// We need to reserve the memory to prevent reallocation. // 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* vertex_point_buffer = new Point[num_v + num_e];
Point* edge_point_buffer = vertex_point_buffer + num_vertex; Point* edge_point_buffer = vertex_point_buffer + num_v;
int i=0; int i=0;
boost::unordered_map<vertex_descriptor,int> v_index; boost::unordered_map<vertex_descriptor,int> v_index;
BOOST_FOREACH(vertex_descriptor vh, vertices(p)){ BOOST_FOREACH(vertex_descriptor vh, p_vertices){
v_index[vh]= i++; v_index[vh]= i++;
} }
std::vector<bool> v_onborder(num_vertex); std::vector<bool> v_onborder(num_v);
{ {
std::size_t i = 0; std::size_t i = 0;
BOOST_FOREACH(edge_descriptor ed, edges(p)){ BOOST_FOREACH(edge_descriptor ed, p_edges){
if(! is_border(ed,p)){ if(! is_border(ed,p)){
mask.edge_node(halfedge(ed,p), edge_point_buffer[i]); mask.edge_node(halfedge(ed,p), edge_point_buffer[i]);
} else{ } else{
@ -222,8 +226,8 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) {
++i; ++i;
} }
} }
vertex_iterator vitr = vertices(p).first; typename std::vector<vertex_descriptor>::iterator vitr = p_vertices.begin();
for (typename boost::graph_traits<Poly>::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) for (std::size_t i = 0; i < num_v; 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() // 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 // 4. insert_edge() between all other new inserted vertices of step 1 and
// the new inserted vertex of step 3 // the new inserted vertex of step 3
// Step 1. // Step 1.
edge_iterator eitr = edges(p).first; typename std::vector<edge_descriptor>::iterator eit = p_edges.begin();
for (typename boost::graph_traits<Poly>::edges_size_type i = 0; i < num_edge; i++, ++eitr) { for (std::size_t i = 0; i < num_e; i++, ++eit) {
vertex_descriptor vh = insert_vertex(p, halfedge(*eitr,p)); vertex_descriptor vh = insert_vertex(p, halfedge(*eit,p));
put(vpm,vh, edge_point_buffer[i]); put(vpm,vh, edge_point_buffer[i]);
} }
face_iterator fitr = faces(p).first;
for (typename boost::graph_traits<Poly>::faces_size_type i = 0; i < num_facet; i++, ++fitr) { typename std::vector<face_descriptor>::iterator fitr = p_faces.begin();
for (std::size_t i = 0; i < num_f; i++, ++fitr) {
// Step 2. // Step 2.
Halfedge_around_face_circulator hcir_begin(halfedge(*fitr,p),p); Halfedge_around_face_circulator hcir_begin(halfedge(*fitr,p),p);
Halfedge_around_face_circulator hcir = hcir_begin; 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 // Update the geometry data of the newly inserted vertices by the
// vertices buffer // vertices buffer
vitr = vertices(p).first; vitr = p_vertices.begin();
for (typename boost::graph_traits<Poly>::vertices_size_type i = 0; i < num_vertex; i++, ++vitr) for (std::size_t i = 0; i < num_v; i++, ++vitr)
put(vpm, *vitr, vertex_point_buffer[i]); put(vpm, *vitr, vertex_point_buffer[i]);
// CGAL_postcondition(p.is_valid()); // CGAL_postcondition(p.is_valid());
@ -555,19 +560,21 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask,
typedef typename boost::graph_traits<Poly>::edge_descriptor edge_descriptor; typedef typename boost::graph_traits<Poly>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Poly>::face_descriptor face_descriptor; typedef typename boost::graph_traits<Poly>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Poly>::edge_iterator edge_iterator;
typedef typename boost::graph_traits<Poly>::face_iterator face_iterator;
typedef typename boost::property_traits<VertexPointMap>::value_type Point; typedef typename boost::property_traits<VertexPointMap>::value_type Point;
typename boost::graph_traits<Poly>::vertices_size_type num_v = num_vertices(p); //First back up initial vertices/faces/edges
typename boost::graph_traits<Poly>::halfedges_size_type num_e = num_halfedges(p)/2; std::vector<vertex_descriptor> p_vertices(vertices(p).first, vertices(p).second);
typename boost::graph_traits<Poly>::faces_size_type num_f = num_faces(p); std::vector<face_descriptor> p_faces(faces(p).first, faces(p).second);
std::vector<edge_descriptor> 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 // reserve enough size for the new points
typename boost::graph_traits<Poly>::faces_size_type new_pts_size = num_f; std::size_t new_pts_size = num_f;
if(refine_border) { if(refine_border) {
BOOST_FOREACH(edge_descriptor ed, edges(p)){ BOOST_FOREACH(edge_descriptor ed, p_edges){
if(is_border(ed, p)) if(is_border(ed, p))
++new_pts_size; ++new_pts_size;
} }
@ -586,7 +593,7 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask,
// compute the positions of new points // compute the positions of new points
std::size_t i = 0; std::size_t i = 0;
std::size_t face_id = 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!"); //ASSERTION_MSG(circulator_size(fitr->facet_begin())==3, "(ERROR) Non-triangle facet!");
if(refine_border) { if(refine_border) {
BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(halfedge(fd, p), p)) { 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 // smooth the position of existing vertices
BOOST_FOREACH(vertex_descriptor vd, vertices(p)){ BOOST_FOREACH(vertex_descriptor vd, p_vertices){
Point pt; Point pt;
if(!is_border(vd, p)) { if(!is_border(vd, p)) {
mask.vertex_node(vd, pt); mask.vertex_node(vd, pt);
@ -622,10 +629,9 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask,
} }
// insert the new subdividing points // insert the new subdividing points
face_iterator b,e; typename std::vector<face_descriptor>::iterator fit=p_faces.begin();
boost::tie(b,e) = faces(p); for(std::size_t i=0, cpt_id=0; i < num_f; ++i, ++fit){
for(typename boost::graph_traits<Poly>::faces_size_type i=0, cpt_id=0; i < num_f; ++i, ++b){ face_descriptor fd = *fit;
face_descriptor fd = *b;
halfedge_descriptor hd = face_halfedge_border[i]; halfedge_descriptor hd = face_halfedge_border[i];
if(refine_border && hd != boost::graph_traits<Poly>::null_halfedge()) { if(refine_border && hd != boost::graph_traits<Poly>::null_halfedge()) {
halfedge_descriptor hd_next = next(hd, p); 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) // flip the old edges (except the border edges)
edge_iterator eitr = edges(p).first; typename std::vector<edge_descriptor>::iterator eitr = p_edges.begin();
for (typename boost::graph_traits<Poly>::edges_size_type i = 0; i < num_e; ++i) { for (std::size_t i = 0; i < num_e; ++i) {
halfedge_descriptor e = halfedge(*eitr,p); halfedge_descriptor e = halfedge(*eitr,p);
++eitr; // move to next edge before flip since flip destroys current edge ++eitr; // move to next edge before flip since flip destroys current edge
if (! is_border(edge(e,p),p)) { if (! is_border(edge(e,p),p)) {