Wildmeshing Toolkit
Loading...
Searching...
No Matches
volume_geometry.hpp
1#pragma once
2
3#include "volume_complex.hpp"
4
5#include <Eigen/Core>
6
7#include <map>
8#include <optional>
9#include <vector>
10
14
17using Positions = std::vector<Eigen::Vector3d>;
18
20int orient(
21 const Eigen::Vector3d& a,
22 const Eigen::Vector3d& b,
23 const Eigen::Vector3d& c,
24 const Eigen::Vector3d& d);
25
27bool inside(
28 const Eigen::Vector3d& p,
29 const Eigen::Vector3d& a,
30 const Eigen::Vector3d& b,
31 const Eigen::Vector3d& c,
32 const Eigen::Vector3d& d);
36Eigen::Vector4d barycentric(
37 const Eigen::Vector3d& p,
38 const Eigen::Vector3d& a,
39 const Eigen::Vector3d& b,
40 const Eigen::Vector3d& c,
41 const Eigen::Vector3d& d);
44Eigen::Vector4d exact_barycentric(
45 const Eigen::Vector3d& p,
46 const Eigen::Vector3d& a,
47 const Eigen::Vector3d& b,
48 const Eigen::Vector3d& c,
49 const Eigen::Vector3d& d);
52struct Outside
53{
54 int faces = 0;
55 double distance = 0; // the largest
56};
57Outside outside_of(
58 const Eigen::Vector3d& p,
59 const Eigen::Vector3d& a,
60 const Eigen::Vector3d& b,
61 const Eigen::Vector3d& c,
62 const Eigen::Vector3d& d);
71{
72 size_t tet;
73 Eigen::Vector4d b;
74 double min_coordinate;
75};
76template <typename Accept>
77std::optional<Location>
78locate_in(const Tets& T, const Positions& X, const Eigen::Vector3d& p, const Accept& accept)
79{
80 if (!p.allFinite()) return std::nullopt;
81 std::vector<size_t> within_rounding;
82 for (size_t k = 0; k < T.size(); ++k) {
83 if (!accept(k)) continue;
84 const auto& t = T[k];
85 // only a tet whose box (grown by a rounding) holds p can hold it or be a rounding off
86 Eigen::Vector3d lo = X[t[0]], hi = lo;
87 for (int c = 1; c < 4; ++c) {
88 lo = lo.cwiseMin(X[t[c]]);
89 hi = hi.cwiseMax(X[t[c]]);
90 }
91 const double size = (hi - lo).norm(), eps = 1e-9 * size;
92 if (((p.array() < lo.array() - eps) || (p.array() > hi.array() + eps)).any()) continue;
93 const Outside o = outside_of(p, X[t[0]], X[t[1]], X[t[2]], X[t[3]]);
94 if (o.faces == 0) {
95 Eigen::Vector4d b = barycentric(p, X[t[0]], X[t[1]], X[t[2]], X[t[3]]);
96 if (!(b.minCoeff() >= -1e-9 && b.maxCoeff() <= 1 + 1e-9)) {
97 b = exact_barycentric(p, X[t[0]], X[t[1]], X[t[2]], X[t[3]]);
98 }
99 b = b.cwiseMax(0.);
100 return Location{k, b / b.sum(), 0.};
101 }
102 if (o.distance <= eps) within_rounding.push_back(k);
103 }
104 std::optional<Location> out;
105 if (!within_rounding.empty()) {
106 for (const size_t k : within_rounding) {
107 const auto& t = T[k];
108 const Eigen::Vector4d b = exact_barycentric(p, X[t[0]], X[t[1]], X[t[2]], X[t[3]]);
109 if (!out || b.minCoeff() > out->min_coordinate) out = Location{k, b, b.minCoeff()};
110 }
111 }
112 if (out) {
113 out->b = out->b.cwiseMax(0.);
114 out->b /= out->b.sum();
115 }
116 return out;
117}
118
124{
125public:
127 static std::optional<StarPatch> make(const Tets& T, const Positions& P);
128
129 const Tets& tets() const { return m_T; }
130 const Positions& positions() const { return m_P; }
132 const std::vector<Tri>& faces() const { return m_F; }
134 double scale() const { return m_scale; }
136 std::optional<Vid> boundary_apex() const;
138 std::optional<Vid> interior_apex() const;
139
141 bool sees_all(const Eigen::Vector3d& s) const;
143 bool set_centre(const Eigen::Vector3d& s);
144 const Eigen::Vector3d& centre() const { return m_s; }
146 double margin() const;
147
150 struct Exit
151 {
152 size_t face;
153 Eigen::Vector3d w;
154 double t;
155 };
156 Exit exit(const Eigen::Vector3d& x) const;
159 struct Located
160 {
161 size_t tet;
162 Eigen::Vector4d b;
163 };
164 Located locate(const Eigen::Vector3d& y) const;
166 std::optional<size_t> index_of(const Tet& t) const;
168 size_t bytes() const;
169
171 std::vector<Eigen::Vector3d> normals, corners;
172
173private:
174 Tets m_T;
175 Positions m_P;
176 std::vector<Tri> m_F, m_Fo;
177 std::vector<std::pair<Tet, uint32_t>> m_index; // by sorted vertices, sorted
178 double m_scale = 0;
179 Eigen::Vector3d m_s = Eigen::Vector3d::Zero();
180};
181
188std::optional<std::pair<Eigen::Vector3d, double>> chebyshev(
189 const std::vector<Eigen::Vector3d>& N,
190 const std::vector<double>& b,
191 const Eigen::Vector3d& x0,
192 double L,
193 double t_max);
194
197std::optional<Eigen::Vector3d> kernel(const std::vector<const StarPatch*>& patches);
200std::optional<Eigen::Vector3d> apex_centre(const StarPatch& S);
203std::optional<Eigen::Vector3d> centre_of(const StarPatch& S, bool* thin = nullptr);
204
215std::optional<Positions> spherical(const Tets& T, const Positions& P, double fat = 0.05);
219std::optional<Positions> bowl(const Tets& T, const Positions& P);
222std::optional<Positions> convex(const Tets& T, const Positions& P);
223
224} // namespace wmtk::components::tracking::volume
Tets embedded with every one the same way round, and a centre that sees every boundary face from insi...
Definition volume_geometry.hpp:124
bool set_centre(const Eigen::Vector3d &s)
Sets the centre; false (and nothing set) if it does not see every face.
Definition volume_geometry.cpp:219
double scale() const
The diameter of the patch's bounding box.
Definition volume_geometry.hpp:134
static std::optional< StarPatch > make(const Tets &T, const Positions &P)
Nothing if a tet is flat, or the tets are not all the same way round (exactly).
Definition volume_geometry.cpp:143
std::vector< Eigen::Vector3d > normals
The outward normal and a corner of each face (the plane is n.(x - a) = 0).
Definition volume_geometry.hpp:171
std::optional< Vid > interior_apex() const
The vertex every tet shares, inside the patch (the star of a vertex).
Definition volume_geometry.cpp:201
bool sees_all(const Eigen::Vector3d &s) const
Whether s is strictly inside every boundary face's plane, exactly.
Definition volume_geometry.cpp:211
std::optional< Vid > boundary_apex() const
Whether every vertex is the apex of a cone: shared by every tet and on the boundary.
Definition volume_geometry.cpp:191
std::optional< size_t > index_of(const Tet &t) const
The index in tets() of a tet given by its vertices, any order.
Definition volume_geometry.cpp:285
const std::vector< Tri > & faces() const
The boundary faces, sorted, and the same faces oriented outwards.
Definition volume_geometry.hpp:132
size_t bytes() const
About the memory it holds, in bytes.
Definition volume_geometry.cpp:183
double margin() const
The centre's distance to the nearest face plane, over scale().
Definition volume_geometry.cpp:226
Definition volume_complex.cpp:8
std::optional< Positions > bowl(const Tets &T, const Positions &P)
Definition volume_geometry.cpp:961
Eigen::Vector4d barycentric(const Eigen::Vector3d &p, const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c, const Eigen::Vector3d &d)
Definition volume_geometry.cpp:42
std::optional< Eigen::Vector3d > centre_of(const StarPatch &S, bool *thin)
Definition volume_geometry.cpp:434
bool inside(const Eigen::Vector3d &p, const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c, const Eigen::Vector3d &d)
Whether p is in the closed tet (a, b, c, d), exactly.
Definition volume_geometry.cpp:29
Eigen::Vector4d exact_barycentric(const Eigen::Vector3d &p, const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c, const Eigen::Vector3d &d)
Definition volume_geometry.cpp:84
std::optional< std::pair< Eigen::Vector3d, double > > chebyshev(const std::vector< Eigen::Vector3d > &N, const std::vector< double > &b, const Eigen::Vector3d &x0, const double L, const double t_max)
max t subject to N_i . x + t <= b_i, |x - x0|_inf <= L and t <= t_max, by a dense simplex: the larges...
Definition volume_geometry.cpp:351
int orient(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c, const Eigen::Vector3d &d)
The sign of det(b - a, c - a, d - a), exactly.
Definition volume_geometry.cpp:18
std::optional< Positions > spherical(const Tets &T, const Positions &P, const double fat)
A fallback embedding of a cone from a boundary apex c: every vertex keeps its distance from c,...
Definition volume_geometry.cpp:681
std::vector< Eigen::Vector3d > Positions
Definition volume_geometry.hpp:17
std::optional< Eigen::Vector3d > apex_centre(const StarPatch &S)
Definition volume_geometry.cpp:413
std::optional< Positions > convex(const Tets &T, const Positions &P)
Definition volume_geometry.cpp:1014
std::optional< Eigen::Vector3d > kernel(const std::vector< const StarPatch * > &patches)
Definition volume_geometry.cpp:384
Definition volume_geometry.hpp:71
Definition volume_geometry.hpp:53
Definition volume_geometry.hpp:151