[Bf-blender-cvs] [5b09a54b410] soc-2020-soft-body: debugging uniform lattice

over0219 noreply at git.blender.org
Tue Jun 16 03:26:30 CEST 2020


Commit: 5b09a54b41084857af4fc00426df9d1e0539e0bd
Author: over0219
Date:   Mon Jun 15 19:56:00 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB5b09a54b41084857af4fc00426df9d1e0539e0bd

debugging uniform lattice

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

M	extern/softbody/src/admmpd_energy.cpp
M	extern/softbody/src/admmpd_lattice.cpp
M	extern/softbody/src/admmpd_lattice.h
M	extern/softbody/src/admmpd_solver.cpp
M	extern/softbody/src/admmpd_solver.h
M	intern/softbody/admmpd_api.cpp
M	intern/softbody/admmpd_api.h
M	source/blender/blenkernel/intern/softbody.c

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

diff --git a/extern/softbody/src/admmpd_energy.cpp b/extern/softbody/src/admmpd_energy.cpp
index 36f0bfa1478..41aebbe0739 100644
--- a/extern/softbody/src/admmpd_energy.cpp
+++ b/extern/softbody/src/admmpd_energy.cpp
@@ -94,7 +94,7 @@ int EnergyTerm::init_tet(
 	volume = edges.determinant() / 6.0f;
 	if( volume < 0 )
 	{
-		printf("**EnergyTerm::init_tet: Inverted initial tet");
+		printf("**admmpd::EnergyTerm Error: Inverted initial tet: %f\n",volume);
 		return 0;
 	}
 	double k = lame.m_bulk_mod;
diff --git a/extern/softbody/src/admmpd_lattice.cpp b/extern/softbody/src/admmpd_lattice.cpp
index be7a5bc63d2..b0c8f6ca556 100644
--- a/extern/softbody/src/admmpd_lattice.cpp
+++ b/extern/softbody/src/admmpd_lattice.cpp
@@ -4,6 +4,7 @@
 #include "admmpd_lattice.h"
 #include "admmpd_math.h"
 #include <iostream>
+#include <unordered_map>
 
 //#include "vdb.h"
 
@@ -52,94 +53,114 @@ inline void map_to_x4i(const std::vector<Vector4i> &x_vec, Eigen::MatrixXi *x)
 
 bool Lattice::generate(
 	const Eigen::MatrixXd &V,
-    Eigen::MatrixXd *x, // lattice vertices, n x 3
-    Eigen::MatrixXi *tets) // lattice elements, m x 4
+    Eigen::MatrixXd *X, // lattice vertices, n x 3
+    Eigen::MatrixXi *T) // lattice elements, m x 4
 {
-	// All vertices enclosed in 5 tets!
-	// Will generate actual lattice in the future.
-	AlignedBox<double,3> box;
-	vtx = V;
-	int nv = vtx.rows();
-	for (int i=0; i<nv; ++i)
+	AlignedBox<double,3> aabb;
+	int nv = V.rows();
+	for(int i=0; i<nv; ++i)
+		aabb.extend(V.row(i).transpose());
+	
+	aabb.extend(aabb.min()-Vector3d::Ones()*1e-6);
+	aabb.extend(aabb.max()+Vector3d::Ones()*1e-6);
+	Vector3d mesh_boxmin = aabb.min();
+	Vector3d sizes = aabb.sizes();
+	double grid_dx = sizes.maxCoeff() * 0.2;
+
+	// Generate vertices and tets
+	std::vector<Vector3d> verts;
+	std::vector<Vector4i> tets;
 	{
-		Vector3d v = vtx.row(i);
-		box.extend(v);
-	}
-	box.extend(box.min() - Vector3d::Ones() * 1e-12);
-	box.extend(box.max() + Vector3d::Ones() * 1e-12);
+		std::unordered_map<std::string, int> vertex_map; // [i,j,k]->index
 
-	std::vector<Vector3d> x_vec;
-	std::vector<Vector4i> t_vec;
-	create_packed_tets(box.min(),box.max(),x_vec,t_vec);
+		auto grid_hash = [&](const Vector3d &x)
+		{
+			Vector3i ll = Vector3i( // nearest gridcell
+				std::round((x[0]-mesh_boxmin[0])/grid_dx),
+				std::round((x[1]-mesh_boxmin[1])/grid_dx),
+				std::round((x[2]-mesh_boxmin[2])/grid_dx));
+			return std::to_string(ll[0])+' '+std::to_string(ll[1])+' '+std::to_string(ll[2]);
+		};
+
+		auto add_box = [&](int i_, int j_, int k_)
+		{
+			Vector3d min = mesh_boxmin + Vector3d(i_*grid_dx, j_*grid_dx, k_*grid_dx);
+			Vector3d max = mesh_boxmin + Vector3d((i_+1)*grid_dx, (j_+1)*grid_dx, (k_+1)*grid_dx);
+			std::vector<Vector3d> v = {
+				// Top plane, clockwise looking down
+				max,
+				Vector3d(min[0], max[1], max[2]),
+				Vector3d(min[0], max[1], min[2]),
+				Vector3d(max[0], max[1], min[2]),
+				// Bottom plan, clockwise looking down
+				Vector3d(max[0], min[1], max[2]),
+				Vector3d(min[0], min[1], max[2]),
+				min,
+				Vector3d(max[0], min[1], min[2])
+			};
+			// Add vertices and get indices of the box
+			std::vector<int> b;
+			for(int i=0; i<8; ++i)
+			{
+				std::string hash = grid_hash(v[i]);
+				if( vertex_map.count(hash)==0 )
+				{
+					vertex_map[hash] = verts.size();
+					verts.emplace_back(v[i]);
+				}
+				b.emplace_back(vertex_map[hash]);
+			}
+			// From the box, create five new tets
+			std::vector<Vector4i> new_tets = {
+				Vector4i( b[0], b[5], b[7], b[4] ),
+				Vector4i( b[5], b[7], b[2], b[0] ),
+				Vector4i( b[5], b[0], b[2], b[1] ),
+				Vector4i( b[7], b[2], b[0], b[3] ),
+				Vector4i( b[5], b[2], b[7], b[6] )
+			};
+			for(int i=0; i<5; ++i)
+				tets.emplace_back(new_tets[i]);
+		};
+
+		int ni = std::ceil(sizes[0]/grid_dx);
+		int nj = std::ceil(sizes[1]/grid_dx);
+		int nk = std::ceil(sizes[2]/grid_dx);
+		for(int i=0; i<ni; ++i)
+		{
+			for(int j=0; j<nj; ++j)
+			{
+				for(int k=0; k<nk; ++k)
+				{
+					add_box(i,j,k);
+				}
+			}
+		}
 
-	// Copy vector data to output
-	map_to_x3d(x_vec, x);
-	map_to_x4i(t_vec, tets);
-	return compute_vtx_tet_mapping(&vtx, &vtx_to_tet, &barys, x, tets);
+	} // end create boxes and vertices
 
-} // end gen lattice
+	// Copy data into matrices
+	{
+		nv = verts.size();
+		X->resize(nv,3);
+		for(int i=0; i<nv; ++i){
+			for(int j=0; j<3; ++j){
+				X->operator()(i,j) = verts[i][j];
+			}
+		}
+		int nt = tets.size();
+		T->resize(nt,4);
+		for(int i=0; i<nt; ++i){
+			for(int j=0; j<4; ++j){
+				T->operator()(i,j) = tets[i][j];
+			}
+		}
+	}
 
-//
-// Original source (BSD-2):
-// github.com/mattoverby/mclscene/blob/master/include/MCL/EmbeddedMesh.hpp
-//
-void Lattice::create_packed_tets(
-	const Eigen::Vector3d &min,
-	const Eigen::Vector3d &max,
-	std::vector<Vector3d> &verts,
-	std::vector<Vector4i> &tets )
-{
+	return compute_vtx_tet_mapping(
+		&V, &vtx_to_tet, &barys,
+		X, T);
 
-	// Top plane, clockwise looking down
-	Vector3d a = max;
-	Vector3d b( min[0], max[1], max[2] );
-	Vector3d c( min[0], max[1], min[2] );
-	Vector3d d( max[0], max[1], min[2] );
-
-	// Bottom plan, clockwise looking down
-	Vector3d e( max[0], min[1], max[2] );
-	Vector3d f( min[0], min[1], max[2] );
-	Vector3d g( min[0], min[1], min[2] );
-	Vector3d h( max[0], min[1], min[2] );
-
-	// Add the verts
-	int nv = verts.size();
-	verts.emplace_back( a ); // 0
-	verts.emplace_back( b ); // 1
-	verts.emplace_back( c ); // 2
-	verts.emplace_back( d ); // 3
-	verts.emplace_back( e ); // 4
-	verts.emplace_back( f ); // 5
-	verts.emplace_back( g ); // 6
-	verts.emplace_back( h ); // 7
-
-	// Pack 5 tets into the cube
-	Vector4i t0( 0, 5, 7, 4 );
-	Vector4i t1( 5, 7, 2, 0 );
-	Vector4i t2( 5, 0, 2, 1 );
-	Vector4i t3( 7, 2, 0, 3 );
-	Vector4i t4( 5, 2, 7, 6 );
-	Vector4i offset(nv,nv,nv,nv);
-
-	// Add the tets
-	tets.emplace_back( t0+offset );
-	tets.emplace_back( t1+offset );
-	tets.emplace_back( t2+offset );
-	tets.emplace_back( t3+offset );
-	tets.emplace_back( t4+offset );
-
-//vdb_point(a[0],a[1],a[2]);
-//vdb_point(b[0],b[1],b[2]);
-//vdb_point(c[0],c[1],c[2]);
-//vdb_point(d[0],d[1],d[2]);
-//vdb_point(e[0],e[1],e[2]);
-//vdb_point(f[0],f[1],f[2]);
-//vdb_point(g[0],g[1],g[2]);
-//vdb_point(h[0],h[1],h[2]);
-//vdb_line(float x0, float y0, float z0, 
-//             float x1, float y1, float z1);
-
-} // end create packed tets
+} // end gen lattice
 
 bool Lattice::compute_vtx_tet_mapping(
 	const Eigen::MatrixXd *vtx_, // embedded vertices, p x 3
@@ -204,27 +225,5 @@ Eigen::Vector3d Lattice::get_mapped_vertex(
 		x_or_v->row(tet[2]) * b[2] +
 		x_or_v->row(tet[3]) * b[3]);
 }
-/*
-void Lattice::map_to_object(
-	const Eigen::MatrixXd *x,
-	const Eigen::MatrixXi *tets,
-	float (*vertexCos)[3])
-{
-  int nv = vtx.rows();
-  for (int i=0; i<nv; ++i)
-  {
-    int t_idx = vtx_to_tet[i];
-    RowVector4i tet = tets->row(t_idx);
-    RowVector4d b = barys.row(i);
-    vtx.row(i) =
-		x->row(tet[0]) * b[0] +
-		x->row(tet[1]) * b[1] +
-		x->row(tet[2]) * b[2] +
-		x->row(tet[3]) * b[3];
-	vertexCos[i][0] = vtx(i,0);
-	vertexCos[i][1] = vtx(i,1);
-	vertexCos[i][2] = vtx(i,2);
-  }
-} // end map to object
-*/
+
 } // namespace admmpd
\ No newline at end of file
diff --git a/extern/softbody/src/admmpd_lattice.h b/extern/softbody/src/admmpd_lattice.h
index b341de636ec..15e2d391d11 100644
--- a/extern/softbody/src/admmpd_lattice.h
+++ b/extern/softbody/src/admmpd_lattice.h
@@ -11,8 +11,6 @@ namespace admmpd {
 
 class Lattice {
 public:
-
-    Eigen::MatrixXd vtx; // rest embedded vertices, p x 3
     Eigen::VectorXi vtx_to_tet; // what tet vtx is embedded in, p x 1
     Eigen::MatrixXd barys; // barycoords of the embedding, p x 4
 
@@ -22,17 +20,15 @@ public:
         Eigen::MatrixXd *x, // lattice vertices, n x 3
         Eigen::MatrixXi *tets); // lattice elements, m x 4
 
-    // Given boxmin and boxmax, adds
-    // 5 tets (and verts) to the vectors
-    void create_packed_tets(
-        const Eigen::Vector3d &min,
-        const Eigen::Vector3d &max,
-        std::vector<Eigen::Vector3d> &verts,
-        std::vector<Eigen::Vector4i> &tets );
+    // Returns the vtx mapped from x/v and tets
+    Eigen::Vector3d get_mapped_vertex(
+        int idx,
+        const Eigen::MatrixXd *x_or_v,
+        const Eigen::MatrixXi *tets );
+
+protected:
 
     // Returns true on success
-    // Works on ptrs intead of local vars in case
-    // I want to use it for something else.
     bool compute_vtx_tet_mapping(
         const Eigen::MatrixXd *vtx_, // embedded vertices, p x 3
         Eigen::VectorXi *vtx_to_tet_, // what tet vtx is embedded in, p x 1
@@ -40,16 +36,6 @@ public:
         const Eigen::MatrixXd *x_, // lattice vertices, n x 3
         const Eigen::MatrixXi *tets_); // lattice elements, m x 4
 
-    // Returns the vtx mapped from x/v and tets
-    Eigen::Vector3d get_mapped_vertex(
-        int idx,
-        const Eigen::MatrixXd *x_or_v,
-        const Eigen::MatrixXi *tets );
-//    void map_to_object(
-//        const Eigen::MatrixXd *x,
-//        const Eigen::MatrixXi *tets,
-//        float (*vertexCos)[3]);
-
 }; // class Lattice
 
 } // namespace admmpd
diff --git a/extern/softbody/src/admmpd_solver.cpp b/extern/softbody/src/admmpd_solver.cpp
index 4756cb76fac..298ba7ff173 100644
--- a/extern/softbody/src/admmpd_solver.cpp
+++ b/extern/softbody/src/admmpd_solver.cpp
@@ -32,9 +32,16 @@ bool Solver::init(
 	if (!data || !options)
 		throw std::runtime_error("init: data/options null");
 
+	if (V.rows()==0)
+		throw std::runtime_error("init: no input vertices");
+
 	data->x = V;
+	data->v.resize(V.rows(),3);
+	data->v.setZero();
 	data->tets = T;
-	compute_matrices(options,data);
+	if (!compute_matrices(options,data))
+		return false;
+
 	return true;
 } // end init
 
@@ -42,6 +49,8 @@ int Solver::solve(
 	const Options *options,
 	Data *data)
 {
+	if ((int)data->A.nonZeros()==0)
+		return 0;
 
 	// Init the solve which computes
 	// quantaties like M_xbar and makes sure
@@ -276,12 +285,15 @@ void Solver::solve_conjugate_gradients(
 
 } // end solve conjugate gradients
 
-void Solver::compute_matrices(
+bool Solver::compute_matrices(
 	const Options *options,
 	Data *data)
 {
 	// Allo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list