| // This file is part of libigl, a simple c++ geometry processing library. |
| // |
| // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com> |
| // |
| // 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 "vertex_components.h" |
| #include "adjacency_matrix.h" |
| #include <queue> |
| #include <vector> |
| |
| template <typename DerivedA, typename DerivedC, typename Derivedcounts> |
| IGL_INLINE void igl::vertex_components( |
| const Eigen::SparseCompressedBase<DerivedA> & A, |
| Eigen::PlainObjectBase<DerivedC> & C, |
| Eigen::PlainObjectBase<Derivedcounts> & counts) |
| { |
| using namespace Eigen; |
| using namespace std; |
| assert(A.rows() == A.cols() && "A should be square."); |
| const size_t n = A.rows(); |
| Array<bool,Dynamic,1> seen = Array<bool,Dynamic,1>::Zero(n,1); |
| C.resize(n,1); |
| typename DerivedC::Scalar id = 0; |
| vector<typename Derivedcounts::Scalar> vcounts; |
| // breadth first search |
| for(int k=0; k<A.outerSize(); ++k) |
| { |
| if(seen(k)) |
| { |
| continue; |
| } |
| queue<int> Q; |
| Q.push(k); |
| vcounts.push_back(0); |
| while(!Q.empty()) |
| { |
| const int f = Q.front(); |
| Q.pop(); |
| if(seen(f)) |
| { |
| continue; |
| } |
| seen(f) = true; |
| C(f,0) = id; |
| vcounts[id]++; |
| // Iterate over inside |
| for(typename DerivedA::InnerIterator it (A,f); it; ++it) |
| { |
| const int g = it.index(); |
| if(!seen(g) && it.value()) |
| { |
| Q.push(g); |
| } |
| } |
| } |
| id++; |
| } |
| assert((size_t) id == vcounts.size()); |
| const size_t ncc = vcounts.size(); |
| assert((size_t)C.maxCoeff()+1 == ncc); |
| counts.resize(ncc,1); |
| for(size_t i = 0;i<ncc;i++) |
| { |
| counts(i) = vcounts[i]; |
| } |
| } |
| |
| template <typename DerivedA, typename DerivedC> |
| IGL_INLINE void igl::vertex_components( |
| const Eigen::SparseCompressedBase<DerivedA> & A, |
| Eigen::PlainObjectBase<DerivedC> & C) |
| { |
| Eigen::VectorXi counts; |
| return vertex_components(A,C,counts); |
| } |
| |
| template <typename DerivedF, typename DerivedC> |
| IGL_INLINE void igl::vertex_components( |
| const Eigen::MatrixBase<DerivedF> & F, |
| Eigen::PlainObjectBase<DerivedC> & C) |
| { |
| Eigen::SparseMatrix<typename DerivedC::Scalar> A; |
| adjacency_matrix(F,A); |
| return vertex_components(A,C); |
| } |
| |
| #ifdef IGL_STATIC_LIBRARY |
| // Explicit template instantiation |
| // generated by autoexplicit.sh |
| template void igl::vertex_components<Eigen::SparseMatrix<bool, 0, int>, Eigen::Array<int, -1, 1, 0, -1, 1> >(Eigen::SparseCompressedBase<Eigen::SparseMatrix<bool, 0, int>> const&, Eigen::PlainObjectBase<Eigen::Array<int, -1, 1, 0, -1, 1> >&); |
| template void igl::vertex_components<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::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&); |
| template void igl::vertex_components<Eigen::SparseMatrix<int, 0, int>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseCompressedBase<Eigen::SparseMatrix<int, 0, int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&); |
| template void igl::vertex_components<Eigen::SparseMatrix<int, 0, int>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::SparseCompressedBase<Eigen::SparseMatrix<int, 0, int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&); |
| template void igl::vertex_components<Eigen::SparseMatrix<double, 0, int>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::SparseCompressedBase<Eigen::SparseMatrix<double, 0, int>> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&); |
| template void igl::vertex_components<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::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&); |
| #endif |