setdiff.cpp 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 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 "setdiff.h"
  9. #include "LinSpaced.h"
  10. #include "list_to_matrix.h"
  11. #include "sort.h"
  12. #include "unique.h"
  13. template <
  14. typename DerivedA,
  15. typename DerivedB,
  16. typename DerivedC,
  17. typename DerivedIA>
  18. IGL_INLINE void igl::setdiff(
  19. const Eigen::MatrixBase<DerivedA> & A,
  20. const Eigen::MatrixBase<DerivedB> & B,
  21. Eigen::PlainObjectBase<DerivedC> & C,
  22. Eigen::PlainObjectBase<DerivedIA> & IA)
  23. {
  24. // boring base cases
  25. if(A.size() == 0)
  26. {
  27. C.resize(0,1);
  28. IA.resize(0,1);
  29. return;
  30. }
  31. // Get rid of any duplicates
  32. typedef Eigen::Matrix<typename DerivedA::Scalar ,Eigen::Dynamic,1> VectorA;
  33. typedef Eigen::Matrix<typename DerivedB::Scalar ,Eigen::Dynamic,1> VectorB;
  34. VectorA uA;
  35. VectorB uB;
  36. typedef DerivedIA IAType;
  37. IAType uIA,uIuA,uIB,uIuB;
  38. unique(A,uA,uIA,uIuA);
  39. unique(B,uB,uIB,uIuB);
  40. // Sort both
  41. VectorA sA;
  42. VectorB sB;
  43. IAType sIA,sIB;
  44. sort(uA,1,true,sA,sIA);
  45. sort(uB,1,true,sB,sIB);
  46. std::vector<typename DerivedB::Scalar> vC;
  47. std::vector<typename DerivedIA::Scalar> vIA;
  48. int bi = 0;
  49. // loop over sA
  50. bool past = false;
  51. bool sBempty = sB.size()==0;
  52. for(int a = 0;a<sA.size();a++)
  53. {
  54. while(!sBempty && !past && sA(a)>sB(bi))
  55. {
  56. bi++;
  57. past = bi>=sB.size();
  58. }
  59. if(sBempty || past || sA(a)<sB(bi))
  60. {
  61. // then sA(a) did not appear in sB
  62. vC.push_back(sA(a));
  63. vIA.push_back(uIA(sIA(a)));
  64. }
  65. }
  66. list_to_matrix(vC,C);
  67. list_to_matrix(vIA,IA);
  68. }
  69. #ifdef IGL_STATIC_LIBRARY
  70. // Explicit template instantiation
  71. // generated by autoexplicit.sh
  72. template void igl::setdiff<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  73. template void igl::setdiff<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  74. template void igl::setdiff<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  75. template void igl::setdiff<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  76. template void igl::setdiff<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  77. #endif