14#include <lagrange/bvh/EdgeAABBTree.h>
15#include <lagrange/utils/assert.h>
16#include <lagrange/utils/point_on_segment.h>
17#include <lagrange/utils/point_segment_squared_distance.h>
20#include <lagrange/utils/warnoff.h>
21#include <igl/barycenter.h>
22#include <lagrange/utils/warnon.h>
35template <
typename Scalar>
53template <
typename Scalar,
int Dim>
54Scalar inner_point_box_squared_distance(
55 const Eigen::Matrix<Scalar, Dim, 1>& p,
56 const Eigen::AlignedBox<Scalar, Dim>& B)
58 assert(B.contains(p));
59 Scalar result = sqr(p[0] - B.min()[0]);
60 result = std::min(result, sqr(p[0] - B.max()[0]));
61 for (
int c = 1; c < Dim; ++c) {
62 result = std::min(result, sqr(p[c] - B.min()[c]));
63 result = std::min(result, sqr(p[c] - B.max()[c]));
79template <
typename Scalar,
int Dim>
80Scalar point_box_signed_squared_distance(
81 const Eigen::Matrix<Scalar, Dim, 1>& p,
82 const Eigen::AlignedBox<Scalar, Dim>& B)
86 for (
int c = 0; c < Dim; c++) {
87 if (p[c] < B.min()[c]) {
89 result += sqr(p[c] - B.min()[c]);
90 }
else if (p[c] > B.max()[c]) {
92 result += sqr(p[c] - B.max()[c]);
96 result = -inner_point_box_squared_distance(p, B);
109template <
typename Scalar,
int Dim>
110Eigen::AlignedBox<Scalar, Dim> bbox_edge(
111 const Eigen::Matrix<Scalar, 1, Dim>& a,
112 const Eigen::Matrix<Scalar, 1, Dim>& b)
114 Eigen::AlignedBox<Scalar, Dim> bbox;
115 bbox.extend(a.transpose());
116 bbox.extend(b.transpose());
124template <
typename VertexArray,
typename EdgeArray,
int Dim>
125EdgeAABBTree<VertexArray, EdgeArray, Dim>::EdgeAABBTree(
const VertexArray& V,
const EdgeArray& E)
133 std::vector<typename AABB<Scalar, Dim>::Box> aabb_boxes(E.rows());
135 for (Index i = 0; i < static_cast<Index>(E.rows()); ++i) {
136 RowVectorType a = V.row(E(i, 0));
137 RowVectorType b = V.row(E(i, 1));
138 auto& bbox = aabb_boxes[i];
140 bbox.extend(a.transpose());
141 bbox.extend(b.transpose());
145 m_aabb.build(
span<
typename AABB<Scalar, Dim>::Box>(aabb_boxes.data(), aabb_boxes.size()));
150template <
typename VertexArray,
typename EdgeArray,
int Dim>
152 const RowVectorType& p,
154 RowVectorType& closest_point,
155 Scalar& closest_sq_dist)
const
157 RowVectorType v0 = m_vertices->row((*m_edges)(element_id, 0));
158 RowVectorType v1 = m_vertices->row((*m_edges)(element_id, 1));
169template <
typename VertexArray,
typename EdgeArray,
int Dim>
171 const RowVectorType& p,
173 function_ref<
void(Scalar, Index,
const RowVectorType&)> func)
const
175 m_aabb.foreach_element_within_radius(p, sq_dist, [&](Index edge_idx) {
176 RowVectorType closest_point;
177 Scalar closest_sq_dist;
179 if (closest_sq_dist <= sq_dist) {
180 func(closest_sq_dist, edge_idx, closest_point);
187template <
typename VertexArray,
typename EdgeArray,
int Dim>
189 const RowVectorType& p,
190 function_ref<
void(Scalar, Index,
const RowVectorType&)> func)
const
193 typename AABB<Scalar, Dim>::Box query_box;
195 query_box.min() = point_vec;
196 query_box.max() = point_vec;
199 m_aabb.
intersect(query_box, [&](Index aabb_idx) {
200 Index edge_idx =
static_cast<Index
>(aabb_idx);
201 RowVectorType p0 = m_vertices->row((*m_edges)(edge_idx, 0));
202 RowVectorType p1 = m_vertices->row((*m_edges)(edge_idx, 1));
204 func(0, edge_idx, p);
212template <
typename VertexArray,
typename EdgeArray,
int Dim>
214 const RowVectorType& query_pt,
216 RowVectorType& closest_point,
217 Scalar& closest_sq_dist,
222 closest_sq_dist = std::numeric_limits<Scalar>::max();
227 if (!filter_func || filter_func(edge_id)) {
229 return closest_sq_dist;
231 return std::numeric_limits<Scalar>::max();
234 element_id = m_aabb.get_closest_element(query_pt.transpose(),
get_closest_point);
Axis-Aligned Bounding Box (AABB) tree for efficient spatial queries.
Definition AABB.h:39
void intersect(const Box &query_box, std::vector< Index > &results) const
Find all boxes that intersect with a query box.
Definition AABB.cpp:127
A lightweight non-owning reference to a callable.
Definition function_ref.h:47
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:174
#define la_debug_assert(...)
Debug assertion check.
Definition assert.h:194
::nonstd::span< T, Extent > span
A bounds-safe view for sequences of objects.
Definition span.h:27
constexpr T invalid()
You can use invalid<T>() to get a value that can represent "invalid" values, such as invalid indices ...
Definition invalid.h:40
void get_element_closest_point(const RowVectorType &p, Index element_id, RowVectorType &closest_point, Scalar &closest_sq_dist) const
Gets the closest point to a given element.
Definition EdgeAABBTree.impl.h:151
void get_closest_point(const RowVectorType &p, Index &element_id, RowVectorType &closest_point, Scalar &closest_sq_dist, function_ref< bool(Index)> filter_func=[](Index) { return true;}) const
Gets the closest point to an element of the tree.
Definition EdgeAABBTree.impl.h:213
bool empty() const
Test whether the tree is empty.
Definition EdgeAABBTree.h:62
void foreach_element_containing(const RowVectorType &p, ActionCallback func) const
Iterate over edges that contain exactly a given query point.
Definition EdgeAABBTree.impl.h:188
void foreach_element_in_radius(const RowVectorType &p, Scalar sq_dist, ActionCallback func) const
Iterate over edges within a prescribed distance from a query point.
Definition EdgeAABBTree.impl.h:170
Main namespace for Lagrange.
auto point_segment_squared_distance(const Eigen::MatrixBase< PointType > &point, const Eigen::MatrixBase< PointType2 > &V0, const Eigen::MatrixBase< PointType2 > &V1, Eigen::PlainObjectBase< PointType > &closest_point, ScalarOf< PointType > &lambda0, ScalarOf< PointType > &lambda1) -> ScalarOf< PointType >
Computes the point closest to a given point in a nd segment.
Definition point_segment_squared_distance.h:73
bool point_on_segment(const Eigen::MatrixBase< PointType > &p, const Eigen::MatrixBase< PointType > &a, const Eigen::MatrixBase< PointType > &b)
Test if a point lies exactly on a segment [a,b] using exact predicates.
Definition point_on_segment.h:43