void Concat::evaluateGen(const MatV& input, MatV& output, std::vector<int>& itmp, std::vector<T>& rtmp) { typename vector<T>::iterator res_it = output[0]->data().begin(); for (int i=0; i<input.size(); ++i) { const vector<T>& arg_i = input[i]->data(); copy(arg_i.begin(), arg_i.end(), res_it); res_it += arg_i.size(); } }
IGL_INLINE void igl::arap_linear_block_spokes( const MatV & V, const MatF & F, const int d, Eigen::SparseMatrix<Scalar> & Kd) { using namespace std; using namespace Eigen; // simplex size (3: triangles, 4: tetrahedra) int simplex_size = F.cols(); // Number of elements int m = F.rows(); // Temporary output Matrix<int,Dynamic,2> edges; Kd.resize(V.rows(), V.rows()); vector<Triplet<Scalar> > Kd_IJV; if(simplex_size == 3) { // triangles Kd.reserve(7*V.rows()); Kd_IJV.reserve(7*V.rows()); edges.resize(3,2); edges << 1,2, 2,0, 0,1; }else if(simplex_size == 4) { // tets Kd.reserve(17*V.rows()); Kd_IJV.reserve(17*V.rows()); edges.resize(6,2); edges << 1,2, 2,0, 0,1, 3,0, 3,1, 3,2; } // gather cotangent weights Matrix<Scalar,Dynamic,Dynamic> C; cotmatrix_entries(V,F,C); // should have weights for each edge assert(C.cols() == edges.rows()); // loop over elements for(int i = 0;i<m;i++) { // loop over edges of element for(int e = 0;e<edges.rows();e++) { int source = F(i,edges(e,0)); int dest = F(i,edges(e,1)); double v = 0.5*C(i,e)*(V(source,d)-V(dest,d)); Kd_IJV.push_back(Triplet<Scalar>(source,dest,v)); Kd_IJV.push_back(Triplet<Scalar>(dest,source,-v)); Kd_IJV.push_back(Triplet<Scalar>(source,source,v)); Kd_IJV.push_back(Triplet<Scalar>(dest,dest,-v)); } } Kd.setFromTriplets(Kd_IJV.begin(),Kd_IJV.end()); Kd.makeCompressed(); }
IGL_INLINE void igl::faces_first( const MatV & V, const MatF & F, MatV & RV, MatF & RF, VecI & IM) { assert(&V != &RV); assert(&F != &RF); using namespace std; using namespace Eigen; vector<bool> in_face(V.rows()); for(int i = 0; i<F.rows(); i++) { for(int j = 0; j<F.cols(); j++) { in_face[F(i,j)] = true; } } // count number of vertices not in faces int num_in_F = 0; for(int i = 0;i<V.rows();i++) { num_in_F += (in_face[i]?1:0); } // list of unique vertices that occur in F VectorXi U(num_in_F); // list of unique vertices that do not occur in F VectorXi NU(V.rows()-num_in_F); int Ui = 0; int NUi = 0; // loop over vertices for(int i = 0;i<V.rows();i++) { if(in_face[i]) { U(Ui) = i; Ui++; }else { NU(NUi) = i; NUi++; } } IM.resize(V.rows()); // reindex vertices that occur in faces to be first for(int i = 0;i<U.size();i++) { IM(U(i)) = i; } // reindex vertices that do not occur in faces to come after those that do for(int i = 0;i<NU.size();i++) { IM(NU(i)) = i+U.size(); } RF.resize(F.rows(),F.cols()); // Reindex faces for(int i = 0; i<F.rows(); i++) { for(int j = 0; j<F.cols(); j++) { RF(i,j) = IM(F(i,j)); } } RV.resize(V.rows(),V.cols()); // Reorder vertices for(int i = 0;i<V.rows();i++) { RV.row(IM(i)) = V.row(i); } }