[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