From 232db68c7bf45ecec428d83ce313ac45a2f321d3 Mon Sep 17 00:00:00 2001 From: Olga Diamanti Date: Thu, 16 Jul 2015 17:50:03 +0200 Subject: [PATCH] tutorial for integrable polyvectors --- include/igl/integrable_polyvector_fields.cpp | 243 +++--- include/igl/integrable_polyvector_fields.h | 3 - ...tor_field_comb_from_matchings_and_cuts.cpp | 4 +- tutorial/705_Integrable/CMakeLists.txt | 11 + tutorial/705_Integrable/main.cpp | 709 ++++++++++++++++++ tutorial/CMakeLists.txt | 1 + 6 files changed, 843 insertions(+), 128 deletions(-) create mode 100644 tutorial/705_Integrable/CMakeLists.txt create mode 100644 tutorial/705_Integrable/main.cpp diff --git a/include/igl/integrable_polyvector_fields.cpp b/include/igl/integrable_polyvector_fields.cpp index cec1bba84..be356829a 100644 --- a/include/igl/integrable_polyvector_fields.cpp +++ b/include/igl/integrable_polyvector_fields.cpp @@ -29,8 +29,7 @@ wCloseUnconstrained(1e-3), wCloseConstrained(100), redFactor_wsmooth(.8), gamma(0.1), -tikh_gamma(1e-8), -do_partial(false) +tikh_gamma(1e-8) {} @@ -41,7 +40,7 @@ namespace igl { class IntegrableFieldSolver { private: - + IntegrableFieldSolverData &data; //Symbolic calculations IGL_INLINE void rj_barrier_face(const Eigen::RowVectorXd &vec2D_a, @@ -71,24 +70,24 @@ namespace igl { Eigen::VectorXd &residuals, bool do_jac = false, Eigen::MatrixXd &Jac = *(Eigen::MatrixXd*)NULL); - + public: IGL_INLINE IntegrableFieldSolver(IntegrableFieldSolverData &cffsoldata); - + IGL_INLINE bool solve(integrable_polyvector_fields_parameters ¶ms, Eigen::PlainObjectBase& current_field, bool current_field_is_not_ccw); - + IGL_INLINE void solveGaussNewton(integrable_polyvector_fields_parameters ¶ms, const Eigen::VectorXd &x_initial, Eigen::VectorXd &x); - + //Compute residuals and Jacobian for Gauss Newton IGL_INLINE double RJ(const Eigen::VectorXd &x, const Eigen::VectorXd &x0, const integrable_polyvector_fields_parameters ¶ms, bool doJacs = false); - + IGL_INLINE void RJ_Smoothness(const Eigen::MatrixXd &sol2D, const double &wSmoothSqrt, const int startRowInJacobian, @@ -104,7 +103,6 @@ namespace igl { const Eigen::MatrixXd &sol02D, const double &wCloseUnconstrainedSqrt, const double &wCloseConstrainedSqrt, - const bool do_partial, const int startRowInJacobian, bool doJacs = false, const int startIndexInVectors = 0); @@ -119,8 +117,8 @@ namespace igl { const int startRowInJacobian, bool doJacs = false, const int startIndexInVectors = 0); - - + + }; }; @@ -177,7 +175,7 @@ initializeConstraints(const Eigen::VectorXi& b, //sort in descending order (so removing rows will work) igl::sort(constrained_unsorted, 1, false, constrained, iSorted); constrained_vec3 = bc.template cast(); - + } template @@ -214,7 +212,7 @@ makeFieldCCW(Eigen::MatrixXd &sol3D) int n1 = 3*2*2-n2; t.segment(0,n1) = t.segment(s1,n1); t.segment(n1, n2) = temp; - + } sol3D.row(fi) = t.segment(0, 2*3); } @@ -231,7 +229,7 @@ initializeOriginalVariable(const Eigen::PlainObjectBase& original_fie xOriginal.setZero(numVariables); for (int i =0; i @@ -243,7 +241,7 @@ computeInteriorEdges() numInteriorEdges = 0; isBorderEdge.setZero(numE,1); indFullToInterior = -1.*Eigen::VectorXi::Ones(numE,1); - + for(unsigned i=0; i @@ -294,7 +292,7 @@ add_jac_indices_face(const int numInnerRows, { for (int fi=0; fi(); if (current_field_is_not_ccw) data.makeFieldCCW(sol3D); - + igl::global2local(data.B1, data.B2, sol3D, sol2D); Eigen::VectorXd x; x.setZero(data.numVariables); for (int i =0; i::infinity()).any()) { std::cerr<<"IntegrableFieldSolver -- residuals: got infinity somewhere"< @@ -655,43 +653,43 @@ RJ(const Eigen::VectorXd &x, sol2D.row(i) = x.segment(i*2*2, 2*2); for (int i =0; i &data) { data.precomputeMesh(V,F); - + data.computeJacobianPattern(); data.computeHessianPattern(); data.solver.analyzePattern(data.Hess); - + data.initializeConstraints(b,bc,constraint_level); data.initializeOriginalVariable(original_field); }; diff --git a/include/igl/integrable_polyvector_fields.h b/include/igl/integrable_polyvector_fields.h index 363744f3a..8869e1e35 100644 --- a/include/igl/integrable_polyvector_fields.h +++ b/include/igl/integrable_polyvector_fields.h @@ -101,9 +101,6 @@ struct igl::integrable_polyvector_fields_parameters double gamma; //tikhonov regularization term (typically not needed, default value should suffice) double tikh_gamma; - //boolean, determines whether the frames at the constrained faces should be treated - //as partial constraints (i.e. only one of the vectors is preserved in the result) - bool do_partial; IGL_INLINE integrable_polyvector_fields_parameters(); diff --git a/include/igl/polyvector_field_comb_from_matchings_and_cuts.cpp b/include/igl/polyvector_field_comb_from_matchings_and_cuts.cpp index 1e8c5d09e..719bbcc2f 100644 --- a/include/igl/polyvector_field_comb_from_matchings_and_cuts.cpp +++ b/include/igl/polyvector_field_comb_from_matchings_and_cuts.cpp @@ -61,8 +61,8 @@ IGL_INLINE void igl::polyvector_field_comb_from_matchings_and_cuts( } else { - assert((E2Fcut(current_edge,1) == f0) && - (E2Fcut(current_edge,0) == f1)); + assert((E2F(current_edge,1) == f0) && + (E2F(current_edge,0) == f1)); //look at match_ba for(int i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +using namespace std; + +// Input mesh +Eigen::MatrixXd V; +Eigen::MatrixXi F; +std::vector V_border; +std::vector > VF, VFi; +std::vector > VV; +Eigen::MatrixXi TT, TTi; +Eigen::MatrixXi E, E2F, F2E; + +// Per face bases (only needed to generate constraints) +Eigen::MatrixXd B1,B2,B3; + +// "Subdivided" mesh obtained by splitting each triangle into 3 (only needed for display) +Eigen::MatrixXd Vbs; +Eigen::MatrixXi Fbs; + +// Scale for visualizing the fields +double global_scale; + +// Scale for visualizing textures +double uv_scale; + +// Data for original PolyVector field +Eigen::MatrixXd two_pv_ori; // field +Eigen::VectorXi singularities_ori; // singularities +Eigen::VectorXd curl_ori; // curl per edge +Eigen::MatrixXi cuts_ori; // cut edges +Eigen::MatrixXd two_pv_poisson_ori; // field after poisson integration +Eigen::VectorXf poisson_error_ori; // poisson integration error +Eigen::MatrixXd scalars_ori; +Eigen::MatrixXd Vcut_ori; +Eigen::MatrixXi Fcut_ori; + +// Data for curl-free PolyVector field +Eigen::MatrixXd two_pv; // field +Eigen::VectorXi singularities; // singularities +Eigen::VectorXd curl; // curl per edge +Eigen::MatrixXi cuts; // cut edges +Eigen::MatrixXd two_pv_poisson; // field after poisson integration +Eigen::VectorXf poisson_error; // poisson integration error +Eigen::MatrixXd scalars; +Eigen::MatrixXd Vcut; +Eigen::MatrixXi Fcut; + +// Vector of constrained faces +Eigen::VectorXi b; + +// Matrix of constraints +Eigen::MatrixXd bc; + +// "constraint level" flag (level=2 indicates that both directions are constrained, +// level = 1 indicates a partially constrained face, i.e. only the first vector will +// be constrained) +Eigen::VectorXi blevel; + +// Face Barycenters (only needed for display) +Eigen::MatrixXd B; + +// percentage of constrained faces +double constraint_percentage = 0.002; + +// Random length factor +double rand_factor = 5; + +// The set of parameters for calculating the curl-free fields +igl::integrable_polyvector_fields_parameters params; + +// Solver data (needed for precomputation) +igl::IntegrableFieldSolverData ipfdata; + +//texture image +Eigen::Matrix texture_R, texture_G, texture_B; + +int display_mode = 1; + +int iter = 0; + +// 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; i0) + color.row(i)<<0.7,0.7,0.7; + // Eigen::RowVector3d color; color<<0.5,0.5,0.5; + viewer.data.add_edges(Bc - global_scale*bc.block(0,n*3,bc.rows(),3), Bc + global_scale*bc.block(0,n*3,bc.rows(),3) , color); + } + +} + + +void colorEdgeMeshFaces(const Eigen::VectorXd &values, + const double &minimum, + const double &maximum, + Eigen::MatrixXd &C) +{ + C.setConstant(Fbs.rows(),3,1); + + Eigen::MatrixXd colors; + igl::jet(values, minimum, maximum, colors); + + for (int ei = 0; ei