예제 #1
0
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 ());
}