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