Lagrange
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
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/bvh/BVH.h>
25#include <lagrange/Logger.h>
26#include <lagrange/utils/assert.h>
27#include <lagrange/utils/safe_cast.h>
28#include <lagrange/utils/range.h>
29
30namespace lagrange {
31namespace bvh {
32
33template <typename _VertexArray, typename _ElementArray = lagrange::Triangles>
34class AABBIGL : public BVH<_VertexArray, _ElementArray>
35{
36public:
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
97 {
98 return false;
99 }
100 std::vector<ClosestPoint> query_k_nearest_neighbours(const PointType& p, int k) const override
101 {
102 (void)p; (void)k;
103 throw std::runtime_error("LibIGL AABB does not support KNN queries");
104 }
105
107 { //
108 return false;
109 }
110 std::vector<ClosestPoint> query_in_sphere_neighbours(const PointType&, const Scalar)
111 const override
112 {
113 throw std::runtime_error("LibIGL AABB does not support radius queries");
114 }
115
116 std::vector<ClosestPoint> batch_query_closest_point(const VertexArray& query_pts) const override
117 {
118 const auto num_queries = query_pts.rows();
119 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> sq_dists(num_queries);
120 Eigen::Matrix<Index, Eigen::Dynamic, 1> embedding_elements(num_queries);
121 VertexArray closest_points(num_queries, m_vertices.cols());
122
123 m_aabb.squared_distance(
124 m_vertices,
125 m_elements,
126 query_pts,
127 sq_dists,
128 embedding_elements,
129 closest_points);
130
131 std::vector<ClosestPoint> r(num_queries);
132 for (auto i : range(num_queries)) {
133 r[i].embedding_element_idx = embedding_elements[i];
134 r[i].squared_distance = sq_dists[i];
135 r[i].closest_point = closest_points.row(i);
136 compute_closest_vertex_within_element(r[i], query_pts.row(i));
137 }
138 return r;
139 }
140
141private:
146 void compute_closest_vertex_within_element(ClosestPoint& entry, const PointType& p) const
147 {
148 assert(entry.embedding_element_idx >= 0);
149 assert(entry.embedding_element_idx < safe_cast<Index>(m_elements.rows()));
150 const auto vertex_per_element = m_elements.cols();
151 Scalar min_v_dist = std::numeric_limits<Scalar>::max();
152 for (auto i : range(vertex_per_element)) {
153 const auto vid = m_elements(entry.embedding_element_idx, i);
154 const auto sq_dist = (m_vertices.row(vid) - p).squaredNorm();
155 if (sq_dist < min_v_dist) {
156 min_v_dist = sq_dist;
157 entry.closest_vertex_idx = vid;
158 }
159 }
160 }
161
162
163private:
164 VertexArray m_vertices;
165 ElementArray m_elements;
166 AABB m_aabb;
167};
168
169} // namespace bvh
170} // 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:116
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:106
Definition: BVH.h:27
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition: range.h:176
Main namespace for Lagrange.
Definition: AABBIGL.h:30