face_occurrences.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[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 "face_occurrences.h"
  9. #include "list_to_matrix.h"
  10. #include "matrix_to_list.h"
  11. #include <map>
  12. #include "sort.h"
  13. #include <cassert>
  14. template <typename IntegerF, typename IntegerC>
  15. IGL_INLINE void igl::face_occurrences(
  16. const std::vector<std::vector<IntegerF> > & F,
  17. std::vector<IntegerC> & C)
  18. {
  19. // Get a list of sorted faces
  20. std::vector<std::vector<IntegerF> > sortedF = F;
  21. for(int i = 0; i < (int)F.size();i++)
  22. {
  23. sort(sortedF[i].begin(),sortedF[i].end());
  24. }
  25. // Count how many times each sorted face occurs
  26. std::map<std::vector<IntegerF>,int> counts;
  27. for(int i = 0; i < (int)sortedF.size();i++)
  28. {
  29. if(counts.find(sortedF[i]) == counts.end())
  30. {
  31. // initialize to count of 1
  32. counts[sortedF[i]] = 1;
  33. }else
  34. {
  35. // increment count
  36. counts[sortedF[i]]++;
  37. assert(counts[sortedF[i]] == 2 && "Input should be manifold");
  38. }
  39. }
  40. // Resize output to fit number of ones
  41. C.resize(F.size());
  42. for(int i = 0;i< (int)F.size();i++)
  43. {
  44. // sorted face should definitely be in counts map
  45. assert(counts.find(sortedF[i]) != counts.end());
  46. C[i] = static_cast<IntegerC>(counts[sortedF[i]]);
  47. }
  48. }
  49. template <typename DerivedF, typename DerivedC>
  50. IGL_INLINE void igl::face_occurrences(
  51. const Eigen::MatrixBase<DerivedF> & F,
  52. Eigen::PlainObjectBase<DerivedC> & C)
  53. {
  54. // Should really just rewrite using Eigen+libigl ...
  55. std::vector<std::vector<typename DerivedF::Scalar> > vF;
  56. matrix_to_list(F,vF);
  57. std::vector<typename DerivedC::Scalar> vC;
  58. igl::face_occurrences(vF,vC);
  59. list_to_matrix(vC,C);
  60. }
  61. #ifdef IGL_STATIC_LIBRARY
  62. // Explicit template instantiation
  63. // generated by autoexplicit.sh
  64. template void igl::face_occurrences<unsigned int, int>(std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > > const&, std::vector<int, std::allocator<int> >&);
  65. template void igl::face_occurrences<int, int>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::vector<int, std::allocator<int> >&);
  66. #endif