outer_facet.cpp 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "outer_facet.h"
  9. #include "../outer_element.h"
  10. #include "order_facets_around_edge.h"
  11. #include <algorithm>
  12. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  13. template<
  14. typename DerivedV,
  15. typename DerivedF,
  16. typename DerivedI,
  17. typename IndexType
  18. >
  19. IGL_INLINE void igl::cgal::outer_facet(
  20. const Eigen::PlainObjectBase<DerivedV> & V,
  21. const Eigen::PlainObjectBase<DerivedF> & F,
  22. const Eigen::PlainObjectBase<DerivedI> & I,
  23. IndexType & f,
  24. bool & flipped) {
  25. // Algorithm:
  26. //
  27. // 1. Find an outer edge (s, d).
  28. //
  29. // 2. Order adjacent facets around this edge. Because the edge is an
  30. // outer edge, there exists a plane passing through it such that all its
  31. // adjacent facets lie on the same side. The implementation of
  32. // order_facets_around_edge() will find a natural start facet such that
  33. // The first and last facets according to this order are on the outside.
  34. //
  35. // 3. Because the vertex s is an outer vertex by construction (see
  36. // implemnetation of outer_edge()). The first adjacent facet is facing
  37. // outside (i.e. flipped=false) if it has positive X normal component.
  38. // If it has zero normal component, it is facing outside if it contains
  39. // directed edge (s, d).
  40. //typedef typename DerivedV::Scalar Scalar;
  41. typedef typename DerivedV::Index Index;
  42. Index s,d;
  43. Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
  44. outer_edge(V, F, I, s, d, incident_faces);
  45. assert(incident_faces.size() > 0);
  46. auto convert_to_signed_index = [&](size_t fid) -> int{
  47. if ((F(fid, 0) == s && F(fid, 1) == d) ||
  48. (F(fid, 1) == s && F(fid, 2) == d) ||
  49. (F(fid, 2) == s && F(fid, 0) == d) ) {
  50. return int(fid+1) * -1;
  51. } else {
  52. return int(fid+1);
  53. }
  54. };
  55. auto signed_index_to_index = [&](int signed_id) -> size_t {
  56. return size_t(abs(signed_id) - 1);
  57. };
  58. std::vector<int> adj_faces(incident_faces.size());
  59. std::transform(incident_faces.data(),
  60. incident_faces.data() + incident_faces.size(),
  61. adj_faces.begin(),
  62. convert_to_signed_index);
  63. DerivedV pivot_point = V.row(s);
  64. pivot_point(0, 0) += 1.0;
  65. Eigen::VectorXi order;
  66. order_facets_around_edge(V, F, s, d, adj_faces, pivot_point, order);
  67. f = signed_index_to_index(adj_faces[order[0]]);
  68. flipped = adj_faces[order[0]] > 0;
  69. }
  70. #ifdef IGL_STATIC_LIBRARY
  71. // Explicit template specialization
  72. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  73. #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
  74. template void igl::cgal::outer_facet<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
  75. template void igl::cgal::outer_facet<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
  76. template void igl::cgal::outer_facet<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
  77. #endif