/** * Finds the exit point of upslope_path on the facet left of h. * * upslope_path must intersect the boundary of the facet in 2 points or a * segment. One of these points must be start_point. If the intersection is a * segment, returns the endpoint that is not start_point. Otherwise returns the * other intersection point. Updates h so it is the halfedge where the * intersection is found. */ Point_2 find_exit(Halfedge_handle& h, const Ray_2& upslope_path, const Point_2& start_point) { Point_2 exit; Plane_3 plane = h->facet()->plane(); typedef Facet::Halfedge_around_facet_circulator Circulator; Circulator current = h->facet()->facet_begin(); Circulator end = h->facet()->facet_begin(); do { Point_2 source = plane.to_2d(current->vertex()->point()); Point_2 target = plane.to_2d(current->opposite()->vertex()->point()); Segment_2 seg = Segment_2(source, target); // Example pulled from http://tinyurl.com/intersect-doc CGAL::Object intersect = CGAL::intersection(upslope_path, seg); // Return for a point intersection if (const CGAL::Point_2<Kernel> *ipoint = CGAL::object_cast<CGAL::Point_2<Kernel> >(&intersect)) { if (*ipoint != start_point) { h = current; return *ipoint; } } // Return the opposite point of the segment for a segment intersection. else if (const CGAL::Segment_2<Kernel> *iseg = CGAL::object_cast<CGAL::Segment_2<Kernel> >(&intersect)) { h = current; if (iseg->source() == start_point) return iseg->target(); return iseg->source(); } } while (++current != end); cout << "Failed to find an intersection point." << endl; cout << "Start: " << start_point << endl; cout << "Upslope path: " << upslope_path << endl; print_facet(*h->facet()); std::abort(); return exit; }
typename Poly::Halfedge_handle make_cube_3( Poly& P) { // appends a cube of size [0,1]^3 to the polyhedron P. CGAL_precondition( P.is_valid()); typedef typename Poly::Point_3 Point; typedef typename Poly::Plane_3 Plane; typedef typename Poly::Halfedge_handle Halfedge_handle; Halfedge_handle h = P.make_tetrahedron( Point( 1, 0, 0), Point( 0, 0, 1), Point( 0, 0, 0), Point( 0, 1, 0)); Halfedge_handle g = h->next()->opposite()->next(); P.split_edge( h->next()); P.split_edge( g->next()); P.split_edge( g); h->next()->vertex()->point() = Point( 1, 0, 1); g->next()->vertex()->point() = Point( 0, 1, 1); g->opposite()->vertex()->point() = Point( 1, 1, 0); Halfedge_handle f = P.split_facet( g->next(), g->next()->next()->next()); Halfedge_handle e = P.split_edge( f); e->vertex()->point() = Point( 1, 1, 1); P.split_facet( e, f->next()->next()); CGAL_postcondition( P.is_valid()); g = h; g->facet()->plane() = Plane( g->vertex()->point(), g->next()->vertex()->point(), g->next()->next()->vertex()->point()); g = h->opposite(); g->facet()->plane() = Plane( g->vertex()->point(), g->next()->vertex()->point(), g->next()->next()->vertex()->point()); g = h->next()->opposite(); g->facet()->plane() = Plane( g->vertex()->point(), g->next()->vertex()->point(), g->next()->next()->vertex()->point()); g = h->next()->next()->opposite(); g->facet()->plane() = Plane( g->vertex()->point(), g->next()->vertex()->point(), g->next()->next()->vertex()->point()); g = h->next()->next()->next()->opposite(); g->facet()->plane() = Plane( g->vertex()->point(), g->next()->vertex()->point(), g->next()->next()->vertex()->point()); g = g->next()->next()->opposite(); g->facet()->plane() = Plane( g->vertex()->point(), g->next()->vertex()->point(), g->next()->next()->vertex()->point()); return h; }
void Boolean_Operations_Component::SubdiviserPolyedre(PolyhedronPtr pMesh) { //Each facet must be triangular if(!pMesh->is_pure_triangle()) { pMesh->triangulate(); return; } Facet_iterator pFacet; Vector Vcenter; //Initialization of the tags for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++) { Halfedge_around_facet_circulator pHEcirc = pFacet->facet_begin(); pFacet->Issub = false; pHEcirc->Isnew = false; pHEcirc->vertex()->Isnew = false; pHEcirc++; pHEcirc->Isnew = false; pHEcirc->vertex()->Isnew = false; pHEcirc++; pHEcirc->Isnew = false; pHEcirc->vertex()->Isnew = false; } //For each facet of the polyhedron for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++) { //We subdivide the facet if it is not already done if(!(pFacet->Issub)) { Halfedge_handle pHE = pFacet->facet_begin(); for(unsigned int i = 0;i!=5;i++) { if(!pHE->Isnew) { //each edge is splited in its center Vcenter = Vector(0.0, 0.0, 0.0); Vcenter = ( (pHE->vertex()->point() - CGAL::ORIGIN) + (pHE->opposite()->vertex()->point() - CGAL::ORIGIN) ) / 2; pHE = pMesh->split_edge(pHE); pHE->vertex()->point() = CGAL::ORIGIN + Vcenter; //update of the tags (the new vertex and the four new halfedges pHE->vertex()->Isnew = true; pHE->Isnew = true; pHE->opposite()->Isnew = true; pHE->next()->Isnew = true; pHE->next()->opposite()->Isnew = true; } pHE = pHE->next(); } //Three new edges are build between the three new vertices, and the tags of the facets are updated if(!pHE->vertex()->Isnew) pHE = pHE->next(); pHE = pMesh->split_facet(pHE, pHE->next()->next()); pHE->opposite()->facet()->Issub = true; pHE = pMesh->split_facet(pHE, pHE->next()->next()); pHE->opposite()->facet()->Issub = true; pHE = pMesh->split_facet(pHE, pHE->next()->next()); pHE->opposite()->facet()->Issub = true; pHE->facet()->Issub = true; } } }
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(); } }