Wildmeshing Toolkit
Loading...
Searching...
No Matches
Sphere.hpp
1#pragma once
2#include <igl/barycentric_coordinates.h>
3#include <igl/point_mesh_squared_distance.h>
4#include <queue>
5#include "TopoOffsetTetMesh.h"
6
7
8namespace wmtk::components::topological_offset {
9
10
11class Sphere
12{
13private:
14 Vector3d m_c;
15 double m_r;
16
17public:
21 static void fit_cube(
22 const Vector3d& p1,
23 const Vector3d& p2,
24 const Vector3d& p3,
25 const Vector3d& p4,
26 Vector3d& c,
27 double& l)
28 {
29 MatrixXd V(4, 3);
30 V.row(0) = p1;
31 V.row(1) = p2;
32 V.row(2) = p3;
33 V.row(3) = p4;
34 Eigen::RowVectorXd mins = V.colwise().minCoeff();
35 Eigen::RowVectorXd maxs = V.colwise().maxCoeff();
36 double x_span = maxs(0) - mins(0);
37 double y_span = maxs(1) - mins(1);
38 double z_span = maxs(2) - mins(2);
39 if (x_span > y_span && x_span > z_span) {
40 l = x_span;
41 } else if (y_span > z_span) {
42 l = y_span;
43 } else {
44 l = z_span;
45 }
46 c(0) = (maxs(0) + mins(0)) / 2.0;
47 c(1) = (maxs(1) + mins(1)) / 2.0;
48 c(2) = (maxs(2) + mins(2)) / 2.0;
49 }
50
51 Sphere(const Vector3d& c, const double r)
52 : m_c(c)
53 , m_r(r)
54 {}
55
56 Sphere(const TopoOffsetTetMesh& mesh, const size_t t_id)
57 {
58 auto vs = mesh.oriented_tet_vids(t_id);
59 double side_length;
60 Vector3d center;
62 mesh.m_vertex_attribute[vs[0]].m_posf,
63 mesh.m_vertex_attribute[vs[1]].m_posf,
64 mesh.m_vertex_attribute[vs[2]].m_posf,
65 mesh.m_vertex_attribute[vs[3]].m_posf,
66 center,
67 side_length);
68 m_c(0) = center(0);
69 m_c(1) = center(1);
70 m_c(2) = center(2);
71 m_r = side_length * sqrt(3.0) / 2.0;
72 }
73
77 double radius() const { return m_r; }
78
82 Vector3d center() const { return m_c; }
83
87 void refine(std::queue<Sphere>& q) const
88 {
89 double c_off_l = m_r / (sqrt(3.0) * 2.0);
90 double new_r = m_r / 2.0;
91 q.emplace(m_c + (c_off_l * Vector3d(-1, -1, -1)), new_r);
92 q.emplace(m_c + (c_off_l * Vector3d(-1, -1, 1)), new_r);
93 q.emplace(m_c + (c_off_l * Vector3d(-1, 1, -1)), new_r);
94 q.emplace(m_c + (c_off_l * Vector3d(-1, 1, 1)), new_r);
95 q.emplace(m_c + (c_off_l * Vector3d(1, -1, -1)), new_r);
96 q.emplace(m_c + (c_off_l * Vector3d(1, -1, 1)), new_r);
97 q.emplace(m_c + (c_off_l * Vector3d(1, 1, -1)), new_r);
98 q.emplace(m_c + (c_off_l * Vector3d(1, 1, 1)), new_r);
99 }
100
104 bool overlaps_tet(const TopoOffsetTetMesh& mesh, const size_t t_id) const
105 {
106 auto vs = mesh.oriented_tet_vids(t_id);
107 MatrixXd V(4, 3);
108 V.row(0) = mesh.m_vertex_attribute[vs[0]].m_posf;
109 V.row(1) = mesh.m_vertex_attribute[vs[1]].m_posf;
110 V.row(2) = mesh.m_vertex_attribute[vs[2]].m_posf;
111 V.row(3) = mesh.m_vertex_attribute[vs[3]].m_posf;
112
113 MatrixXi F(4, 3);
114 F << 0, 2, 1, 0, 1, 3, 1, 2, 3, 0, 3, 2;
115
116 MatrixXd P(1, 3);
117 P.row(0) = m_c;
118
119 // check if sphere center inside tet (if so, there is overlap)
120 MatrixXd L;
121 igl::barycentric_coordinates(P, V.row(0), V.row(1), V.row(2), V.row(3), L);
122 bool in_tet = (L.array() >= 1e-6).all();
123 if (in_tet) {
124 return true;
125 }
126
127 // center not in tet, compute min distance to faces
128 VectorXd sqr_dists;
129 VectorXi I;
130 MatrixXd C_closest;
131 igl::point_mesh_squared_distance(P, V, F, sqr_dists, I, C_closest);
132 return (sqr_dists(0) < (m_r * m_r));
133 }
134};
135
136
137} // namespace wmtk::components::topological_offset
std::array< size_t, 4 > oriented_tet_vids(const Tuple &t) const
Definition TetMesh.cpp:656
bool overlaps_tet(const TopoOffsetTetMesh &mesh, const size_t t_id) const
check if a sphere overlaps given tet
Definition Sphere.hpp:104
static void fit_cube(const Vector3d &p1, const Vector3d &p2, const Vector3d &p3, const Vector3d &p4, Vector3d &c, double &l)
given 3D tet, fit cube to tet (return center and side length)
Definition Sphere.hpp:21
void refine(std::queue< Sphere > &q) const
add refinements of sphere to given queue
Definition Sphere.hpp:87
double radius() const
get radius of sphere
Definition Sphere.hpp:77
Vector3d center() const
get center of sphere
Definition Sphere.hpp:82