setdiff.cpp 3.3 KB

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