Commit: 5fa7cdd77b6c6be5fa12cd11b9032576a600b3fe
Author: mattoverby
Date:   Tue Aug 11 10:07:13 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB5fa7cdd77b6c6be5fa12cd11b9032576a600b3fe

params should be animatable

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

M       extern/softbody/src/admmpd_types.h
M       intern/softbody/admmpd_api.cpp
M       intern/softbody/admmpd_api.h
M       release/scripts/startup/bl_ui/properties_physics_softbody.py
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_types.h 
b/extern/softbody/src/admmpd_types.h
index d8100893114..4a65b865581 100644
--- a/extern/softbody/src/admmpd_types.h
+++ b/extern/softbody/src/admmpd_types.h
@@ -60,6 +60,7 @@ struct Options {
     int max_gs_iters;
     int max_threads; // -1 = auto (num cpu threads - 1)
     int elastic_material; // ENUM, see admmpd_energy.h
+    int substeps; // used externally, ignore in solve()
     double gs_omega; // Gauss-Seidel relaxation
     double mult_ck; // stiffness multiplier for constraints
     double mult_pk; // (global) stiffness multiplier for pins
@@ -79,10 +80,12 @@ struct Options {
         max_cg_iters(10),
         max_gs_iters(100),
         max_threads(-1),
+        elastic_material(ELASTIC_ARAP),
+        substeps(1),
         gs_omega(1),
         mult_ck(3),
         mult_pk(3),
-        min_res(1e-8),
+        min_res(1e-6),
         youngs(1000000),
         poisson(0.399),
         density_kgm3(1522),
@@ -117,7 +120,7 @@ public:
     struct LinSolveData {
         LinSolveData() : last_pk(0) {}
         LinSolveData(const LinSolveData &src); // see comments below
-        mutable std::unique_ptr<Cholesky> ldlt_A_PtP;
+        mutable std::unique_ptr<Cholesky> ldlt_A_PtP; // see copy constructor
         double last_pk; // buffered to flag P update
         Eigen::MatrixXd rhs; // Mxbar + DtW2(z-u) + Ptq + Ctd
         Eigen::MatrixXd Ptq;
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index a68641ab939..73a92fe902f 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -42,13 +42,16 @@
 
 #define ADMMPD_API_DEBUG
 
+
+
 struct ADMMPDInternalData
 {
-  std::shared_ptr<admmpd::Collision> collision;
+  // Created in admmpd_update_mesh
   std::shared_ptr<admmpd::Mesh> mesh;
+  std::shared_ptr<admmpd::Collision> collision;
+  // Created in admmpd_update_solver
   std::shared_ptr<admmpd::Options> options;
   std::shared_ptr<admmpd::SolverData> data;
-  int substeps;
 };
 
 
@@ -60,10 +63,14 @@ static inline void strcpy_error(ADMMPDInterfaceData *iface, 
const std::string &s
 }
 
 static inline void options_from_object(
+  ADMMPDInterfaceData *iface,
+  Scene *scene,
   Object *ob,
   admmpd::Options *op,
   bool skip_require_reset)
 {
+  (void)(iface);
+
   SoftBody *sb = ob->soft;
   if (sb==NULL)
     return;
@@ -82,10 +89,17 @@ static inline void options_from_object(
 
   if (!skip_require_reset)
   {
+    if (scene)
+    {
+      float framerate = scene->r.frs_sec / scene->r.frs_sec_base;
+      float fps = std::min(1000.f,std::max(1.f,framerate));
+      op->timestep_s = (1.0/fps) / float(std::max(1,sb->admmpd_substeps));
+    }
     op->density_kgm3 = std::max(1.f,sb->admmpd_density_kgm3);
     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));
     op->elastic_material = std::max(0, std::min(ELASTIC_NUM-1, 
sb->admmpd_material));
+    op->substeps = std::max(1,sb->admmpd_substeps);
   }
 }
 
@@ -133,23 +147,15 @@ static inline void vecs_from_object(
 
 void admmpd_dealloc(ADMMPDInterfaceData *iface)
 {
-  if (iface==NULL)
-    return;
-
-  // Do not change mesh_totverts or
-  // mesh_totfaces, because those are input and
-  // admmpd_dealloc is called on init.
-
-  iface->out_totverts = 0; // output vertices
+  if (!iface) { return; }
   memset(iface->last_error, 0, sizeof(iface->last_error));
-  if (iface->idata)
-  { // release ownership of ptrs
-    iface->idata->options.reset();
-    iface->idata->data.reset();
-    iface->idata->collision.reset();
-    iface->idata->mesh.reset();
-  }
 
+  if (!iface->idata) { return; }
+  iface->idata->options.reset();
+  iface->idata->data.reset();
+  iface->idata->collision.reset();
+  iface->idata->mesh.reset();
+  MEM_freeN((void*)iface->idata);
   iface->idata = nullptr;
 }
 
@@ -190,7 +196,6 @@ static inline int 
admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
     }
   #endif
 
-  iface->out_totverts = tg.out_totverts;
   iface->idata->mesh = std::make_shared<admmpd::TetMesh>();
   success = iface->idata->mesh->create(
     tg.out_verts,
@@ -200,7 +205,7 @@ static inline int 
admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
     tg.out_tets,
     tg.out_tottets);
 
-  if (!success || iface->out_totverts==0)
+  if (!success)
   {
     strcpy_error(iface, "TetMesh failed on creation");
     return 0;
@@ -219,8 +224,6 @@ static inline int 
admmpd_init_with_lattice(ADMMPDInterfaceData *iface, Object *o
   std::vector<float> v;
   std::vector<unsigned int> f;
   vecs_from_object(ob,vertexCos,v,f);
-
-  iface->out_totverts = 0;
   iface->idata->mesh = std::make_shared<admmpd::EmbeddedMesh>();
 
   admmpd::EmbeddedMesh* emb_msh = 
static_cast<admmpd::EmbeddedMesh*>(iface->idata->mesh.get());
@@ -233,7 +236,6 @@ static inline int 
admmpd_init_with_lattice(ADMMPDInterfaceData *iface, Object *o
     nullptr,
     0);
 
-  iface->out_totverts = iface->idata->mesh->rest_prim_verts()->rows();
   if (!success)
   {
     strcpy_error(iface, "EmbeddedMesh failed on creation");
@@ -250,7 +252,6 @@ static inline int admmpd_init_as_cloth(ADMMPDInterfaceData 
*iface, Object *ob, f
   std::vector<unsigned int> f;
   vecs_from_object(ob,vertexCos,v,f);
 
-  iface->out_totverts = 0;
   iface->idata->mesh = std::make_shared<admmpd::TriangleMesh>();
   bool success = iface->idata->mesh->create(
     v.data(),
@@ -260,7 +261,6 @@ static inline int admmpd_init_as_cloth(ADMMPDInterfaceData 
*iface, Object *ob, f
     nullptr,
     0);
 
-  iface->out_totverts = iface->idata->mesh->rest_facet_verts()->rows();
   if (!success)
   {
     strcpy_error(iface, "TriangleMesh failed on creation");
@@ -295,75 +295,77 @@ static inline int 
admmpd_reinit_solver(ADMMPDInterfaceData *iface)
   return 1;
 }
 
-int admmpd_needs_reinit(ADMMPDInterfaceData *iface, Object *ob, float 
(*vertexCos)[3], int mode)
+int admmpd_mesh_needs_update(ADMMPDInterfaceData *iface, Object *ob)
 {
-  (void)(vertexCos); (void)(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; }
+  if (!ob->soft) { return 0; }
+  if (!iface->idata) { return 1; }
+  if (!iface->idata->mesh) { return 1; }
+
+  // Mode or topology change?
+  int mode = ob->soft->admmpd_init_mode;
+  int mesh_type = iface->idata->mesh->type();
+  if (mode != mesh_type) { return 1; }
+  switch (mode)
+  {
+    default:
+    case MESHTYPE_EMBEDDED:
+    case MESHTYPE_TET: {
+      int nv = iface->idata->mesh->rest_prim_verts()->rows();
+      if (nv != ob->soft->totpoint) { return 1; }
+    } break;
+    case MESHTYPE_TRIANGLE: {
+      int nv = iface->idata->mesh->rest_facet_verts()->rows();
+      if (nv != ob->soft->totpoint) { return 1; }
+    } break;
+  }
 
   return 0;
 }
 
-
-int admmpd_init(ADMMPDInterfaceData *iface, Object *ob, float (*vertexCos)[3], 
int mode)
+int admmpd_update_mesh(ADMMPDInterfaceData *iface, Object *ob, float 
(*vertexCos)[3])
 {
-  if (iface==NULL || ob==NULL)
-  {
-    strcpy_error(iface, "NULL input");
-    return 0;
-  }
-
-  SoftBody *sb = ob->soft;
-  if (sb==NULL)
-  {
-    strcpy_error(iface, "NULL SoftBody input");
-    return 0;
-  }
+  if (!iface) { return 0; }
+  if (!ob) { return 0; }
+  if (!ob->soft) { return 0; }
 
-  // Delete any existing data
-  admmpd_dealloc(iface);
+  if (!iface->idata)
+    iface->idata = 
(ADMMPDInternalData*)MEM_callocN(sizeof(ADMMPDInternalData), "ADMMPD_idata");
 
-  // Generate solver data if it doesn't exist
-  iface->idata = new ADMMPDInternalData();
-  iface->idata->substeps = std::max(1,sb->admmpd_substeps);
-  iface->idata->options = std::make_shared<admmpd::Options>();
-  iface->idata->data = std::make_shared<admmpd::SolverData>();
-  float fps = std::min(1000.f,std::max(1.f,iface->in_framerate));
-  admmpd::Options *op = iface->idata->options.get();
-  op->timestep_s = (1.0/fps) / float(std::max(1,sb->admmpd_substeps));
-  options_from_object(ob,op,false);
+  int mode = ob->soft->admmpd_init_mode;
+  iface->idata->mesh.reset();
 
-  // Initialize the mesh
+  // Try to initialize the mesh
+  const Eigen::MatrixXd *x0 = nullptr;
   try
   {
     int gen_success = 0;
     switch (mode)
     {
       default:
-      case ADMMPD_INIT_MODE_EMBEDDED: {
+      case MESHTYPE_EMBEDDED: {
         gen_success = admmpd_init_with_lattice(iface,ob,vertexCos);
+        if (gen_success) {
+          x0 = iface->idata->mesh->rest_prim_verts();
+        }
       } break;
-      case ADMMPD_INIT_MODE_TETGEN: {
+      case MESHTYPE_TET: {
         gen_success = admmpd_init_with_tetgen(iface,ob,vertexCos);
+        if (gen_success) {
+          x0 = iface->idata->mesh->rest_prim_verts();
+        }
       } break;
-      case ADMMPD_INIT_MODE_TRIANGLE: {
+      case MESHTYPE_TRIANGLE: {
         gen_success = admmpd_init_as_cloth(iface,ob,vertexCos);
+        if (gen_success) {
+          x0 = iface->idata->mesh->rest_facet_verts();
+        }
       } break;
     }
-    if (!gen_success || iface->out_totverts==0)
+    if (!gen_success || !iface->idata->mesh || x0==nullptr)
     {
+      strcpy_error(iface, "failed to init mesh");
       return 0;
     }
   }
@@ -373,65 +375,108 @@ int admmpd_init(ADMMPDInterfaceData *iface, Object *ob, 
float (*vertexCos)[3], i
     return 0;
   }
 
-  // Initialize the solver
-  if (!admmpd_reinit_solver(iface))
-    return 0;
+  // Set up softbody to store defo verts
+  int n_defo_verts = x0->rows();
+  SoftBody *sb = ob->soft;
+  if (sb->bpoint)
+    MEM_freeN(sb->bpoint);
+
+  sb->totpoint = n_defo_verts;
+  sb->totspring = 0;
+  sb->bpoint = (BodyPoint*)MEM_callocN(n_defo_verts*sizeof(BodyPoint), 
"ADMMPD_bpoint");
+
+  // Copy init data to BodyPoint
+  BodyPoint *pts = sb->bpoint;
+  for (

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to