// 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_mismatch.h" #include #include #include #include #include #include #include #include #include #include namespace igl { template class MismatchCalculator { 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 mismatchByCross(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(); double angle_diff = atan2(dir1Rot.dot(PD2.row(f0)),dir1Rot.dot(PD1.row(f0))); 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 MismatchCalculator(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 calculateMismatch(Eigen::PlainObjectBase &Handle_MMatch) { Handle_MMatch.setConstant(F.rows(),3,-1); for (size_t i=0;i IGL_INLINE void igl::cross_field_mismatch(const Eigen::PlainObjectBase &V, const Eigen::PlainObjectBase &F, const Eigen::PlainObjectBase &PD1, const Eigen::PlainObjectBase &PD2, const bool isCombed, Eigen::PlainObjectBase &mismatch) { 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::MismatchCalculator sf(V, F, PD1_combed, PD2_combed); sf.calculateMismatch(mismatch); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template void igl::cross_field_mismatch, Eigen::Matrix >(Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, const bool, Eigen::PlainObjectBase > &); template void igl::cross_field_mismatch, Eigen::Matrix >( Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, const bool, Eigen::PlainObjectBase > &); template void igl::cross_field_mismatch, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, Eigen::PlainObjectBase > const &, const bool, Eigen::PlainObjectBase > &); #endif