void geometryUtils::subdivide(Polyhedron& P) { if (P.size_of_facets() == 0) return; // We use that new vertices/halfedges/facets are appended at the end. std::size_t nv = P.size_of_vertices(); Vertex_iterator last_v = P.vertices_end(); --last_v; // the last of the old vertices Edge_iterator last_e = P.edges_end(); --last_e; // the last of the old edges Facet_iterator last_f = P.facets_end(); --last_f; // the last of the old facets Facet_iterator f = P.facets_begin(); // create new center vertices do { geometryUtils::subdivide_create_center_vertex(P, f); } while (f++ != last_f); std::vector<Point_3> pts; // smooth the old vertices pts.reserve(nv); // get intermediate space for the new points ++last_v; // make it the past-the-end position again std::transform(P.vertices_begin(), last_v, std::back_inserter(pts), Smooth_old_vertex()); std::copy(pts.begin(), pts.end(), P.points_begin()); Edge_iterator e = P.edges_begin(); // flip the old edges ++last_e; // make it the past-the-end position again while (e != last_e) { Halfedge_handle h = e; ++e; // careful, incr. before flip since flip destroys current edge geometryUtils::subdivide_flip_edge(P, h); }; CGAL_postcondition(P.is_valid()); };
// Subdivide each facet of the lcc by using sqrt(3)-subdivision. void subdivide_lcc_3 (LCC & m) { if (m.number_of_darts () == 0) return; LCC::size_type mark = m.get_new_mark (); LCC::size_type treated = m.get_new_mark (); m.negate_mark (mark); // All the old darts are marked in O(1). // 1) We smoth the old vertices. std::vector <std::pair<Point_3, Dart_handle> > vertices; // smooth the old vertices vertices.reserve (m.number_of_attributes<0> ()); // get intermediate space std::transform (m.vertex_attributes().begin (), m.vertex_attributes().end (), std::back_inserter (vertices), Smooth_old_vertex (m, mark)); // 2) We subdivide each facet. m.negate_mark (treated); // All the darts are marked in O(1). unsigned int nb = 0; for (LCC::Dart_range::iterator it (m.darts().begin ()); m.number_of_marked_darts (treated) > 0; ++it) { ++nb; if (m.is_marked (it, treated)) { // We unmark the darts of the facet to process only once dart/facet. CGAL::unmark_cell < LCC, 2 > (m, it, treated); // We triangulate the facet. m.insert_barycenter_in_cell<2>(it); } } CGAL_assertion (m.is_whole_map_unmarked (treated)); CGAL_assertion (m.is_valid ()); m.free_mark (treated); // 3) We update the coordinates of old vertices. for (std::vector<std::pair<Point_3, Dart_handle> >::iterator vit=vertices.begin(); vit!=vertices.end(); ++vit) { m.point(vit->second)=vit->first; } // 4) We flip all the old edges. m.negate_mark (mark); // Now only new darts are marked. Dart_handle d2 =LCC::null_handle; for (LCC::Dart_range::iterator it (m.darts().begin ()); it != m.darts().end ();) { d2 = it++; if (!m.is_marked (d2, mark)) // This is an old dart. { // We process only the last dart of a same edge. if (!m.is_free(d2,2) && (m.beta(d2,2,3)==m.beta(d2,3,2))) { if (m.is_marked(m.beta(d2,2), mark) && (m.is_free(d2,3) || (m.is_marked(m.beta(d2,3), mark) && m.is_marked(m.beta(d2,2,3), mark)))) { flip_edge (m, d2); m.mark(d2, mark); } else m.mark (d2, mark); } else m.mark (d2, mark); } } CGAL_assertion (m.is_whole_map_marked (mark)); m.free_mark (mark); CGAL_postcondition ( m.is_valid ()); }