/**
 * 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;
		}
	}
}
Beispiel #4
0
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();
	}
}