// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2015 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 "outer_facet.h" #include "sort.h" #include "vertex_triangle_adjacency.h" #include #define IGL_OUTER_FACET_DEBUG template < typename DerivedV, typename DerivedF, typename DerivedN, typename DerivedI, typename f_type> IGL_INLINE void igl::outer_facet( const Eigen::PlainObjectBase & V, const Eigen::PlainObjectBase & F, const Eigen::PlainObjectBase & N, const Eigen::PlainObjectBase & I, f_type & max_f, bool & flip) { using namespace std; typedef typename DerivedV::Scalar Scalar; typedef typename DerivedV::Index Index; typedef typename Eigen::Matrix VectorXI; typedef typename Eigen::Matrix VectorXS; // "Direct repair of self-intersecting meshes" [Attene 14] const Index mi = I.size(); assert(V.cols() == 3); assert(N.cols() == 3); Index max_v = -1; auto generic_fabs = [&](Scalar val) { if (val >= 0) return val; else return -val; }; for(size_t d = 0;d<(size_t)V.cols();d++) { Scalar max_d = -1e26; Scalar max_nd = -1e26; for(Index i = 0;i0) { for(Index c = 0;c<3;c++) { const Index v = F(f,c); if(v == max_v) { if(generic_fabs(nd) > max_nd) { // Just update max face and normal max_f = f; max_nd = generic_fabs(nd); flip = nd<0; } else if (generic_fabs(nd) == max_nd) { if (nd == max_nd) { if (flip) { max_f = f; max_nd = nd; flip = false; } else if (f > (Index)max_f){ max_f = f; max_nd = nd; flip = false; } } else { if (flip && f < (Index)max_f) { max_f = f; max_nd = generic_fabs(nd); flip = true; } } } }else { const Scalar vd = V(v,d); if(vd>max_d) { // update max vertex, face and normal max_v = v; max_d = vd; max_f = f; max_nd = generic_fabs(nd); flip = nd<0; } } } } } if(max_v >= 0) { break; } // if we get here and max_v is still -1 then there were no faces with // |N(d)| > 0 } #ifdef IGL_OUTER_FACET_DEBUG if(max_v <0) { cerr<<"Very degenerate case, no suitable face found."<=0 && "Very degenerate case, no suitable face found."); } #ifdef IGL_STATIC_LIBRARY // Explicit template specialization template void igl::outer_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, int>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, int&, bool&); template void igl::outer_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, unsigned long>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, unsigned long&, bool&); template void igl::outer_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, int>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, int&, bool&); template void igl::outer_facet, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, int>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, int&, bool&); #endif