void SoftBody::updateNeighborhoods() { auto kdTree = KdTree(posRest); std::vector<uint32_t> indices; indices.reserve(Neighborhood::MAX_SIZE + 1); auto neighbor_it = neighborhoods.begin(); auto radius_it = radii.begin(); uint32_t index = 0; for (auto& u : posRest) { // // A particle's neighborhood should not include itself. However, this // kdTree will return an index for the current particle. So increment // the neighbor count by 1, and then remove the "self" particle when // we're done. // kdTree.neighbors(posRest, u, Neighborhood::MAX_SIZE + 1, *radius_it, indices); auto selfLocation = std::find(indices.begin(), indices.end(), index); if (selfLocation != indices.end()) { indices.erase(selfLocation); } // If we find a neighbor we didn't already have, add it with an initial // weight of zero. // Neighborhood newNeighbors; for (auto j : indices) { if (neighbor_it->hasNeighbor(j)) { newNeighbors.push_back(neighbor_it->findNeighbor(j)); } else { Vector3d u_ij = posRest[j] - u; Neighbor n(j, u_ij, 0.0); newNeighbors.push_back(n); } } *neighbor_it = newNeighbors; ++neighbor_it; ++radius_it; ++index; } }
void mergeNeighborhoods(Neighborhood &n1, Neighborhood &n2) { Neighborhood::iterator it1, it2; bool present; for (it2 = n2.begin(); it2 != n2.end(); it2++) { present = false; for (it1 = n1.begin(); it1 != n1.end(); it1++) { if ( *it1 == *it2 ) { present = true; break; } } if (!present) { n1.push_back( *it2 ); } } }