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 ); } }
// 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; }
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 ); } }
/** * 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(); }
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(); }
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 ); }
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(); } }
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 ); }
// 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 ); } } }
// Releases all compiled geometries. void GeometryDatabase::ReleaseGeometries() { for (GeometrySet::iterator i = geometries.begin(); i != geometries.end(); ++i) (*i)->Release(); }
// Removes a geometry from the database. void GeometryDatabase::RemoveGeometry(Geometry* geometry) { geometries.erase(geometry); }
// Adds a geometry to the database. void GeometryDatabase::AddGeometry(Geometry* geometry) { geometries.insert(geometry); }
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 ); } } }