[Bf-blender-cvs] [cf9d9931f11] soc-2020-soft-body: added strain limiting for option if doing a cloth solve

mattoverby noreply at git.blender.org
Wed Aug 12 22:08:15 CEST 2020


Commit: cf9d9931f111fbe694e41e1ee9a98e3100437625
Author: mattoverby
Date:   Wed Aug 12 15:08:11 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rBcf9d9931f111fbe694e41e1ee9a98e3100437625

added strain limiting for option if doing a cloth solve

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

M	extern/softbody/src/admmpd_energy.cpp
M	extern/softbody/src/admmpd_energy.h
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_energy.cpp b/extern/softbody/src/admmpd_energy.cpp
index ff0e31c3a5c..7ee3a60428d 100644
--- a/extern/softbody/src/admmpd_energy.cpp
+++ b/extern/softbody/src/admmpd_energy.cpp
@@ -12,7 +12,6 @@ using namespace Eigen;
 
 Lame::Lame()
 {
-	m_limit = Vector2d(-999,999);
 	set_from_youngs_poisson(10000000,0.399);
 }
 
@@ -135,6 +134,9 @@ void EnergyTerm::update_tri(
 {
 	Lame lame;
 	lame.set_from_youngs_poisson(options->youngs,options->poisson);
+	Vector2d limit = options->strain_limit;
+	limit[0] = std::min(limit[0], 1.0);
+	limit[1] = std::max(limit[1], 1.0);
 
 	(void)(options);
 	typedef Matrix<double,2,3> Matrix23d;
@@ -155,15 +157,15 @@ void EnergyTerm::update_tri(
 	zi_T = (kv*p + w2*zi_T) / (w2 + kv);
 
 	// Apply strain limiting
-	bool check_strain = lame.m_limit[0] > 0.0 || lame.m_limit[1] < 99.0;
+	bool check_strain = limit[0] > 0.0 || limit[1] < 99.0;
 	if (check_strain)
 	{
 		double l_col0 = zi_T.col(0).norm();
 		double l_col1 = zi_T.col(1).norm();
-		if (l_col0 < lame.m_limit[0]) { zi_T.col(0) *= ( lame.m_limit[0]/l_col0 ); }
-		if (l_col1 < lame.m_limit[0]) { zi_T.col(1) *= ( lame.m_limit[0]/l_col1 ); }
-		if (l_col0 > lame.m_limit[1]) { zi_T.col(0) *= ( lame.m_limit[1]/l_col0 ); }
-		if (l_col1 > lame.m_limit[1]) { zi_T.col(1) *= ( lame.m_limit[1]/l_col1 ); }
+		if (l_col0 < limit[0]) { zi_T.col(0) *= ( limit[0]/l_col0 ); }
+		if (l_col1 < limit[0]) { zi_T.col(1) *= ( limit[0]/l_col1 ); }
+		if (l_col0 > limit[1]) { zi_T.col(0) *= ( limit[1]/l_col0 ); }
+		if (l_col1 > limit[1]) { zi_T.col(1) *= ( limit[1]/l_col1 ); }
 	}
 
 	ui += (Dix - zi_T.transpose());
diff --git a/extern/softbody/src/admmpd_energy.h b/extern/softbody/src/admmpd_energy.h
index 1b88efa9f54..ff9b9f40473 100644
--- a/extern/softbody/src/admmpd_energy.h
+++ b/extern/softbody/src/admmpd_energy.h
@@ -16,7 +16,6 @@ public:
 	double m_mu;
 	double m_lambda;
 	double m_bulk_mod;
-	Eigen::Vector2d m_limit; // [min,max]
 	void set_from_youngs_poisson(double youngs, double poisson);
 	Lame();
 };
diff --git a/extern/softbody/src/admmpd_types.h b/extern/softbody/src/admmpd_types.h
index f6e8db6666f..85dbc1f77b3 100644
--- a/extern/softbody/src/admmpd_types.h
+++ b/extern/softbody/src/admmpd_types.h
@@ -76,6 +76,7 @@ struct Options {
     double floor; // floor location
     double collision_thickness;
     bool self_collision; // process self collisions
+    Eigen::Vector2d strain_limit; // min=[-inf,1], max=[1,inf]
     Eigen::Vector3d grav;
     Options() :
         timestep_s(1.0/24.0),
@@ -98,6 +99,7 @@ struct Options {
         floor(-std::numeric_limits<double>::max()),
         collision_thickness(1e-6),
         self_collision(false),
+        strain_limit(0,100),
         grav(0,0,-9.8)
         {}
 };
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index 684b3efdbda..2da12e91c6b 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -97,6 +97,8 @@ static inline void options_from_object(
   op->grav = Eigen::Vector3d(0,0,sb->admmpd_gravity);
   op->max_threads = sb->admmpd_maxthreads;
   op->linsolver = std::max(0, std::min(LINSOLVER_NUM-1, sb->admmpd_linsolver));
+  op->strain_limit[0] = std::min(1.f, sb->admmpd_strainlimit_min);
+  op->strain_limit[1] = std::max(1.f, sb->admmpd_strainlimit_max);
 
   if (!skip_require_reset)
   {
diff --git a/intern/softbody/admmpd_api.h b/intern/softbody/admmpd_api.h
index dc9ea71fde5..5a14aff8f8e 100644
--- a/intern/softbody/admmpd_api.h
+++ b/intern/softbody/admmpd_api.h
@@ -58,13 +58,13 @@ int admmpd_update_solver(ADMMPDInterfaceData*, Scene*, Object*, float (*vertexCo
 // to internal vertex position and velocity
 void admmpd_copy_from_object(ADMMPDInterfaceData*, Object*);
 
-// Copies ADMM-PD data to SoftBody::bpoint and vertexCos
+// Copies ADMM-PD data to SoftBody::bpoint and vertexCos.
+// If vertexCos is NULL, it is ignored.
 void admmpd_copy_to_object(ADMMPDInterfaceData*, Object*, float (*vertexCos)[3]);
 
 // Sets the obstacle data for collisions.
 // Update obstacles has a different interface because of the
-// complexity of grabbing obstacle mesh data. We'll just do
-// that in softbody.c
+// complexity of grabbing obstacle mesh data. We'll leave that in softbody.c
 void admmpd_update_obstacles(
     ADMMPDInterfaceData*,
     float *in_verts_0,
diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py
index 013a39faa40..acaea6869f7 100644
--- a/release/scripts/startup/bl_ui/properties_physics_softbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py
@@ -92,12 +92,18 @@ class PHYSICS_PT_softbody_object(PhysicButtonsPanel, Panel):
         elif softbody.solver_mode=='ADMMPD':
 
             col = flow.column()
+            col.prop(softbody, "admmpd_init_mode")
             col.prop(softbody, "admmpd_material")
             col.prop(softbody, "admmpd_embed_res")
             col.prop(softbody, "admmpd_youngs_exp")
             col.prop(softbody, "admmpd_poisson")
             col.prop(softbody, "admmpd_density_kgm3")
 
+            if softbody.admmpd_init_mode == 'CLOTH':
+                col.prop(softbody, "admmpd_strainlimit_min")
+                col.prop(softbody, "admmpd_strainlimit_max")
+
+
 
 class PHYSICS_PT_softbody_simulation(PhysicButtonsPanel, Panel):
     bl_label = "Simulation"
@@ -422,7 +428,6 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel):
         elif softbody.solver_mode == 'ADMMPD':
 
             col = flow.column(align=True)
-            col.prop(softbody, "admmpd_init_mode")
             col.prop(softbody, "admmpd_linsolver")
             col.prop(softbody, "admmpd_substeps")
             col.prop(softbody, "admmpd_max_admm_iters")
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 5a34196cad6..7ec047b5593 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3134,10 +3134,12 @@ SoftBody *sbNew(Scene *scene)
   sb->admmpd_youngs_exp = 6;
   sb->admmpd_poisson = 0.399;
   sb->admmpd_density_kgm3 = 1522;
-  sb->admmpd_ck_exp = 6;
+  sb->admmpd_ck_exp = 7;
   sb->admmpd_pk_exp = 4;
   sb->admmpd_floor_z = -999;
   sb->admmpd_gravity = -9.8;
+  sb->admmpd_strainlimit_min = 0; // no compression limit
+  sb->admmpd_strainlimit_max = 100; // 100x stretch limit
   sb->admmpd_maxthreads = -1;
   sb->admmpd_loglevel = 1; // low
   sb->admmpd_linsolver = 1; // PCG
diff --git a/source/blender/makesdna/DNA_object_force_types.h b/source/blender/makesdna/DNA_object_force_types.h
index 91a76aedaeb..6220f3aba29 100644
--- a/source/blender/makesdna/DNA_object_force_types.h
+++ b/source/blender/makesdna/DNA_object_force_types.h
@@ -231,6 +231,8 @@ typedef struct SoftBody {
   float admmpd_pk_exp; // goal stiffness exponent (10^n)
   float admmpd_floor_z; // floor position
   float admmpd_gravity; // in m/s^2
+  float admmpd_strainlimit_min; // [0,1]
+  float admmpd_strainlimit_max; // [1,100]
   int admmpd_maxthreads; // -1 = auto
   int admmpd_loglevel; // 0=none, 1=low, 2=high
   int admmpd_linsolver; // global step
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index d60847ce3a6..eabbe37e791 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -1908,10 +1908,22 @@ static void rna_def_softbody(BlenderRNA *brna)
   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
   RNA_def_property_update(prop, 0, "rna_softbody_update");
 
+  prop = RNA_def_property(srna, "admmpd_strainlimit_min", PROP_FLOAT, PROP_NONE);
+  RNA_def_property_float_sdna(prop, NULL, "admmpd_strainlimit_min");
+  RNA_def_property_range(prop, 0.0f, 1.f);
+  RNA_def_property_ui_text(prop, "Min Strain Limit", "Limits compression: higher reduces compression");
+  RNA_def_property_update(prop, 0, "rna_softbody_update");
+
+  prop = RNA_def_property(srna, "admmpd_strainlimit_max", PROP_FLOAT, PROP_NONE);
+  RNA_def_property_float_sdna(prop, NULL, "admmpd_strainlimit_max");
+  RNA_def_property_range(prop, 1.0f, 100.f);
+  RNA_def_property_ui_text(prop, "Max Strain Limit", "Limits stetch: lower reduces stretching");
+  RNA_def_property_update(prop, 0, "rna_softbody_update");
+
   prop = RNA_def_property(srna, "admmpd_loglevel", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_sdna(prop, NULL, "admmpd_loglevel");
   RNA_def_property_enum_items(prop, admmpd_loglevel_items);
-  RNA_def_property_ui_text(prop, "Log Level", "Terminal ouput verbosity");
+  RNA_def_property_ui_text(prop, "Verbosity", "Controls the amount of terminal ouput");
   RNA_def_property_update(prop, 0, "rna_softbody_update");
 
   prop = RNA_def_property(srna, "admmpd_linsolver", PROP_ENUM, PROP_NONE);



More information about the Bf-blender-cvs mailing list