[Bf-blender-cvs] [50e2c479cc2] soc-2020-soft-body: changed up interface for lattice a bit

over0219 noreply at git.blender.org
Tue Jun 23 01:45:41 CEST 2020


Commit: 50e2c479cc22d0efd1d744720df64311d8fefb80
Author: over0219
Date:   Mon Jun 22 18:45:38 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB50e2c479cc22d0efd1d744720df64311d8fefb80

changed up interface for lattice a bit

===================================================================

M	extern/softbody/CMakeLists.txt
M	extern/softbody/src/admmpd_collision.cpp
M	extern/softbody/src/admmpd_collision.h
R079	extern/softbody/src/admmpd_lattice.cpp	extern/softbody/src/admmpd_embeddedmesh.cpp
A	extern/softbody/src/admmpd_embeddedmesh.h
D	extern/softbody/src/admmpd_lattice.h
M	extern/softbody/src/admmpd_solver.cpp
M	extern/softbody/src/admmpd_solver.h
A	extern/softbody/src/admmpd_types.h
M	intern/softbody/admmpd_api.cpp
M	source/blender/blenkernel/intern/softbody.c

===================================================================

diff --git a/extern/softbody/CMakeLists.txt b/extern/softbody/CMakeLists.txt
index 09fdc947dde..4d6ff3328b8 100644
--- a/extern/softbody/CMakeLists.txt
+++ b/extern/softbody/CMakeLists.txt
@@ -29,20 +29,21 @@ set(INC_SYS
 )
 
 set(SRC
-  src/admmpd_math.h
-  src/admmpd_math.cpp
-  src/admmpd_energy.h
-  src/admmpd_energy.cpp
-  src/admmpd_lattice.h
-  src/admmpd_lattice.cpp
-  src/admmpd_solver.h
-  src/admmpd_solver.cpp
-  src/admmpd_collision.h
-  src/admmpd_collision.cpp
   src/admmpd_bvh.h
   src/admmpd_bvh.cpp
   src/admmpd_bvh_traverse.h
   src/admmpd_bvh_traverse.cpp
+  src/admmpd_collision.h
+  src/admmpd_collision.cpp
+  src/admmpd_embeddedmesh.h
+  src/admmpd_embeddedmesh.cpp
+  src/admmpd_energy.h
+  src/admmpd_energy.cpp
+  src/admmpd_math.h
+  src/admmpd_math.cpp
+  src/admmpd_solver.h
+  src/admmpd_solver.cpp
+  src/admmpd_types.h
 )
 
 set(LIB
diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 7a53c91a150..02a197c4138 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -2,9 +2,101 @@
 // Distributed under the MIT License.
 
 #include "admmpd_collision.h"
+#include "BLI_assert.h"
 
 namespace admmpd {
+using namespace Eigen;
 
+void EmbeddedMeshCollision::set_obstacles(
+	const float *v0,
+	const float *v1,
+	int nv,
+	const int *faces,
+	int nf)
+{
+	if (obs_V0.rows() != nv)
+		obs_V0.resize(nv,3);
+
+	if (obs_V1.rows() != nv)
+		obs_V1.resize(nv,3);
+
+	for (int i=0; i<nv; ++i)
+	{
+		for (int j=0; j<3; ++j)
+		{
+			obs_V0(i,j) = v0[i*3+j];
+			obs_V1(i,j) = v1[i*3+j];
+		}
+	}
+
+	if (obs_F.rows() != nf)
+	{
+		obs_F.resize(nf,3);
+		obs_aabbs.resize(nf);
+	}
+
+	for (int i=0; i<nf; ++i)
+	{
+		obs_aabbs[i].setEmpty();
+		for (int j=0; j<3; ++j)
+		{
+			int fj = faces[i*3+j];
+			obs_F(i,j) = fj;
+			obs_aabbs[i].extend(obs_V0.row(fj).transpose());
+			obs_aabbs[i].extend(obs_V1.row(fj).transpose());
+		}
+	}
+
+	obs_tree.init(obs_aabbs);
+
+} // end add obstacle
+
+void EmbeddedMeshCollision::detect(const Eigen::MatrixXd *x0, const Eigen::MatrixXd *x1)
+{
+	/*
+	// First, update the positions of the embedded vertex
+	// and perform collision detection against obstacles
+	int n_ev = emb_V0.rows();
+	std::vector<int> colliding(n_ev,0);
+	for (int i=0; i<n_ev; ++i)
+	{
+		int t = vtx_to_tet->operator[](i);
+		BLI_assert(t >= 0);
+		BLI_assert(t < tets->rows());
+		RowVector4i tet = tets->row(t);
+		Vector4d bary = emb_barys->row(i);
+//		emb_V0.row(i) =
+//			bary[0] * x0->row(tet[0]) +
+//			bary[1] * x0->row(tet[1]) +
+//			bary[2] * x0->row(tet[2]) +
+//			bary[3] * x0->row(tet[3]);
+		Vector3d pt = 
+			bary[0] * x1->row(tet[0]) +
+			bary[1] * x1->row(tet[1]) +
+			bary[2] * x1->row(tet[2]) +
+			bary[3] * x1->row(tet[3]);
+//		emb_V1.row(i) =
+
+		// Check if we are inside the mesh.
+		// If so, find the nearest face in the rest pose.
+		PointInTriangleMeshTraverse<double> pt_in_mesh(pt, &obs_V1, &obs_F);
+		obs_tree.traverse(pt_in_mesh);
+		if (pt_in_mesh.output.num_hits() % 2 == 1)
+		{
+			// Find 
+//			hit = true;
+		}
+
+//		colliding[i] = hit;
+	}
+
+	// Only bother with self collision if it
+	// is not colliding with an obstacle.
+	// This is only useful for discrete tests.
+*/
+} // end emb collision detect
+
+/*
 void FloorCollider::detect(const Eigen::MatrixXd *x)
 {
 	(void)(x);
@@ -32,5 +124,5 @@ void FloorCollider::jacobian(
 		l->emplace_back(floor_z);
 	}
 } // end floor collider Jacobian
-
+*/
 } // namespace admmpd
diff --git a/extern/softbody/src/admmpd_collision.h b/extern/softbody/src/admmpd_collision.h
index c3fd9cb8c4f..5126d1a6958 100644
--- a/extern/softbody/src/admmpd_collision.h
+++ b/extern/softbody/src/admmpd_collision.h
@@ -5,7 +5,9 @@
 #define ADMMPD_COLLISION_H_
 
 #include <Eigen/Sparse>
+#include <Eigen/Geometry>
 #include <vector>
+#include "admmpd_bvh.h"
 
 namespace admmpd {
 
@@ -14,21 +16,80 @@ namespace admmpd {
 // Probably will work better to use uber-collision class for
 // all self and obstacle collisions, reducing the amount of
 // for-all vertices loops.
-class Collider {
+class Collision {
 public:
-    virtual void detect(
-        const Eigen::MatrixXd *x) = 0;
-    virtual void jacobian(
+//    virtual void detect(
+//        int meshnum,
+//        const Eigen::MatrixXd *x,
+//        const Eigen::MatrixXi *faces) = 0;
+//    virtual void jacobian(
+//        const Eigen::MatrixXd *x,
+//    	std::vector<Eigen::Triplet<double> > *trips_x,
+//        std::vector<Eigen::Triplet<double> > *trips_y,
+//    	std::vector<Eigen::Triplet<double> > *trips_z,
+//		std::vector<double> *l) = 0;
+};
+
+// Collision detection against multiple meshes
+class EmbeddedMeshCollision : public Collision {
+protected:
+    // We progressively build a list of vertices and faces with each
+    // add_obstacle call, reindexing as needed. Then we build a tree
+    // with all of them. Alternatively we could just build separate trees and combine them.
+    Eigen::MatrixXd obs_V0, obs_V1;
+    Eigen::MatrixXi obs_F;
+    std::vector<Eigen::AlignedBox<double,3> > obs_aabbs;
+    AABBTree<double,3> obs_tree;
+
+    Eigen::MatrixXd emb_V0, emb_V1; // copy of embedded vertices
+    const Eigen::MatrixXd *emb_barys; // barys of the embedded vtx
+    const Eigen::VectorXi *vtx_to_tet; // vertex to tet embedding
+    const Eigen::MatrixXi *tets; // tets that embed faces
+
+    struct CollisionPair {
+        int p; // point
+        int q; // face
+        Eigen::Vector3d barys; // barycoords of collision
+    };
+
+public:
+    // 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.
+    void set_obstacles(
+        const float *v0,
+        const float *v1,
+        int nv,
+        const int *faces,
+        int nf);
+
+    // Unlike set_obstacles, the pointers 
+    void set_embedded(
+        const Eigen::MatrixXd *emb_barys,
+        const Eigen::VectorXi *vtx_to_tet,
+        const Eigen::MatrixXi *tets){}
+
+    // Given a list of deformable vertices (the lattice)
+    // perform collision detection of the surface mesh against
+    // obstacles and possibly self.
+    void detect(const Eigen::MatrixXd *x0, const Eigen::MatrixXd *x1);
+
+    void jacobian(
         const Eigen::MatrixXd *x,
     	std::vector<Eigen::Triplet<double> > *trips_x,
         std::vector<Eigen::Triplet<double> > *trips_y,
     	std::vector<Eigen::Triplet<double> > *trips_z,
-		std::vector<double> *l) = 0;
+		std::vector<double> *l)
+    {
+        
+    }
 };
-
+/*
 class FloorCollider : public Collider {
 public:
-    void detect(const Eigen::MatrixXd *x);
+    virtual void detect(
+        int meshnum,
+        const Eigen::MatrixXd *x,
+        const Eigen::MatrixXi *faces);
     void jacobian(
         const Eigen::MatrixXd *x,
     	std::vector<Eigen::Triplet<double> > *trips_x,
@@ -36,7 +97,7 @@ public:
     	std::vector<Eigen::Triplet<double> > *trips_z,
 		std::vector<double> *l);
 };
-
+*/
 } // namespace admmpd
 
 #endif // ADMMPD_COLLISION_H_
diff --git a/extern/softbody/src/admmpd_lattice.cpp b/extern/softbody/src/admmpd_embeddedmesh.cpp
similarity index 79%
rename from extern/softbody/src/admmpd_lattice.cpp
rename to extern/softbody/src/admmpd_embeddedmesh.cpp
index d97ab9c7bc8..0fd012c34f3 100644
--- a/extern/softbody/src/admmpd_lattice.cpp
+++ b/extern/softbody/src/admmpd_embeddedmesh.cpp
@@ -1,7 +1,7 @@
 // Copyright Matt Overby 2020.
 // Distributed under the MIT License.
 
-#include "admmpd_lattice.h"
+#include "admmpd_embeddedmesh.h"
 #include "admmpd_math.h"
 #include "admmpd_bvh.h"
 #include "admmpd_bvh_traverse.h"
@@ -63,12 +63,20 @@ static void parallel_keep_tet(
 
 } // end parallel test if keep tet
 
-bool Lattice::generate(
-	const Eigen::MatrixXd &V,
-	const Eigen::MatrixXi &F,
-    Eigen::MatrixXd *X, // lattice vertices, n x 3
-    Eigen::MatrixXi *T) // lattice elements, m x 4
+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
 {
+	if (emb_mesh==NULL)
+		return false;
+	if (x_tets==NULL)
+		return false;
+
+	emb_mesh->faces = F;
+	emb_mesh->x_rest = V;
+
 	AlignedBox<double,3> aabb;
 	int nv = V.rows();
 	for(int i=0; i<nv; ++i)
@@ -201,8 +209,6 @@ bool Lattice::generate(
 			else { it = tets.erase(it); }
 		}
 
-		printf("Lattice: removed %d tets\n", tet_idx-(int)tets.size());
-
 	} // end remove unnecessary tets
 
 	// Copy data into matrices and remove unreferenced
@@ -213,14 +219,14 @@ bool Lattice::generate(
 		int ntv0 = verts.size(); // original num verts
 		int ntv1 = refd_verts.size(); // reduced num verts
 		BLI_assert(ntv1 <= ntv0);
-		X->resize(ntv1,3);
+		x_tets->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->operator()(vtx_count,j) = verts[i][j];
+					x_tets->operator()(vtx_count,j) = verts[i][j];
 				}
 				vtx_old_to_new[i] = vtx_count;
 				vtx_count++;
@@ -229,30 +235,27 @@ bool Lattice::generate(
 
 		// Copy tets to matrix data and update vertices
 		int nt = tets.size();
-		T->resize(nt,4);
+		emb_mesh->tets.resize(nt,4);
 		for(int i=0; i<nt; ++i){
 			for(int j=0; j<4; ++j){
 				int old_idx = tets[i][j];
 				BLI_assert(vtx_old_to_new.count(old_idx)>0);
-				T->operator()(i,j) = vtx_old_to_new[old_idx];
+				emb_mesh->tets(i,j) = vtx_old_to_new[old_idx];
 			}
 		}
 	}
 
 	// Now compute the baryweighting for embedded vertices
-	return compute_vtx_tet_mapping(
-		&V, &vtx_to_tet, &barys,
-		X, T);
+	return compute_embedding(
+		emb_mesh, &V, x_tets);
 
 } // end gen lattice
 
 typedef struct FindTetThreadData {
 	AABBTree<double,3> *tree;
-	const MatrixXd *pts;
-	VectorXi *pts_to_tet;
-	MatrixXd *barys;
-	const MatrixXd *tet_x;
-	const MatrixXi *tets;
+	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(
@@ -261,43 +264,42 @@ static void parallel_point_in_tet(
 	const Ta

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list