3#include <igl/predicates/predicates.h>
6#include <wmtk/utils/Logger.hpp>
7#include <wmtk/utils/Rational.hpp>
12using MatrixX = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
14using MatrixXd = MatrixX<double>;
15using MatrixXi = MatrixX<int>;
16using MatrixXr = MatrixX<Rational>;
17using Matrix2d = Eigen::Matrix2d;
18using Matrix3d = Eigen::Matrix3d;
19using Matrix4d = Eigen::Matrix4d;
22using MatrixS = Eigen::SparseMatrix<T>;
24using MatrixSi = MatrixS<int>;
25using MatrixSd = MatrixS<double>;
27template <
typename T,
int R>
28using Vector = Eigen::Matrix<T, R, 1>;
30using VectorX = Vector<T, Eigen::Dynamic>;
32using Vector2d = Vector<double, 2>;
33using Vector3d = Vector<double, 3>;
34using Vector4d = Vector<double, 4>;
35using VectorXd = Vector<double, Eigen::Dynamic>;
37using Vector2r = Vector<Rational, 2>;
38using Vector3r = Vector<Rational, 3>;
40using Vector2i = Vector<int, 2>;
41using Vector3i = Vector<int, 3>;
42using Vector4i = Vector<int, 4>;
43using VectorXi = Vector<int, Eigen::Dynamic>;
46using VectorS = Eigen::SparseVector<T>;
48using VectorSi = VectorS<int>;
49using VectorSd = VectorS<double>;
51inline Vector3r to_rational(
const Vector3d& p0)
53 Vector3r p(p0[0], p0[1], p0[2]);
57inline Vector3d to_double(
const Vector3r& p0)
59 Vector3d p(p0[0].to_double(), p0[1].to_double(), p0[2].to_double());
63inline Vector4d to_homogenuous(
const Vector3d& x)
65 return Vector4d(x[0], x[1], x[2], 1);
68inline Vector3d from_homogenuous(
const Vector4d& x)
70 return Vector3d(x[0] / x[3], x[1] / x[3], x[2] / x[3]);
73using V_MAP = Eigen::Map<
const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>>;
74using F_MAP = Eigen::Map<
const Eigen::Matrix<int, -1, -1, Eigen::RowMajor>>;
76inline void vectors_to_VF(
77 const std::vector<Vector3d>& vertices,
78 const std::vector<std::array<size_t, 3>>& faces,
82 V.resize(vertices.size(), 3);
83 F.resize(faces.size(), 3);
85 for (
int i = 0; i < V.rows(); i++) {
86 V.row(i) = vertices[i];
88 for (
int i = 0; i < F.rows(); i++) {
89 F.row(i) = Vector3i((
int)faces[i][0], (
int)faces[i][1], (
int)faces[i][2]);
93inline void VF_to_vectors(
96 std::vector<Vector3d>& vertices,
97 std::vector<std::array<size_t, 3>>& faces)
99 vertices.resize(V.rows());
100 faces.resize(F.rows());
102 for (
int i = 0; i < V.rows(); i++) {
103 vertices[i] = V.row(i);
105 for (
int i = 0; i < F.rows(); i++) {
106 faces[i][0] = F(i, 0);
107 faces[i][1] = F(i, 1);
108 faces[i][2] = F(i, 2);
113tet_is_inverted(
const Vector3d& v0,
const Vector3d& v1,
const Vector3d& v2,
const Vector3d& v3)
115 igl::predicates::exactinit();
116 auto res = igl::predicates::orient3d(v0, v1, v2, v3);
118 if (res == igl::predicates::Orientation::POSITIVE)
120 else if (res == igl::predicates::Orientation::NEGATIVE)
130inline bool tri_is_inverted(
const Vector2d& v0,
const Vector2d& v1,
const Vector2d& v2)
132 igl::predicates::exactinit();
133 auto res = igl::predicates::orient2d(v0, v1, v2);
135 if (res == igl::predicates::Orientation::POSITIVE)
137 else if (res == igl::predicates::Orientation::NEGATIVE)
152inline bool VF_rational_to_double(
const MatrixXr& V_in,
const MatrixXi& F, MatrixXd& V_out)
154 V_out.resizeLike(V_in);
155 for (
int i = 0; i < V_in.size(); ++i) {
156 V_out(i) = V_in(i).to_double();
162 for (
int i = 0; i < F.rows(); ++i) {
163 const auto& s = F.row(i);
164 if (tri_is_inverted(V_out.row(s[0]), V_out.row(s[1]), V_out.row(s[2]))) {
168 }
else if (F.cols() == 4) {
170 for (
int i = 0; i < F.rows(); ++i) {
171 const auto& s = F.row(i);
181 log_and_throw_error(
"Unknown dimension in VF_rational_to_double");
191struct fmt::formatter<
194 std::is_base_of_v<Eigen::DenseBase<T>, T> && !fmt::is_range<T, char>::value,
195 char>> : ostream_formatter