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()); } }
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; }
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; }