#include "cross_field_missmatch.h" #include "comb_cross_field.h" #include #include #include "per_face_normals.h" #include "is_border_vertex.h" #include "vf.h" #include "tt.h" namespace igl { template class MissMatchCalculator { public: const Eigen::PlainObjectBase &V; const Eigen::PlainObjectBase &F; const Eigen::PlainObjectBase &PD1; const Eigen::PlainObjectBase &PD2; Eigen::PlainObjectBase N; private: // internal std::vector V_border; // bool std::vector > VF; std::vector > VFi; Eigen::PlainObjectBase TT; Eigen::PlainObjectBase TTi; private: ///return true if a vertex is singluar by looking at initialized missmatches // possible bugs, verify deleted flag vs IsD() // not sorted vf, but should not make a difference // olga: TODO: this returns the index modulo 4. int oneRingMissMatch(const int vid) { ///check that is on border.. if (V_border[vid]) return 0; int missmatch=0; for (unsigned int i=0;i dir0 = PD1.row(f0); Eigen::Matrix dir1 = PD1.row(f1); Eigen::Matrix n0 = N.row(f0); Eigen::Matrix n1 = N.row(f1); Eigen::Matrix dir1Rot = Comb::Rotate(n1,n0,dir1); dir1Rot.normalize(); // TODO: this should be equivalent to the other code below, to check! // Compute the angle between the two vectors // double a0 = atan2(dir0.dot(B2.row(f0)),dir0.dot(B1.row(f0))); // double a1 = atan2(dir1Rot.dot(B2.row(f0)),dir1Rot.dot(B1.row(f0))); // // double angle_diff = a1-a0; //VectToAngle(f0,dir1Rot); double angle_diff = atan2(dir1Rot.dot(PD2.row(f0)),dir1Rot.dot(PD1.row(f0))); // std::cerr << "Dani: " << dir0(0) << " " << dir0(1) << " " << dir0(2) << " " << dir1Rot(0) << " " << dir1Rot(1) << " " << dir1Rot(2) << " " << angle_diff << std::endl; double step=M_PI/2.0; int i=(int)floor((angle_diff/step)+0.5); int k=0; if (i>=0) k=i%4; else k=(-(3*i))%4; return k; } public: MissMatchCalculator(const Eigen::PlainObjectBase &_V, const Eigen::PlainObjectBase &_F, const Eigen::PlainObjectBase &_PD1, const Eigen::PlainObjectBase &_PD2 ): V(_V), F(_F), PD1(_PD1), PD2(_PD2) { igl::per_face_normals(V,F,N); V_border = igl::is_border_vertex(V,F); igl::vf(V,F,VF,VFi); igl::tt(V,F,TT,TTi); } void calculateMissmatch(Eigen::PlainObjectBase &Handle_MMatch) { Handle_MMatch.setConstant(F.rows(),3,-1); for (unsigned int i=0;i IGL_INLINE void igl::cross_field_missmatch(const Eigen::PlainObjectBase &V, const Eigen::PlainObjectBase &F, const Eigen::PlainObjectBase &PD1, const Eigen::PlainObjectBase &PD2, const bool isCombed, Eigen::PlainObjectBase &missmatch) { Eigen::PlainObjectBase PD1_combed; Eigen::PlainObjectBase PD2_combed; if (!isCombed) igl::comb_cross_field(V,F,PD1,PD2,PD1_combed,PD2_combed); else { PD1_combed = PD1; PD2_combed = PD2; } igl::MissMatchCalculator sf(V, F, PD1_combed, PD2_combed); sf.calculateMissmatch(missmatch); }