// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2018 Alec Jacobson // // 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 "is_intrinsic_delaunay.h" #include "unique_edge_map.h" #include "tan_half_angle.h" #include "EPS.h" #include "cotmatrix_entries.h" #include #include template < typename Derivedl, typename DerivedF, typename DerivedD> IGL_INLINE void igl::is_intrinsic_delaunay( const Eigen::MatrixBase & l, const Eigen::MatrixBase & F, Eigen::PlainObjectBase & D) { typedef Eigen::Matrix MatrixX2I; typedef Eigen::Matrix VectorXI; MatrixX2I E,uE; VectorXI EMAP; std::vector > uE2E; igl::unique_edge_map(F, E, uE, EMAP, uE2E); return is_intrinsic_delaunay(l,F,uE2E,D); } template < typename Derivedl, typename DerivedF, typename uE2EType, typename DerivedD> IGL_INLINE void igl::is_intrinsic_delaunay( const Eigen::MatrixBase & l, const Eigen::MatrixBase & F, const std::vector > & uE2E, Eigen::PlainObjectBase & D) { const int num_faces = F.rows(); D.setConstant(F.rows(),F.cols(),false); // loop over all unique edges for(int ue = 0;ue < uE2E.size(); ue++) { const bool ue_is_d = is_intrinsic_delaunay(l,uE2E,num_faces,ue); // Set for all instances for(int e = 0;e IGL_INLINE bool igl::is_intrinsic_delaunay( const Eigen::MatrixBase & l, const std::vector > & uE2E, const Index num_faces, const Index uei) { if(uE2E[uei].size() == 1) return true; if(uE2E[uei].size() > 2) return false; typedef typename Derivedl::Scalar Scalar; const auto cot_alpha = []( const Scalar & a, const Scalar & b, const Scalar & c)->Scalar { // Fisher 2007 const Scalar t = tan_half_angle(a,b,c); return (1.0-t*t)/(2*t); }; // 2 // // /|\ // // a/ | \d // // / e \ // // / | \ // //0.α---|-f-β.3 // // \ | / // // \ | / // // b\ | /c // // \|/ // // . // // 1 // Fisher 2007 assert(uE2E[uei].size() == 2 && "edge should have 2 incident faces"); const Index he1 = uE2E[uei][0]; const Index he2 = uE2E[uei][1]; const Index f1 = he1%num_faces; const Index c1 = he1/num_faces; const Index f2 = he2%num_faces; const Index c2 = he2/num_faces; assert( std::abs(l(f1,c1)-l(f2,c2)) < igl::EPS()); const Scalar e = l(f1,c1); const Scalar a = l(f1,(c1+1)%3); const Scalar b = l(f1,(c1+2)%3); const Scalar c = l(f2,(c2+1)%3); const Scalar d = l(f2,(c2+2)%3); const Scalar w = cot_alpha(e,a,b) + cot_alpha(e,c,d); //// Test //{ // Eigen::MatrixXd l(2,3); // l<1e-10) // { // std::cout<= 0; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template bool igl::is_intrinsic_delaunay, int, int>(Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, int, int); // generated by autoexplicit.sh template bool igl::is_intrinsic_delaunay, int, int>(Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, int, int); // generated by autoexplicit.sh template void igl::is_intrinsic_delaunay, Eigen::Matrix, int, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, std::vector >, std::allocator > > > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::is_intrinsic_delaunay, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::is_intrinsic_delaunay, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); #endif