#include #include #include #include #include #include #include #include #include #include #include #include #include #include "tutorial_shared_path.h" // Input mesh Eigen::MatrixXd V; Eigen::MatrixXi F; // Face barycenters Eigen::MatrixXd B; // Scale for visualizing the fields double global_scale; // Input constraints Eigen::VectorXi b; Eigen::MatrixXd bc; Eigen::MatrixXd smooth_pvf; Eigen::MatrixXd conjugate_pvf; Eigen::VectorXd conjugacy_s; Eigen::VectorXd conjugacy_c; igl::ConjugateFFSolverData *csdata; bool key_down(igl::viewer::Viewer& viewer, unsigned char key, int modifier) { using namespace std; using namespace Eigen; if (key <'1' || key >'5') return false; viewer.data.lines.resize(0,9); // Highlight in red the constrained faces MatrixXd C = MatrixXd::Constant(F.rows(),3,1); for (unsigned i=0; i(V,F); conjugate_pvf = smooth_pvf; // Optimize the field int conjIter = 20; double lambdaOrtho = .1; double lambdaInit = 100; double lambdaMultFactor = 1.01; bool doHardConstraints = true; double lambdaOut; VectorXi isConstrained = VectorXi::Constant(F.rows(),0); for (unsigned i=0; i pvU, pvV; pvU.resize(F.rows(),2); pvV.resize(F.rows(),2); //smooth const Eigen::MatrixXd &Us = smooth_pvf.leftCols(3); const Eigen::MatrixXd &Vs = smooth_pvf.rightCols(3); pvU << igl::dot_row(Us,B1), igl::dot_row(Us,B2); pvV << igl::dot_row(Vs,B1), igl::dot_row(Vs,B2); csdata->evaluateConjugacy(pvU, pvV, conjugacy_s); //conjugate const Eigen::MatrixXd &Uc = conjugate_pvf.leftCols(3); const Eigen::MatrixXd &Vc = conjugate_pvf.rightCols(3); pvU << igl::dot_row(Uc,B1), igl::dot_row(Uc,B2); pvV << igl::dot_row(Vc,B1), igl::dot_row(Vc,B2); csdata->evaluateConjugacy(pvU, pvV, conjugacy_c); // Launch the viewer igl::viewer::Viewer viewer; viewer.core.invert_normals = true; viewer.core.show_lines = false; viewer.core.show_texture = false; viewer.data.set_mesh(V, F); viewer.callback_key_down = &key_down; key_down(viewer,'1',0); viewer.launch(); }