// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 Daniele Panozzo , Olga Diamanti // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "cross_field_missmatch.h" #include #include #include #include #include #include #include #include #include #include namespace igl { template class MissMatchCalculator { public: const Eigen::PlainObjectBase &V; const Eigen::PlainObjectBase &F; const Eigen::PlainObjectBase &PD1; const Eigen::PlainObjectBase &PD2; DerivedV N; private: // internal std::vector V_border; // bool std::vector > VF; std::vector > VFi; DerivedF TT; DerivedF TTi; private: ///compute the mismatch between 2 faces inline int MissMatchByCross(const int f0, const int f1) { Eigen::Matrix 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 = igl::rotation_matrix_from_directions(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=igl::PI/2.0; int i=(int)std::floor((angle_diff/step)+0.5); int k=0; if (i>=0) k=i%4; else k=(-(3*i))%4; return k; } public: inline 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::vertex_triangle_adjacency(V,F,VF,VFi); igl::triangle_triangle_adjacency(F,TT,TTi); } inline void calculateMissmatch(Eigen::PlainObjectBase &Handle_MMatch) { Handle_MMatch.setConstant(F.rows(),3,-1); for (size_t 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) { DerivedV PD1_combed; DerivedV 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); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template void igl::cross_field_missmatch, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, bool, Eigen::PlainObjectBase >&); template void igl::cross_field_missmatch, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, bool, Eigen::PlainObjectBase >&); template void igl::cross_field_missmatch, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, bool, Eigen::PlainObjectBase >&); #endif