setdiff.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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 "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::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. return;
  32. }
  33. // Get rid of any duplicates
  34. typedef Matrix<typename DerivedA::Scalar,Dynamic,1> VectorA;
  35. typedef Matrix<typename DerivedB::Scalar,Dynamic,1> VectorB;
  36. VectorA uA;
  37. VectorB uB;
  38. typedef DerivedIA IAType;
  39. IAType uIA,uIuA,uIB,uIuB;
  40. unique(A,uA,uIA,uIuA);
  41. unique(B,uB,uIB,uIuB);
  42. // Sort both
  43. VectorA sA;
  44. VectorB sB;
  45. IAType sIA,sIB;
  46. sort(uA,1,true,sA,sIA);
  47. sort(uB,1,true,sB,sIB);
  48. vector<typename DerivedB::Scalar> vC;
  49. vector<typename DerivedIA::Scalar> vIA;
  50. int bi = 0;
  51. // loop over sA
  52. bool past = false;
  53. bool sBempty = sB.size()==0;
  54. for(int a = 0;a<sA.size();a++)
  55. {
  56. while(!sBempty && !past && sA(a)>sB(bi))
  57. {
  58. bi++;
  59. past = bi>=sB.size();
  60. }
  61. if(sBempty || past || sA(a)<sB(bi))
  62. {
  63. // then sA(a) did not appear in sB
  64. vC.push_back(sA(a));
  65. vIA.push_back(uIA(sIA(a)));
  66. }
  67. }
  68. list_to_matrix(vC,C);
  69. list_to_matrix(vIA,IA);
  70. }
  71. #ifdef IGL_STATIC_LIBRARY
  72. // Explicit template instantiation
  73. // generated by autoexplicit.sh
  74. 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> >&);
  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::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> >&);
  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::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> >&);
  77. 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> >&);
  78. 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> >&);
  79. #endif