|
@@ -332,7 +332,7 @@ IGL_INLINE double compute_soft_constraint_energy(const SCAFData &s)
|
|
|
return e;
|
|
return e;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-IGL_INLINE double compute_energy(SCAFData &s, Eigen::MatrixXd &w_uv, bool whole)
|
|
|
|
|
|
|
+IGL_INLINE double compute_energy(SCAFData &s, const Eigen::MatrixXd &w_uv, bool whole)
|
|
|
{
|
|
{
|
|
|
if (w_uv.rows() != s.v_num)
|
|
if (w_uv.rows() != s.v_num)
|
|
|
assert(!whole);
|
|
assert(!whole);
|
|
@@ -529,6 +529,30 @@ IGL_INLINE void build_scaffold_linear_system(const SCAFData &s, Eigen::SparseMat
|
|
|
rhs = Aut * (frhs - Ae * known_pos);
|
|
rhs = Aut * (frhs - Ae * known_pos);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+IGL_INLINE void build_weighted_arap_system(SCAFData &s, Eigen::SparseMatrix<double> &L, Eigen::VectorXd &rhs)
|
|
|
|
|
+{
|
|
|
|
|
+ // fixed frame solving:
|
|
|
|
|
+ // x_e as the fixed frame, x_u for unknowns (mesh + unknown scaffold)
|
|
|
|
|
+ // min ||(A_u*x_u + A_e*x_e) - b||^2
|
|
|
|
|
+ // => A_u'*A_u*x_u = Au'* (b - A_e*x_e) := Au'* b_u
|
|
|
|
|
+ //
|
|
|
|
|
+ // separate matrix build:
|
|
|
|
|
+ // min ||A_m x_m - b_m||^2 + ||A_s x_all - b_s||^2 + soft + proximal
|
|
|
|
|
+ // First change dimension of A_m to fit for x_all
|
|
|
|
|
+ // (Not just at the end, since x_all is flattened along dimensions)
|
|
|
|
|
+ // L = A_m'*A_m + A_s'*A_s + soft + proximal
|
|
|
|
|
+ // rhs = A_m'* b_m + A_s' * b_s + soft + proximal
|
|
|
|
|
+ //
|
|
|
|
|
+ Eigen::SparseMatrix<double> L_m, L_s;
|
|
|
|
|
+ Eigen::VectorXd rhs_m, rhs_s;
|
|
|
|
|
+ build_surface_linear_system(s, L_m, rhs_m); // complete Am, with soft
|
|
|
|
|
+ build_scaffold_linear_system(s, L_s, rhs_s); // complete As, without proximal
|
|
|
|
|
+
|
|
|
|
|
+ L = L_m + L_s;
|
|
|
|
|
+ rhs = rhs_m + rhs_s;
|
|
|
|
|
+ L.makeCompressed();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
IGL_INLINE void solve_weighted_arap(SCAFData &s, Eigen::MatrixXd &uv)
|
|
IGL_INLINE void solve_weighted_arap(SCAFData &s, Eigen::MatrixXd &uv)
|
|
|
{
|
|
{
|
|
|
using namespace Eigen;
|
|
using namespace Eigen;
|
|
@@ -562,27 +586,7 @@ IGL_INLINE void solve_weighted_arap(SCAFData &s, Eigen::MatrixXd &uv)
|
|
|
|
|
|
|
|
Eigen::SparseMatrix<double> L;
|
|
Eigen::SparseMatrix<double> L;
|
|
|
Eigen::VectorXd rhs;
|
|
Eigen::VectorXd rhs;
|
|
|
-
|
|
|
|
|
- // fixed frame solving:
|
|
|
|
|
- // x_e as the fixed frame, x_u for unknowns (mesh + unknown scaffold)
|
|
|
|
|
- // min ||(A_u*x_u + A_e*x_e) - b||^2
|
|
|
|
|
- // => A_u'*A_u*x_u = Au'* (b - A_e*x_e) := Au'* b_u
|
|
|
|
|
- //
|
|
|
|
|
- // separate matrix build:
|
|
|
|
|
- // min ||A_m x_m - b_m||^2 + ||A_s x_all - b_s||^2 + soft + proximal
|
|
|
|
|
- // First change dimension of A_m to fit for x_all
|
|
|
|
|
- // (Not just at the end, since x_all is flattened along dimensions)
|
|
|
|
|
- // L = A_m'*A_m + A_s'*A_s + soft + proximal
|
|
|
|
|
- // rhs = A_m'* b_m + A_s' * b_s + soft + proximal
|
|
|
|
|
- //
|
|
|
|
|
- Eigen::SparseMatrix<double> L_m, L_s;
|
|
|
|
|
- Eigen::VectorXd rhs_m, rhs_s;
|
|
|
|
|
- build_surface_linear_system(s, L_m, rhs_m); // complete Am, with soft
|
|
|
|
|
- build_scaffold_linear_system(s, L_s, rhs_s); // complete As, without proximal
|
|
|
|
|
-
|
|
|
|
|
- L = L_m + L_s;
|
|
|
|
|
- rhs = rhs_m + rhs_s;
|
|
|
|
|
- L.makeCompressed();
|
|
|
|
|
|
|
+ build_weighted_arap_system(s, L, rhs);
|
|
|
|
|
|
|
|
Eigen::VectorXd unknown_Uc((v_n - s.frame_ids.size() - s.fixed_ids.size()) * dim), Uc(dim * v_n);
|
|
Eigen::VectorXd unknown_Uc((v_n - s.frame_ids.size() - s.fixed_ids.size()) * dim), Uc(dim * v_n);
|
|
|
|
|
|
|
@@ -612,6 +616,7 @@ IGL_INLINE double perform_iteration(SCAFData &s)
|
|
|
whole_E, -1) /
|
|
whole_E, -1) /
|
|
|
s.mesh_measure;
|
|
s.mesh_measure;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -702,5 +707,24 @@ IGL_INLINE Eigen::MatrixXd igl::scaf_solve(SCAFData &s, int iter_num)
|
|
|
return s.w_uv.topRows(s.mv_num);
|
|
return s.w_uv.topRows(s.mv_num);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+IGL_INLINE void igl::scaf_system(SCAFData &s, Eigen::SparseMatrix<double> &L, Eigen::VectorXd &rhs)
|
|
|
|
|
+{
|
|
|
|
|
+ s.energy = igl::scaf::compute_energy(s, s.w_uv, false) / s.mesh_measure;
|
|
|
|
|
+
|
|
|
|
|
+ s.total_energy = igl::scaf::compute_energy(s, s.w_uv, true) / s.mesh_measure;
|
|
|
|
|
+ s.rect_frame_V = Eigen::MatrixXd();
|
|
|
|
|
+ igl::scaf::mesh_improve(s);
|
|
|
|
|
+
|
|
|
|
|
+ double new_weight = s.mesh_measure * s.energy / (s.sf_num * 100);
|
|
|
|
|
+ s.scaffold_factor = new_weight;
|
|
|
|
|
+ igl::scaf::update_scaffold(s);
|
|
|
|
|
+
|
|
|
|
|
+ igl::scaf::compute_jacobians(s, s.w_uv, true);
|
|
|
|
|
+ igl::slim_update_weights_and_closest_rotations_with_jacobians(s.Ji_m, s.slim_energy, 0, s.W_m, s.Ri_m);
|
|
|
|
|
+ igl::slim_update_weights_and_closest_rotations_with_jacobians(s.Ji_s, s.scaf_energy, 0, s.W_s, s.Ri_s);
|
|
|
|
|
+
|
|
|
|
|
+ igl::scaf::build_weighted_arap_system(s, L, rhs);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
|
#endif
|
|
#endif
|