void arrangement::compute_neighbours() { neighbours.resize(nonCriticalRegions.number_of_faces() - 1); // minus unbounded face for (Arrangement_2::Face_iterator face = nonCriticalRegions.faces_begin(); face != nonCriticalRegions.faces_end(); ++face) { if (!face->is_unbounded() && face->data() != -1) { Arrangement_2::Ccb_halfedge_circulator first_outer_ccb = face->outer_ccb(); Arrangement_2::Ccb_halfedge_circulator outer_ccb = face->outer_ccb(); int id_face = face->data(); std::vector<int> voisins; do { Arrangement_2::Face_handle adjacent_face = outer_ccb->twin()->face(); if (!adjacent_face->is_unbounded()) voisins.push_back(adjacent_face->data()); ++outer_ccb; } while (outer_ccb != first_outer_ccb); neighbours[id_face] = voisins; } } // clean neighbours for (int i = 0; i < (int) neighbours.size(); ++i) for (int j = 0; j < (int) neighbours[i].size(); ++j) for (int k = 0; k < j; ++k) if (neighbours[i][j] == neighbours[i][k]) { neighbours[i].erase(neighbours[i].begin() + j); --j; break; } // print results print_neighbours(); }
int main () { Arrangement_2 arr; // Construct an arrangement of seven intersecting line segments. insert (arr, Segment_2 (Point_2 (1, 1), Point_2 (7, 1))); insert (arr, Segment_2 (Point_2 (1, 1), Point_2 (3, 7))); insert (arr, Segment_2 (Point_2 (1, 4), Point_2 (7, 1))); insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (9, 3))); insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (4, 4))); insert (arr, Segment_2 (Point_2 (7, 1), Point_2 (9, 3))); insert (arr, Segment_2 (Point_2 (3, 7), Point_2 (9, 3))); // Create a mapping of the arrangement faces to indices. CGAL::Arr_face_index_map<Arrangement_2> index_map (arr); // Perform breadth-first search from the unbounded face, and use the BFS // visitor to associate each arrangement face with its discover time. Discover_time_bfs_visitor<CGAL::Arr_face_index_map<Arrangement_2> > bfs_visitor (index_map); Arrangement_2::Face_handle uf = arr.unbounded_face(); boost::breadth_first_search (Dual_arrangement_2 (arr), uf, boost::vertex_index_map (index_map). visitor (bfs_visitor)); // Print the results: Arrangement_2::Face_iterator fit; for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) { std::cout << "Discover time " << fit->data() << " for "; if (fit != uf) { std::cout << "face "; print_ccb<Arrangement_2> (fit->outer_ccb()); } else std::cout << "the unbounded face." << std::endl; } return (0); }
GeometryPtr Overlay::process(const Polyline2DPtr& p1, const Polyline2DPtr& p2) { if (!p1 || !p2 || p1->getPointListSize() < 2 || p2->getPointListSize() < 2) return GeometryPtr(); #ifdef WITH_CGAL // Construct the first arrangement, containing a polyline 1. Arrangement_2 arr1; for (Point2Array::const_iterator it1 = p1->getPointList()->begin()+1; it1 != p1->getPointList()->end(); ++it1) insert_non_intersecting_curve(arr1,toSegment(*(it1-1),*it1)); // to be a closed face, first and last point should be exactly the same. // However we should not duplicate the same point twice at the end. Vector2& fp1 = p1->getPointList()->getAt(0); Vector2& lp1 = *(p1->getPointList()->end()-1); if (fp1.x() != lp1.x() || fp1.y() != lp1.y()) insert_non_intersecting_curve(arr1,toSegment(lp1,fp1)); // std::cerr << arr1.number_of_vertices() << " " << arr1.number_of_edges() << " " << arr1.number_of_faces() << std::endl; // Mark just the bounded face. Arrangement_2::Face_iterator fit; CGAL_assertion (arr1.number_of_faces() == 2); for (fit = arr1.faces_begin(); fit != arr1.faces_end(); ++fit) fit->set_data (fit != arr1.unbounded_face()); // Construct the second arrangement. Arrangement_2 arr2; for (Point2Array::const_iterator it2 = p2->getPointList()->begin()+1; it2 != p2->getPointList()->end(); ++it2) insert(arr2,toSegment(*(it2-1),*it2)); // to be a closed face, first and last point should be exactly the same. // However we should not duplicate the same point twice at the end. Vector2& fp2 = p2->getPointList()->getAt(0); Vector2& lp2 = *(p2->getPointList()->end()-1); if (fp2.x() != lp2.x() || fp2.y() != lp2.y()) insert(arr2,toSegment(lp2,fp2)); // std::cerr << arr2.number_of_vertices() << " " << arr2.number_of_edges() << " " << arr2.number_of_faces() << std::endl; CGAL_assertion (arr2.number_of_faces() == 2); for (fit = arr2.faces_begin(); fit != arr2.faces_end(); ++fit) fit->set_data (fit != arr2.unbounded_face()); // Compute the overlay of the two arrangements. Arrangement_2 overlay_arr; Overlay_traits overlay_traits; overlay (arr1, arr2, overlay_arr, overlay_traits); // std::cerr << overlay_arr.number_of_vertices() << " " << overlay_arr.number_of_edges() << " " << overlay_arr.number_of_faces() << std::endl; // conversion between cgal structures and plantgl ones. GeometryArrayPtr geomarray(new GeometryArray(0)); for (Arrangement_2::Face_iterator face = overlay_arr.faces_begin(); face != overlay_arr.faces_end(); ++face) { if (face->is_fictitious () || face->is_unbounded()) continue; if (! face->data()) continue; Arrangement_2::Ccb_halfedge_circulator curr = face->outer_ccb(); Point2ArrayPtr pointSet( new Point2Array(1,toVec2(curr->source()->point()))); do { pointSet->push_back(toVec2(curr->target()->point())); ++curr; } while (curr != face->outer_ccb()); if (pointSet->size() == 1){ geomarray->push_back(GeometryPtr(new PointSet2D(pointSet))); } else if(pointSet->size() > 1){ geomarray->push_back(GeometryPtr(new Polyline2D(pointSet))); } } if (geomarray->empty())return GeometryPtr(); else if (geomarray->size() == 1) return geomarray->getAt(0); else return GeometryPtr(new Group(geomarray)); #else #ifdef _MSC_VER #pragma message("CGAL not included. Overlay routine will not work.") #else #warning "CGAL not included. Overlay routine will not work." #endif pglError("CGAL not included. Overlay routine will not work."); return GeometryPtr(); #endif }