// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2016 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "ismember.h" #include "colon.h" #include "list_to_matrix.h" #include "sort.h" #include "sortrows.h" #include "unique.h" #include "unique_rows.h" #include template < typename DerivedA, typename DerivedB, typename DerivedIA, typename DerivedLOCB> IGL_INLINE void igl::ismember( const Eigen::MatrixBase & A, const Eigen::MatrixBase & B, Eigen::PlainObjectBase & IA, Eigen::PlainObjectBase & LOCB) { using namespace Eigen; using namespace std; IA.resizeLike(A); IA.setConstant(false); LOCB.resizeLike(A); LOCB.setConstant(-1); // boring base cases if(A.size() == 0) { return; } if(B.size() == 0) { return; } // Get rid of any duplicates typedef Matrix VectorA; typedef Matrix VectorB; const VectorA vA(Eigen::Map(DerivedA(A).data(), A.cols()*A.rows(),1)); const VectorB vB(Eigen::Map(DerivedB(B).data(), B.cols()*B.rows(),1)); VectorA uA; VectorB uB; Eigen::Matrix uIA,uIuA,uIB,uIuB; unique(vA,uA,uIA,uIuA); unique(vB,uB,uIB,uIuB); // Sort both VectorA sA; VectorB sB; Eigen::Matrix sIA,sIB; sort(uA,1,true,sA,sIA); sort(uB,1,true,sB,sIB); Eigen::Matrix uF = Eigen::Matrix::Zero(sA.size(),1); Eigen::Matrix uLOCB = Eigen::Matrix:: Constant(sA.size(),1,-1); { int bi = 0; // loop over sA bool past = false; for(int a = 0;asB(bi)) { bi++; past = bi>=sB.size(); } if(!past && sA(a)==sB(bi)) { uF(sIA(a)) = true; uLOCB(sIA(a)) = uIB(sIB(bi)); } } } Map< Matrix > vIA(IA.data(),IA.cols()*IA.rows(),1); Map< Matrix > vLOCB(LOCB.data(),LOCB.cols()*LOCB.rows(),1); for(int a = 0;a IGL_INLINE void igl::ismember_rows( const Eigen::MatrixBase & A, const Eigen::MatrixBase & B, Eigen::PlainObjectBase & IA, Eigen::PlainObjectBase & LOCB) { using namespace Eigen; using namespace std; assert(A.cols() == B.cols() && "number of columns must match"); IA.resize(A.rows(),1); IA.setConstant(false); LOCB.resize(A.rows(),1); LOCB.setConstant(-1); // boring base cases if(A.size() == 0) { return; } if(B.size() == 0) { return; } // Get rid of any duplicates DerivedA uA; DerivedB uB; Eigen::Matrix uIA,uIuA,uIB,uIuB; unique_rows(A,uA,uIA,uIuA); unique_rows(B,uB,uIB,uIuB); // Sort both DerivedA sA; DerivedB sB; Eigen::Matrix sIA,sIB; sortrows(uA,true,sA,sIA); sortrows(uB,true,sB,sIB); Eigen::Matrix uF = Eigen::Matrix::Zero(sA.size(),1); Eigen::Matrix uLOCB = Eigen::Matrix:: Constant(sA.size(),1,-1); const auto & row_greater_than = [&sA,&sB](const int a, const int b) { for(int c = 0;c sB(b,c)) return true; if(sA(a,c) < sB(b,c)) return false; } return false; }; { int bi = 0; // loop over sA bool past = false; for(int a = 0;a=sB.rows(); } if(!past && (sA.row(a).array()==sB.row(bi).array()).all() ) { uF(sIA(a)) = true; uLOCB(sIA(a)) = uIB(sIB(bi)); } } } for(int a = 0;a, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::ismember_rows, Eigen::Matrix, Eigen::Array, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::ismember_rows, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::ismember_rows, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::ismember_rows, Eigen::Matrix, Eigen::Array, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif