From 9943160cbcbea99400939e51e2eeaa9a5b8430bb Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 1 Jul 2026 15:17:12 +0200 Subject: [PATCH 1/4] fix(IntersectionDetection): missing segment/segment 3D --- .../geode/geometry/intersection_detection.hpp | 6 +- src/geode/geometry/intersection_detection.cpp | 198 +++++++++++------- .../detail/mesh_intersection_detection.cpp | 4 +- src/geode/mesh/helpers/ray_tracing.cpp | 4 +- 4 files changed, 128 insertions(+), 84 deletions(-) diff --git a/include/geode/geometry/intersection_detection.hpp b/include/geode/geometry/intersection_detection.hpp index 1dfb5a346..b5f33ab3e 100644 --- a/include/geode/geometry/intersection_detection.hpp +++ b/include/geode/geometry/intersection_detection.hpp @@ -50,9 +50,11 @@ namespace geode * Returns outside-outside if there is no intersection or parallel-pallel * if all points are colinear */ - [[nodiscard]] SegmentSegmentIntersection opengeode_geometry_api + template < index_t dimension > + [[nodiscard]] SegmentSegmentIntersection segment_segment_intersection_detection( - const Segment2D& segment0, const Segment2D& segment1 ); + const Segment< dimension >& segment0, + const Segment< dimension >& segment1 ); /*! * Detect the configuration between two 2D colinear segments diff --git a/src/geode/geometry/intersection_detection.cpp b/src/geode/geometry/intersection_detection.cpp index a1a849613..b3633dde2 100644 --- a/src/geode/geometry/intersection_detection.cpp +++ b/src/geode/geometry/intersection_detection.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include namespace { @@ -40,7 +42,7 @@ namespace geode::POSITION::vertex2, geode::POSITION::vertex0 }; - std::array< geode::local_index_t, 2 > best_projection_axis( + geode::local_index_t best_projection_axis( const geode::Triangle3D& triangle, const geode::Segment3D& segment ) { geode::local_index_t largest_axis{ 2 }; @@ -69,15 +71,62 @@ namespace } } } - if( largest_axis == 0 ) + return largest_axis; + } + + geode::SegmentSegmentIntersection segment_segment_intersection_detection2D( + const geode::Segment2D& segment0, const geode::Segment2D& segment1 ) + { + const auto s0_p0_side = + geode::point_side_to_segment( segment0.vertices()[0], segment1 ); + const auto s0_p1_side = + geode::point_side_to_segment( segment0.vertices()[1], segment1 ); + const auto s1_p0_side = + geode::point_side_to_segment( segment1.vertices()[0], segment0 ); + const auto s1_p1_side = + geode::point_side_to_segment( segment1.vertices()[1], segment0 ); + if( s0_p0_side == s0_p1_side || s1_p0_side == s1_p1_side ) + { + if( s0_p0_side == geode::SIDE::zero + && s1_p0_side == geode::SIDE::zero ) + { + return { geode::POSITION::parallel, geode::POSITION::parallel }; + } + return { geode::POSITION::outside, geode::POSITION::outside }; + } + if( s0_p0_side == geode::SIDE::zero ) + { + if( s1_p0_side == geode::SIDE::zero ) + { + return { geode::POSITION::vertex0, geode::POSITION::vertex0 }; + } + if( s1_p1_side == geode::SIDE::zero ) + { + return { geode::POSITION::vertex0, geode::POSITION::vertex1 }; + } + return { geode::POSITION::vertex0, geode::POSITION::inside }; + } + if( s0_p1_side == geode::SIDE::zero ) { - return { 1, 2 }; + if( s1_p0_side == geode::SIDE::zero ) + { + return { geode::POSITION::vertex1, geode::POSITION::vertex0 }; + } + if( s1_p1_side == geode::SIDE::zero ) + { + return { geode::POSITION::vertex1, geode::POSITION::vertex1 }; + } + return { geode::POSITION::vertex1, geode::POSITION::inside }; } - if( largest_axis == 1 ) + if( s1_p0_side == geode::SIDE::zero ) { - return { 2, 0 }; + return { geode::POSITION::inside, geode::POSITION::vertex0 }; } - return { 0, 1 }; + if( s1_p1_side == geode::SIDE::zero ) + { + return { geode::POSITION::inside, geode::POSITION::vertex1 }; + } + return { geode::POSITION::inside, geode::POSITION::inside }; } geode::SegmentTriangleIntersection @@ -85,32 +134,25 @@ namespace const geode::Segment3D& segment, const geode::Triangle3D& triangle ) { const auto projection_axis = best_projection_axis( triangle, segment ); - const geode::Point2D segment_proj_p0{ - { segment.vertices()[0].get().value( projection_axis[0] ), - segment.vertices()[0].get().value( projection_axis[1] ) } - }; - const geode::Point2D segment_proj_p1{ - { segment.vertices()[1].get().value( projection_axis[0] ), - segment.vertices()[1].get().value( projection_axis[1] ) } - }; + const auto segment_proj_p0 = + segment.vertices()[0].get().project_point( projection_axis ); + const auto segment_proj_p1 = + segment.vertices()[1].get().project_point( projection_axis ); const geode::Segment2D segment_projection{ segment_proj_p0, segment_proj_p1 }; std::array< geode::Point2D, 3 > triangle_points_projection; for( const auto triangle_pt : geode::LRange{ 3 } ) { triangle_points_projection[triangle_pt] = - geode::Point2D{ { triangle.vertices()[triangle_pt].get().value( - projection_axis[0] ), - triangle.vertices()[triangle_pt].get().value( - projection_axis[1] ) } }; + triangle.vertices()[triangle_pt].get().project_point( + projection_axis ); } geode::SegmentTriangleIntersection result{ geode::POSITION::outside, geode::POSITION::outside }; for( const auto edge_v0 : geode::LRange{ 3 } ) { const auto seg_edge_inter = - geode::segment_segment_intersection_detection( - segment_projection, + segment_segment_intersection_detection2D( segment_projection, { triangle_points_projection[edge_v0], triangle_points_projection[edge_v0 == 2 ? 0 @@ -150,62 +192,62 @@ namespace } return result; } -} // namespace -namespace geode -{ - SegmentSegmentIntersection segment_segment_intersection_detection( - const Segment2D& segment0, const Segment2D& segment1 ) + geode::SegmentSegmentIntersection segment_segment_intersection_detection3D( + const geode::Segment3D& segment0, const geode::Segment3D& segment1 ) { - const auto s0_p0_side = - point_side_to_segment( segment0.vertices()[0], segment1 ); - const auto s0_p1_side = - point_side_to_segment( segment0.vertices()[1], segment1 ); - const auto s1_p0_side = - point_side_to_segment( segment1.vertices()[0], segment0 ); - const auto s1_p1_side = - point_side_to_segment( segment1.vertices()[1], segment0 ); - if( s0_p0_side == s0_p1_side || s1_p0_side == s1_p1_side ) + if( geode::tetrahedron_volume_sign( geode::Tetrahedron{ + segment0.vertices()[0].get(), segment0.vertices()[1].get(), + segment1.vertices()[0].get(), segment1.vertices()[1].get() } ) + != geode::Sign::zero ) { - if( s0_p0_side == SIDE::zero && s1_p0_side == SIDE::zero ) - { - return std::make_pair( POSITION::parallel, POSITION::parallel ); - } - return std::make_pair( POSITION::outside, POSITION::outside ); + return { geode::POSITION::outside, geode::POSITION::outside }; } - if( s0_p0_side == SIDE::zero ) + geode::local_index_t largest_axis{ 2 }; + auto bbox = segment0.bounding_box(); + bbox.add_box( segment1.bounding_box() ); + const auto diagonal = bbox.diagonal(); + for( const auto other_axis : geode::LRange{ 2 } ) { - if( s1_p0_side == SIDE::zero ) + if( std::fabs( diagonal.value( other_axis ) ) + < std::fabs( diagonal.value( largest_axis ) ) ) { - return std::make_pair( POSITION::vertex0, POSITION::vertex0 ); + largest_axis = other_axis; } - if( s1_p1_side == SIDE::zero ) - { - return std::make_pair( POSITION::vertex0, POSITION::vertex1 ); - } - return std::make_pair( POSITION::vertex0, POSITION::inside ); } - if( s0_p1_side == SIDE::zero ) - { - if( s1_p0_side == SIDE::zero ) - { - return std::make_pair( POSITION::vertex1, POSITION::vertex0 ); - } - if( s1_p1_side == SIDE::zero ) - { - return std::make_pair( POSITION::vertex1, POSITION::vertex1 ); - } - return std::make_pair( POSITION::vertex1, POSITION::inside ); - } - if( s1_p0_side == SIDE::zero ) - { - return std::make_pair( POSITION::inside, POSITION::vertex0 ); - } - if( s1_p1_side == SIDE::zero ) - { - return std::make_pair( POSITION::inside, POSITION::vertex1 ); - } - return std::make_pair( POSITION::inside, POSITION::inside ); + const auto segment0_proj_p0 = + segment0.vertices()[0].get().project_point( largest_axis ); + const auto segment0_proj_p1 = + segment0.vertices()[1].get().project_point( largest_axis ); + const auto segment1_proj_p0 = + segment1.vertices()[0].get().project_point( largest_axis ); + const auto segment1_proj_p1 = + segment1.vertices()[1].get().project_point( largest_axis ); + const geode::Segment2D segment0_projection{ segment0_proj_p0, + segment0_proj_p1 }; + const geode::Segment2D segment1_projection{ segment1_proj_p0, + segment1_proj_p1 }; + return segment_segment_intersection_detection2D( + segment0_projection, segment1_projection ); + } +} // namespace + +namespace geode +{ + template <> + SegmentSegmentIntersection opengeode_geometry_api + segment_segment_intersection_detection< 2 >( + const Segment2D& segment0, const Segment2D& segment1 ) + { + return segment_segment_intersection_detection2D( segment0, segment1 ); + } + + template <> + SegmentSegmentIntersection opengeode_geometry_api + segment_segment_intersection_detection< 3 >( + const Segment3D& segment0, const Segment3D& segment1 ) + { + return segment_segment_intersection_detection3D( segment0, segment1 ); } SegmentSegmentIntersection colinear_segment_segment_intersection_detection( @@ -229,18 +271,18 @@ namespace geode || s1_p0_position == POSITION::inside || s1_p1_position == POSITION::inside ) { - return std::make_pair( POSITION::parallel, POSITION::parallel ); + return { POSITION::parallel, POSITION::parallel }; } if( s0_p0_position == POSITION::vertex0 ) { if( s0_p1_position == POSITION::outside || s0_p1_position == POSITION::vertex0 ) { - return std::make_pair( POSITION::vertex0, POSITION::vertex0 ); + return { POSITION::vertex0, POSITION::vertex0 }; } else // s0_p1_position == POSITION::vertex1 { - return std::make_pair( POSITION::parallel, POSITION::parallel ); + return { POSITION::parallel, POSITION::parallel }; } } if( s0_p0_position == POSITION::vertex1 ) @@ -248,11 +290,11 @@ namespace geode if( s0_p1_position == POSITION::outside || s0_p1_position == POSITION::vertex1 ) { - return std::make_pair( POSITION::vertex0, POSITION::vertex1 ); + return { POSITION::vertex0, POSITION::vertex1 }; } else // s0_p1_position == POSITION::vertex0 { - return std::make_pair( POSITION::parallel, POSITION::parallel ); + return { POSITION::parallel, POSITION::parallel }; } } if( s1_p0_position == POSITION::vertex0 ) @@ -260,11 +302,11 @@ namespace geode if( s1_p1_position == POSITION::outside || s1_p1_position == POSITION::vertex0 ) { - return std::make_pair( POSITION::vertex0, POSITION::vertex0 ); + return { POSITION::vertex0, POSITION::vertex0 }; } else // s1_p1_position == POSITION::vertex1 { - return std::make_pair( POSITION::parallel, POSITION::parallel ); + return { POSITION::parallel, POSITION::parallel }; } } if( s1_p0_position == POSITION::vertex1 ) @@ -272,14 +314,14 @@ namespace geode if( s1_p1_position == POSITION::outside || s1_p1_position == POSITION::vertex1 ) { - return std::make_pair( POSITION::vertex1, POSITION::vertex0 ); + return { POSITION::vertex1, POSITION::vertex0 }; } else // s1_p1_position == POSITION::vertex0 { - return std::make_pair( POSITION::parallel, POSITION::parallel ); + return { POSITION::parallel, POSITION::parallel }; } } - return std::make_pair( POSITION::outside, POSITION::outside ); + return { POSITION::outside, POSITION::outside }; } POSITION segment_line_intersection_detection( diff --git a/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp b/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp index 862cbee13..548e379dc 100644 --- a/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp +++ b/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp @@ -184,12 +184,12 @@ namespace third_point_index( triangle_vertices, common_points ) ); const auto& other_third_point = mesh.point( third_point_index( other_triangle_vertices, common_points ) ); - if( geode::segment_segment_intersection_detection( + if( geode::segment_segment_intersection_detection< 2 >( { common_point0, third_point }, { common_point1, other_third_point } ) .first != geode::POSITION::outside - || geode::segment_segment_intersection_detection( + || geode::segment_segment_intersection_detection< 2 >( { common_point1, third_point }, { common_point0, other_third_point } ) .first diff --git a/src/geode/mesh/helpers/ray_tracing.cpp b/src/geode/mesh/helpers/ray_tracing.cpp index 94231ed49..521aeb876 100644 --- a/src/geode/mesh/helpers/ray_tracing.cpp +++ b/src/geode/mesh/helpers/ray_tracing.cpp @@ -312,8 +312,8 @@ namespace geode bool compute( index_t edge_id ) { const auto segment = mesh_.segment( edge_id ); - const auto result = - segment_segment_intersection_detection( segment_, segment ); + const auto result = segment_segment_intersection_detection< 2 >( + segment_, segment ); if( result.first == POSITION::outside ) { return false; From cfecefb5d9ad8b2cf29b9752543324952926b936 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 1 Jul 2026 15:41:39 +0200 Subject: [PATCH 2/4] python --- .../src/geometry/intersection_detection.cpp | 4 +- .../geometry/basic_objects/infinite_line.hpp | 3 +- .../geode/geometry/basic_objects/polygon.hpp | 8 ++-- .../geode/geometry/basic_objects/triangle.hpp | 14 +++--- include/geode/geometry/bounding_box.hpp | 12 ++--- include/geode/mesh/core/surface_mesh.hpp | 6 +-- .../geometry/basic_objects/infinite_line.cpp | 2 +- src/geode/geometry/basic_objects/polygon.cpp | 6 +-- src/geode/geometry/basic_objects/triangle.cpp | 12 ++--- src/geode/geometry/bounding_box.cpp | 6 +-- src/geode/geometry/intersection_detection.cpp | 44 +++++++------------ src/geode/mesh/core/surface_mesh.cpp | 4 +- .../detail/mesh_intersection_detection.cpp | 18 +++----- 13 files changed, 61 insertions(+), 78 deletions(-) diff --git a/bindings/python/src/geometry/intersection_detection.cpp b/bindings/python/src/geometry/intersection_detection.cpp index 4b614015b..eff854493 100644 --- a/bindings/python/src/geometry/intersection_detection.cpp +++ b/bindings/python/src/geometry/intersection_detection.cpp @@ -34,7 +34,9 @@ namespace geode void define_intersection_detection( pybind11::module& module ) { module.def( "segment_segment_intersection_detection2D", - &segment_segment_intersection_detection ); + &segment_segment_intersection_detection< 2 > ); + module.def( "segment_segment_intersection_detection3D", + &segment_segment_intersection_detection< 3 > ); module.def( "colinear_segment_segment_intersection_detection2D", &colinear_segment_segment_intersection_detection ); module.def( "segment_line_intersection_detection2D", diff --git a/include/geode/geometry/basic_objects/infinite_line.hpp b/include/geode/geometry/basic_objects/infinite_line.hpp index 480f901bc..724843dc2 100644 --- a/include/geode/geometry/basic_objects/infinite_line.hpp +++ b/include/geode/geometry/basic_objects/infinite_line.hpp @@ -57,8 +57,7 @@ namespace geode [[nodiscard]] const Point< dimension >& origin() const; [[nodiscard]] const Vector< dimension >& direction() const; template < index_t T = dimension > - [[nodiscard]] typename std::enable_if< T == 2, double >::type - line_constant() const; + [[nodiscard]] std::enable_if_t< T == 2, double > line_constant() const; private: Vector< dimension > direction_; diff --git a/include/geode/geometry/basic_objects/polygon.hpp b/include/geode/geometry/basic_objects/polygon.hpp index afffb3986..52dc39d8a 100644 --- a/include/geode/geometry/basic_objects/polygon.hpp +++ b/include/geode/geometry/basic_objects/polygon.hpp @@ -63,15 +63,13 @@ namespace geode [[nodiscard]] Point< dimension > barycenter() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< Vector3D > >::type - normal() const; + std::enable_if_t< T == 3, std::optional< Vector3D > > normal() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< Plane > >::type - plane() const; + std::enable_if_t< T == 3, std::optional< Plane > > plane() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< OwnerPlane > >::type + std::enable_if_t< T == 3, std::optional< OwnerPlane > > owner_plane() const; [[nodiscard]] index_t nb_vertices() const; void set_point( index_t vertex, PointType point ); diff --git a/include/geode/geometry/basic_objects/triangle.hpp b/include/geode/geometry/basic_objects/triangle.hpp index 5031b69ea..22eefc1ac 100644 --- a/include/geode/geometry/basic_objects/triangle.hpp +++ b/include/geode/geometry/basic_objects/triangle.hpp @@ -64,23 +64,21 @@ namespace geode [[nodiscard]] Point< dimension > barycenter() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< Vector3D > >::type - normal() const; + std::enable_if_t< T == 3, std::optional< Vector3D > > normal() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< Plane > >::type - plane() const; + std::enable_if_t< T == 3, std::optional< Plane > > plane() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< OwnerPlane > >::type + std::enable_if_t< T == 3, std::optional< OwnerPlane > > owner_plane() const; template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< local_index_t > >::type + std::enable_if_t< T == 3, std::optional< local_index_t > > pivot() const; template < index_t T = dimension > - [[nodiscard]] typename std::enable_if< T == 3, - std::optional< std::pair< local_index_t, Vector3D > > >::type + [[nodiscard]] std::enable_if_t< T == 3, + std::optional< std::pair< local_index_t, Vector3D > > > pivot_and_normal() const; void set_point( local_index_t vertex, PointType point ); [[nodiscard]] const std::array< PointType, 3 >& vertices() const; diff --git a/include/geode/geometry/bounding_box.hpp b/include/geode/geometry/bounding_box.hpp index c7aa62605..ae250b82a 100644 --- a/include/geode/geometry/bounding_box.hpp +++ b/include/geode/geometry/bounding_box.hpp @@ -87,15 +87,15 @@ namespace geode * the bbox in 2D) */ template < index_t T = dimension > - [[nodiscard]] typename std::enable_if< T == 2 || T == 3, bool >::type - intersects( const Triangle< T >& triangle ) const; + [[nodiscard]] std::enable_if_t< T == 2 || T == 3, bool > intersects( + const Triangle< T >& triangle ) const; /*! * Returns true if the element is crossing, is inside, or is containing * the bbox */ template < index_t T = dimension > - [[nodiscard]] typename std::enable_if< T == 3, bool >::type intersects( + [[nodiscard]] std::enable_if_t< T == 3, bool > intersects( const Tetrahedron& tetra ) const; /*! @@ -115,12 +115,12 @@ namespace geode const Segment< dimension >& segment ) const; template < index_t T = dimension > - [[nodiscard]] typename std::enable_if< T == 2 || T == 3, bool >::type + [[nodiscard]] std::enable_if_t< T == 2 || T == 3, bool > epsilon_intersects( const Triangle< T >& triangle ) const; template < index_t T = dimension > - [[nodiscard]] typename std::enable_if< T == 3, bool >::type - epsilon_intersects( const Tetrahedron& tetra ) const; + [[nodiscard]] std::enable_if_t< T == 3, bool > epsilon_intersects( + const Tetrahedron& tetra ) const; /*! * Returns the distance between the point and the box. diff --git a/include/geode/mesh/core/surface_mesh.hpp b/include/geode/mesh/core/surface_mesh.hpp index 5cd43bc17..8bb4996a8 100644 --- a/include/geode/mesh/core/surface_mesh.hpp +++ b/include/geode/mesh/core/surface_mesh.hpp @@ -370,15 +370,15 @@ namespace geode */ template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< Vector3D > >::type - polygon_normal( index_t polygon_id ) const; + std::enable_if_t< T == 3, std::optional< Vector3D > > polygon_normal( + index_t polygon_id ) const; /*! * Return the normal at a polygon vertex */ template < index_t T = dimension > [[nodiscard]] - typename std::enable_if< T == 3, std::optional< Vector3D > >::type + std::enable_if_t< T == 3, std::optional< Vector3D > > polygon_vertex_normal( index_t vertex_id ) const; /*! diff --git a/src/geode/geometry/basic_objects/infinite_line.cpp b/src/geode/geometry/basic_objects/infinite_line.cpp index b94f640eb..4dacd4a1a 100644 --- a/src/geode/geometry/basic_objects/infinite_line.cpp +++ b/src/geode/geometry/basic_objects/infinite_line.cpp @@ -71,7 +71,7 @@ namespace geode } template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 2, double >::type + std::enable_if_t< T == 2, double > GenericLine< PointType, dimension >::line_constant() const { double line_constant{ 0.0 }; diff --git a/src/geode/geometry/basic_objects/polygon.cpp b/src/geode/geometry/basic_objects/polygon.cpp index 56839b162..91cefabc4 100644 --- a/src/geode/geometry/basic_objects/polygon.cpp +++ b/src/geode/geometry/basic_objects/polygon.cpp @@ -133,7 +133,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< Vector3D > >::type + std::enable_if_t< T == 3, std::optional< Vector3D > > GenericPolygon< PointType, dimension >::normal() const { Vector3D normal; @@ -160,7 +160,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< Plane > >::type + std::enable_if_t< T == 3, std::optional< Plane > > GenericPolygon< PointType, dimension >::plane() const { if( const auto polygon_normal = this->normal() ) @@ -173,7 +173,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< OwnerPlane > >::type + std::enable_if_t< T == 3, std::optional< OwnerPlane > > GenericPolygon< PointType, dimension >::owner_plane() const { if( const auto polygon_normal = this->normal() ) diff --git a/src/geode/geometry/basic_objects/triangle.cpp b/src/geode/geometry/basic_objects/triangle.cpp index e2ad944db..8e96c6248 100644 --- a/src/geode/geometry/basic_objects/triangle.cpp +++ b/src/geode/geometry/basic_objects/triangle.cpp @@ -119,7 +119,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< Vector3D > >::type + std::enable_if_t< T == 3, std::optional< Vector3D > > GenericTriangle< PointType, dimension >::normal() const { if( const auto result = pivot_and_normal() ) @@ -131,7 +131,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< Plane > >::type + std::enable_if_t< T == 3, std::optional< Plane > > GenericTriangle< PointType, dimension >::plane() const { if( const auto triangle_normal = this->normal() ) @@ -144,7 +144,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< OwnerPlane > >::type + std::enable_if_t< T == 3, std::optional< OwnerPlane > > GenericTriangle< PointType, dimension >::owner_plane() const { if( const auto triangle_normal = this->normal() ) @@ -157,7 +157,7 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< local_index_t > >::type + std::enable_if_t< T == 3, std::optional< local_index_t > > GenericTriangle< PointType, dimension >::pivot() const { if( const auto result = pivot_and_normal() ) @@ -169,8 +169,8 @@ namespace geode template < typename PointType, index_t dimension > template < index_t T > - typename std::enable_if< T == 3, - std::optional< std::pair< local_index_t, Vector3D > > >::type + std::enable_if_t< T == 3, + std::optional< std::pair< local_index_t, Vector3D > > > GenericTriangle< PointType, dimension >::pivot_and_normal() const { const auto result = simple_pivot_and_normal( diff --git a/src/geode/geometry/bounding_box.cpp b/src/geode/geometry/bounding_box.cpp index 068e12bfc..d3ab82daa 100644 --- a/src/geode/geometry/bounding_box.cpp +++ b/src/geode/geometry/bounding_box.cpp @@ -654,8 +654,8 @@ namespace geode template < index_t dimension > template < index_t T > - typename std::enable_if< T == 3, bool >::type - BoundingBox< dimension >::intersects( const Tetrahedron& tetra ) const + std::enable_if_t< T == 3, bool > BoundingBox< dimension >::intersects( + const Tetrahedron& tetra ) const { if( point_tetrahedron_position( center(), tetra ) == POSITION::inside ) { @@ -681,7 +681,7 @@ namespace geode template < index_t dimension > template < index_t T > - typename std::enable_if< T == 3, bool >::type + std::enable_if_t< T == 3, bool > BoundingBox< dimension >::epsilon_intersects( const Tetrahedron& tetra ) const { diff --git a/src/geode/geometry/intersection_detection.cpp b/src/geode/geometry/intersection_detection.cpp index b3633dde2..fd2e4fb7e 100644 --- a/src/geode/geometry/intersection_detection.cpp +++ b/src/geode/geometry/intersection_detection.cpp @@ -37,7 +37,7 @@ namespace { - static constexpr std::array< geode::POSITION, 4 > VERTEX_ID_TO_POSITION{ + constexpr std::array< geode::POSITION, 4 > VERTEX_ID_TO_POSITION{ geode::POSITION::vertex0, geode::POSITION::vertex1, geode::POSITION::vertex2, geode::POSITION::vertex0 }; @@ -56,19 +56,17 @@ namespace largest_axis = other_axis; } } + return largest_axis; } - else + auto bbox = triangle.bounding_box(); + bbox.add_box( segment.bounding_box() ); + const auto diagonal = bbox.diagonal(); + for( const auto other_axis : geode::LRange{ 2 } ) { - auto bbox = triangle.bounding_box(); - bbox.add_box( segment.bounding_box() ); - const auto diagonal = bbox.diagonal(); - for( const auto other_axis : geode::LRange{ 2 } ) + if( std::fabs( diagonal.value( other_axis ) ) + < std::fabs( diagonal.value( largest_axis ) ) ) { - if( std::fabs( diagonal.value( other_axis ) ) - < std::fabs( diagonal.value( largest_axis ) ) ) - { - largest_axis = other_axis; - } + largest_axis = other_axis; } } return largest_axis; @@ -280,10 +278,8 @@ namespace geode { return { POSITION::vertex0, POSITION::vertex0 }; } - else // s0_p1_position == POSITION::vertex1 - { - return { POSITION::parallel, POSITION::parallel }; - } + // s0_p1_position == POSITION::vertex1 + return { POSITION::parallel, POSITION::parallel }; } if( s0_p0_position == POSITION::vertex1 ) { @@ -292,10 +288,8 @@ namespace geode { return { POSITION::vertex0, POSITION::vertex1 }; } - else // s0_p1_position == POSITION::vertex0 - { - return { POSITION::parallel, POSITION::parallel }; - } + // s0_p1_position == POSITION::vertex0 + return { POSITION::parallel, POSITION::parallel }; } if( s1_p0_position == POSITION::vertex0 ) { @@ -304,10 +298,8 @@ namespace geode { return { POSITION::vertex0, POSITION::vertex0 }; } - else // s1_p1_position == POSITION::vertex1 - { - return { POSITION::parallel, POSITION::parallel }; - } + // s1_p1_position == POSITION::vertex1 + return { POSITION::parallel, POSITION::parallel }; } if( s1_p0_position == POSITION::vertex1 ) { @@ -316,10 +308,8 @@ namespace geode { return { POSITION::vertex1, POSITION::vertex0 }; } - else // s1_p1_position == POSITION::vertex0 - { - return { POSITION::parallel, POSITION::parallel }; - } + // s1_p1_position == POSITION::vertex0 + return { POSITION::parallel, POSITION::parallel }; } return { POSITION::outside, POSITION::outside }; } diff --git a/src/geode/mesh/core/surface_mesh.cpp b/src/geode/mesh/core/surface_mesh.cpp index 11fe1b75f..5d6c77054 100644 --- a/src/geode/mesh/core/surface_mesh.cpp +++ b/src/geode/mesh/core/surface_mesh.cpp @@ -1189,7 +1189,7 @@ namespace geode template < index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< Vector3D > >::type + std::enable_if_t< T == 3, std::optional< Vector3D > > SurfaceMesh< dimension >::polygon_normal( index_t polygon_id ) const { check_polygon_id( *this, polygon_id ); @@ -1199,7 +1199,7 @@ namespace geode template < index_t dimension > template < index_t T > - typename std::enable_if< T == 3, std::optional< Vector3D > >::type + std::enable_if_t< T == 3, std::optional< Vector3D > > SurfaceMesh< dimension >::polygon_vertex_normal( index_t vertex_id ) const { diff --git a/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp b/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp index 548e379dc..d3002a520 100644 --- a/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp +++ b/src/geode/mesh/helpers/detail/mesh_intersection_detection.cpp @@ -60,7 +60,7 @@ namespace { const auto next_apex = ( apex + edge ) % polygon.size(); const auto next_next_apex = - next_apex + 1 == polygon.size() ? 0u : next_apex + 1; + next_apex + 1 == polygon.size() ? 0U : next_apex + 1; triangles.emplace_back( geode::PolygonVertices{ polygon[apex], polygon[next_apex], polygon[next_next_apex] } ); } @@ -135,7 +135,7 @@ namespace } template < typename Mesh > - typename std::enable_if< Mesh::dim == 3, bool >::type triangles_intersect( + std::enable_if_t< Mesh::dim == 3, bool > triangles_intersect( const Mesh& mesh, const geode::PolygonVertices& triangle_vertices, const geode::PolygonVertices& other_triangle_vertices, @@ -159,18 +159,14 @@ namespace == geode::POSITION::parallel; } const auto triangle = mesh_triangle( mesh, triangle_vertices ); - if( triangle_intersects_other( triangle, other_triangle, - triangle_vertices, other_triangle_vertices, common_points ) - || triangle_intersects_other( other_triangle, triangle, - other_triangle_vertices, triangle_vertices, common_points ) ) - { - return true; - } - return false; + return triangle_intersects_other( triangle, other_triangle, + triangle_vertices, other_triangle_vertices, common_points ) + || triangle_intersects_other( other_triangle, triangle, + other_triangle_vertices, triangle_vertices, common_points ); } template < typename Mesh > - typename std::enable_if< Mesh::dim == 2, bool >::type triangles_intersect( + std::enable_if_t< Mesh::dim == 2, bool > triangles_intersect( const Mesh& mesh, const geode::PolygonVertices& triangle_vertices, const geode::PolygonVertices& other_triangle_vertices, From d0386235889c4b8ead28f6d1248edac0f2db7f07 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 2 Jul 2026 09:57:10 +0200 Subject: [PATCH 3/4] [skip ci] update doc --- include/geode/geometry/intersection_detection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/geode/geometry/intersection_detection.hpp b/include/geode/geometry/intersection_detection.hpp index b5f33ab3e..c04b9d7bb 100644 --- a/include/geode/geometry/intersection_detection.hpp +++ b/include/geode/geometry/intersection_detection.hpp @@ -45,7 +45,7 @@ namespace geode using SegmentTriangleIntersection = std::pair< POSITION, POSITION >; /*! - * Detect if there is an intersection between two 2D segments + * Detect if there is an intersection between two segments * @return the position of the intersection on the two segments. * Returns outside-outside if there is no intersection or parallel-pallel * if all points are colinear From f45d7d88bb3ebb2b56159135287677a28d017265 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 2 Jul 2026 10:08:19 +0200 Subject: [PATCH 4/4] trigger ci