setdiff.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <alecjacobson@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 "setdiff.h"
  9. #include "colon.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::DenseBase<DerivedA> & A,
  20. const Eigen::DenseBase<DerivedB> & B,
  21. Eigen::PlainObjectBase<DerivedC> & C,
  22. Eigen::PlainObjectBase<DerivedIA> & IA)
  23. {
  24. using namespace Eigen;
  25. using namespace std;
  26. // boring base cases
  27. if(A.size() == 0)
  28. {
  29. C.resize(0,1);
  30. IA.resize(0,1);
  31. }
  32. if(B.size() == 0)
  33. {
  34. C.resize(A.size(),1);
  35. int k = 0;
  36. for(int j = 0;j<A.cols();j++)
  37. {
  38. for(int i = 0;i<A.rows();i++)
  39. {
  40. C(k++) = A(i,j);
  41. }
  42. }
  43. assert(k == C.size());
  44. IA = Eigen::Matrix<typename DerivedIA::Scalar,Eigen::Dynamic,1>::LinSpaced(
  45. C.size(),0,C.size()-1);
  46. }
  47. // Get rid of any duplicates
  48. typedef Matrix<typename DerivedA::Scalar,Dynamic,1> VectorA;
  49. typedef Matrix<typename DerivedB::Scalar,Dynamic,1> VectorB;
  50. VectorA uA;
  51. VectorB uB;
  52. typedef DerivedIA IAType;
  53. IAType uIA,uIuA,uIB,uIuB;
  54. unique(A,uA,uIA,uIuA);
  55. unique(B,uB,uIB,uIuB);
  56. // Sort both
  57. VectorA sA;
  58. VectorB sB;
  59. IAType sIA,sIB;
  60. sort(uA,1,true,sA,sIA);
  61. sort(uB,1,true,sB,sIB);
  62. vector<typename DerivedB::Scalar> vC;
  63. vector<typename DerivedIA::Scalar> vIA;
  64. int bi = 0;
  65. // loop over sA
  66. bool past = false;
  67. for(int a = 0;a<sA.size();a++)
  68. {
  69. while(!past && sA(a)>sB(bi))
  70. {
  71. bi++;
  72. past = bi>=sB.size();
  73. }
  74. if(past || sA(a)<sB(bi))
  75. {
  76. // then sA(a) did not appear in sB
  77. vC.push_back(sA(a));
  78. vIA.push_back(uIA(sIA(a)));
  79. }
  80. }
  81. list_to_matrix(vC,C);
  82. list_to_matrix(vIA,IA);
  83. }
  84. #ifdef IGL_STATIC_LIBRARY
  85. // Explicit template specialization
  86. // generated by autoexplicit.sh
  87. 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::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::DenseBase<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> >&);
  88. 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::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::DenseBase<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> >&);
  89. 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::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::DenseBase<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> >&);
  90. 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::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::DenseBase<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> >&);
  91. #endif