Skip to content

Commit 1aa0d5a

Browse files
authored
Merge pull request #177 from Geode-solutions/fix/surface_remesh_introduces_internal_line_intersection
fix(ModelIntersection): add computation of intersection between lines…
2 parents b682511 + 5671003 commit 1aa0d5a

2 files changed

Lines changed: 182 additions & 4 deletions

File tree

commitlint.config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const Configuration = {
1414
"type-empty": [0],
1515
"type-enum": [2, "always", ["feat", "fix", "perf"]],
1616
},
17-
}
17+
defaultIgnores: false,
18+
};
1819

19-
export default Configuration
20+
export default Configuration;

src/geode/inspector/criterion/intersections/model_intersections.cpp

Lines changed: 179 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
#include <geode/geometry/intersection_detection.hpp>
3636
#include <geode/geometry/position.hpp>
3737

38+
#include <geode/mesh/core/edged_curve.hpp>
3839
#include <geode/mesh/core/triangulated_surface.hpp>
3940
#include <geode/mesh/helpers/aabb_surface_helpers.hpp>
4041

4142
#include <geode/model/helpers/aabb_model_helpers.hpp>
43+
#include <geode/model/mixin/core/line.hpp>
4244
#include <geode/model/mixin/core/surface.hpp>
4345
#include <geode/model/representation/core/brep.hpp>
4446
#include <geode/model/representation/core/section.hpp>
@@ -75,6 +77,88 @@ namespace
7577
return triangles;
7678
}
7779

80+
class BRepLineSurfacesIntersection
81+
{
82+
public:
83+
BRepLineSurfacesIntersection( const geode::BRep& model,
84+
const geode::uuid& surface_id,
85+
const geode::uuid& line_id )
86+
: surface_( model.surface( surface_id ) ),
87+
line_( model.line( line_id ) ),
88+
surface_mesh_( surface_.mesh() ),
89+
line_mesh_( line_.mesh() )
90+
{
91+
}
92+
93+
bool operator()( geode::index_t polygon_id, geode::index_t edge_id )
94+
{
95+
if( polygon_edge_intersect( polygon_id, edge_id ) )
96+
{
97+
emplace( polygon_id, edge_id );
98+
}
99+
return false;
100+
}
101+
102+
std::vector< std::pair< geode::index_t, geode::index_t > >
103+
intersecting_elements()
104+
{
105+
return std::move( intersecting_surface_polygon_line_edge_ );
106+
}
107+
108+
private:
109+
bool polygon_edge_intersect( geode::index_t p_id, geode::index_t e_id )
110+
{
111+
const auto polygon_vertices =
112+
surface_mesh_.polygon_vertices( p_id );
113+
const auto fan_triangles =
114+
polygon_fan_triangles( polygon_vertices, 0 );
115+
const auto line_segment = line_mesh_.segment( e_id );
116+
for( const auto& triangle_vertices : fan_triangles )
117+
{
118+
geode::Triangle3D triangle{ surface_mesh_.point(
119+
triangle_vertices[0] ),
120+
surface_mesh_.point( triangle_vertices[1] ),
121+
surface_mesh_.point( triangle_vertices[2] ) };
122+
const auto segment_triangle_intersection =
123+
geode::segment_triangle_intersection_detection(
124+
line_segment, triangle );
125+
if( segment_triangle_intersection.first
126+
== geode::POSITION::inside
127+
|| segment_triangle_intersection.second
128+
== geode::POSITION::inside
129+
|| segment_triangle_intersection.first
130+
== geode::POSITION::edge0
131+
|| segment_triangle_intersection.first
132+
== geode::POSITION::edge1
133+
|| segment_triangle_intersection.second
134+
== geode::POSITION::edge0
135+
|| segment_triangle_intersection.second
136+
== geode::POSITION::edge1
137+
|| segment_triangle_intersection.second
138+
== geode::POSITION::edge2
139+
|| segment_triangle_intersection.first
140+
== geode::POSITION::edge2 )
141+
{
142+
return true;
143+
}
144+
}
145+
return false;
146+
}
147+
void emplace( geode::index_t p_id, geode::index_t e_id )
148+
{
149+
intersecting_surface_polygon_line_edge_.emplace_back( p_id, e_id );
150+
}
151+
152+
private:
153+
const geode::Surface3D& surface_;
154+
const geode::Line3D& line_;
155+
const geode::SurfaceMesh3D& surface_mesh_;
156+
const geode::EdgedCurve3D& line_mesh_;
157+
std::vector< std::pair< geode::index_t, geode::index_t > >
158+
intersecting_surface_polygon_line_edge_;
159+
std::mutex mutex_;
160+
};
161+
78162
template < typename Model >
79163
class ModelSurfacesIntersectionBase
80164
{
@@ -171,7 +255,6 @@ namespace
171255

172256
void emplace( geode::index_t p1_id, geode::index_t p2_id )
173257
{
174-
std::lock_guard< std::mutex > lock( mutex_ );
175258
intersecting_polygons_.emplace_back( p1_id, p2_id );
176259
}
177260

@@ -554,6 +637,34 @@ namespace geode
554637
}
555638
}
556639

640+
void add_intersecting_lines_surfaces_elements(
641+
InspectionIssues< std::pair< ComponentMeshElement,
642+
ComponentMeshElement > >& intersection_issues ) const
643+
{
644+
if constexpr( Model::dim == 3 )
645+
{
646+
const auto intersections =
647+
intersecting_lines_surfaces( model_ );
648+
for( const auto& element_pair : intersections )
649+
{
650+
const auto& surface =
651+
model_.surface( element_pair.first.component_id.id() );
652+
const auto& line =
653+
model_.line( element_pair.second.component_id.id() );
654+
intersection_issues.add_issue( element_pair,
655+
absl::StrCat( "Surface ",
656+
surface.name().value_or( surface.id().string() ),
657+
" (", element_pair.first.component_id.id().string(),
658+
") and Line ",
659+
line.name().value_or( line.id().string() ), " (",
660+
element_pair.second.component_id.id().string(),
661+
") intersect on polygon ",
662+
element_pair.first.element_id, " and edge ",
663+
element_pair.second.element_id ) );
664+
}
665+
}
666+
}
667+
557668
private:
558669
template < typename Action >
559670
std::vector< std::pair< ComponentMeshElement, ComponentMeshElement > >
@@ -569,7 +680,8 @@ namespace geode
569680
geode::Logger::warn(
570681
"One of the surface meshes has an empty mesh, cannot "
571682
"compute the AABBTree used for detecting the mesh "
572-
"intersections, no intersections will be computed." );
683+
"intersections, no intersections will be "
684+
"computed." );
573685
return component_intersections;
574686
}
575687
}
@@ -622,6 +734,69 @@ namespace geode
622734
return component_intersections;
623735
}
624736

737+
std::vector< std::pair< ComponentMeshElement, ComponentMeshElement > >
738+
intersecting_lines_surfaces( const BRep& brep ) const
739+
{
740+
std::vector<
741+
std::pair< ComponentMeshElement, ComponentMeshElement > >
742+
component_intersections;
743+
for( const auto& surface : brep.active_surfaces() )
744+
{
745+
if( surface.mesh().nb_polygons() == 0 )
746+
{
747+
geode::Logger::warn(
748+
"One of the surface meshes has an empty mesh, "
749+
"skipping "
750+
"line-surface intersection detection." );
751+
return component_intersections;
752+
}
753+
}
754+
for( const auto& line : brep.active_lines() )
755+
{
756+
if( line.mesh().nb_edges() == 0 )
757+
{
758+
geode::Logger::warn(
759+
"One of the line meshes has an empty mesh, "
760+
"skipping "
761+
"line-surface intersection detection." );
762+
return component_intersections;
763+
}
764+
}
765+
const auto surfaces_model_tree =
766+
create_surface_meshes_aabb_trees( brep );
767+
const auto lines_model_tree = create_line_meshes_aabb_trees( brep );
768+
for( const auto& surface : brep.active_surfaces() )
769+
{
770+
const auto& surface_tree =
771+
surfaces_model_tree.mesh_trees_[surfaces_model_tree
772+
.mesh_tree_ids_.at( surface.id() )];
773+
for( const auto& line : brep.active_lines() )
774+
{
775+
if( brep.nb_embedding_blocks( line ) == 0 )
776+
{
777+
continue;
778+
}
779+
BRepLineSurfacesIntersection action{ brep, surface.id(),
780+
line.id() };
781+
const auto& line_tree =
782+
lines_model_tree.mesh_trees_[lines_model_tree
783+
.mesh_tree_ids_.at( line.id() )];
784+
surface_tree.compute_other_element_bbox_intersections(
785+
line_tree, action );
786+
for( const auto& element_pair :
787+
action.intersecting_elements() )
788+
{
789+
component_intersections.emplace_back(
790+
ComponentMeshElement{
791+
surface.component_id(), element_pair.first },
792+
ComponentMeshElement{
793+
line.component_id(), element_pair.second } );
794+
}
795+
}
796+
}
797+
return component_intersections;
798+
}
799+
625800
private:
626801
const Model& model_;
627802
};
@@ -650,6 +825,8 @@ namespace geode
650825
ElementsIntersectionsInspectionResult results;
651826
impl_->add_intersecting_surfaces_elements(
652827
results.elements_intersections );
828+
impl_->add_intersecting_lines_surfaces_elements(
829+
results.elements_intersections );
653830
return results;
654831
}
655832

0 commit comments

Comments
 (0)