[Bf-blender-cvs] [bdcfbf64f30] soc-2020-soft-body: has bugs, working on animatable

mattoverby noreply at git.blender.org
Thu Aug 6 04:32:16 CEST 2020


Commit: bdcfbf64f30900ef47dd903fbdb739558fbc537d
Author: mattoverby
Date:   Wed Aug 5 21:32:11 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBbdcfbf64f30900ef47dd903fbdb739558fbc537d

has bugs, working on animatable

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

M	extern/softbody/src/admmpd_collision.cpp
M	extern/softbody/src/admmpd_collision.h
M	extern/softbody/src/admmpd_linsolve.cpp
M	extern/softbody/src/admmpd_solver.cpp
M	extern/softbody/src/admmpd_types.h
M	intern/softbody/admmpd_api.cpp
M	intern/softbody/admmpd_api.h
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/softbody.c
M	source/blender/makesdna/DNA_object_force_types.h
M	source/blender/makesrna/intern/rna_object_force.c

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

diff --git a/extern/softbody/src/admmpd_collision.cpp b/extern/softbody/src/admmpd_collision.cpp
index 1d37ffc688e..ddae43c017b 100644
--- a/extern/softbody/src/admmpd_collision.cpp
+++ b/extern/softbody/src/admmpd_collision.cpp
@@ -457,6 +457,7 @@ void EmbeddedMeshCollision::graph(
 } // end graph
 
 void EmbeddedMeshCollision::linearize(
+	const Options *options,
 	const Eigen::MatrixXd *x,
 	std::vector<Eigen::Triplet<double> > *trips,
 	std::vector<double> *d) const
@@ -471,6 +472,7 @@ void EmbeddedMeshCollision::linearize(
 	//int nx = x->rows();
 	d->reserve((int)d->size() + np);
 	trips->reserve((int)trips->size() + np*3*4);
+	double eta = std::max(0.0,options->collision_thickness);
 
 	for (int i=0; i<np; ++i)
 	{
@@ -490,7 +492,7 @@ void EmbeddedMeshCollision::linearize(
 			int tet_idx = meshdata.mesh->emb_vtx_to_tet()->operator[](emb_p_idx);
 			RowVector4i tet = meshdata.mesh->prims()->row(tet_idx);
 			int c_idx = d->size();
-			d->emplace_back(pair.q_n.dot(pair.q_pt));
+			d->emplace_back(pair.q_n.dot(pair.q_pt) + eta);
 			for (int j=0; j<4; ++j)
 			{
 				trips->emplace_back(c_idx, tet[j]*3+0, bary[j]*pair.q_n[0]);
@@ -505,7 +507,7 @@ void EmbeddedMeshCollision::linearize(
 		else
 		{
 			int c_idx = d->size();
-			d->emplace_back(0);
+			d->emplace_back(eta);
 
 			// Compute the normal in the deformed space
 			RowVector3i q_face = meshdata.mesh->facets()->row(pair.q_idx);
diff --git a/extern/softbody/src/admmpd_collision.h b/extern/softbody/src/admmpd_collision.h
index 4228a53f8f4..083e13632e8 100644
--- a/extern/softbody/src/admmpd_collision.h
+++ b/extern/softbody/src/admmpd_collision.h
@@ -66,6 +66,7 @@ public:
     // Linearizes active collision pairs about x
     // for the constraint Cx=d
     virtual void linearize(
+        const Options *options,
         const Eigen::MatrixXd *x,
     	std::vector<Eigen::Triplet<double> > *trips,
 		std::vector<double> *d) const = 0;
@@ -105,6 +106,7 @@ public:
     // Linearizes the collision pairs about x
     // for the constraint Cx=d
     void linearize(
+        const Options *options,
         const Eigen::MatrixXd *x,
     	std::vector<Eigen::Triplet<double> > *trips,
 		std::vector<double> *d) const;
diff --git a/extern/softbody/src/admmpd_linsolve.cpp b/extern/softbody/src/admmpd_linsolve.cpp
index 5330e07cfaf..28a028cdf0a 100644
--- a/extern/softbody/src/admmpd_linsolve.cpp
+++ b/extern/softbody/src/admmpd_linsolve.cpp
@@ -110,8 +110,7 @@ void LDLT::solve(
 	{
 		std::vector<double> d_coeffs;
 		std::vector<Eigen::Triplet<double> > trips;
-		collision->linearize(&data->x, &trips, &d_coeffs);
-
+		collision->linearize(options, &data->x, &trips, &d_coeffs);
 		int nc = d_coeffs.size();
 		if (nc>0)
 		{
@@ -237,7 +236,7 @@ void ConjugateGradients::solve(
 	{
 		std::vector<double> d_coeffs;
 		std::vector<Eigen::Triplet<double> > trips;
-		collision->linearize(&data->x, &trips, &d_coeffs);
+		collision->linearize(options, &data->x, &trips, &d_coeffs);
 		int nc = d_coeffs.size();
 		if (nc>0)
 		{
@@ -305,12 +304,12 @@ void ConjugateGradients::apply_preconditioner(
 	Eigen::MatrixXd &x,
 	const Eigen::MatrixXd &b)
 {
+	x = m_ldlt->cholesky()->solve(b);
+/*
 	BLI_assert(b.cols()==3);
 	if (x.rows() != b.rows())
 		x.resize(b.rows(),3);
 
-	//x = m_ldlt->cholesky()->solve(b);
-
 	Cholesky *chol = m_ldlt->cholesky();
 	const auto & linsolve = [&x,&b,&chol](int col)
 	{
@@ -327,6 +326,7 @@ void ConjugateGradients::apply_preconditioner(
 		if (pool[i].joinable())
 			pool[i].join();
 	}
+*/
 }
 
 #if 0
diff --git a/extern/softbody/src/admmpd_solver.cpp b/extern/softbody/src/admmpd_solver.cpp
index 1ad6e22536f..130a9bd2587 100644
--- a/extern/softbody/src/admmpd_solver.cpp
+++ b/extern/softbody/src/admmpd_solver.cpp
@@ -27,9 +27,9 @@ class SolverLog {
 protected:
 	std::unordered_map<int,double> elapsed_ms;
 	std::unordered_map<int,MicroTimer> curr_timer;
-	double m_log_level;
+	int m_log_level; // copied from options
 public:
-	double &log_level() { return m_log_level; }
+	int &log_level() { return m_log_level; }
 	void reset();
 	void start_state(int state);
 	double stop_state(int state); // ret time elapsed
@@ -57,6 +57,11 @@ bool Solver::init(
 	BLI_assert(options != NULL);
 	BLI_assert(mesh != NULL);
 
+    data->energies_graph.clear();
+	data->indices.clear();
+	data->rest_volumes.clear();
+	data->weights.clear();
+
 	switch (mesh->type())
 	{
 		case MESHTYPE_EMBEDDED:
@@ -167,7 +172,7 @@ int Solver::solve(
 
 	solverlog.stop_state(SOLVERSTATE_SOLVE);
 
-	if (options->log_level >= LOGLEVEL_DEBUG)
+	if (options->log_level >= LOGLEVEL_HIGH)
 		printf("Timings:\n%s", solverlog.to_string().c_str());
 
 	return iters;
@@ -502,7 +507,7 @@ void SolverLog::reset()
 
 void SolverLog::start_state(int state)
 {
-	if (m_log_level <= LOGLEVEL_NONE)
+	if (m_log_level < LOGLEVEL_HIGH)
 		return;
 
 	if (m_log_level >= LOGLEVEL_DEBUG)
@@ -520,7 +525,7 @@ void SolverLog::start_state(int state)
 // Returns time elapsed
 double SolverLog::stop_state(int state)
 {
-	if (m_log_level <= LOGLEVEL_NONE)
+	if (m_log_level < LOGLEVEL_HIGH)
 		return 0;
 
 	if (m_log_level >= LOGLEVEL_DEBUG)
diff --git a/extern/softbody/src/admmpd_types.h b/extern/softbody/src/admmpd_types.h
index c2eac090aba..32101cbf7de 100644
--- a/extern/softbody/src/admmpd_types.h
+++ b/extern/softbody/src/admmpd_types.h
@@ -41,8 +41,9 @@ typedef Discregrid::CubicLagrangeDiscreteGrid SDFType;
 
 #define LOGLEVEL_NONE 0
 #define LOGLEVEL_LOW 1
-#define LOGLEVEL_DEBUG 2
-#define LOGLEVEL_NUM 3
+#define LOGLEVEL_HIGH 2
+#define LOGLEVEL_DEBUG 3
+#define LOGLEVEL_NUM 4
 
 #define LINSOLVER_LDLT 0 // Eigen's LDL^T
 #define LINSOLVER_PCG 1 // Precon. Conj. Grad.
@@ -73,7 +74,7 @@ struct Options {
         timestep_s(1.0/24.0),
         log_level(LOGLEVEL_NONE),
         linsolver(LINSOLVER_PCG),
-        max_admm_iters(30),
+        max_admm_iters(20),
         max_cg_iters(10),
         max_gs_iters(100),
         max_threads(-1),
@@ -106,16 +107,6 @@ struct SolverData {
     RowSparseMatrix<double> A; // M + DtW'WD
     RowSparseMatrix<double> W; // weight matrix
     double A_diag_max; // Max coeff of diag of A
-
-//  RowSparseMatrix<double> A3_plus_PtP; // A + pk PtP replicated
-//	Eigen::SimplicialLDLT<Eigen::SparseMatrix<double> > ldlt_A3;
-
-//    std::set<int> pin_inds; // indices of the pinned surface verts
-//    RowSparseMatrix<double> P; // pin constraint Px=q (P.cols=3n)
-//    Eigen::VectorXd q; // pin constraint rhs
-//    RowSparseMatrix<double> C; // collision constraints Cx=d (C.cols=3n)
-//    Eigen::VectorXd d; // collision constraints rhs
-
     // Set in append_energies:
     std::vector<std::set<int> > energies_graph; // per-vertex adjacency list (graph)
 	std::vector<Eigen::Vector3i> indices; // per-energy index into D (row, num rows, type)
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index c8fdb504f5a..b49ec32f45d 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -65,12 +65,8 @@ static inline void strcpy_error(ADMMPDInterfaceData *iface, const std::string &s
 static inline void options_from_object(
   Object *ob,
   admmpd::Options *op,
-  bool &reset_mesh,
-  bool &reset_solver)
+  bool skip_require_reset)
 {
-  reset_mesh = false;
-  reset_solver = false;
-
   SoftBody *sb = ob->soft;
   if (sb==NULL)
     return;
@@ -84,35 +80,15 @@ static inline void options_from_object(
   op->self_collision = sb->admmpd_self_collision;
   op->log_level = std::max(0, std::min(LOGLEVEL_NUM-1, sb->admmpd_loglevel));
   op->grav = Eigen::Vector3d(0,0,sb->admmpd_gravity);
+  op->max_threads = sb->admmpd_maxthreads;
 
-  const double diffeps = 1e-10;
-
-  // Options that cause considerable change in
-  // precomupted variables:
-  if (std::abs(op->density_kgm3 - sb->admmpd_density_kgm3)>diffeps) {
+  if (!skip_require_reset)
+  {
     op->density_kgm3 = std::max(1.f,sb->admmpd_density_kgm3);
-    reset_solver = true;
-  }
-  double new_youngs = std::pow(10.f, std::max(0.f,sb->admmpd_youngs_exp));
-  if (std::abs(op->youngs - new_youngs)>diffeps) {
-    op->density_kgm3 = new_youngs;
-    reset_solver = true;
-  }
-  if (std::abs(op->poisson - sb->admmpd_poisson)>diffeps) {
-    op->poisson = std::max(0.f,std::min(0.499f,sb->admmpd_poisson));
-    reset_solver = true;
-  }
-  if (std::abs(op->poisson - sb->admmpd_poisson)>diffeps) {
+    op->youngs = std::pow(10.f, std::max(0.f,sb->admmpd_youngs_exp));
     op->poisson = std::max(0.f,std::min(0.499f,sb->admmpd_poisson));
-    reset_solver = true;
-  }
-  if (op->linsolver != sb->admmpd_linsolver) {
     op->linsolver = std::max(0, std::min(LINSOLVER_NUM-1, sb->admmpd_linsolver));
-    reset_solver = true;
-  }
-  if (op->elastic_material != sb->admmpd_material) {
     op->elastic_material = std::max(0, std::min(ELASTIC_NUM-1, sb->admmpd_material));
-    reset_solver = true;
   }
 }
 
@@ -302,6 +278,13 @@ static inline int admmpd_init_as_cloth(ADMMPDInterfaceData *iface, Object *ob, f
 // Given the mesh, options, and data, initializes the solver
 static inline int admmpd_reinit_solver(ADMMPDInterfaceData *iface)
 {
+  if (!iface) { return 0; }
+  if (!iface->idata) { return 0; }
+  if (!iface->idata->solver) { return 0; }
+  if (!iface->idata->mesh) { return 0; }
+  if (!iface->idata->options) { return 0; }
+  if (!iface->idata->data) { return 0; }
+
   try
   {
     iface->idata->solver->init(
@@ -317,6 +300,25 @@ static inline int admmpd_reinit_solver(ADMMPDInterfaceData *iface)
   return 1;
 }
 
+int admmpd_needs_reinit(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3], int mode)
+{
+  // Only return true if we need to RE-init the solver on topology change.
+  if (!iface) { return 0; }
+  if (!ob) { return 0; }
+  Mesh *me = (Mesh*)ob->data;
+  if (!me) { return 0; }
+  if (!iface->idata) { return 0; }
+  if (!iface->idata->mesh) { return 0; }
+  if (!iface->idata->data) { return 0; }
+  
+  // Has the defo verts changed?
+  if (iface->out_totverts != iface->idata->data->x.rows()) { return 1; }
+  int n_facet_verts = iface->idata->mesh->rest_facet_verts()->rows();
+  if ( n_facet_verts != me->totvert ) { return 1; }
+
+  return 0;
+}
+
 
 int admmpd_init(ADMMPDInterfaceData *iface, Object *ob, f

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list