#include #include #include #include #include #include template void igl::polyvector_field_one_ring_matchings(const Eigen::PlainObjectBase &V, const Eigen::PlainObjectBase &F, const std::vector >& VF, const Eigen::MatrixXi& E2F, const Eigen::MatrixXi& F2E, const Eigen::PlainObjectBase& TT, const Eigen::PlainObjectBase &match_ab, const Eigen::PlainObjectBase &match_ba, const int vi, const int vector_to_match, Eigen::VectorXi &mvi, Eigen::VectorXi &fi) { int half_degree = match_ab.cols(); mvi.resize(VF[vi].size()+1,1); fi.resize(VF[vi].size()+1,1); //start from one face const int &fstart = VF[vi][0]; int current_face = fstart; int i =0; mvi[i] = vector_to_match; fi[i] = current_face; int next_face = -1; while (next_face != fstart) { // look for the vertex int j=-1; for (unsigned z=0; z<3; ++z) if (F(current_face,z) == vi) j=z; assert(j!=-1); next_face = TT(current_face, j); ++i; // look at the edge between the two faces const int ¤t_edge = F2E(current_face,j); // check its orientation to determine whether match_ab or match_ba should be used if ((E2F(current_edge,0) == current_face) && (E2F(current_edge,1) == next_face) ) { //look at match_ab mvi[i] = match_ab(current_edge,(mvi[i-1])%half_degree); } else { assert((E2F(current_edge,1) == current_face) && (E2F(current_edge,0) == next_face)); //look at match_ba mvi[i] = match_ba(current_edge,(mvi[i-1])%half_degree); } if (mvi[i-1]>=half_degree) mvi[i] = (mvi[i]+half_degree)%(2*half_degree); current_face = next_face; fi[i] = current_face; } } template IGL_INLINE void igl::polyvector_field_singularities_from_matchings( const Eigen::PlainObjectBase &V, const Eigen::PlainObjectBase &F, const Eigen::PlainObjectBase &match_ab, const Eigen::PlainObjectBase &match_ba, Eigen::PlainObjectBase &singularities) { std::vector V_border = igl::is_border_vertex(V,F); std::vector > VF, VFi; igl::vertex_triangle_adjacency(V,F,VF,VFi); Eigen::MatrixXi TT, TTi; igl::triangle_triangle_adjacency(F,TT,TTi); Eigen::MatrixXi E, E2F, F2E; igl::edge_topology(V,F,E,F2E,E2F); igl::polyvector_field_singularities_from_matchings(V, F, V_border, VF, TT, E2F, F2E, match_ab, match_ba, singularities); } template IGL_INLINE void igl::polyvector_field_singularities_from_matchings( const Eigen::PlainObjectBase &V, const Eigen::PlainObjectBase &F, const std::vector &V_border, const std::vector > &VF, const Eigen::MatrixXi &TT, const Eigen::MatrixXi &E2F, const Eigen::MatrixXi &F2E, const Eigen::PlainObjectBase &match_ab, const Eigen::PlainObjectBase &match_ba, Eigen::PlainObjectBase &singularities) { int numV = V.rows(); std::vector singularities_v; int half_degree = match_ab.cols(); //pick one of the vectors to check for singularities for (int vector_to_match = 0; vector_to_match < half_degree; ++vector_to_match) { for (int vi =0; vi, Eigen::Matrix, Eigen::Matrix, int, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector > const&, std::vector >, std::allocator > > > const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); template void igl::polyvector_field_singularities_from_matchings, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase >&); #endif