outer_facet.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. template<
  13. typename DerivedV,
  14. typename DerivedF,
  15. typename DerivedI,
  16. typename IndexType
  17. >
  18. IGL_INLINE void igl::cgal::outer_facet(
  19. const Eigen::PlainObjectBase<DerivedV> & V,
  20. const Eigen::PlainObjectBase<DerivedF> & F,
  21. const Eigen::PlainObjectBase<DerivedI> & I,
  22. IndexType & f,
  23. bool & flipped) {
  24. // Algorithm:
  25. // Find an outer edge.
  26. // Order adjacent facets around the edge.
  27. // For consecutive facets, check if the tetrahedron formed by them is
  28. // positively oriented.
  29. // If yes, check the next pair.
  30. // If not, return either face.
  31. typedef typename DerivedV::Scalar Scalar;
  32. typedef typename DerivedV::Index Index;
  33. const size_t INVALID = std::numeric_limits<size_t>::max();
  34. Index s,d;
  35. Eigen::Matrix<Index,Eigen::Dynamic,1> incident_faces;
  36. outer_edge(V, F, I, s, d, incident_faces);
  37. assert(incident_faces.size() > 0);
  38. auto convert_to_signed_index = [&](size_t fid) -> int{
  39. if ((F(fid, 0) == s && F(fid, 1) == d) ||
  40. (F(fid, 1) == s && F(fid, 2) == d) ||
  41. (F(fid, 2) == s && F(fid, 0) == d) ) {
  42. return int(fid+1) * -1;
  43. } else {
  44. return int(fid+1);
  45. }
  46. };
  47. auto signed_index_to_index = [&](int signed_id) -> size_t {
  48. return size_t(abs(signed_id) - 1);
  49. };
  50. std::vector<int> adj_faces(incident_faces.size());
  51. std::transform(incident_faces.data(),
  52. incident_faces.data() + incident_faces.size(),
  53. adj_faces.begin(),
  54. convert_to_signed_index);
  55. Eigen::VectorXi order;
  56. order_facets_around_edge(V, F, s, d, adj_faces, order);
  57. f = signed_index_to_index(adj_faces[order[0]]);
  58. flipped = adj_faces[order[0]] > 0;
  59. }