// 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 "order_facets_around_edges.h" #include "order_facets_around_edge.h" #include "../../sort_angles.h" #include #include #include template< typename DerivedV, typename DerivedF, typename DerivedN, typename DeriveduE, typename uE2EType, typename uE2oEType, typename uE2CType > IGL_INLINE typename std::enable_if::value, void>::type igl::copyleft::cgal::order_facets_around_edges( const Eigen::PlainObjectBase& V, const Eigen::PlainObjectBase& F, const Eigen::PlainObjectBase& N, const Eigen::PlainObjectBase& uE, const std::vector >& uE2E, std::vector >& uE2oE, std::vector >& uE2C ) { typedef Eigen::Matrix Vector3F; const typename DerivedV::Scalar EPS = 1e-12; const size_t num_faces = F.rows(); const size_t num_undirected_edges = uE.rows(); auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; }; auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; }; uE2oE.resize(num_undirected_edges); uE2C.resize(num_undirected_edges); for(size_t ui = 0;ui 0); const auto ref_edge = adj_edges[0]; const auto ref_face = edge_index_to_face_index(ref_edge); Vector3F ref_normal = N.row(ref_face); const auto ref_corner_o = edge_index_to_corner_index(ref_edge); const auto ref_corner_s = (ref_corner_o+1)%3; const auto ref_corner_d = (ref_corner_o+2)%3; const typename DerivedF::Scalar o = F(ref_face, ref_corner_o); const typename DerivedF::Scalar s = F(ref_face, ref_corner_s); const typename DerivedF::Scalar d = F(ref_face, ref_corner_d); Vector3F edge = V.row(d) - V.row(s); auto edge_len = edge.norm(); bool degenerated = edge_len < EPS; if (degenerated) { if (edge_valance <= 2) { // There is only one way to order 2 or less faces. edge.setZero(); } else { edge.setZero(); Eigen::Matrix normals(edge_valance, 3); for (size_t fei=0; fei= EPS) { edge.normalize(); break; } } // Ensure edge direction are consistent with reference face. Vector3F in_face_vec = V.row(o) - V.row(s); if (edge.cross(in_face_vec).dot(ref_normal) < 0) { edge *= -1; } if (edge.norm() < EPS) { std::cerr << "=====================================" << std::endl; std::cerr << " ui: " << ui << std::endl; std::cerr << "edge: " << ref_edge << std::endl; std::cerr << "face: " << ref_face << std::endl; std::cerr << " vs: " << V.row(s) << std::endl; std::cerr << " vd: " << V.row(d) << std::endl; std::cerr << "adj face normals: " << std::endl; std::cerr << normals << std::endl; std::cerr << "Very degenerated case detected:" << std::endl; std::cerr << "Near zero edge surrounded by " << edge_valance << " neearly colinear faces" << std::endl; std::cerr << "=====================================" << std::endl; } } } else { edge.normalize(); } Eigen::MatrixXd angle_data(edge_valance, 3); std::vector cons(edge_valance); for (size_t fei=0; fei IGL_INLINE typename std::enable_if::value, void>::type igl::copyleft::cgal::order_facets_around_edges( const Eigen::PlainObjectBase& V, const Eigen::PlainObjectBase& F, const Eigen::PlainObjectBase& N, const Eigen::PlainObjectBase& uE, const std::vector >& uE2E, std::vector >& uE2oE, std::vector >& uE2C ) { typedef Eigen::Matrix Vector3F; typedef Eigen::Matrix Vector3E; const typename DerivedV::Scalar EPS = 1e-12; const size_t num_faces = F.rows(); const size_t num_undirected_edges = uE.rows(); auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; }; auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; }; uE2oE.resize(num_undirected_edges); uE2C.resize(num_undirected_edges); for(size_t ui = 0;ui 0); const auto ref_edge = adj_edges[0]; const auto ref_face = edge_index_to_face_index(ref_edge); Vector3F ref_normal = N.row(ref_face); const auto ref_corner_o = edge_index_to_corner_index(ref_edge); const auto ref_corner_s = (ref_corner_o+1)%3; const auto ref_corner_d = (ref_corner_o+2)%3; const typename DerivedF::Scalar o = F(ref_face, ref_corner_o); const typename DerivedF::Scalar s = F(ref_face, ref_corner_s); const typename DerivedF::Scalar d = F(ref_face, ref_corner_d); Vector3E exact_edge = V.row(d) - V.row(s); exact_edge.array() /= exact_edge.squaredNorm(); Vector3F edge( CGAL::to_double(exact_edge[0]), CGAL::to_double(exact_edge[1]), CGAL::to_double(exact_edge[2])); edge.normalize(); Eigen::MatrixXd angle_data(edge_valance, 3); std::vector cons(edge_valance); for (size_t fei=0; fei IGL_INLINE void igl::copyleft::cgal::order_facets_around_edges( const Eigen::PlainObjectBase& V, const Eigen::PlainObjectBase& F, const Eigen::PlainObjectBase& uE, const std::vector >& uE2E, std::vector >& uE2oE, std::vector >& uE2C ) { //typedef Eigen::Matrix Vector3E; const size_t num_faces = F.rows(); const size_t num_undirected_edges = uE.rows(); auto edge_index_to_face_index = [&](size_t ei) { return ei % num_faces; }; auto edge_index_to_corner_index = [&](size_t ei) { return ei / num_faces; }; uE2oE.resize(num_undirected_edges); uE2C.resize(num_undirected_edges); for(size_t ui = 0;ui 0); const auto ref_edge = adj_edges[0]; const auto ref_face = edge_index_to_face_index(ref_edge); const auto ref_corner_o = edge_index_to_corner_index(ref_edge); const auto ref_corner_s = (ref_corner_o+1)%3; const auto ref_corner_d = (ref_corner_o+2)%3; //const typename DerivedF::Scalar o = F(ref_face, ref_corner_o); const typename DerivedF::Scalar s = F(ref_face, ref_corner_s); const typename DerivedF::Scalar d = F(ref_face, ref_corner_d); std::vector cons(edge_valance); std::vector adj_faces(edge_valance); for (size_t fei=0; fei, Eigen::Matrix, Eigen::Matrix, int, int, bool>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); // generated by autoexplicit.sh template std::enable_if::Scalar, CGAL::Lazy_exact_nt >::value), void>::type igl::copyleft::cgal::order_facets_around_edges, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, int, int, bool>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); template void igl::copyleft::cgal::order_facets_around_edges, -1, 3, 0, -1, 3>, Eigen::Matrix, Eigen::Matrix, long, long, bool>(Eigen::PlainObjectBase, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); template void igl::copyleft::cgal::order_facets_around_edges, Eigen::Matrix, Eigen::Matrix, long, long, bool>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); template void igl::copyleft::cgal::order_facets_around_edges, Eigen::Matrix, Eigen::Matrix, long, long, bool>(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); template void igl::copyleft::cgal::order_facets_around_edges, -1, -1, 0, -1, -1>, Eigen::Matrix, Eigen::Matrix, long, long, bool>(Eigen::PlainObjectBase, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, std::vector >, std::allocator > > > const&, std::vector >, std::allocator > > >&, std::vector >, std::allocator > > >&); #endif