From 673819311370a0b68d08f18d0cfa7566431b84fe Mon Sep 17 00:00:00 2001 From: BenPinet Date: Tue, 19 May 2026 09:54:35 +0200 Subject: [PATCH 1/4] fix(ModelIntersection): add computation of intersection between lines internal to block and surfaces --- .../intersections/model_intersections.cpp | 183 +++++++++++++++++- 1 file changed, 182 insertions(+), 1 deletion(-) diff --git a/src/geode/inspector/criterion/intersections/model_intersections.cpp b/src/geode/inspector/criterion/intersections/model_intersections.cpp index 585b52f..20d44c6 100644 --- a/src/geode/inspector/criterion/intersections/model_intersections.cpp +++ b/src/geode/inspector/criterion/intersections/model_intersections.cpp @@ -35,10 +35,12 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -75,6 +77,91 @@ namespace return triangles; } + class BRepLineSurfacesIntersection + { + public: + BRepLineSurfacesIntersection( const geode::BRep& model, + const geode::uuid& surface_id, + const geode::uuid& line_id ) + : model_( model ), + surface_( model.surface( surface_id ) ), + line_( model.line( line_id ) ), + surface_mesh_( surface_.mesh() ), + line_mesh_( line_.mesh() ) + { + } + + bool operator()( geode::index_t polygon_id, geode::index_t edge_id ) + { + if( polygon_edge_intersect( polygon_id, edge_id ) ) + { + emplace( polygon_id, edge_id ); + } + return false; + } + + std::vector< std::pair< geode::index_t, geode::index_t > > + intersecting_elements() + { + return std::move( intersecting_surface_polygon_line_edge_ ); + } + + private: + bool polygon_edge_intersect( geode::index_t p_id, geode::index_t e_id ) + { + const auto polygon_vertices = + surface_mesh_.polygon_vertices( p_id ); + const auto fan_triangles = + polygon_fan_triangles( polygon_vertices, 0 ); + const auto line_segment = line_mesh_.segment( e_id ); + for( const auto& triangle_vertices : fan_triangles ) + { + geode::Triangle3D triangle{ surface_mesh_.point( + triangle_vertices[0] ), + surface_mesh_.point( triangle_vertices[1] ), + surface_mesh_.point( triangle_vertices[2] ) }; + const auto segment_triangle_intersection = + geode::segment_triangle_intersection_detection( + line_segment, triangle ); + if( segment_triangle_intersection.first + == geode::POSITION::inside + || segment_triangle_intersection.second + == geode::POSITION::inside + || segment_triangle_intersection.first + == geode::POSITION::edge0 + || segment_triangle_intersection.first + == geode::POSITION::edge1 + || segment_triangle_intersection.second + == geode::POSITION::edge0 + || segment_triangle_intersection.second + == geode::POSITION::edge1 + || segment_triangle_intersection.second + == geode::POSITION::edge2 + || segment_triangle_intersection.first + == geode::POSITION::edge2 ) + { + return true; + } + } + return false; + } + void emplace( geode::index_t p_id, geode::index_t e_id ) + { + std::lock_guard< std::mutex > lock( mutex_ ); + intersecting_surface_polygon_line_edge_.emplace_back( p_id, e_id ); + } + + private: + const geode::BRep& model_; + const geode::Surface3D& surface_; + const geode::Line3D& line_; + const geode::SurfaceMesh3D& surface_mesh_; + const geode::EdgedCurve3D& line_mesh_; + std::vector< std::pair< geode::index_t, geode::index_t > > + intersecting_surface_polygon_line_edge_; + std::mutex mutex_; + }; + template < typename Model > class ModelSurfacesIntersectionBase { @@ -554,6 +641,34 @@ namespace geode } } + void add_intersecting_lines_surfaces_elements( + InspectionIssues< std::pair< ComponentMeshElement, + ComponentMeshElement > >& intersection_issues ) const + { + if constexpr( Model::dim == 3 ) + { + const auto intersections = + intersecting_lines_surfaces( model_ ); + for( const auto& element_pair : intersections ) + { + const auto& surface = + model_.surface( element_pair.first.component_id.id() ); + const auto& line = + model_.line( element_pair.second.component_id.id() ); + intersection_issues.add_issue( element_pair, + absl::StrCat( "Surface ", + surface.name().value_or( surface.id().string() ), + " (", element_pair.first.component_id.id().string(), + ") and Line ", + line.name().value_or( line.id().string() ), " (", + element_pair.second.component_id.id().string(), + ") intersect on polygon ", + element_pair.first.element_id, " and edge ", + element_pair.second.element_id ) ); + } + } + } + private: template < typename Action > std::vector< std::pair< ComponentMeshElement, ComponentMeshElement > > @@ -569,7 +684,8 @@ namespace geode geode::Logger::warn( "One of the surface meshes has an empty mesh, cannot " "compute the AABBTree used for detecting the mesh " - "intersections, no intersections will be computed." ); + "intersections, no intersections will be " + "computed." ); return component_intersections; } } @@ -622,6 +738,69 @@ namespace geode return component_intersections; } + std::vector< std::pair< ComponentMeshElement, ComponentMeshElement > > + intersecting_lines_surfaces( const geode::BRep& brep ) const + { + std::vector< + std::pair< ComponentMeshElement, ComponentMeshElement > > + component_intersections; + for( const auto& surface : brep.active_surfaces() ) + { + if( surface.mesh().nb_polygons() == 0 ) + { + geode::Logger::warn( + "One of the surface meshes has an empty mesh, " + "skipping " + "line-surface intersection detection." ); + return component_intersections; + } + } + for( const auto& line : brep.active_lines() ) + { + if( line.mesh().nb_edges() == 0 ) + { + geode::Logger::warn( + "One of the line meshes has an empty mesh, " + "skipping " + "line-surface intersection detection." ); + return component_intersections; + } + } + const auto surfaces_model_tree = + create_surface_meshes_aabb_trees( brep ); + const auto lines_model_tree = create_line_meshes_aabb_trees( brep ); + for( const auto& surface : brep.active_surfaces() ) + { + const auto& surface_tree = + surfaces_model_tree.mesh_trees_[surfaces_model_tree + .mesh_tree_ids_.at( surface.id() )]; + for( const auto& line : brep.active_lines() ) + { + if( brep.nb_embedding_blocks( line ) == 0 ) + { + continue; + } + BRepLineSurfacesIntersection action{ brep, surface.id(), + line.id() }; + const auto& line_tree = + lines_model_tree.mesh_trees_[lines_model_tree + .mesh_tree_ids_.at( line.id() )]; + surface_tree.compute_other_element_bbox_intersections( + line_tree, action ); + for( const auto& element_pair : + action.intersecting_elements() ) + { + component_intersections.emplace_back( + ComponentMeshElement{ + surface.component_id(), element_pair.first }, + ComponentMeshElement{ + line.component_id(), element_pair.second } ); + } + } + } + return component_intersections; + } + private: const Model& model_; }; @@ -650,6 +829,8 @@ namespace geode ElementsIntersectionsInspectionResult results; impl_->add_intersecting_surfaces_elements( results.elements_intersections ); + impl_->add_intersecting_lines_surfaces_elements( + results.elements_intersections ); return results; } From 185284b0d36eac8a64aca620ad3f977f660510fd Mon Sep 17 00:00:00 2001 From: BenPinet <126688250+BenPinet@users.noreply.github.com> Date: Tue, 19 May 2026 07:59:09 +0000 Subject: [PATCH 2/4] Apply prepare changes --- commitlint.config.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/commitlint.config.js b/commitlint.config.js index a397334..0c07c26 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -14,6 +14,7 @@ const Configuration = { "type-empty": [0], "type-enum": [2, "always", ["feat", "fix", "perf"]], }, -} + defaultIgnores: false, +}; -export default Configuration +export default Configuration; From d97a81454c9cca7aab1677e1653ff809471cfed3 Mon Sep 17 00:00:00 2001 From: BenPinet Date: Tue, 19 May 2026 10:09:40 +0200 Subject: [PATCH 3/4] fix compilation --- .../criterion/intersections/model_intersections.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/geode/inspector/criterion/intersections/model_intersections.cpp b/src/geode/inspector/criterion/intersections/model_intersections.cpp index 20d44c6..3e1b5d9 100644 --- a/src/geode/inspector/criterion/intersections/model_intersections.cpp +++ b/src/geode/inspector/criterion/intersections/model_intersections.cpp @@ -83,8 +83,7 @@ namespace BRepLineSurfacesIntersection( const geode::BRep& model, const geode::uuid& surface_id, const geode::uuid& line_id ) - : model_( model ), - surface_( model.surface( surface_id ) ), + : surface_( model.surface( surface_id ) ), line_( model.line( line_id ) ), surface_mesh_( surface_.mesh() ), line_mesh_( line_.mesh() ) @@ -152,7 +151,6 @@ namespace } private: - const geode::BRep& model_; const geode::Surface3D& surface_; const geode::Line3D& line_; const geode::SurfaceMesh3D& surface_mesh_; @@ -739,7 +737,7 @@ namespace geode } std::vector< std::pair< ComponentMeshElement, ComponentMeshElement > > - intersecting_lines_surfaces( const geode::BRep& brep ) const + intersecting_lines_surfaces( const BRep& brep ) const { std::vector< std::pair< ComponentMeshElement, ComponentMeshElement > > From 5671003080db0ef0931e25ab59fda9e2ab5d0c0b Mon Sep 17 00:00:00 2001 From: BenPinet Date: Tue, 19 May 2026 16:50:43 +0200 Subject: [PATCH 4/4] remove lock_guard --- .../inspector/criterion/intersections/model_intersections.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/geode/inspector/criterion/intersections/model_intersections.cpp b/src/geode/inspector/criterion/intersections/model_intersections.cpp index 3e1b5d9..19866ce 100644 --- a/src/geode/inspector/criterion/intersections/model_intersections.cpp +++ b/src/geode/inspector/criterion/intersections/model_intersections.cpp @@ -146,7 +146,6 @@ namespace } void emplace( geode::index_t p_id, geode::index_t e_id ) { - std::lock_guard< std::mutex > lock( mutex_ ); intersecting_surface_polygon_line_edge_.emplace_back( p_id, e_id ); } @@ -256,7 +255,6 @@ namespace void emplace( geode::index_t p1_id, geode::index_t p2_id ) { - std::lock_guard< std::mutex > lock( mutex_ ); intersecting_polygons_.emplace_back( p1_id, p2_id ); }