[Bf-blender-cvs] [c4484057685] soc-2020-soft-body: fixed mcgs
over0219
noreply at git.blender.org
Thu Jul 2 01:26:29 CEST 2020
Commit: c4484057685a905876ed472a61a0fc0f6085f885
Author: over0219
Date: Wed Jul 1 18:26:23 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBc4484057685a905876ed472a61a0fc0f6085f885
fixed mcgs
===================================================================
M extern/softbody/src/admmpd_collision.cpp
M extern/softbody/src/admmpd_collision.h
M extern/softbody/src/admmpd_embeddedmesh.cpp
M extern/softbody/src/admmpd_embeddedmesh.h
M extern/softbody/src/admmpd_linsolve.cpp
M extern/softbody/src/admmpd_linsolve.h
M extern/softbody/src/admmpd_solver.cpp
M extern/softbody/src/admmpd_types.h
M intern/softbody/admmpd_api.cpp
===================================================================
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 289af9fc68b..3ff7f949215 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -75,7 +75,6 @@ void Collision::detect_discrete_vf(
const Eigen::MatrixXd *mesh_x,
const Eigen::MatrixXi *mesh_tris,
bool mesh_is_obs,
- double floor_z,
std::vector<VFCollisionPair> *pairs)
{
// Any faces to detect against?
@@ -170,9 +169,9 @@ static void parallel_detect(
if (td->embmesh != nullptr)
{
- int tet_idx = td->embmesh->vtx_to_tet[i];
+ int tet_idx = td->embmesh->emb_vtx_to_tet[i];
RowVector4i tet = td->embmesh->tets.row(tet_idx);
- Vector4d bary = td->embmesh->barys.row(i);
+ Vector4d bary = td->embmesh->emb_barys.row(i);
Vector3d pt =
bary[0] * td->x1->row(tet[0]) +
bary[1] * td->x1->row(tet[1]) +
@@ -198,7 +197,6 @@ static void parallel_detect(
&td->obsdata->V1,
&td->obsdata->F,
true,
- td->floor_z,
&tl_pairs );
// Collision::detect_discrete_vf(
@@ -227,6 +225,10 @@ int EmbeddedMeshCollision::detect(
std::vector<std::vector<VFCollisionPair> > pt_vf_pairs
(max_threads, std::vector<VFCollisionPair>());
+ double floor_z = this->settings.floor_z;
+ if (!this->settings.test_floor)
+ floor_z = -std::numeric_limits<double>::max();
+
DetectThreadData thread_data = {
.tetmesh = nullptr,
.embmesh = mesh,
@@ -237,11 +239,10 @@ int EmbeddedMeshCollision::detect(
.pt_vf_pairs = &pt_vf_pairs
};
- int nev = mesh->x_rest.rows();
-
- TaskParallelSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- BLI_task_parallel_range(0, nev, &thread_data, parallel_detect, &settings);
+ int nev = mesh->emb_rest_x.rows();
+ TaskParallelSettings thrd_settings;
+ BLI_parallel_range_settings_defaults(&thrd_settings);
+ BLI_task_parallel_range(0, nev, &thread_data, parallel_detect, &thrd_settings);
// Combine thread-local results
vf_pairs.clear();
@@ -254,6 +255,59 @@ int EmbeddedMeshCollision::detect(
return vf_pairs.size();
} // end detect
+void EmbeddedMeshCollision::graph(
+ std::vector<std::set<int> > &g)
+{
+ int np = vf_pairs.size();
+ if (np==0)
+ return;
+
+ int nv = mesh->rest_x.rows();
+ if ((int)g.size() < nv)
+ g.resize(nv, std::set<int>());
+
+ for (int i=0; i<np; ++i)
+ {
+ VFCollisionPair &pair = vf_pairs[i];
+ std::set<int> stencil;
+
+ if (!pair.p_is_obs)
+ {
+ int tet_idx = mesh->emb_vtx_to_tet[pair.p_idx];
+ RowVector4i tet = mesh->tets.row(tet_idx);
+ stencil.emplace(tet[0]);
+ stencil.emplace(tet[1]);
+ stencil.emplace(tet[2]);
+ stencil.emplace(tet[3]);
+ }
+ if (!pair.q_is_obs)
+ {
+ RowVector3i emb_face = mesh->emb_faces.row(pair.q_idx);
+ for (int j=0; j<3; ++j)
+ {
+ int tet_idx = mesh->emb_vtx_to_tet[emb_face[j]];
+ RowVector4i tet = mesh->tets.row(tet_idx);
+ stencil.emplace(tet[0]);
+ stencil.emplace(tet[1]);
+ stencil.emplace(tet[2]);
+ stencil.emplace(tet[3]);
+ }
+ }
+
+ for (std::set<int>::iterator it = stencil.begin();
+ it != stencil.end(); ++it)
+ {
+ for (std::set<int>::iterator it2 = stencil.begin();
+ it2 != stencil.end(); ++it2)
+ {
+ if (*it == *it2)
+ continue;
+ g[*it].emplace(*it2);
+ }
+ }
+ }
+} // end graph
+
void EmbeddedMeshCollision::linearize(
const Eigen::MatrixXd *x,
std::vector<Eigen::Triplet<double> > *trips,
@@ -314,8 +368,8 @@ void EmbeddedMeshCollision::linearize(
// Obstacle collision
if (pair.q_is_obs)
{
- RowVector4d bary = mesh->barys.row(emb_p_idx);
- int tet_idx = mesh->vtx_to_tet[emb_p_idx];
+ RowVector4d bary = mesh->emb_barys.row(emb_p_idx);
+ int tet_idx = mesh->emb_vtx_to_tet[emb_p_idx];
RowVector4i tet = mesh->tets.row(tet_idx);
int c_idx = d->size();
d->emplace_back(q_n.dot(pair.pt_on_q));
diff --git a/extern/softbody/src/admmpd_collision.h b/extern/softbody/src/admmpd_collision.h
index 95623510969..22d7dd58f8c 100644
--- a/extern/softbody/src/admmpd_collision.h
+++ b/extern/softbody/src/admmpd_collision.h
@@ -6,6 +6,7 @@
#include "admmpd_bvh.h"
#include "admmpd_types.h"
+#include <set>
namespace admmpd {
@@ -29,6 +30,16 @@ public:
AABBTree<double,3> tree;
} obsdata;
+ struct Settings {
+ double floor_z;
+ bool test_floor;
+ Settings() :
+ floor_z(0),
+// floor_z(-std::numeric_limits<double>::max()),
+ test_floor(true)
+ {}
+ } settings;
+
virtual ~Collision() {}
// Performs collision detection.
@@ -37,6 +48,11 @@ public:
const Eigen::MatrixXd *x0,
const Eigen::MatrixXd *x1) = 0;
+ // Appends the per-vertex graph of dependencies
+ // for constraints (ignores obstacles).
+ virtual void graph(
+ std::vector<std::set<int> > &g) = 0;
+
// Set the soup of obstacles for this time step.
// I don't really like having to switch up interface style, but we'll
// do so here to avoid copies that would happen in admmpd_api.
@@ -48,7 +64,8 @@ public:
int nf);
// Special case for floor since it's common.
- virtual void set_floor(double z) = 0;
+ virtual void set_floor(double z) { settings.floor_z=z; }
+ virtual double get_floor() const { return settings.floor_z; }
// Linearize the constraints and return Jacobian.
virtual void linearize(
@@ -68,31 +85,22 @@ public:
const Eigen::MatrixXd *mesh_x,
const Eigen::MatrixXi *mesh_tris,
bool mesh_is_obs,
- double floor_z,
std::vector<VFCollisionPair> *pairs);
};
// Collision detection against multiple meshes
class EmbeddedMeshCollision : public Collision {
public:
- EmbeddedMeshCollision(const EmbeddedMeshData *mesh_) :
- mesh(mesh_),
-// floor_z(-std::numeric_limits<double>::max())
- floor_z(0)
- {}
-
- // A floor is so common that it makes sense to hard
- // code floor collision instead of using a floor mesh.
- void set_floor(double z)
- {
- floor_z = z;
- };
+ EmbeddedMeshCollision(const EmbeddedMeshData *mesh_) : mesh(mesh_){}
// Performs collision detection and stores pairs
int detect(
const Eigen::MatrixXd *x0,
const Eigen::MatrixXd *x1);
+ void graph(
+ std::vector<std::set<int> > &g);
+
// Linearizes the collision pairs about x
// for the constraint Kx=l
void linearize(
@@ -103,7 +111,6 @@ public:
protected:
// A ptr to the embedded mesh data
const EmbeddedMeshData *mesh;
- double floor_z;
// Pairs are compute on detect
std::vector<VFCollisionPair> vf_pairs;
diff --git a/extern/softbody/src/admmpd_embeddedmesh.cpp b/extern/softbody/src/admmpd_embeddedmesh.cpp
index 0c2cdcac938..17e2b28c0e8 100644
--- a/extern/softbody/src/admmpd_embeddedmesh.cpp
+++ b/extern/softbody/src/admmpd_embeddedmesh.cpp
@@ -215,11 +215,10 @@ bool EmbeddedMesh::generate(
const Eigen::MatrixXd &V, // embedded verts
const Eigen::MatrixXi &F, // embedded faces
EmbeddedMeshData *emb_mesh, // where embedding is stored
- Eigen::MatrixXd *x_tets, // lattice vertices, n x 3
bool trim_lattice)
{
- emb_mesh->faces = F;
- emb_mesh->x_rest = V;
+ emb_mesh->emb_faces = F;
+ emb_mesh->emb_rest_x = V;
AlignedBox<double,3> aabb;
int nev = V.rows();
@@ -315,14 +314,14 @@ bool EmbeddedMesh::generate(
int ntv0 = data.verts.size(); // original num verts
int ntv1 = refd_verts.size(); // reduced num verts
BLI_assert(ntv1 <= ntv0);
- x_tets->resize(ntv1,3);
+ emb_mesh->rest_x.resize(ntv1,3);
int vtx_count = 0;
for (int i=0; i<ntv0; ++i)
{
if (refd_verts.count(i)>0)
{
for(int j=0; j<3; ++j){
- x_tets->operator()(vtx_count,j) = data.verts[i][j];
+ emb_mesh->rest_x(vtx_count,j) = data.verts[i][j];
}
vtx_old_to_new[i] = vtx_count;
vtx_count++;
@@ -342,8 +341,7 @@ bool EmbeddedMesh::generate(
}
// Now compute the baryweighting for embedded vertices
- return compute_embedding(
- emb_mesh, &V, x_tets);
+ return compute_embedding(emb_mesh);
} // end gen lattice
@@ -352,16 +350,10 @@ bool EmbeddedMesh::generate(
void EmbeddedMesh::compute_masses(
EmbeddedMeshData *emb_mesh, // where embedding is stored
- const Eigen::MatrixXd *x_embed, // embedded vertices, p x 3
- const Eigen::MatrixXd *x_tets, // lattice vertices, n x 3
Eigen::VectorXd *masses_tets, // masses of the lattice verts
double density_kgm3)
{
BLI_assert(emb_mesh != NULL);
- BLI_assert(x_embed != NULL);
- BLI_assert(x_tets != NULL);
- BLI_assert(x_tets->rows() > 0);
- BLI_assert(x_tets->cols() == 3);
BLI_assert(masses_tets != NULL);
BLI_assert(density_kgm3 > 0);
@@ -371,18 +363,18 @@ void EmbeddedMesh::compute_masses(
// Source: https://github.com/mattoverby/mclscene/blob/master/include/MCL/TetMesh.hpp
// Computes volume-weighted masses for each vertex
// density_kgm3 is the unit-volume density
- int nx = x_tets->rows();
+ int nx = emb_mesh->rest_x.rows();
masses_tets->resize(nx);
masses_tets->setZero();
int n_tets = emb_mesh->tets.rows();
for (int t=0; t<n_tets; ++t)
{
RowVector4i tet = emb_mesh->tets.row(t);
- RowVector3d tet_v0 = x_tets->row(tet[0]);
+ RowVector3d tet_v0 = emb_mesh->rest_x.row(tet[0]);
Matrix3d edges;
- edges.col(0) = x_tets->row(tet[1]) - tet_v0;
- edges.col(1) = x_tets->row(tet[2]) - tet_v0;
- edges.col(2) = x_tets->row(tet[3]) - tet_v0;
+ edges.col(0) = emb_mesh->rest_x.row(tet[1]) - tet_v0;
+ edges.col(1) = emb_mesh->rest_x.row(tet[2]) - tet_v0;
+ edges.col(2) = emb_mesh->rest_x.row(tet[3]) - tet_v0;
double vol = std::abs((edges).determinant()/6.f);
double tet_mass = density_kgm3 * vol;
masses_tets->operator[](tet[0]) += tet_mass / 4.f;
@@ -405,8 +397,6 @@ void EmbeddedMesh::compute_masses(
typedef struct FindTetThreadData {
AABBTree<double,3> *tree;
EmbeddedMeshData *emb_mesh; // thread sets vtx_to_tet and barys
- const Eigen::MatrixXd *x_embed;
- const Eigen::MatrixXd *x_tets;
} FindTetThreadData;
static void parallel_point_in_tet(
@@ -415,41 +405,40 @@ static void parallel_point_in_tet(
const TaskParallelTLS *__restrict UNUSED(tls))
{
FindTetThreadData *td = (F
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list