outer_facet.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Qingnan Zhou <[email protected]>
  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_edge.h"
  10. #include "order_facets_around_edge.h"
  11. #include "../../PlainMatrix.h"
  12. #include <algorithm>
  13. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  14. template<
  15. typename DerivedV,
  16. typename DerivedF,
  17. typename DerivedI,
  18. typename IndexType
  19. >
  20. IGL_INLINE void igl::copyleft::cgal::outer_facet(
  21. const Eigen::MatrixBase<DerivedV> & V,
  22. const Eigen::MatrixBase<DerivedF> & F,
  23. const Eigen::MatrixBase<DerivedI> & I,
  24. IndexType & f,
  25. bool & flipped) {
  26. // Algorithm:
  27. //
  28. // 1. Find an outer edge (s, d).
  29. //
  30. // 2. Order adjacent facets around this edge. Because the edge is an
  31. // outer edge, there exists a plane passing through it such that all its
  32. // adjacent facets lie on the same side. The implementation of
  33. // order_facets_around_edge() will find a natural start facet such that
  34. // The first and last facets according to this order are on the outside.
  35. //
  36. // 3. Because the vertex s is an outer vertex by construction (see
  37. // implemnetation of outer_edge()). The first adjacent facet is facing
  38. // outside (i.e. flipped=false) if it has positive X normal component.
  39. // If it has zero normal component, it is facing outside if it contains
  40. // directed edge (s, d).
  41. //typedef typename DerivedV::Scalar Scalar;
  42. typedef typename DerivedV::Index Index;
  43. Index s,d;
  44. Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
  45. outer_edge(V, F, I, s, d, incident_faces);
  46. assert(incident_faces.size() > 0);
  47. auto convert_to_signed_index = [&](size_t fid) -> int{
  48. if ((F(fid, 0) == s && F(fid, 1) == d) ||
  49. (F(fid, 1) == s && F(fid, 2) == d) ||
  50. (F(fid, 2) == s && F(fid, 0) == d) ) {
  51. return int(fid+1) * -1;
  52. } else {
  53. return int(fid+1);
  54. }
  55. };
  56. auto signed_index_to_index = [&](int signed_id) -> size_t {
  57. return size_t(abs(signed_id) - 1);
  58. };
  59. std::vector<int> adj_faces(incident_faces.size());
  60. std::transform(incident_faces.data(),
  61. incident_faces.data() + incident_faces.size(),
  62. adj_faces.begin(),
  63. convert_to_signed_index);
  64. PlainMatrix<DerivedV,1> pivot_point = V.row(s);
  65. pivot_point(0, 0) += 1.0;
  66. Eigen::VectorXi order;
  67. order_facets_around_edge(V, F, s, d, adj_faces, pivot_point, order);
  68. f = signed_index_to_index(adj_faces[order[0]]);
  69. flipped = adj_faces[order[0]] > 0;
  70. }
  71. template<
  72. typename DerivedV,
  73. typename DerivedF,
  74. typename DerivedN,
  75. typename DerivedI,
  76. typename IndexType
  77. >
  78. IGL_INLINE void igl::copyleft::cgal::outer_facet(
  79. const Eigen::MatrixBase<DerivedV> & V,
  80. const Eigen::MatrixBase<DerivedF> & F,
  81. const Eigen::MatrixBase<DerivedN> & N,
  82. const Eigen::MatrixBase<DerivedI> & I,
  83. IndexType & f,
  84. bool & flipped) {
  85. // Algorithm:
  86. // Find an outer edge.
  87. // Find the incident facet with the largest absolute X normal component.
  88. // If there is a tie, keep the one with positive X component.
  89. // If there is still a tie, pick the face with the larger signed index
  90. // (flipped face has negative index).
  91. typedef typename DerivedV::Scalar Scalar;
  92. typedef typename DerivedV::Index Index;
  93. const size_t INVALID = std::numeric_limits<size_t>::max();
  94. Index v1,v2;
  95. Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
  96. outer_edge(V, F, I, v1, v2, incident_faces);
  97. assert(incident_faces.size() > 0);
  98. auto generic_fabs = [&](const Scalar& val) -> const Scalar {
  99. if (val >= 0) return val;
  100. else return -val;
  101. };
  102. Scalar max_nx = 0;
  103. size_t outer_fid = INVALID;
  104. const size_t num_incident_faces = incident_faces.size();
  105. for (size_t i=0; i<num_incident_faces; i++)
  106. {
  107. const auto& fid = incident_faces(i);
  108. const Scalar nx = N(fid, 0);
  109. if (outer_fid == INVALID) {
  110. max_nx = nx;
  111. outer_fid = fid;
  112. } else {
  113. if (generic_fabs(nx) > generic_fabs(max_nx)) {
  114. max_nx = nx;
  115. outer_fid = fid;
  116. } else if (nx == -max_nx && nx > 0) {
  117. max_nx = nx;
  118. outer_fid = fid;
  119. } else if (nx == max_nx) {
  120. if ((max_nx >= 0 && outer_fid < fid) ||
  121. (max_nx < 0 && outer_fid > fid)) {
  122. max_nx = nx;
  123. outer_fid = fid;
  124. }
  125. }
  126. }
  127. }
  128. assert(outer_fid != INVALID);
  129. f = outer_fid;
  130. flipped = max_nx < 0;
  131. }
  132. #ifdef IGL_STATIC_LIBRARY
  133. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  134. #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
  135. // Explicit template instantiation
  136. // generated by autoexplicit.sh
  137. #include <cstdint>
  138. template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, std::ptrdiff_t>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, std::ptrdiff_t&, bool&);
  139. // generated by autoexplicit.sh
  140. template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
  141. template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Index>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Index &, bool&);
  142. template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
  143. template void igl::copyleft::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>, Eigen::Index>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Index&, bool&);
  144. template void igl::copyleft::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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int&, bool&);
  145. template void igl::copyleft::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::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int&, bool&);
  146. //template void igl::copyleft::cgal::outer_facet<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<long, -1, 1, 0, -1, 1>, int>(Eigen::MatrixBase<Eigen::Matrix<CGAL::Epeck::FT, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
  147. //template void igl::copyleft::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::MatrixBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int&, bool&);
  148. #ifdef WIN32
  149. #endif
  150. #endif