diff --git a/src/algorithm/Intersection3D.cpp b/src/algorithm/Intersection3D.cpp index 989d0c3d..c94884b9 100644 --- a/src/algorithm/Intersection3D.cpp +++ b/src/algorithm/Intersection3D.cpp @@ -35,6 +35,11 @@ #include +#include +#include +#include +#include + using namespace SFCGAL::detail; namespace SFCGAL { @@ -320,9 +325,49 @@ void _intersection_solid_solid( const MarkedPolyhedron& pa, const MarkedPolyhedr } // else, we have an intersection - MarkedPolyhedron* res_poly = result[0].first; - output.addPrimitive( *res_poly ); - delete res_poly; + std::vector> res_poly; + res_poly.reserve(result.size()); + + Decomposition::const_iterator end_citer = result.cend(); + for ( Decomposition::const_iterator citer = result.cbegin(); citer != end_citer; ++citer ) { + res_poly.push_back( std::unique_ptr( citer->first ) ); + } + + // Decompose the intersection geometry into separate + // convex parts. + using Nef_polyhedron_3 + = CGAL::Nef_polyhedron_3; + + Nef_polyhedron_3 N( *res_poly[0] ); + + CGAL::convex_decomposition_3( N ); + std::list convex_parts; + + // The first volume is the outer volume, which should be + // ignored in the decomposition, so we skip it. + using Volume_const_iterator = Nef_polyhedron_3::Volume_const_iterator; + + Volume_const_iterator ci = ++N.volumes_begin(); + while ( ci != N.volumes_end() ) { + if ( ci->mark() ) { + MarkedPolyhedron P; + N.convert_inner_shell_to_polyhedron( ci->shells_begin(), P ); + convex_parts.push_back( P ); + } + + ++ci; + } + + // Add convex parts to output geometry collection. + if ( convex_parts.size() == 1 ) { + // Don't bother copying the original Polyhedron + // if it is the only part. + output.addPrimitive( *res_poly[0] ); + } else { + for ( const MarkedPolyhedron& mp : convex_parts ) { + output.addPrimitive( mp ); + } + } } }