#include #include #include #include #include #include #include #include #include #include #include #include #include #include // Input mesh Eigen::MatrixXd V; Eigen::MatrixXi F; // Face barycenters Eigen::MatrixXd B; // Scale for visualizing the fields double global_scale; // Input frame field constraints Eigen::VectorXi b; Eigen::MatrixXd bc1; Eigen::MatrixXd bc2; // Interpolated frame field Eigen::MatrixXd FF1, FF2; // Deformed mesh Eigen::MatrixXd V_deformed; Eigen::MatrixXd B_deformed; // Frame field on deformed Eigen::MatrixXd FF1_deformed; Eigen::MatrixXd FF2_deformed; // Cross field on deformed Eigen::MatrixXd X1_deformed; Eigen::MatrixXd X2_deformed; // Global parametrization Eigen::MatrixXd V_uv; Eigen::MatrixXi F_uv; // Create a texture that hides the integer translation in the parametrization void line_texture(Eigen::Matrix &texture_R, Eigen::Matrix &texture_G, Eigen::Matrix &texture_B) { unsigned size = 128; unsigned size2 = size/2; unsigned lineWidth = 3; texture_R.setConstant(size, size, 255); for (unsigned i=0; i'6') return false; viewer.data().clear(); viewer.data().show_lines = false; viewer.data().show_texture = false; if (key == '1') { // Frame field constraints viewer.data().set_mesh(V, F); MatrixXd F1_t = MatrixXd::Zero(FF1.rows(),FF1.cols()); MatrixXd F2_t = MatrixXd::Zero(FF2.rows(),FF2.cols()); // Highlight in red the constrained faces MatrixXd C = MatrixXd::Constant(F.rows(),3,1); for (unsigned i=0; i texture_R, texture_G, texture_B; line_texture(texture_R, texture_G, texture_B); viewer.data().set_texture(texture_R, texture_B, texture_G); viewer.core().align_camera_center(viewer.data().V,viewer.data().F); return false; } int main(int argc, char *argv[]) { using namespace Eigen; // Load a mesh in OBJ format igl::readOBJ(TUTORIAL_SHARED_PATH "/bumpy-cube.obj", V, F); // Compute face barycenters igl::barycenter(V, F, B); // Compute scale for visualizing fields global_scale = .2*igl::avg_edge_length(V, F); // Load constraints MatrixXd temp; igl::readDMAT(TUTORIAL_SHARED_PATH "/bumpy-cube.dmat",temp); b = temp.block(0,0,temp.rows(),1).cast(); bc1 = temp.block(0,1,temp.rows(),3); bc2 = temp.block(0,4,temp.rows(),3); // Interpolate the frame field igl::copyleft::comiso::frame_field(V, F, b, bc1, bc2, FF1, FF2); // Deform the mesh to transform the frame field in a cross field igl::frame_field_deformer( V,F,FF1,FF2,V_deformed,FF1_deformed,FF2_deformed); // Compute face barycenters deformed mesh igl::barycenter(V_deformed, F, B_deformed); // Find the closest crossfield to the deformed frame field igl::frame_to_cross_field(V_deformed,F,FF1_deformed,FF2_deformed,X1_deformed); // Find a smooth crossfield that interpolates the deformed constraints MatrixXd bc_x(b.size(),3); for (unsigned i=0; i