Lagrange
Loading...
Searching...
No Matches
AABBIGL.h
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <exception>
15#include <limits>
16#include <memory>
17
18// clang-format off
19#include <lagrange/utils/warnoff.h>
20#include <igl/AABB.h>
21#include <lagrange/utils/warnon.h>
22// clang-format on
23
24#include <lagrange/Logger.h>
25#include <lagrange/bvh/BVH.h>
26#include <lagrange/utils/assert.h>
27#include <lagrange/utils/range.h>
28#include <lagrange/utils/safe_cast.h>
29
30namespace lagrange {
31namespace bvh {
32
33template <typename _VertexArray, typename _ElementArray = lagrange::Triangles>
34class AABBIGL : public BVH<_VertexArray, _ElementArray>
35{
36public:
37 using Parent = BVH<_VertexArray, _ElementArray>;
38 using VertexArray = typename Parent::VertexArray;
39 using ElementArray = typename Parent::ElementArray;
40 using Scalar = typename Parent::Scalar;
41 using Index = typename Parent::Index;
42 using PointType = typename Parent::PointType;
43 using ClosestPoint = typename Parent::ClosestPoint;
44 using AABB = igl::AABB<VertexArray, 3>;
45
46public:
47 BVHType get_bvh_type() const override
48 { //
49 return BVHType::IGL;
50 }
51
52 bool does_support_pointcloud() const override
53 { //
54 // This is actually not true for at least the current version of
55 // libigl. https://github.com/libigl/libigl/issues/1040
56 return false;
57 }
58 bool does_support_triangles() const override
59 { //
60 return true;
61 }
62 bool does_support_lines() const override
63 { //
64 return false;
65 }
66
67 void build(const VertexArray& vertices, const ElementArray& elements) override
68 {
69 la_runtime_assert(elements.cols() == 3, "LibIGL AABB only supports triangles mesh");
70 m_vertices = vertices;
71 m_elements = elements;
72 m_aabb.init(m_vertices, m_elements);
73 }
74
75 void build(const VertexArray&) override
76 {
77 la_runtime_assert(0, "LibIGL AABB does not support a pointcloud");
78 }
79
81 { //
82 return true;
83 }
84 ClosestPoint query_closest_point(const PointType& p) const override
85 {
86 ClosestPoint r;
87 int idx = -1;
88 r.squared_distance =
89 m_aabb.squared_distance(m_vertices, m_elements, p, idx, r.closest_point);
90 r.embedding_element_idx = safe_cast<Index>(idx);
91
92 compute_closest_vertex_within_element(r, p);
93 return r;
94 }
95
96 bool does_support_query_k_nearest_neighbours() const override { return false; }
97 std::vector<ClosestPoint> query_k_nearest_neighbours(const PointType& p, int k) const override
98 {
99 (void)p;
100 (void)k;
101 throw std::runtime_error("LibIGL AABB does not support KNN queries");
102 }
103
105 { //
106 return false;
107 }
108 std::vector<ClosestPoint> query_in_sphere_neighbours(const PointType&, const Scalar)
109 const override
110 {
111 throw std::runtime_error("LibIGL AABB does not support radius queries");
112 }
113
114 std::vector<ClosestPoint> batch_query_closest_point(const VertexArray& query_pts) const override
115 {
116 const auto num_queries = query_pts.rows();
117 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> sq_dists(num_queries);
118 Eigen::Matrix<Index, Eigen::Dynamic, 1> embedding_elements(num_queries);
119 VertexArray closest_points(num_queries, m_vertices.cols());
120
121 m_aabb.squared_distance(
122 m_vertices,
123 m_elements,
124 query_pts,
125 sq_dists,
126 embedding_elements,
127 closest_points);
128
129 std::vector<ClosestPoint> r(num_queries);
130 for (auto i : range(num_queries)) {
131 r[i].embedding_element_idx = embedding_elements[i];
132 r[i].squared_distance = sq_dists[i];
133 r[i].closest_point = closest_points.row(i);
134 compute_closest_vertex_within_element(r[i], query_pts.row(i));
135 }
136 return r;
137 }
138
139private:
144 void compute_closest_vertex_within_element(ClosestPoint& entry, const PointType& p) const
145 {
146 assert(entry.embedding_element_idx >= 0);
147 assert(entry.embedding_element_idx < safe_cast<Index>(m_elements.rows()));
148 const auto vertex_per_element = m_elements.cols();
149 Scalar min_v_dist = std::numeric_limits<Scalar>::max();
150 for (auto i : range(vertex_per_element)) {
151 const auto vid = m_elements(entry.embedding_element_idx, i);
152 const auto sq_dist = (m_vertices.row(vid) - p).squaredNorm();
153 if (sq_dist < min_v_dist) {
154 min_v_dist = sq_dist;
155 entry.closest_vertex_idx = vid;
156 }
157 }
158 }
159
160
161private:
162 VertexArray m_vertices;
163 ElementArray m_elements;
164 AABB m_aabb;
165};
166
167} // namespace bvh
168} // namespace lagrange
Definition AABBIGL.h:35
bool does_support_pointcloud() const override
Does it support supplying elements or just points?
Definition AABBIGL.h:52
std::vector< ClosestPoint > batch_query_closest_point(const VertexArray &query_pts) const override
Batch query closest points.
Definition AABBIGL.h:114
bool does_support_query_k_nearest_neighbours() const override
Query for the k nearest neighbours.
Definition AABBIGL.h:96
BVHType get_bvh_type() const override
Get the enum type.
Definition AABBIGL.h:47
bool does_support_query_closest_point() const override
Query for the closest point.
Definition AABBIGL.h:80
bool does_support_query_in_sphere_neighbours() const override
Query for the closest point with in radius.
Definition AABBIGL.h:104
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:174
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition range.h:176
constexpr auto safe_cast(SourceType value) -> std::enable_if_t<!std::is_same< SourceType, TargetType >::value, TargetType >
Perform safe cast from SourceType to TargetType, where "safe" means:
Definition safe_cast.h:50
Main namespace for Lagrange.