// 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 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); 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,F,uE2E,ue); // Set for all instances for(int e = 0;e IGL_INLINE bool igl::is_intrinsic_delaunay( const Eigen::MatrixBase & l, const Eigen::MatrixBase & F, const std::vector > & uE2E, const ueiType uei) { if(uE2E[uei].size() == 1) return true; if(uE2E[uei].size() > 2) return false; typedef typename Derivedl::Scalar Scalar; typedef typename DerivedF::Scalar Index; // . // /| // c/ | // / | // / | // .α | a // \ | // \ | // b\ | // \| // // tan(α/2) const auto tan_alpha_over_2 = []( const Scalar & a, const Scalar & b, const Scalar & c)->Scalar { // Fisher 2007 return sqrt(((a-b+c)*(a+b-c))/((a+b+c)*(-a+b+c))); }; const auto cot_alpha = [&tan_alpha_over_2]( const Scalar & a, const Scalar & b, const Scalar & c)->Scalar { // Fisher 2007 const Scalar t = tan_alpha_over_2(a,b,c); return (1.0-t*t)/(2*t); }; // . // // /|\ // // a/ | \d // // / e \ // // / | \ // // .α---|-f-β. // // \ | / // // \ | / // // b\ | /c // // \|/ // // . // const Index num_faces = F.rows(); assert(uE2E[uei].size() == 2 && "edge should have 2 incident faces"); const Index he_left = uE2E[uei][0]; const Index he_right = uE2E[uei][1]; const Index f_left = he_left%num_faces; const Index c_left = he_left/num_faces; const Index f_right = he_right%num_faces; const Index c_right = he_right/num_faces; assert( std::abs(l(f_left,c_left)-l(f_right,c_right) < igl::EPS()) ); const Scalar e = l(f_left,c_left); const Scalar a = l(f_left,(c_left+1)%3); const Scalar b = l(f_left,(c_left+2)%3); const Scalar c = l(f_right,(c_right+1)%3); const Scalar d = l(f_right,(c_right+2)%3); const Scalar w = cot_alpha(e,a,b) + cot_alpha(e,c,d); return w >= 0; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::is_intrinsic_delaunay, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); #endif