// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 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 "grad.h" #include #include template IGL_INLINE void igl::grad(const Eigen::PlainObjectBase&V, const Eigen::PlainObjectBase&F, Eigen::SparseMatrix &G) { Eigen::Matrix eperp21(F.rows(),3), eperp13(F.rows(),3); for (int i=0;i v32 = V.row(i3) - V.row(i2); Eigen::Matrix v13 = V.row(i1) - V.row(i3); Eigen::Matrix v21 = V.row(i2) - V.row(i1); // area of parallelogram is twice area of triangle // area of parallelogram is || v1 x v2 || Eigen::Matrix n = v32.cross(v13); // This does correct l2 norm of rows, so that it contains #F list of twice // triangle areas double dblA = std::sqrt(n.dot(n)); // now normalize normals to get unit normals Eigen::Matrix u = n / dblA; // rotate each vector 90 degrees around normal double norm21 = std::sqrt(v21.dot(v21)); double norm13 = std::sqrt(v13.dot(v13)); eperp21.row(i) = u.cross(v21); eperp21.row(i) = eperp21.row(i) / std::sqrt(eperp21.row(i).dot(eperp21.row(i))); eperp21.row(i) *= norm21 / dblA; eperp13.row(i) = u.cross(v13); eperp13.row(i) = eperp13.row(i) / std::sqrt(eperp13.row(i).dot(eperp13.row(i))); eperp13.row(i) *= norm13 / dblA; } std::vector rs; rs.reserve(F.rows()*4*3); std::vector cs; cs.reserve(F.rows()*4*3); std::vector vs; vs.reserve(F.rows()*4*3); // row indices for(int r=0;r<3;r++) { for(int j=0;j<4;j++) { for(int i=r*F.rows();i<(r+1)*F.rows();i++) rs.push_back(i); } } // column indices for(int r=0;r<3;r++) { for(int i=0;i > triplets; for (int i=0;i<(int)vs.size();++i) { triplets.push_back(Eigen::Triplet(rs[i],cs[i],vs[i])); } G.setFromTriplets(triplets.begin(), triplets.end()); } #ifdef IGL_STATIC_LIBRARY // Explicit template specialization // template void igl::grad(Eigen::Matrix const&, Eigen::Matrix const&,Eigen::SparseMatrix&); template void igl::grad, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::SparseMatrix::Scalar, 0, int>&); //template void igl::grad, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::SparseMatrix::Scalar, 0, int>&); template void igl::grad, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::SparseMatrix::Scalar, 0, int>&); #endif