Ejemplo n.º 1
0
void set_geometry_of_dual(LCC& alcc, TR& tr,
                          std::map<typename TR::Cell_handle,
                                   typename LCC::Dart_handle>& assoc)
{
  for ( typename std::map<typename TR::Cell_handle, typename LCC::Dart_handle>
          ::iterator it=assoc.begin(), itend=assoc.end(); it!=itend; ++it)
  {
    if ( !tr.is_infinite(it->first) )
      alcc.set_vertex_attribute
        (it->second,alcc.create_vertex_attribute(tr.dual(it->first)));
    else
      alcc.set_vertex_attribute(it->second,alcc.create_vertex_attribute());
  }
}
Ejemplo n.º 2
0
void transform_dart_to_their_dual(LCC& alcc, LCC& adual,
                                  std::map<typename TR::Cell_handle,
                                           typename LCC::Dart_handle>& assoc)
{
  typename LCC::Dart_range::iterator it1=alcc.darts().begin();
  typename LCC::Dart_range::iterator it2=adual.darts().begin();

  std::map<typename LCC::Dart_handle, typename LCC::Dart_handle> dual;
  
  for ( ; it1!=alcc.darts().end(); ++it1, ++it2 )
  {
    dual[it1]=it2;
  }

  for ( typename std::map<typename TR::Cell_handle, typename LCC::Dart_handle>
          ::iterator it=assoc.begin(), itend=assoc.end(); it!=itend; ++it)
  {
    assoc[it->first]=dual[it->second];
  }
}
int main( int argc, char** argv )
{
  if (argc<2 || argc>3)
  {
    std::cout<<"Usage: simplification_Linear_cell_complex inofffile [outofffile]"<<std::endl;
    return EXIT_FAILURE;
  }

  LCC lcc;
  CGAL::read_off(argv[1], lcc);

  lcc.display_characteristics(std::cout)<<", is_valid="<<CGAL::is_valid(lcc)<<std::endl;

  // This is a stop predicate (defines when the algorithm terminates).
  // In this example, the simplification stops when the number of undirected edges
  // left in the surface mesh drops below the specified number (1000)
  SMS::Count_stop_predicate<LCC> stop(1000);
  // This the actual call to the simplification algorithm.
  // The surface mesh and stop conditions are mandatory arguments.
  // The index maps are needed because the vertices and edges
  // of this surface mesh lack an "id()" field.
  int r = SMS::edge_collapse
    (lcc
     ,stop
     ,CGAL::parameters::halfedge_index_map(get(CGAL::halfedge_index, lcc))
          .vertex_index_map(get(boost::vertex_index, lcc))
          .get_cost(SMS::Edge_length_cost<LCC>())
          .get_placement(SMS::Midpoint_placement<LCC>())
     );

  std::cout << "\nFinished...\n" << r << " edges removed.\n"
            << (lcc.number_of_darts()/2) << " final edges.\n" ;

  lcc.display_characteristics(std::cout)<<", is_valid="<<CGAL::is_valid(lcc)<<std::endl;

  CGAL::write_off((argc > 2 ? argv[2] : "out.off"), lcc);
  return EXIT_SUCCESS;
}
Ejemplo n.º 4
0
int main()
{
  LCC lcc;
  Dart_handle dh1=
    lcc.make_hexahedron(Point(0,0,0), Point(5,0,0),
                        Point(5,5,0), Point(0,5,0),
                        Point(0,5,4), Point(0,0,4),
                        Point(5,0,4), Point(5,5,4));
  Dart_handle dh2=
    lcc.make_hexahedron(Point(5,0,0), Point(10,0,0),
                        Point(10,5,0), Point(5,5,0),
                        Point(5,5,4), Point(5,0,4),
                        Point(10,0,4), Point(10,5,4));

  lcc.sew<3>(lcc.beta(dh1, 1, 1, 2), lcc.beta(dh2, 2));
  
  lcc.display_characteristics(std::cout)<<", valid=" 
                                        <<lcc.is_valid()<<std::endl;
  CGAL::draw(lcc);

  return EXIT_SUCCESS;
}
// Subdivide each facet of the lcc by using pqq-subdivision.
void
subdivide_lcc_pqq (LCC & m)
{
  if (m.number_of_darts () == 0)
    return;

  LCC::size_type old = m.get_new_mark ();
  LCC::size_type treated = m.get_new_mark ();
  m.negate_mark (old);  // All the old darts are marked in O(1).

  // 1) We subdivide each edge.
  m.negate_mark (treated);  // All the darts are marked in O(1).
  
  for (LCC::Dart_range::iterator it (m.darts().begin ());
       m.number_of_marked_darts (treated) > 0; ++it)
  {
    if (m.is_marked (it, treated))
    {
      // We unmark the darts of the facet to process only once dart/facet.
      CGAL::unmark_cell < LCC, 1 > (m, it, treated);

      // We insert barycenter in the middle of the edge.
      m.insert_barycenter_in_cell<1>(it);
    }
  }

  // 2) We create a barycenter point for each facets.
  Dart_handle dc;
  std::vector<Dart_handle> remove;
  remove.resize(0);

  m.negate_mark (treated);  // All the darts are marked in O(1).
  for (LCC::Dart_range::iterator it (m.darts().begin ());
       m.number_of_marked_darts (treated) > 0; ++it)
  {
    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 insert barycenter of the facet.
      dc =  m.insert_barycenter_in_cell<2>(it);

      // We remove useless edges.
      for (LCC::One_dart_per_incident_cell_range<1,0>::iterator it2 =
             m.one_dart_per_incident_cell<1,0>(dc).begin(); 
          it2 != m.one_dart_per_incident_cell<1,0>(dc).end(); ++it2)
      {
        // If the edge join the center and a corner.
        // We remove the edge.
        if( m.is_marked(m.beta(it2,1), old) )
        {
          remove.push_back(it2);
        }
      }

      // Remove edges. 
      for (std::vector <Dart_handle>::iterator dit = remove.begin ();
          dit != remove.end (); ++dit)
      {
        CGAL_assertion( (m.is_removable<1>(*dit)) );
        m.remove_cell<1>(*dit);
      }
      remove.resize(0); 
      // CGAL_assertion( m.is_valid() );
    }
  }

  m.negate_mark (treated);
  CGAL_assertion (m.is_whole_map_marked (treated));
  m.free_mark (treated);

  // 3) Smooth old points. 
  std::vector < Vertex > old_vertices; // smooth the old vertices.
  old_vertices.reserve (m.number_of_attributes<0> ()); // get intermediate space.
  std::transform (m.vertex_attributes().begin (), 
		  m.vertex_attributes().end (),
		  std::back_inserter (old_vertices), 
		  Smooth_vertex_pqq (m, old));

  // Update.
  for (std::vector < Vertex >::iterator vit = old_vertices.begin ();
      vit != old_vertices.end (); ++vit)
  {
    m.point(vit->dart())=vit->point();
  }

  // 4) Smooth new edges points.	  
  std::vector < Vertex > 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_edge_pqq (m, old));

  // Update.
  for (std::vector < Vertex >::iterator vit = vertices.begin ();
      vit != vertices.end (); ++vit)
  {
    m.point(vit->dart())=vit->point();
  }

  m.unmark_all (old);
  m.free_mark (old);
  CGAL_postcondition ( m.is_valid ());
}
// Flip an edge, work only in 2D and 3D
Dart_handle
flip_edge (LCC & m, Dart_handle d)
{
  CGAL_assertion ( !m.is_free(d,2) );
  CGAL_assertion ( !m.is_free(d,1) && !m.is_free(d,0) );
  CGAL_assertion ( !m.is_free(m.beta(d,2), 0) && !m.is_free(m.beta(d, 2), 1) );
  
  if (!m.is_removable<1>(d)) return LCC::null_handle;

  Dart_handle d1 = m.beta(d,1);
  Dart_handle d2 = m.beta(d,2,0);

  CGAL_assertion ( !m.is_free(d1,1) && !m.is_free(d2,0) );

  Dart_handle d3 = m.beta(d1,1);
  Dart_handle d4 = m.beta(d2, 0);

  // We isolated the edge
  m.basic_link_beta_1(m.beta(d,0), m.beta(d,2,1));
  m.basic_link_beta_0(m.beta(d,1), m.beta(d,2,0));
  if ( !m.is_free(d,3) )
  {
    m.basic_link_beta_0(m.beta(d,0,3), m.beta(d,2,1,3));
    m.basic_link_beta_1(m.beta(d,1,3), m.beta(d,2,0,3));
  }

  // Then we push the two extremities.
  m.basic_link_beta_0(d3, d);
  m.basic_link_beta_0(d2, m.beta(d,2));
  m.link_beta_1(d4, d);
  m.link_beta_1(d1, m.beta(d,2));

  if ( !m.is_free(d,3) )
  {
    m.basic_link_beta_0(m.beta(d4,3), m.beta(d,3));
    m.basic_link_beta_0(m.beta(d1,3), m.beta(d,2,3));
    m.link_beta_1(m.beta(d3,3), m.beta(d,3));
    m.link_beta_1(m.beta(d2,3), m.beta(d,2,3));
  }
  
  // CGAL::remove_cell<LCC,1>(m, d);
  // insert_cell_1_in_cell_2(m, d1, d1->beta(1)->beta(1));

  return d;
}
// 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 ());
}
void run_test()
{
  typedef typename LCC::Point Point;
  typedef typename LCC::Dart_handle Dart_handle;
  
  LCC lcc;
  
  Dart_handle dh1 = lcc.
    make_hexahedron(Point(0,0,0),Point(1,0,0),
                    Point(1,2,0),Point(0,2,0),
                    Point(0,3,4),Point(0,0,4),
                    Point(6,0,4),Point(6,3,4));
  Dart_handle dh2 = lcc.
    make_hexahedron(Point(0,-5,0),Point(2,-5,0),
                    Point(2,-2,0),Point(0,-2,0),
                    Point(1,-1,5),Point(1,-2,5),
                    Point(5,-2,5),Point(5,-2,5));
  Dart_handle dh3 = lcc.
    make_hexahedron(Point(1,0,5),Point(0,0,6),
                    Point(0,2,5),Point(1,2,6),
                    Point(1,3,8),Point(0,0,8),
                    Point(5,0,9),Point(7,3,9));
  
  lcc.template sew<3>(dh1,lcc.other_orientation
                      (lcc.template opposite<2>
                       (lcc.next(lcc.next(lcc.template opposite<2>(dh2))))));
  lcc.template sew<3>(lcc.template opposite<2>(lcc.next(dh1)),
                      lcc.other_orientation(lcc.template opposite<2>(lcc.previous(dh3))));

  lcc.insert_cell_1_in_cell_2(lcc.next(dh1),
                              Alpha1<LCC>::run(lcc, lcc.previous(dh1)));
  dh2=lcc.template opposite<2>(lcc.next(lcc.next
                                        (lcc.template opposite<2>(dh1))));
  lcc.insert_cell_1_in_cell_2(dh2, Alpha1<LCC>::run
                              (lcc, lcc.next(lcc.next(dh2))));

  std::vector<Dart_handle> path;
  path.push_back(lcc.next(dh1));
  path.push_back(lcc.next(lcc.template opposite<2>(lcc.previous(dh1))));
  path.push_back(lcc.previous(dh2));
  path.push_back(lcc.next(lcc.template opposite<2>(dh2)));
  lcc.insert_cell_2_in_cell_3(path.begin(),path.end());

  lcc.display_characteristics(std::cout) << ", valid=" 
                                         << lcc.is_valid() << std::endl;  
}