Exemplo n.º 1
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 );
    }
}
Exemplo n.º 2
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 );
    }
}
Exemplo n.º 3
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 );
        }
    }
}
Exemplo n.º 4
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 );
        }
    }
}