Skip to content

Commit ca5a405

Browse files
Merge pull request #112 from Geode-solutions/feat/polygon-intersection-detection
fix(OpenGeode): update to new intersections
2 parents 2f43722 + 9c5979b commit ca5a405

File tree

1 file changed

+28
-287
lines changed

1 file changed

+28
-287
lines changed

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

Lines changed: 28 additions & 287 deletions
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,19 @@
3737

3838
#include <geode/mesh/core/triangulated_surface.hpp>
3939
#include <geode/mesh/helpers/aabb_surface_helpers.hpp>
40+
#include <geode/mesh/helpers/detail/mesh_intersection_detection.hpp>
4041

4142
namespace
4243
{
43-
geode::local_index_t surface_vertex_position_to_index(
44-
geode::POSITION position )
45-
{
46-
if( position == geode::POSITION::vertex0 )
47-
{
48-
return 0;
49-
}
50-
if( position == geode::POSITION::vertex1 )
51-
{
52-
return 1;
53-
}
54-
if( position == geode::POSITION::vertex2 )
55-
{
56-
return 2;
57-
}
58-
return geode::NO_LID;
59-
}
60-
6144
template < geode::index_t dimension >
62-
class TriangleTriangleIntersectionBase
45+
class TriangleTriangleIntersection
6346
{
6447
public:
65-
TriangleTriangleIntersectionBase(
66-
const geode::TriangulatedSurface< dimension >& mesh )
67-
: mesh_( mesh )
48+
TriangleTriangleIntersection(
49+
const geode::TriangulatedSurface< dimension >& mesh,
50+
bool stop_at_first_intersection )
51+
: mesh_( mesh ),
52+
stop_at_first_intersection_{ stop_at_first_intersection }
6853
{
6954
}
7055

@@ -74,56 +59,6 @@ namespace
7459
return std::move( intersecting_triangles_ );
7560
}
7661

77-
protected:
78-
void emplace( geode::index_t t1_id, geode::index_t t2_id )
79-
{
80-
intersecting_triangles_.emplace_back( t1_id, t2_id );
81-
}
82-
83-
const geode::TriangulatedSurface< dimension >& mesh() const
84-
{
85-
return mesh_;
86-
}
87-
88-
geode::PolygonVertices triangles_common_points(
89-
const geode::PolygonVertices& t1_vertices,
90-
const geode::PolygonVertices& t2_vertices ) const
91-
{
92-
geode::PolygonVertices common_points;
93-
for( const auto vertex_id : t1_vertices )
94-
{
95-
if( absl::c_find( t2_vertices, vertex_id )
96-
!= t2_vertices.end() )
97-
{
98-
common_points.push_back( vertex_id );
99-
}
100-
}
101-
return common_points;
102-
}
103-
104-
bool triangles_intersect( geode::index_t t1_id,
105-
geode::index_t t2_id,
106-
const geode::PolygonVertices& t1_vertices,
107-
const geode::PolygonVertices& t2_vertices,
108-
const geode::PolygonVertices& common_points ) const;
109-
110-
private:
111-
const geode::TriangulatedSurface< dimension >& mesh_;
112-
std::vector< std::pair< geode::index_t, geode::index_t > >
113-
intersecting_triangles_;
114-
};
115-
116-
template < geode::index_t dimension >
117-
class OneTriangleTriangleIntersection
118-
: public TriangleTriangleIntersectionBase< dimension >
119-
{
120-
public:
121-
OneTriangleTriangleIntersection(
122-
const geode::TriangulatedSurface< dimension >& surface )
123-
: TriangleTriangleIntersectionBase< dimension >( surface )
124-
{
125-
}
126-
12762
bool operator()( geode::index_t t1_id, geode::index_t t2_id )
12863
{
12964
if( t1_id == t2_id )
@@ -132,225 +67,33 @@ namespace
13267
}
13368
const auto t1_vertices = this->mesh().polygon_vertices( t1_id );
13469
const auto t2_vertices = this->mesh().polygon_vertices( t2_id );
135-
const auto common_points =
136-
this->triangles_common_points( t1_vertices, t2_vertices );
137-
if( common_points.size() == 3
138-
|| this->triangles_intersect(
139-
t1_id, t2_id, t1_vertices, t2_vertices, common_points ) )
70+
if( geode::detail::polygons_intersection_detection<
71+
geode::SurfaceMesh< dimension > >(
72+
mesh_, t1_vertices, t2_vertices ) )
14073
{
14174
this->emplace( t1_id, t2_id );
142-
return true;
75+
return stop_at_first_intersection_;
14376
}
14477
return false;
14578
}
146-
};
147-
148-
template < geode::index_t dimension >
149-
class AllTriangleTriangleIntersection
150-
: public TriangleTriangleIntersectionBase< dimension >
151-
{
152-
public:
153-
AllTriangleTriangleIntersection(
154-
const geode::TriangulatedSurface< dimension >& surface )
155-
: TriangleTriangleIntersectionBase< dimension >( surface )
156-
{
157-
}
15879

159-
bool operator()( geode::index_t t1_id, geode::index_t t2_id )
160-
{
161-
if( t1_id == t2_id )
162-
{
163-
return false;
164-
}
165-
const auto t1_vertices = this->mesh().polygon_vertices( t1_id );
166-
const auto t2_vertices = this->mesh().polygon_vertices( t2_id );
167-
const auto common_points =
168-
this->triangles_common_points( t1_vertices, t2_vertices );
169-
if( common_points.size() == 3
170-
|| this->triangles_intersect(
171-
t1_id, t2_id, t1_vertices, t2_vertices, common_points ) )
172-
{
173-
this->emplace( t1_id, t2_id );
174-
}
175-
return false;
176-
}
177-
};
178-
179-
geode::index_t third_point_index( const geode::PolygonVertices& vertices,
180-
const geode::PolygonVertices& vertices_to_avoid )
181-
{
182-
for( const auto vertex_id : vertices )
183-
{
184-
if( vertex_id == vertices_to_avoid[0]
185-
|| vertex_id == vertices_to_avoid[1] )
186-
{
187-
continue;
188-
}
189-
return vertex_id;
190-
}
191-
OPENGEODE_ASSERT_NOT_REACHED( "Should have found a third point index" );
192-
return geode::NO_ID;
193-
}
194-
195-
template <>
196-
bool TriangleTriangleIntersectionBase< 2 >::triangles_intersect(
197-
geode::index_t t1_id,
198-
geode::index_t t2_id,
199-
const geode::PolygonVertices& t1_vertices,
200-
const geode::PolygonVertices& t2_vertices,
201-
const geode::PolygonVertices& common_points ) const
202-
{
203-
if( common_points.size() == 2 )
204-
{
205-
const auto& common_pt0 = mesh_.point( common_points[0] );
206-
const auto& common_pt1 = mesh_.point( common_points[1] );
207-
const auto& t1_third_pt =
208-
mesh_.point( third_point_index( t1_vertices, common_points ) );
209-
const auto& t2_third_pt =
210-
mesh_.point( third_point_index( t2_vertices, common_points ) );
211-
if( geode::segment_segment_intersection_detection(
212-
{ common_pt0, t1_third_pt }, { common_pt1, t2_third_pt } )
213-
.first
214-
!= geode::POSITION::outside
215-
|| geode::segment_segment_intersection_detection(
216-
{ common_pt1, t1_third_pt },
217-
{ common_pt0, t2_third_pt } )
218-
.first
219-
!= geode::POSITION::outside )
220-
{
221-
return true;
222-
}
223-
const auto t1 = mesh_.triangle( t1_id );
224-
const auto t2 = mesh_.triangle( t2_id );
225-
if( geode::point_triangle_position( t1_third_pt, t2 )
226-
!= geode::POSITION::outside
227-
|| geode::point_triangle_position( t2_third_pt, t1 )
228-
!= geode::POSITION::outside )
229-
{
230-
return true;
231-
}
232-
return false;
233-
}
234-
for( const auto t1_edge_v : geode::LRange{ 3 } )
80+
protected:
81+
void emplace( geode::index_t t1_id, geode::index_t t2_id )
23582
{
236-
const std::array< geode::index_t, 2 > edge1_vertices{
237-
t1_vertices[t1_edge_v],
238-
t1_vertices[t1_edge_v == 2 ? 0 : t1_edge_v + 1]
239-
};
240-
const geode::Segment2D t1_edge{ mesh_.point( edge1_vertices[0] ),
241-
mesh_.point( edge1_vertices[1] ) };
242-
for( const auto t2_edge_v : geode::LRange{ 3 } )
243-
{
244-
const std::array< geode::index_t, 2 > edge2_vertices{
245-
t2_vertices[t2_edge_v],
246-
t2_vertices[t2_edge_v == 2 ? 0 : t2_edge_v + 1]
247-
};
248-
const auto edge_edge_inter =
249-
geode::segment_segment_intersection_detection(
250-
t1_edge, { mesh_.point( edge2_vertices[0] ),
251-
mesh_.point( edge2_vertices[1] ) } );
252-
if( edge_edge_inter.first == geode::POSITION::outside
253-
|| edge_edge_inter.first == geode::POSITION::parallel )
254-
{
255-
continue;
256-
}
257-
if( common_points.size() != 1 )
258-
{
259-
return true;
260-
}
261-
const auto t1_edge_inter_pt_id =
262-
surface_vertex_position_to_index( edge_edge_inter.first );
263-
const auto t2_edge_inter_pt_id =
264-
surface_vertex_position_to_index( edge_edge_inter.second );
265-
if( t1_edge_inter_pt_id == geode::NO_LID
266-
|| t2_edge_inter_pt_id == geode::NO_LID )
267-
{
268-
return true;
269-
}
270-
if( edge1_vertices[t1_edge_inter_pt_id]
271-
!= edge2_vertices[t2_edge_inter_pt_id]
272-
|| edge1_vertices[t1_edge_inter_pt_id] != common_points[0] )
273-
{
274-
return true;
275-
}
276-
}
83+
intersecting_triangles_.emplace_back( t1_id, t2_id );
27784
}
278-
return false;
279-
}
28085

281-
bool triangle_intersects_other( const geode::Triangle3D& t1,
282-
const geode::Triangle3D& t2,
283-
const geode::PolygonVertices& t1_vertices,
284-
const geode::PolygonVertices& t2_vertices,
285-
const geode::PolygonVertices& common_points )
286-
{
287-
for( const auto v_id : geode::LRange{ 3 } )
86+
const geode::TriangulatedSurface< dimension >& mesh() const
28887
{
289-
const auto v2_id = v_id == 2 ? 0 : v_id + 1;
290-
const auto intersection = segment_triangle_intersection_detection(
291-
{ t1.vertices()[v_id], t1.vertices()[v2_id] }, t2 );
292-
if( intersection.first != geode::POSITION::outside )
293-
{
294-
if( common_points.size() != 1 )
295-
{
296-
return true;
297-
}
298-
const auto edge_inter_pt_id =
299-
surface_vertex_position_to_index( intersection.first );
300-
const auto t2_inter_pt_id =
301-
surface_vertex_position_to_index( intersection.second );
302-
if( edge_inter_pt_id == geode::NO_LID
303-
|| t2_inter_pt_id == geode::NO_LID )
304-
{
305-
return true;
306-
}
307-
if( t1_vertices[edge_inter_pt_id == 0 ? v_id : v2_id]
308-
!= t2_vertices[t2_inter_pt_id]
309-
|| t2_vertices[t2_inter_pt_id] != common_points[0] )
310-
{
311-
return true;
312-
}
313-
}
88+
return mesh_;
31489
}
315-
return false;
316-
}
31790

318-
template <>
319-
bool TriangleTriangleIntersectionBase< 3 >::triangles_intersect(
320-
geode::index_t t1_id,
321-
geode::index_t t2_id,
322-
const geode::PolygonVertices& t1_vertices,
323-
const geode::PolygonVertices& t2_vertices,
324-
const geode::PolygonVertices& common_points ) const
325-
{
326-
const auto t2 = mesh_.triangle( t2_id );
327-
if( common_points.size() == 2 )
328-
{
329-
const auto& t1_third_pt =
330-
mesh_.point( third_point_index( t1_vertices, common_points ) );
331-
if( geode::segment_triangle_intersection_detection(
332-
{ mesh_.point( common_points[0] ), t1_third_pt }, t2 )
333-
.first
334-
== geode::POSITION::parallel
335-
|| geode::segment_triangle_intersection_detection(
336-
{ mesh_.point( common_points[1] ), t1_third_pt }, t2 )
337-
.first
338-
== geode::POSITION::parallel )
339-
{
340-
return true;
341-
}
342-
return false;
343-
}
344-
const auto t1 = mesh_.triangle( t1_id );
345-
if( triangle_intersects_other(
346-
t1, t2, t1_vertices, t2_vertices, common_points )
347-
|| triangle_intersects_other(
348-
t2, t1, t2_vertices, t1_vertices, common_points ) )
349-
{
350-
return true;
351-
}
352-
return false;
353-
}
91+
private:
92+
const geode::TriangulatedSurface< dimension >& mesh_;
93+
bool stop_at_first_intersection_;
94+
std::vector< std::pair< geode::index_t, geode::index_t > >
95+
intersecting_triangles_;
96+
};
35497
} // namespace
35598

35699
namespace geode
@@ -366,8 +109,7 @@ namespace geode
366109

367110
bool mesh_has_self_intersections() const
368111
{
369-
const auto intersections = intersecting_triangles<
370-
OneTriangleTriangleIntersection< dimension > >();
112+
const auto intersections = intersecting_triangles( true );
371113
if( intersections.empty() )
372114
{
373115
return false;
@@ -378,8 +120,7 @@ namespace geode
378120
InspectionIssues< std::pair< index_t, index_t > >
379121
intersecting_elements() const
380122
{
381-
const auto intersections = intersecting_triangles<
382-
AllTriangleTriangleIntersection< dimension > >();
123+
const auto intersections = intersecting_triangles( false );
383124
InspectionIssues< std::pair< index_t, index_t > > issues{
384125
"Triangle - triangle intersections."
385126
};
@@ -394,12 +135,12 @@ namespace geode
394135
}
395136

396137
private:
397-
template < typename Action >
398-
std::vector< std::pair< index_t, index_t > >
399-
intersecting_triangles() const
138+
std::vector< std::pair< index_t, index_t > > intersecting_triangles(
139+
bool stop_at_first_intersection ) const
400140
{
401141
const auto surface_aabb = create_aabb_tree( mesh_ );
402-
Action action{ mesh_ };
142+
TriangleTriangleIntersection< dimension > action{ mesh_,
143+
stop_at_first_intersection };
403144
surface_aabb.compute_self_element_bbox_intersections( action );
404145
return action.intersecting_triangles();
405146
}

0 commit comments

Comments
 (0)