11 bool apply_slim(
const Eigen::MatrixXd &
V,
const Eigen::MatrixXi &
F,
const Eigen::MatrixXd &V_new, Eigen::MatrixXd &V_smooth,
const int max_iters)
13 const int dim =
F.cols() - 1;
21 Eigen::MatrixXd V_extended;
22 V_extended.setZero(
V.rows(), 3);
23 V_extended.leftCols(dim) =
V;
25 Eigen::VectorXi boundary_indices;
27 Eigen::MatrixXi boundary;
28 igl::boundary_facets(
F, boundary);
29 std::set<int> slim_constrained_nodes;
30 for (
int i = 0; i < boundary.rows(); ++i)
31 for (
int j = 0; j < boundary.cols(); ++j)
32 slim_constrained_nodes.insert(boundary(i, j));
35 boundary_indices.setZero(slim_constrained_nodes.size());
37 for (
const auto &c : slim_constrained_nodes)
38 boundary_indices(i++) = c;
41 const double soft_const_p = 1e5;
42 const int slim_iters = 2;
43 const double tol = 1e-8;
45 const Eigen::MatrixXd boundary_constraints = V_new(boundary_indices, Eigen::all);
47 igl::SLIMData slim_data;
48 slim_data.exp_factor = 5;
54 igl::SYMMETRIC_DIRICHLET,
59 V_smooth.setZero(
V.rows(),
V.cols());
63 bool good_enough =
false;
67 igl::slim_solve(slim_data, slim_iters);
68 error = (slim_data.V_o(boundary_indices, Eigen::all) - boundary_constraints).squaredNorm() / boundary_indices.size();
69 good_enough = error < 1e-7;
70 V_smooth = slim_data.V_o.leftCols(dim);
72 }
while (it < max_iters && !good_enough);
74 V_smooth(boundary_indices, Eigen::all) = boundary_constraints;
75 logger().debug(
"SLIM finished in {} iterations", it);
78 logger().debug(
"SLIM succeeded.");
80 logger().warn(
"SLIM cannot smooth correctly. Error: {}", error);