5#include <geogram/mesh/mesh_io.h>
6#include <igl/writeMESH.h>
8#include <boost/filesystem.hpp>
22#ifdef POLYFEM_WITH_MMG
25 const int max_num_quadrature_points = 2048;
27 bool mmg_remesh_volume(
const Eigen::MatrixXd &
V,
const Eigen::MatrixXi &
F,
const Eigen::MatrixXi &T,
28 Eigen::MatrixXd &TV, Eigen::MatrixXi &TF, Eigen::MatrixXi &TT)
30 using namespace boost;
32 double scaling = (
V.colwise().maxCoeff() -
V.colwise().minCoeff()).maxCoeff();
33 Eigen::RowVector3d translation =
V.colwise().minCoeff();
35 auto tmp_dir = filesystem::temp_directory_path();
36 auto base_path = tmp_dir / filesystem::unique_path(
"polyfem_%%%%-%%%%-%%%%-%%%%");
37 auto f_input = base_path;
38 f_input +=
"_in.mesh";
39 auto f_output = base_path;
40 f_output +=
"_out.mesh";
41 auto f_sol = base_path;
44 TV = (
V.rowwise() - translation) / scaling;
45 igl::writeMESH(f_input.string(), TV, T,
F);
47 std::string app(POLYFEM_MMG_PATH);
48 std::string cmd = app +
" -ar 20 -hausd 0.01 -v 0 -in " + f_input.string() +
" -out " + f_output.string();
50 cmd +=
" &> /dev/null";
52 std::cout <<
"Running command:\n" + cmd << std::endl;
53 if (::system(cmd.c_str()) == 0)
56 GEO::mesh_load(f_output.string(), M);
58 TV = (scaling * TV).rowwise() + translation;
60 filesystem::remove(f_input);
61 filesystem::remove(f_output);
62 filesystem::remove(f_sol);
67 filesystem::remove(f_input);
74 template <
class TriMat>
75 double transform_pts(
const TriMat &tri,
const Eigen::MatrixXd &pts, Eigen::MatrixXd &transformed)
77 Eigen::Matrix3d matrix;
78 matrix.row(0) = tri.row(1) - tri.row(0);
79 matrix.row(1) = tri.row(2) - tri.row(0);
80 matrix.row(2) = tri.row(3) - tri.row(0);
82 transformed = pts * matrix;
84 transformed.col(0).array() += tri(0, 0);
85 transformed.col(1).array() += tri(0, 1);
86 transformed.col(2).array() += tri(0, 2);
88 return matrix.determinant();
96 const Eigen::RowVector3d &kernel,
const int order,
Quadrature &quadr)
98 std::string flags =
"Qpq2.0";
100 Eigen::MatrixXd VV, OV, TV;
101 Eigen::MatrixXi OF, TF, tets;
108 double scaling = (
V.colwise().maxCoeff() -
V.colwise().minCoeff()).maxCoeff();
109 Eigen::RowVector3d translation =
V.colwise().minCoeff();
113#ifdef POLYFEM_WITH_MMG
114 if (tet_quadr_pts.
weights.size() * tets.rows() > max_num_quadrature_points)
117 Eigen::MatrixXi F0, T0;
118 bool res = mmg_remesh_volume(TV, TF, tets,
V0, F0, T0);
125 if (res && T0.rows() < tets.rows())
162 const long offset = tet_quadr_pts.
weights.rows();
163 quadr.
points.resize(tets.rows() * offset, 3);
164 quadr.
weights.resize(tets.rows() * offset, 1);
166 Eigen::MatrixXd transformed_points;
168 for (
long i = 0; i < tets.rows(); ++i)
170 Eigen::Matrix<double, 4, 3> tetra;
171 const auto &indices = tets.row(i);
172 tetra.row(0) = TV.row(indices(0));
173 tetra.row(1) = TV.row(indices(1));
174 tetra.row(2) = TV.row(indices(2));
175 tetra.row(3) = TV.row(indices(3));
181 const double det = transform_pts(tetra, tet_quadr_pts.
points, transformed_points);
184 quadr.
points.block(i * offset, 0, transformed_points.rows(), transformed_points.cols()) = transformed_points;
static void get_quadrature(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, const Eigen::RowVector3d &kernel, const int order, Quadrature &quadr)
Gets the quadrature points & weights for a polyhedron.
void get_quadrature(const int order, Quadrature &quad)
void from_geogram_mesh(const GEO::Mesh &M, Eigen::MatrixXd &V, Eigen::MatrixXi &F, Eigen::MatrixXi &T)
Extract simplices from a Geogram mesh.
void tertrahedralize_star_shaped_surface(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, const Eigen::RowVector3d &kernel, Eigen::MatrixXd &OV, Eigen::MatrixXi &OF, Eigen::MatrixXi &OT)
Tetrahedralize a star-shaped mesh, with a given point in its kernel.