Пример #1
0
void difference( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b, GeometrySet<Dim>& output )
{
    typename SFCGAL::detail::HandleCollection<Dim>::Type ahandles, bhandles;
    typename SFCGAL::detail::BoxCollection<Dim>::Type aboxes, bboxes;
    a.computeBoundingBoxes( ahandles, aboxes );
    b.computeBoundingBoxes( bhandles, bboxes );

    for ( size_t i = 0; i < aboxes.size(); ++i ) {
        bool intersectsA = false;
        GeometrySet<Dim> tempOut;

        for ( size_t j = 0; j < bboxes.size(); ++j ) {
            if ( CGAL::do_overlap( aboxes[i].bbox(), bboxes[j].bbox() ) ) {
                const PrimitiveHandle<Dim>* pa = aboxes[i].handle();
                const PrimitiveHandle<Dim>* pb = bboxes[j].handle();

                if ( algorithm::intersects( *pa, *pb ) ) {
                    intersectsA = true;

                    difference_primitive( *pa, *pb, tempOut );
                }
            }
        }

        if ( ! intersectsA ) {
            tempOut.addPrimitive( *aboxes[i].handle() );
        }

        filter_self_intersection( tempOut, output );
    }
}
Пример #2
0
// local function : get the number of intersection points between rings of a polygon
int numIntersectionPoints( const CGAL::Polygon_with_holes_2<Kernel>& poly )
{
    int numIntersectionPoints = 0;
    CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = poly.holes_begin();

    for ( int i = 0; i == 0 || hit != poly.holes_end(); ++i ) {
        GeometrySet<2> ringI;

        if ( i == 0 ) {
            ringI.addSegments( poly.outer_boundary().edges_begin(), poly.outer_boundary().edges_end() );
        }
        else {
            ringI.addSegments( hit->edges_begin(), hit->edges_end() );
            hit++;
        }

        for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hjt = hit;
                hjt != poly.holes_end();
                ++hjt ) {
            GeometrySet<2> ringJ, inter;
            ringJ.addSegments( hjt->edges_begin(), hjt->edges_end() );

            algorithm::intersection( ringI, ringJ, inter );
            numIntersectionPoints += inter.points().size();
        }
    }

    return numIntersectionPoints;
}
Пример #3
0
static void substract_from_segment( const PrimitiveHandle<Dim>& seg, const PrimitiveHandle<Dim>& prim, GeometrySet<Dim>& output )
{
    if ( prim.handle.which() == PrimitiveSegment ) {
        const typename Segment_d<Dim>::Type* sega = seg.template as<typename Segment_d<Dim>::Type>();
        const typename Segment_d<Dim>::Type* segb = prim.template as<typename Segment_d<Dim>::Type>();
        typename Point_d<Dim>::Type pA( sega->source() );
        typename Point_d<Dim>::Type pB( sega->target() );
        typename Point_d<Dim>::Type pC( segb->source() );
        typename Point_d<Dim>::Type pD( segb->target() );
        Kernel::FT sC = point_position( *sega, pC );
        Kernel::FT sD = point_position( *sega, pD );

        if ( sC > sD ) {
            std::swap( sC, sD );
            std::swap( pC, pD );
        }

        if ( sC > 0 ) {
            output.addPrimitive( typename Segment_d<Dim>::Type( pA, pC ) );
        }

        if ( sD < 1 ) {
            output.addPrimitive( typename Segment_d<Dim>::Type( pD, pB ) );
        }
    }
    else {
        output.addPrimitive( seg );
    }
}
Пример #4
0
/**
 * intersection post processing
 */
void post_intersection( const GeometrySet<2>& input, GeometrySet<2>& output )
{
    //
    // reverse orientation of polygons if needed
    for ( GeometrySet<2>::SurfaceCollection::const_iterator it = input.surfaces().begin();
            it != input.surfaces().end();
            ++it ) {
        const CGAL::Polygon_with_holes_2<Kernel>& p = it->primitive();
        CGAL::Polygon_2<Kernel> outer = p.outer_boundary();

        if ( outer.orientation() == CGAL::CLOCKWISE ) {
            outer.reverse_orientation();
        }

        std::list<CGAL::Polygon_2<Kernel> > rings;

        for ( CGAL::Polygon_with_holes_2<Kernel>::Hole_const_iterator hit = p.holes_begin();
                hit != p.holes_end();
                ++hit ) {
            rings.push_back( *hit );

            if ( hit->orientation() == CGAL::COUNTERCLOCKWISE ) {
                rings.back().reverse_orientation();
            }
        }

        output.surfaces().push_back( CGAL::Polygon_with_holes_2<Kernel>( outer, rings.begin(), rings.end() ) );
    }

    output.points() = input.points();
    output.segments() = input.segments();
    output.volumes() = input.volumes();
}
Пример #5
0
	std::auto_ptr<Geometry> intersection( const Geometry& ga, const Geometry& gb )
	{
		GeometrySet<2> gsa( ga ), gsb( gb ), output;
		algorithm::intersection( gsa, gsb, output );

		GeometrySet<2> filtered;
		output.filterCovered( filtered );
		return filtered.recompose();
	}
Пример #6
0
	void intersection( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b, GeometrySet<Dim>& output )
	{
		typename SFCGAL::HandleCollection<Dim>::Type ahandles, bhandles;
		typename SFCGAL::BoxCollection<Dim>::Type aboxes, bboxes;
		a.computeBoundingBoxes( ahandles, aboxes );
		b.computeBoundingBoxes( bhandles, bboxes );

		intersection_cb<Dim> cb( output );
		CGAL::box_intersection_d( aboxes.begin(), aboxes.end(),
					  bboxes.begin(), bboxes.end(),
					  cb );
	}
Пример #7
0
namespace Core {

typedef Container::set< Geometry* >::Type GeometrySet;
GeometrySet geometries;

// Adds a geometry to the database.
void GeometryDatabase::AddGeometry(Geometry* geometry)
{
    geometries.insert(geometry);
}

// Removes a geometry from the database.
void GeometryDatabase::RemoveGeometry(Geometry* geometry)
{
    geometries.erase(geometry);
}

// Releases all compiled geometries.
void GeometryDatabase::ReleaseGeometries()
{
    for (GeometrySet::iterator i = geometries.begin(); i != geometries.end(); ++i)
        (*i)->Release();
}

}
Пример #8
0
void intersection( const GeometrySet<Dim>& a, const GeometrySet<Dim>& b, GeometrySet<Dim>& output )
{
    typename SFCGAL::detail::HandleCollection<Dim>::Type ahandles, bhandles;
    typename SFCGAL::detail::BoxCollection<Dim>::Type aboxes, bboxes;
    a.computeBoundingBoxes( ahandles, aboxes );
    b.computeBoundingBoxes( bhandles, bboxes );

    GeometrySet<Dim> temp, temp2;
    intersection_cb<Dim> cb( temp );
    CGAL::box_intersection_d( aboxes.begin(), aboxes.end(),
                              bboxes.begin(), bboxes.end(),
                              cb );

    post_intersection( temp, temp2 );
    output.merge( temp2 );
}
Пример #9
0
// pa and pb intersects
static void difference_primitive( const PrimitiveHandle<Dim>& pa, const PrimitiveHandle<Dim>& pb, GeometrySet<Dim>& output )
{
    if ( pa.handle.which() == PrimitivePoint ) {
        // difference = empty
    }
    else if ( pa.handle.which() == PrimitiveSegment ) {
        GeometrySet<Dim> inter;
        algorithm::intersection( pa, pb, inter );

        if ( ! inter.segments().empty() ) {
            for ( typename GeometrySet<Dim>::SegmentCollection::const_iterator it = inter.segments().begin();
                    it != inter.segments().end();
                    ++it ) {
                PrimitiveHandle<Dim> p( &it->primitive() );
                substract_from_segment( pa, p, output );
            }
        }
        else {
            output.addPrimitive( pa );
        }
    }
}
Пример #10
0
// Releases all compiled geometries.
void GeometryDatabase::ReleaseGeometries()
{
    for (GeometrySet::iterator i = geometries.begin(); i != geometries.end(); ++i)
        (*i)->Release();
}
Пример #11
0
// Removes a geometry from the database.
void GeometryDatabase::RemoveGeometry(Geometry* geometry)
{
    geometries.erase(geometry);
}
Пример #12
0
// Adds a geometry to the database.
void GeometryDatabase::AddGeometry(Geometry* geometry)
{
    geometries.insert(geometry);
}
Пример #13
0
static void filter_self_intersection( const GeometrySet<Dim>& input, GeometrySet<Dim>& output )
{
    {
        typedef std::list< CollectionElement<typename Point_d<Dim>::Type> > PointList;
        PointList points;

        std::copy( input.points().begin(), input.points().end(), std::back_inserter( points ) );

        typename PointList::iterator it = points.begin();

        while ( it != points.end() ) {
            bool intersectsA = false;

            for ( typename PointList::iterator it2 = points.begin(); it2 != points.end(); ++it2 ) {
                if ( it == it2 ) {
                    continue;
                }

                PrimitiveHandle<Dim> pa1( &it->primitive() );
                PrimitiveHandle<Dim> pa2( &it2->primitive() );

                if ( CGAL::do_overlap( it->primitive().bbox(), it2->primitive().bbox() ) &&
                        algorithm::intersects( pa1, pa2 ) ) {
                    intersectsA = true;
                    GeometrySet<Dim> temp;
                    algorithm::intersection( pa1, pa2, temp );
                    std::copy( temp.points().begin(), temp.points().end(), std::back_inserter( points ) );
                    // erase it2
                    points.erase( it2 );
                    break;
                }
            }

            if ( ! intersectsA ) {
                output.addPrimitive( it->primitive() );
            }

            // suppress A
            it = points.erase( it );
        }
    }
    {
        typedef std::list< CollectionElement<typename Segment_d<Dim>::Type> > SegmentList;
        SegmentList segments;

        std::copy( input.segments().begin(), input.segments().end(), std::back_inserter( segments ) );

        typename SegmentList::iterator it = segments.begin();

        while ( it != segments.end() ) {
            bool intersectsA = false;

            for ( typename SegmentList::iterator it2 = segments.begin(); it2 != segments.end(); ++it2 ) {
                if ( it == it2 ) {
                    continue;
                }

                PrimitiveHandle<Dim> pa1( &it->primitive() );
                PrimitiveHandle<Dim> pa2( &it2->primitive() );

                if ( CGAL::do_overlap( it->primitive().bbox(), it2->primitive().bbox() ) &&
                        algorithm::intersects( pa1, pa2 ) ) {
                    intersectsA = true;
                    GeometrySet<Dim> temp;
                    algorithm::intersection( pa1, pa2, temp );
                    std::copy( temp.segments().begin(), temp.segments().end(), std::back_inserter( segments ) );
                    // erase it2
                    segments.erase( it2 );
                    break;
                }
            }

            if ( ! intersectsA ) {
                output.addPrimitive( it->primitive() );
            }

            // suppress A
            it = segments.erase( it );
        }
    }
}