Wildmeshing Toolkit
Loading...
Searching...
No Matches
Envelope.hpp
1#pragma once
2
3#include <Eigen/Core>
4#include <array>
5#include <cstdint>
6#include <memory>
7#include <vector>
8
9// clang-format off
10#include <wmtk/utils/DisableWarnings.hpp>
11#include <fastenvelope/FastEnvelope.h>
12#include <fastenvelope/FastEnvelope2D.h>
13#include <SimpleBVH/BVH.hpp>
14#include <wmtk/utils/EnableWarnings.hpp>
15// clang-format on
16
17namespace wmtk {
19{
20public:
31 enum class Kind { Uninitialized, Triangles3d, Edges3d, Edges2d };
32
39 Envelope(bool exact = true)
40 : use_exact(exact) {};
41 virtual ~Envelope() = default;
50 double eps2 = 1e-6;
70 double eps2_edge = 1e-6;
71 double sampling_dist = 1e-3;
72
84 void set_max_threads(int n) { m_max_threads = n < 1 ? 1 : n; }
85 bool use_exact = true;
86
100 bool disabled = false;
101 virtual void init(
102 const std::vector<Eigen::Vector3d>& m_ver,
103 const std::vector<Eigen::Vector3i>& m_faces,
104 const double);
105 void init(
106 const std::vector<Eigen::Vector3d>& m_ver,
107 const std::vector<Eigen::Vector2i>& m_edges,
108 const double);
109 void init(
110 const std::vector<Eigen::Vector2d>& m_ver,
111 const std::vector<Eigen::Vector2i>& m_edges,
112 const double);
113
124 void init(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const double eps);
133 virtual bool is_outside(const std::array<Eigen::Vector3d, 3>& tris) const;
134 bool is_outside(const std::array<Eigen::Vector3d, 2>& edge) const;
135 virtual bool is_outside(const std::array<Eigen::Vector2d, 2>& edge) const;
136 virtual bool is_outside(const Eigen::Vector3d& pts) const;
137 virtual bool is_outside(const Eigen::Vector2d& pts) const;
138 double nearest_point(const Eigen::Vector3d& pts, Eigen::Vector3d& result) const;
139 double nearest_point(const Eigen::Vector2d& pts, Eigen::Vector2d& result) const;
140
152 const Eigen::Vector2d& p,
153 Eigen::Vector2d& result,
154 bool& on_corner,
155 Eigen::Vector2d& seg_normal,
156 int& feature_id) const;
157
166 const Eigen::Vector3d& p,
167 Eigen::Vector3d& result,
168 int& feature_dim,
169 Eigen::Vector3d& dir,
170 long long& feature_id) const;
171 bool initialized() { return m_bvh != nullptr; };
172
173 Kind kind() const { return m_kind; }
174
175 double squared_distance(const Eigen::Vector3d& p) const;
176 double squared_distance(const Eigen::Vector2d& p) const;
177
178 // Per-primitive queries, for a caller that needs the distance d_i to each input primitive i
179 // on its own rather than to their union: each d_i is convex (the distance to a convex set),
180 // and the min over i is not, so a bound that rests on convexity needs the pieces.
181 //
182 // A primitive is one entry of the list given to init(), and its id is its index in that
183 // list: a triangle for Triangles3d, a segment for Edges3d and Edges2d -- including the
184 // degenerate (i, i) entries that stand for isolated points. squared_distance(), and
185 // nearest_point(), which returns the same squared distance, is the square of the min over
186 // all primitives of primitive_distance(), up to rounding: the BVH computes its own foot point
187 // with different arithmetic.
188 //
189 // Each query comes in the dimension of the init() that built the envelope: the 3D ones on
190 // Triangles3d and Edges3d, the 2D ones on Edges2d. Either asked of the other kind, or of an
191 // envelope no init() has filled in, throws rather than answering against the wrong copy of
192 // the input or dereferencing an empty BVH.
193
207 const Eigen::Vector3d& lo,
208 const Eigen::Vector3d& hi,
209 std::vector<int64_t>& ids) const;
212 const Eigen::Vector2d& lo,
213 const Eigen::Vector2d& hi,
214 std::vector<int64_t>& ids) const;
215
231 double primitive_distance(
232 int64_t id,
233 const Eigen::Vector3d& p,
234 Eigen::Vector3d* grad = nullptr,
235 Eigen::Matrix3d* hess = nullptr) const;
242 double primitive_distance(
243 int64_t id,
244 const Eigen::Vector2d& p,
245 Eigen::Vector2d* grad = nullptr,
246 Eigen::Matrix2d* hess = nullptr) const;
247
262 double primitive_triangle_distance(int64_t id, const std::array<Eigen::Vector3d, 3>& tri) const;
263
274 double primitive_segment_distance(int64_t id, const std::array<Eigen::Vector2d, 2>& seg) const;
275
276private:
279 void require_primitive_query(int dim, const char* query) const;
280 void require_primitive(int64_t id, int dim, const char* query) const;
281 void require_exact_kind(Kind expected, const char* query) const;
282 void require_exact_3d(const char* query) const;
283 void require_exact_built(const char* query) const;
284
285 template <typename VertexList>
286 void
287 init_exact_edges(const VertexList& V, const std::vector<Eigen::Vector2i>& F, const double _eps);
288
289 std::vector<int> geo_vertex_ind;
290 std::vector<int> geo_face_ind;
292 std::vector<Eigen::Vector2d> m_v2;
293 std::vector<Eigen::Vector2i> m_e2;
294 std::vector<Eigen::Vector3d> m_v3;
295 std::vector<Eigen::Vector3i> m_f3;
296 std::vector<Eigen::Vector2i> m_e3;
297 std::shared_ptr<SimpleBVH::BVH> m_bvh;
298
299private:
301 fastEnvelope::FastEnvelope exact_envelope;
303 fastEnvelope::FastEnvelope2D exact_envelope_2d;
304 Kind m_kind = Kind::Uninitialized;
307 bool m_exact_built = false;
308
311 bool samples_outside_parallel(const std::vector<Eigen::Vector3d>& ps) const;
312};
313} // namespace wmtk
Definition Envelope.hpp:19
double primitive_segment_distance(int64_t id, const std::array< Eigen::Vector2d, 2 > &seg) const
The 2D counterpart, for Edges2d: the distance between the segment seg and primitive id alone – a 2D f...
Definition Envelope.cpp:1104
void primitives_in_box(const Eigen::Vector3d &lo, const Eigen::Vector3d &hi, std::vector< int64_t > &ids) const
The ids of every primitive whose bounding box meets the closed box [lo, hi], ascending,...
Definition Envelope.cpp:991
bool m_exact_built
Definition Envelope.hpp:307
fastEnvelope::FastEnvelope exact_envelope
Serves both Triangles3d and Edges3d: FastEnvelope has an init() for each.
Definition Envelope.hpp:301
void init_exact_edges(const VertexList &V, const std::vector< Eigen::Vector2i > &F, const double _eps)
Definition Envelope.cpp:154
Envelope(bool exact=true)
Definition Envelope.hpp:39
fastEnvelope::FastEnvelope2D exact_envelope_2d
Edges2d only. A separate class upstream, not an overload.
Definition Envelope.hpp:303
void set_max_threads(int n)
How many threads one triangle query may use. 1, the default: every sample is checked on the calling t...
Definition Envelope.hpp:84
void require_exact_kind(Kind expected, const char *query) const
Definition Envelope.cpp:321
void require_exact_3d(const char *query) const
Definition Envelope.cpp:337
double eps2
Definition Envelope.hpp:50
double nearest_point_feature(const Eigen::Vector2d &p, Eigen::Vector2d &result, bool &on_corner, Eigen::Vector2d &seg_normal, int &feature_id) const
Definition Envelope.cpp:565
bool samples_outside_parallel(const std::vector< Eigen::Vector3d > &ps) const
The sampled triangle query's loop over ps, split among idle workers.
Definition Envelope.cpp:391
double primitive_distance(int64_t id, const Eigen::Vector3d &p, Eigen::Vector3d *grad=nullptr, Eigen::Matrix3d *hess=nullptr) const
The distance d from p to primitive id alone, with its gradient and Hessian when asked for (nullptr = ...
Definition Envelope.cpp:1017
double primitive_triangle_distance(int64_t id, const std::array< Eigen::Vector3d, 3 > &tri) const
The distance between the triangle tri and primitive id alone.
Definition Envelope.cpp:1051
bool disabled
Definition Envelope.hpp:100
int m_max_threads
Definition Envelope.hpp:309
virtual bool is_outside(const std::array< Eigen::Vector3d, 3 > &tris) const
Definition Envelope.cpp:434
void require_primitive_query(int dim, const char *query) const
Definition Envelope.cpp:962
Kind
Definition Envelope.hpp:31
double eps2_edge
Definition Envelope.hpp:70
std::vector< Eigen::Vector2d > m_v2
Input copies backing nearest_point_feature (filled by the matching init only).
Definition Envelope.hpp:292