void initWeights( Polyhedron & poly ) { // assign the same IDs to the identical/ opposite halfedges for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { hi->fixed() = false; } }
void edge_node(Halfedge_iterator eitr, Point& pt) { Point& p1 = eitr->vertex()->point(); Point& p2 = eitr->opposite()->vertex()->point(); Point& f1 = eitr->next()->vertex()->point(); Point& f2 = eitr->opposite()->next()->vertex()->point(); pt = Point((3*(p1[0]+p2[0])+f1[0]+f2[0])/8, (3*(p1[1]+p2[1])+f1[1]+f2[1])/8, (3*(p1[2]+p2[2])+f1[2]+f2[2])/8 ); }
Halfedge_handle DegradeAnObject::getHalfedgeBetweenTwoPoints(Point_3 p1, Point_3 p2, int index) { bool found = false; Halfedge_iterator hi = polys[index].halfedges_begin(); while(!found) { if(p1 == hi->vertex()->point() && p2 == hi->opposite()->vertex()->point()) { found = true; } else { hi++; } } return hi; }
void border_node(Halfedge_iterator eitr, Point& ept, Point& vpt) { Point& ep1 = eitr->vertex()->point(); Point& ep2 = eitr->opposite()->vertex()->point(); ept = Point((ep1[0]+ep2[0])/2, (ep1[1]+ep2[1])/2, (ep1[2]+ep2[2])/2); Halfedge_around_vertex_circulator vcir = eitr->vertex_begin(); Point& vp1 = vcir->opposite()->vertex()->point(); Point& vp0 = vcir->vertex()->point(); Point& vp_1 = (--vcir)->opposite()->vertex()->point(); vpt = Point((vp_1[0] + 6*vp0[0] + vp1[0])/8, (vp_1[1] + 6*vp0[1] + vp1[1])/8, (vp_1[2] + 6*vp0[2] + vp1[2])/8 ); }
// Perform the standard normalization and also // make every border vertex point to its incident border halfedge. void HDS_overlay::normalize_border_vertices() { Base::normalize_border(); // Loop through all the border halfedges Halfedge_iterator it; for ( it=border_halfedges_begin(); it!=halfedges_end(); ++it) { RFC_assertion(!it->is_border()); ++it; RFC_assertion(it->is_border()); Vertex *v = it->vertex(); if ( v->halfedge() != &*it) v->set_halfedge( &*it); } }
void renewAttrs( Polyhedron & poly ) { // assign IDs to vertices for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->nCuts() = 0; } // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) { fi->piece() = NO_INDEX; Vector3 sum( 0.0, 0.0, 0.0 ); Halfedge_facet_circulator hfc = fi->facet_begin(); do { sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN ); } while ( ++hfc != fi->facet_begin() ); sum = sum / ( double )CGAL::circulator_size( hfc ); fi->center() = CGAL::ORIGIN + sum; } // assign the same IDs to the identical/ opposite halfedges for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { hi->label() = DEFAULT_LABEL; hi->match() = DEFAULT_LABEL; hi->cycle() = NO_INDEX; hi->connect() = true; hi->visit() = false; hi->path() = NO_INDEX; hi->orient() = true; // We individually handle hi->fixed } }
//------------------------------------------------------------------------------ // Initialize the dual center //------------------------------------------------------------------------------ void initAttrs( Polyhedron & poly ) { // assign IDs to vertices int vID = 0; for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->id() = vID++; vi->label() = DEFAULT_LABEL; vi->nCuts() = 0; } cerr << "Total number of vertices = " << vID << endl; // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates int fID = 0; for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) { fi->id() = fID++; // fi->label() = DEFAULT_LABEL; fi->piece() = NO_INDEX; Vector3 sum( 0.0, 0.0, 0.0 ); Halfedge_facet_circulator hfc = fi->facet_begin(); do { sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN ); } while ( ++hfc != fi->facet_begin() ); sum = sum / ( double )CGAL::circulator_size( hfc ); fi->center() = CGAL::ORIGIN + sum; // cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl; } cerr << "Total number of facets = " << fID << endl; // initialize the halfedge IDs for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { hi->id() = NO_INDEX; } // assign the same IDs to the identical/ opposite halfedges int eID = 0; for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { if ( hi->id() == NO_INDEX ) { assert( hi->opposite()->id() == NO_INDEX ); hi->id() = eID; hi->opposite()->id() = eID; eID++; hi->label() = hi->opposite()->label() = DEFAULT_LABEL; hi->match() = hi->opposite()->match() = DEFAULT_LABEL; hi->cycle() = hi->opposite()->cycle() = NO_INDEX; hi->weight() = hi->opposite()->weight() = 0.0; hi->connect() = hi->opposite()->connect() = true; hi->visit() = hi->opposite()->visit() = false; // We individually handle hi->fixed } } cerr << "Total number of edges = " << eID << endl; }
//------------------------------------------------------------------------------ // Compute and store the results of dual graphs into appropriate variables // // computeDual( mesh, whole, bary, mid ); //------------------------------------------------------------------------------ void computeDual( Polyhedron & poly, Graph & dual, vector< Point3 > & bary, vector< Point3 > & mid ) { // initialize the array of face barycenters: refer to the point at which the gravitational forces exerted by 2 objects are equal bary.clear(); bary.resize( poly.size_of_facets() ); // initialize the dual graph with dual vertices dual.clear(); int fid = 0; for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) { // add a vertex: each face equals to each dual vertex add_vertex( dual ); bary[ fid++ ] = fi->center(); // cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl; } int size_of_edges = poly.size_of_halfedges() / 2; //redundant // initialize the array of midpoints mid.clear(); mid.resize( size_of_edges ); // initialize the array of lengths // length.clear(); // length.resize( size_of_edges ); // construct the connecitivity of the dual graph for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) { int origID = hi->facet()->id(); // the face int destID = hi->opposite()->facet()->id(); // the neighbor face Point3 origCoord = hi->vertex()->point(); Point3 destCoord = hi->opposite()->vertex()->point(); Vector3 dispVec = origCoord - destCoord; Point3 midCoord = destCoord + 0.5 * dispVec; // double curLength = sqrt( dispVec.squared_length() ); // the length between two connected vertices #ifdef DEBUG cerr << origID << " -- " << destID << endl; #endif // DEBUG if ( origID < destID ) add_edge( origID, destID, hi->id(), dual ); mid[ hi->id() ] = midCoord; hi->mid() = hi->opposite()->mid() = midCoord; hi->weight() = hi->opposite()->weight() = 1.0; } }
bool test_one_file(std::ifstream& in, int verbose_level) { std::list<X_monotone_curve_2> xcurves; std::list<Point_2> isolated_points; read_arr(in, std::back_inserter(xcurves), std::back_inserter(isolated_points)); Arrangement arr1; construct_arr(arr1, xcurves.begin(), xcurves.end(), isolated_points.begin(), isolated_points.end(), verbose_level); isolated_points.clear(); xcurves.clear(); init_arr(arr1, verbose_level); read_arr(in, std::back_inserter(xcurves), std::back_inserter(isolated_points)); Arrangement arr2; construct_arr(arr2, xcurves.begin(), xcurves.end(), isolated_points.begin(), isolated_points.end(), verbose_level); isolated_points.clear(); xcurves.clear(); init_arr(arr2, verbose_level); // Read the number of cells left. Arrangement::Size num_vertices, num_edges, num_faces; in >> num_vertices >> num_edges >> num_faces; // Read the expected face data: std::vector<int> fdata(num_faces); std::copy(std::istream_iterator<int>(in), std::istream_iterator<int>(), fdata.begin()); Arrangement arr; Overlay_traits overlay_traits; if (verbose_level > 2) std::cout << "overlaying" << " ... "; std::cout.flush(); CGAL::overlay(arr1, arr2, arr, overlay_traits); if (verbose_level > 2) std::cout << "overlaid" << std::endl; // Verify the resulting arrangement. Arrangement::Size num_vertices_res = arr.number_of_vertices(); Arrangement::Size num_edges_res = arr.number_of_edges(); Arrangement::Size num_faces_res = arr.number_of_faces(); if (verbose_level > 0) std::cout << "Arrangement Output: " << std::endl; if (verbose_level > 1) { std::cout << "Halfedge Data: " << std::endl; Halfedge_iterator heit; for (heit = arr.halfedges_begin(); heit != arr.halfedges_end(); ++heit) std::cout << heit->source()->point() << " " << heit->target()->point() << " " << heit->data() << std::endl; } if (verbose_level > 0) { std::cout << "Face Data: " << std::endl; Face_iterator fit; for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) std::cout << fit->data() << std::endl; } if ((num_vertices_res != num_vertices) || (num_edges_res != num_edges) || (num_faces_res != num_faces)) { std::cerr << "ERROR: The number of arrangement cells is incorrect:" << std::endl << " V = " << arr.number_of_vertices() << ", E = " << arr.number_of_edges() << ", F = " << arr.number_of_faces() << std::endl; arr.clear(); return false; } std::vector<int> fdata_res(num_faces); std::vector<int>::iterator it = fdata_res.begin(); Face_iterator fit; for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) *it++ = fit->data(); std::sort(fdata_res.begin(), fdata_res.end()); if (! std::equal(fdata_res.begin(), fdata_res.end(), fdata.begin())) { std::cerr << "ERROR: Incorrect face data:" << std::endl; std::copy(fdata_res.begin(), fdata_res.end(), std::ostream_iterator<int>(std::cout, "\n")); arr.clear(); return false; } arr.clear(); return true; }
//! Initialize an arrangement void init_arr(Arrangement& arr, int verbose_level) { // Initialize the data of the halfedges of the arrangement. Halfedge_iterator heit; for (heit = arr.halfedges_begin(); heit != arr.halfedges_end(); ++heit) heit->set_data(heit->curve().data() * ((heit->direction() == CGAL::ARR_LEFT_TO_RIGHT) ? 1 : 2)); // Initialize the data of the faces of the arrangement. Face_iterator fit; for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) { unsigned int count = 0; // Outer ccb Outer_ccb_iterator ocit; for (ocit = fit->outer_ccbs_begin(); ocit != fit->outer_ccbs_end(); ++ocit) { Ccb_halfedge_circulator curr = *ocit; do count += curr->data() * 2; while (++curr != *ocit); } // Inner ccbs Inner_ccb_iterator icit; for (icit = fit->inner_ccbs_begin(); icit != fit->inner_ccbs_end(); ++icit) { Ccb_halfedge_circulator curr = *icit; do count += curr->data(); while (++curr != *icit); } fit->set_data(count); } // Initialize the data of the vertices of the arrangement. Vertex_iterator vit; for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) { unsigned int count = 0; if (vit->is_isolated()) count = vit->face()->data(); else { Halfedge_around_vertex_const_circulator curr = vit->incident_halfedges(); do count += curr->data(); while (++curr != vit->incident_halfedges()); } vit->set_data(count); } if (verbose_level > 0) std::cout << "Arrangement Input: " << std::endl; if (verbose_level > 1) { std::cout << "Halfedge Data: " << std::endl; Halfedge_iterator heit; for (heit = arr.halfedges_begin(); heit != arr.halfedges_end(); ++heit) std::cout << heit->source()->point() << " " << heit->target()->point() << " " << heit->data() << std::endl; } if (verbose_level > 0) { std::cout << "Face Data: " << std::endl; Face_iterator fit; for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) std::cout << fit->data() << std::endl; } }
void PolyDataGenerator::ClosePolygon(void){ Halfedge_iterator j; Halfedge_iterator k; Halfedge_iterator l; Halfedge_iterator m; Halfedge_handle newedge; cout << "The polyhedron has " << ClippedCGALSurface->size_of_facets() << " facets " << ClippedCGALSurface->size_of_halfedges() << " halfedges " << ClippedCGALSurface->size_of_border_halfedges() << " border halfedges " << ClippedCGALSurface->size_of_vertices() << " vertices " << endl; int ncompremoved = ClippedCGALSurface->keep_largest_connected_components(1); cout << "Removing " << ncompremoved << " non connected components" << endl; cout << "The polyhedron has " << ClippedCGALSurface->size_of_facets() << " facets " << ClippedCGALSurface->size_of_halfedges() << " halfedges " << ClippedCGALSurface->size_of_border_halfedges() << " border halfedges " << ClippedCGALSurface->size_of_vertices() << " vertices " << endl; while(!this->ClippedCGALSurface->is_closed()){ for (j = ClippedCGALSurface->border_halfedges_begin(); j != ClippedCGALSurface->halfedges_end(); ++j){ // We itterate over all border half edges. Half of them are opposite border edegs and thus not // real borders so test this first. // it.next() it the next border edge along the hole. This might not be the same as ++it k = j->next(); l = k->next(); m = l->next(); if (j->is_border() && l->is_border() && k->is_border()){ //First find size of hole and make sure that this is simple. i.e. //No two different halfedges points to the same vertex. //If this is the case we delete one of them and start over. Halfedge_iterator tempit = k; Halfedge_iterator tempit2; int sizehole = 1; bool Simplehole = true; while(tempit != j){ for(tempit2 = j; tempit2 != tempit ; tempit2=tempit2->next() ){ if (tempit2->vertex() == tempit->vertex()){ Simplehole = false; ClippedCGALSurface->erase_facet(tempit2->opposite()); break; //remove one facet and start over. } } if(!Simplehole){ break; //ugly Break inermost while loop. } tempit = tempit->next(); ++sizehole; } if (Simplehole){ //cout << "Hole has " << sizehole << endl; if (j != m){ //more than 3 edges in hole. Have to subdivide newedge = ClippedCGALSurface->add_facet_to_border(j,l); //cout << "Filling " << j->vertex()->point() << " , " << k->vertex()->point() << " to " << newedge->vertex()->point() << endl; } else{ //cout << "Closing " << j->vertex()->point() << " to " << k->vertex()->point() << endl; newedge = ClippedCGALSurface->fill_hole(j); } // now find the iolet type from neighbors. tempit = newedge; bool start = true; std::vector<size_t> neighborIds; while(tempit != newedge || start){ start = false; if (!tempit->opposite()->is_border()){ neighborIds.push_back(tempit->opposite()->facet()->id()); } tempit = tempit->next(); } std::vector<size_t>::iterator max = std::max_element(neighborIds.begin(), neighborIds.end()); std::vector<size_t>::iterator min = std::min_element(neighborIds.begin(), neighborIds.end()); if (*max != *min){ // if max is min they are all the same. throw GenerationErrorMessage("Could not determin IOlet id of inserted facet."); } else{ newedge->facet()->id() = *max; } break; //we have to normalize the border and restart the forloop since // filling with add_facet_to_border invalidated the order of border/non border edges. } else { //cout << "Could not fill since hole is not simple, deleted connected facet instead" << endl; break; } } } ClippedCGALSurface->normalize_border(); } }