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 ); } }
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 ); } }
// 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 ); } } }
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 ); } } }