Skip to content

Commit c67d9cd

Browse files
Merge pull request #1155 from Geode-solutions/fix/block_bbox_from_mesh
fix(block_bounding_box): Added case to compute block bounding box fro…
2 parents df0db87 + 338b081 commit c67d9cd

File tree

6 files changed

+415
-21
lines changed

6 files changed

+415
-21
lines changed

include/geode/mesh/helpers/ray_tracing.hpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,63 @@
3535

3636
namespace geode
3737
{
38+
FORWARD_DECLARATION_DIMENSION_CLASS( EdgedCurve );
3839
FORWARD_DECLARATION_DIMENSION_CLASS( SurfaceMesh );
40+
ALIAS_2D( EdgedCurve );
3941
ALIAS_3D( SurfaceMesh );
4042
} // namespace geode
4143

4244
namespace geode
4345
{
46+
class opengeode_mesh_api RayTracing2D
47+
{
48+
public:
49+
struct EdgeDistance
50+
{
51+
EdgeDistance() = default;
52+
53+
EdgeDistance( index_t edge_in,
54+
double distance_in,
55+
POSITION position_in,
56+
Point2D point_in )
57+
: edge{ edge_in },
58+
distance{ distance_in },
59+
position{ position_in },
60+
point{ std::move( point_in ) }
61+
{
62+
}
63+
64+
[[nodiscard]] bool operator<( const EdgeDistance& other ) const
65+
{
66+
return std::fabs( distance ) < std::fabs( other.distance );
67+
}
68+
69+
index_t edge{ NO_ID };
70+
double distance{ 0 };
71+
POSITION position{ POSITION::outside };
72+
Point2D point;
73+
};
74+
75+
public:
76+
RayTracing2D( const EdgedCurve2D& mesh, const Ray2D& ray );
77+
RayTracing2D(
78+
const EdgedCurve2D& mesh, const InfiniteLine2D& infinite_line );
79+
RayTracing2D( RayTracing2D&& other ) noexcept;
80+
~RayTracing2D();
81+
82+
[[nodiscard]] std::optional< EdgeDistance > closest_edge() const;
83+
84+
[[nodiscard]] std::optional< absl::FixedArray< EdgeDistance > >
85+
closest_edges( index_t nb_closest_wanted ) const;
86+
87+
[[nodiscard]] std::vector< EdgeDistance > all_intersections() const;
88+
89+
[[nodiscard]] bool operator()( index_t edge_id );
90+
91+
private:
92+
IMPLEMENTATION_MEMBER( impl_ );
93+
};
94+
4495
class opengeode_mesh_api RayTracing3D
4596
{
4697
public:
@@ -80,7 +131,7 @@ namespace geode
80131
[[nodiscard]] std::optional< PolygonDistance > closest_polygon() const;
81132

82133
[[nodiscard]] std::optional< absl::FixedArray< PolygonDistance > >
83-
closest_polygons( index_t size ) const;
134+
closest_polygons( index_t nb_closest_wanted ) const;
84135

85136
[[nodiscard]] std::vector< PolygonDistance > all_intersections() const;
86137

include/geode/model/helpers/ray_tracing.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232
namespace geode
3333
{
3434
FORWARD_DECLARATION_DIMENSION_CLASS( Block );
35-
ALIAS_3D( Block );
3635
FORWARD_DECLARATION_DIMENSION_CLASS( Surface );
37-
ALIAS_3D( Surface );
36+
ALIAS_3D( Block );
37+
ALIAS_2D( Surface );
3838
class BRep;
39+
class Section;
3940
struct uuid;
4041
} // namespace geode
4142

@@ -57,4 +58,12 @@ namespace geode
5758

5859
[[nodiscard]] std::optional< uuid > opengeode_model_api
5960
block_containing_point( const BRep& brep, const Point3D& point );
61+
62+
bool opengeode_model_api is_point_inside_surface( const Section& section,
63+
const Surface2D& surface,
64+
const Point2D& point );
65+
66+
[[nodiscard]] std::optional< uuid >
67+
opengeode_model_api surface_containing_point(
68+
const Section& section, const Point2D& point );
6069
} // namespace geode

src/geode/mesh/helpers/ray_tracing.cpp

Lines changed: 208 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,63 @@
3434
#include <geode/geometry/intersection.hpp>
3535
#include <geode/geometry/intersection_detection.hpp>
3636

37+
#include <geode/mesh/core/edged_curve.hpp>
3738
#include <geode/mesh/core/surface_mesh.hpp>
3839

3940
namespace
4041
{
41-
template < typename Line >
42-
geode::Point3D begin( const geode::SurfaceMesh3D& mesh, const Line& line )
42+
template < typename Mesh, typename Line >
43+
geode::Point< Mesh::dim > begin( const Mesh& mesh, const Line& line )
4344
{
4445
auto bbox = mesh.bounding_box();
4546
bbox.add_point( line.origin() );
4647
const auto diagonal = bbox.diagonal();
4748
return line.origin() - line.direction() * diagonal.length();
4849
}
4950

50-
template < typename Line >
51-
geode::Point3D end( const geode::SurfaceMesh3D& mesh, const Line& line )
51+
template < typename Mesh, typename Line >
52+
geode::Point< Mesh::dim > end( const Mesh& mesh, const Line& line )
5253
{
5354
auto bbox = mesh.bounding_box();
5455
bbox.add_point( line.origin() );
5556
const auto diagonal = bbox.diagonal();
5657
return line.origin() + line.direction() * diagonal.length();
5758
}
5859

60+
bool test_vertex_mode( const geode::EdgedCurve2D& mesh,
61+
const geode::RayTracing2D::EdgeDistance& edge0,
62+
const geode::RayTracing2D::EdgeDistance& edge1 )
63+
{
64+
geode::EdgeVertex edge_vertex0{ edge0.edge, geode::NO_LID };
65+
if( edge0.position == geode::POSITION::vertex0 )
66+
{
67+
edge_vertex0.vertex_id = 0;
68+
}
69+
else if( edge0.position == geode::POSITION::vertex1 )
70+
{
71+
edge_vertex0.vertex_id = 1;
72+
}
73+
else
74+
{
75+
return false;
76+
}
77+
geode::EdgeVertex edge_vertex1{ edge1.edge, geode::NO_LID };
78+
if( edge1.position == geode::POSITION::vertex0 )
79+
{
80+
edge_vertex1.vertex_id = 0;
81+
}
82+
else if( edge1.position == geode::POSITION::vertex1 )
83+
{
84+
edge_vertex1.vertex_id = 1;
85+
}
86+
else
87+
{
88+
return false;
89+
}
90+
return mesh.edge_vertex( edge_vertex0 )
91+
== mesh.edge_vertex( edge_vertex1 );
92+
}
93+
5994
bool test_vertex_mode( const geode::SurfaceMesh3D& mesh,
6095
const geode::RayTracing3D::PolygonDistance& polygon0,
6196
const geode::RayTracing3D::PolygonDistance& polygon1 )
@@ -139,6 +174,28 @@ namespace
139174
return mesh.polygon_adjacent_edge( polygon_edge0 ) == polygon_edge1;
140175
}
141176

177+
bool are_equal( const geode::EdgedCurve2D& mesh,
178+
const geode::RayTracing2D::EdgeDistance& edge0,
179+
const geode::RayTracing2D::EdgeDistance& edge1 )
180+
{
181+
if( std::fabs( edge0.distance - edge1.distance )
182+
> geode::GLOBAL_EPSILON )
183+
{
184+
return false;
185+
}
186+
if( edge0.position == geode::POSITION::inside
187+
|| edge0.position == geode::POSITION::parallel )
188+
{
189+
return false;
190+
}
191+
if( edge1.position == geode::POSITION::inside
192+
|| edge1.position == geode::POSITION::parallel )
193+
{
194+
return false;
195+
}
196+
return test_vertex_mode( mesh, edge0, edge1 );
197+
}
198+
142199
bool are_equal( const geode::SurfaceMesh3D& mesh,
143200
const geode::RayTracing3D::PolygonDistance& polygon0,
144201
const geode::RayTracing3D::PolygonDistance& polygon1 )
@@ -168,6 +225,153 @@ namespace
168225

169226
namespace geode
170227
{
228+
class RayTracing2D::Impl
229+
{
230+
public:
231+
Impl( const EdgedCurve2D& mesh, const Ray2D& ray )
232+
: mesh_( mesh ),
233+
origin_( ray.origin() ),
234+
segment_{ ray.origin(), end( mesh, ray ) }
235+
{
236+
}
237+
238+
Impl( const EdgedCurve2D& mesh, const InfiniteLine2D& infinite_line )
239+
: mesh_( mesh ),
240+
origin_( infinite_line.origin() ),
241+
segment_{ begin( mesh, infinite_line ),
242+
end( mesh, infinite_line ) }
243+
{
244+
}
245+
246+
std::optional< EdgeDistance > closest_edge() const
247+
{
248+
if( results_.empty() )
249+
{
250+
return std::nullopt;
251+
}
252+
sort_results();
253+
return results_.front();
254+
}
255+
256+
std::optional< absl::FixedArray< RayTracing2D::EdgeDistance > >
257+
closest_edges( index_t size ) const
258+
{
259+
if( results_.empty() )
260+
{
261+
return std::nullopt;
262+
}
263+
sort_results();
264+
std::optional< absl::FixedArray< RayTracing2D::EdgeDistance > >
265+
closest_edges{ std::min(
266+
size, static_cast< index_t >( results_.size() ) ) };
267+
for( const auto i : Indices{ closest_edges.value() } )
268+
{
269+
closest_edges->at( i ) = results_[i];
270+
}
271+
return closest_edges;
272+
}
273+
274+
std::vector< EdgeDistance > all_intersections() const
275+
{
276+
if( results_.empty() )
277+
{
278+
return {};
279+
}
280+
sort_results();
281+
return results_;
282+
}
283+
284+
bool compute( index_t edge_id )
285+
{
286+
const auto segment = mesh_.segment( edge_id );
287+
const auto result =
288+
segment_segment_intersection_detection( segment_, segment );
289+
if( result.first == POSITION::outside )
290+
{
291+
return false;
292+
}
293+
if( auto intersection =
294+
segment_segment_intersection( segment_, segment ) )
295+
{
296+
auto& intersection_result = intersection.result.value();
297+
auto distance =
298+
point_point_distance( origin_, intersection_result );
299+
if( Vector2D{ origin_, intersection_result }.dot(
300+
segment_.direction() )
301+
< 0 )
302+
{
303+
distance *= -1.;
304+
}
305+
std::lock_guard< std::mutex > lock{ mutex_ };
306+
results_.emplace_back( edge_id, distance, result.second,
307+
std::move( intersection_result ) );
308+
}
309+
return false;
310+
}
311+
312+
private:
313+
void sort_results() const
314+
{
315+
if( are_results_sorted_ )
316+
{
317+
return;
318+
}
319+
absl::c_sort( results_ );
320+
const auto last = std::unique( results_.begin(), results_.end(),
321+
[this]( const EdgeDistance& edge0, const EdgeDistance& edge1 ) {
322+
return are_equal( this->mesh_, edge0, edge1 );
323+
} );
324+
results_.erase( last, results_.end() );
325+
are_results_sorted_ = true;
326+
}
327+
328+
private:
329+
const EdgedCurve2D& mesh_;
330+
const Point2D& origin_;
331+
DEBUG_CONST OwnerSegment2D segment_;
332+
mutable std::vector< EdgeDistance > results_;
333+
mutable bool are_results_sorted_{ false };
334+
std::mutex mutex_;
335+
};
336+
337+
RayTracing2D::RayTracing2D( const EdgedCurve2D& mesh, const Ray2D& ray )
338+
: impl_{ mesh, ray }
339+
{
340+
}
341+
342+
RayTracing2D::RayTracing2D(
343+
const EdgedCurve2D& mesh, const InfiniteLine2D& infinite_line )
344+
: impl_{ mesh, infinite_line }
345+
{
346+
}
347+
348+
RayTracing2D::RayTracing2D( RayTracing2D&& ) noexcept = default;
349+
350+
RayTracing2D::~RayTracing2D() = default;
351+
352+
std::optional< RayTracing2D::EdgeDistance >
353+
RayTracing2D::closest_edge() const
354+
{
355+
return impl_->closest_edge();
356+
}
357+
358+
std::optional< absl::FixedArray< RayTracing2D::EdgeDistance > >
359+
RayTracing2D::closest_edges( index_t size ) const
360+
{
361+
return impl_->closest_edges( size );
362+
}
363+
364+
std::vector< RayTracing2D::EdgeDistance >
365+
RayTracing2D::all_intersections() const
366+
{
367+
return impl_->all_intersections();
368+
}
369+
370+
bool RayTracing2D::operator()( index_t edge_id )
371+
{
372+
return impl_->compute( edge_id );
373+
}
374+
171375
class RayTracing3D::Impl
172376
{
173377
public:

src/geode/model/helpers/component_mensurations.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <geode/geometry/point.hpp>
3232

3333
#include <geode/mesh/core/edged_curve.hpp>
34+
#include <geode/mesh/core/solid_mesh.hpp>
3435
#include <geode/mesh/core/surface_mesh.hpp>
3536

3637
#include <geode/model/helpers/component_mesh_edges.hpp>
@@ -174,6 +175,10 @@ namespace geode
174175

175176
BoundingBox3D block_bounding_box( const BRep& brep, const Block3D& block )
176177
{
178+
if( block.mesh().nb_vertices() != 0 )
179+
{
180+
return block.mesh().bounding_box();
181+
}
177182
BoundingBox3D result;
178183
for( const auto& surface : brep.boundaries( block ) )
179184
{

0 commit comments

Comments
 (0)