37 const Eigen::MatrixX3f& vertices,
42 const Eigen::Index nVert = vertices.rows();
43 const Eigen::Index nContacts = contacts.rows();
44 Eigen::SparseMatrix<double> w(nVert, nContacts);
45 if (nVert == 0 || nContacts == 0 || distance <= 0.0)
49 const Eigen::MatrixX3d rr = vertices.cast<
double>();
50 std::vector<std::vector<std::pair<Eigen::Index, double>>> near(
static_cast<size_t>(nVert));
51 const double reach2 = distance * distance;
52 for (Eigen::Index c = 0; c < nContacts; ++c) {
53 Eigen::RowVector3d pos = contacts.row(c).cast<
double>();
56 Eigen::VectorXd d2 = (rr.rowwise() - pos).rowwise().squaredNorm();
58 Eigen::Index nearest = 0;
59 d2.minCoeff(&nearest);
60 pos = rr.row(nearest);
61 d2 = (rr.rowwise() - pos).rowwise().squaredNorm();
63 for (Eigen::Index v = 0; v < nVert; ++v) {
65 near[size_t(v)].emplace_back(c, 1.0 - std::sqrt(d2(v)) / distance);
69 std::vector<Eigen::Triplet<double>> entries;
70 for (Eigen::Index v = 0; v < nVert; ++v) {
71 auto& list = near[size_t(v)];
76 auto best = list.begin();
77 for (
auto it = list.begin(); it != list.end(); ++it) {
78 if (it->second > best->second)
87 for (
const auto& [c, weight] : list)
89 norm = sum > 0.0 ? sum : 1.0;
91 for (
const auto& [c, weight] : list) {
93 entries.emplace_back(v, c, weight / norm);
96 w.setFromTriplets(entries.begin(), entries.end());
static Eigen::SparseMatrix< double > weights(const Eigen::MatrixX3f &contacts, const Eigen::MatrixX3f &vertices, double distance=0.01, IeegSurfaceMapMode mode=IeegSurfaceMapMode::Sum, bool project=true)