[Bf-blender-cvs] [158568e] alembic: Another curve mapping to control bending stiffness along hair strands.

Lukas Tönne noreply at git.blender.org
Fri May 8 10:48:22 CEST 2015


Commit: 158568e347ee88aaf260cdb97e37395182b274e5
Author: Lukas Tönne
Date:   Fri May 8 10:45:08 2015 +0200
Branches: alembic
https://developer.blender.org/rB158568e347ee88aaf260cdb97e37395182b274e5

Another curve mapping to control bending stiffness along hair strands.

This already exists for goal springs. Bending stiffness, however, is
preferable to global goal springs for physical realism. Controlling
stiffness in this way allows using bending forces to also simulate
unconventional hair, such as clumpy strands that are thicker and stiffer
at the base.

Note that hair interaction can also be simulated with this tool in some
way, although eventually better methods may be needed for such effects.

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

M	release/scripts/startup/bl_ui/properties_object.py
M	source/blender/blenkernel/intern/cache_library.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_cache_library_types.h
M	source/blender/makesrna/intern/rna_cache_library.c
M	source/blender/physics/intern/BPH_mass_spring.cpp

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

diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index c9033d5..28fd129 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -523,6 +523,10 @@ class OBJECT_PT_cache_library(ObjectButtonsPanel, Panel):
         row = col.row(align=True)
         row.prop(params, "bend_stiffness")
         row.prop(params, "bend_damping")
+        row.prop(params, "use_bend_stiffness_curve")
+        if params.use_bend_stiffness_curve:
+            sub = col.column()
+            sub.template_curve_mapping(params, "bend_stiffness_curve")
 
         row = col.row(align=True)
         row.prop(params, "goal_stiffness")
diff --git a/source/blender/blenkernel/intern/cache_library.c b/source/blender/blenkernel/intern/cache_library.c
index d462346..6b24919 100644
--- a/source/blender/blenkernel/intern/cache_library.c
+++ b/source/blender/blenkernel/intern/cache_library.c
@@ -889,6 +889,14 @@ static void hairsim_params_init(HairSimParams *params)
 		cm->cm[0].curve[1].y = 0.0f;
 		params->goal_stiffness_mapping = cm;
 	}
+	{
+		CurveMapping *cm = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+		cm->cm[0].curve[0].x = 0.0f;
+		cm->cm[0].curve[0].y = 1.0f;
+		cm->cm[0].curve[1].x = 1.0f;
+		cm->cm[0].curve[1].y = 1.0f;
+		params->bend_stiffness_mapping = cm;
+	}
 	
 	params->effector_weights = BKE_add_effector_weights(NULL);
 }
@@ -907,6 +915,8 @@ static void hairsim_copy(HairSimCacheModifier *hsmd, HairSimCacheModifier *thsmd
 		thsmd->sim_params.effector_weights = MEM_dupallocN(hsmd->sim_params.effector_weights);
 	if (hsmd->sim_params.goal_stiffness_mapping)
 		thsmd->sim_params.goal_stiffness_mapping = curvemapping_copy(hsmd->sim_params.goal_stiffness_mapping);
+	if (hsmd->sim_params.bend_stiffness_mapping)
+		thsmd->sim_params.bend_stiffness_mapping = curvemapping_copy(hsmd->sim_params.bend_stiffness_mapping);
 }
 
 static void hairsim_free(HairSimCacheModifier *hsmd)
@@ -915,6 +925,8 @@ static void hairsim_free(HairSimCacheModifier *hsmd)
 		MEM_freeN(hsmd->sim_params.effector_weights);
 	if (hsmd->sim_params.goal_stiffness_mapping)
 		curvemapping_free(hsmd->sim_params.goal_stiffness_mapping);
+	if (hsmd->sim_params.bend_stiffness_mapping)
+		curvemapping_free(hsmd->sim_params.bend_stiffness_mapping);
 }
 
 static void hairsim_foreach_id_link(HairSimCacheModifier *hsmd, CacheLibrary *cachelib, CacheModifier_IDWalkFunc walk, void *userdata)
@@ -951,8 +963,10 @@ static void hairsim_process(HairSimCacheModifier *hsmd, CacheProcessContext *ctx
 	
 	/* skip first step and potential backward steps */
 	if (frame > frame_prev) {
-		if (hsmd->sim_params.flag & eHairSimParams_Flag_UseGoalStiffnessCurve)
+		if (hsmd->sim_params.flag & eHairSimParams_Flag_UseGoalStiffnessCurve && hsmd->sim_params.goal_stiffness_mapping)
 			curvemapping_changed_all(hsmd->sim_params.goal_stiffness_mapping);
+		if (hsmd->sim_params.flag & eHairSimParams_Flag_UseBendStiffnessCurve && hsmd->sim_params.bend_stiffness_mapping)
+			curvemapping_changed_all(hsmd->sim_params.bend_stiffness_mapping);
 		
 		if (ob)
 			mul_m4_m4m4(mat, data->mat, ob->obmat);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8b311be..277b070 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2052,6 +2052,9 @@ static void direct_link_cache_modifiers(FileData *fd, ListBase *modifiers)
 				hsmd->sim_params.goal_stiffness_mapping = newdataadr(fd, hsmd->sim_params.goal_stiffness_mapping);
 				if (hsmd->sim_params.goal_stiffness_mapping)
 					direct_link_curvemapping(fd, hsmd->sim_params.goal_stiffness_mapping);
+				hsmd->sim_params.bend_stiffness_mapping = newdataadr(fd, hsmd->sim_params.bend_stiffness_mapping);
+				if (hsmd->sim_params.bend_stiffness_mapping)
+					direct_link_curvemapping(fd, hsmd->sim_params.bend_stiffness_mapping);
 				break;
 			}
 			case eCacheModifierType_StrandsKey: {
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 46a0e34..b27c6b0 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3550,6 +3550,8 @@ static void write_cache_modifiers(WriteData *wd, CacheLibrary *cachelib)
 				writestruct(wd, DATA, "EffectorWeights", 1, hsmd->sim_params.effector_weights);
 				if (hsmd->sim_params.goal_stiffness_mapping)
 					write_curvemapping(wd, hsmd->sim_params.goal_stiffness_mapping);
+				if (hsmd->sim_params.bend_stiffness_mapping)
+					write_curvemapping(wd, hsmd->sim_params.bend_stiffness_mapping);
 				break;
 			}
 		}
diff --git a/source/blender/makesdna/DNA_cache_library_types.h b/source/blender/makesdna/DNA_cache_library_types.h
index 17b4764..85bbd1b 100644
--- a/source/blender/makesdna/DNA_cache_library_types.h
+++ b/source/blender/makesdna/DNA_cache_library_types.h
@@ -189,10 +189,12 @@ typedef struct HairSimParams {
 	struct CurveMapping *goal_stiffness_mapping;
 	float stretch_stiffness, stretch_damping;
 	float bend_stiffness, bend_damping;
+	struct CurveMapping *bend_stiffness_mapping;
 } HairSimParams;
 
 typedef enum eHairSimParams_Flag {
 	eHairSimParams_Flag_UseGoalStiffnessCurve        = (1 << 0),
+	eHairSimParams_Flag_UseBendStiffnessCurve        = (1 << 1),
 } eHairSimParams_Flag;
 
 typedef struct HairSimCacheModifier {
diff --git a/source/blender/makesrna/intern/rna_cache_library.c b/source/blender/makesrna/intern/rna_cache_library.c
index e351eb5..3d34ec2 100644
--- a/source/blender/makesrna/intern/rna_cache_library.c
+++ b/source/blender/makesrna/intern/rna_cache_library.c
@@ -459,11 +459,23 @@ static void rna_def_hair_sim_params(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Goal Stiffness Curve", "Stiffness of goal springs along the strand curves");
 	RNA_def_property_update(prop, 0, "rna_CacheModifier_update");
 	
+	prop = RNA_def_property(srna, "use_bend_stiffness_curve", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", eHairSimParams_Flag_UseBendStiffnessCurve);
+	RNA_def_property_ui_text(prop, "Use Bend Stiffness Curve", "Use a curve to define bend resistance along the strand");
+	RNA_def_property_update(prop, 0, "rna_CacheModifier_update");
+	
+	prop = RNA_def_property(srna, "bend_stiffness_curve", PROP_POINTER, PROP_NONE);
+	RNA_def_property_pointer_sdna(prop, NULL, "bend_stiffness_mapping");
+	RNA_def_property_struct_type(prop, "CurveMapping");
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Bend Stiffness Curve", "Resistance to bending along the strand curves");
+	RNA_def_property_update(prop, 0, "rna_CacheModifier_update");
+	
 	prop = RNA_def_property(srna, "stretch_stiffness", PROP_FLOAT, PROP_NONE);
 	RNA_def_property_range(prop, 0.0f, FLT_MAX);
 	RNA_def_property_ui_range(prop, 0.0f, 10000.0f, 0.1f, 3);
 	RNA_def_property_float_default(prop, 10000.0f);
-	RNA_def_property_ui_text(prop, "Stretch Stiffness", "Resistence to stretching");
+	RNA_def_property_ui_text(prop, "Stretch Stiffness", "Resistance to stretching");
 	RNA_def_property_update(prop, 0, "rna_CacheModifier_update");
 	
 	prop = RNA_def_property(srna, "stretch_damping", PROP_FLOAT, PROP_FACTOR);
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index 0c18e24..ce5585e 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -1240,14 +1240,31 @@ static void strands_calc_curve_stretch_forces(Strands *strands, float UNUSED(spa
 	}
 }
 
+static float strands_bending_stiffness(Strands *UNUSED(strands), HairSimParams *params, StrandsVertex *UNUSED(vert), float t)
+{
+	float weight;
+	
+	if (params->flag & eHairSimParams_Flag_UseBendStiffnessCurve)
+		weight = curvemapping_evaluateF(params->bend_stiffness_mapping, 0, t);
+	else
+		weight = 1.0f;
+	CLAMP(weight, 0.0f, 1.0f);
+	
+	return params->bend_stiffness * weight;
+}
+
 /* bending forces aim to restore the rest shape of each strand locally */
 static void strands_calc_curve_bending_forces(Strands *strands, float space[4][4], HairSimParams *params, Implicit_Data *data, StrandIterator *it_strand)
 {
 	StrandBendIterator it_bend;
 	
-	const float stiffness = params->bend_stiffness;
-	const float damping = stiffness * params->bend_damping;
+	float length = 0.0f;
+	StrandEdgeIterator it_edge;
+	for (BKE_strand_edge_iter_init(&it_edge, it_strand); BKE_strand_edge_iter_valid(&it_edge); BKE_strand_edge_iter_next(&it_edge))
+		length += len_v3v3(it_edge.vertex1->co, it_edge.vertex0->co);
+	float length_inv = length > 0.0f ? 1.0f / length : 0.0f;
 	
+	float t = 0.0f;
 	BKE_strand_bend_iter_init(&it_bend, it_strand);
 	if (!BKE_strand_bend_iter_valid(&it_bend))
 		return;
@@ -1304,6 +1321,9 @@ static void strands_calc_curve_bending_forces(Strands *strands, float space[4][4
 		float target_state[3];
 		mul_v3_m3v3(target_state, mat, target);
 		
+		const float stiffness = strands_bending_stiffness(strands, params, it_bend.vertex0, t * length_inv);
+		const float damping = stiffness * params->bend_damping;
+		
 		int vroot = BKE_strand_bend_iter_vertex0_offset(strands, &it_bend); /* root velocity used as goal velocity */
 		int vj = BKE_strand_bend_iter_vertex1_offset(strands, &it_bend);
 		float goal[3], rootvel[3];
@@ -1313,6 +1333,9 @@ static void strands_calc_curve_bending_forces(Strands *strands, float space[4][4
 	}
 	
 	do {
+		float restlen = len_v3v3(it_bend.vertex1->co, it_bend.vertex0->co);
+		t += restlen;
+		
 		{ /* advance the coordinate frame */
 			float rotrest[3][3], rotrest_inv[3][3], rotstate[3][3], rotstate_inv[3][3];
 			BKE_strand_bend_iter_transform_rest(&it_bend, rotrest);
@@ -1335,6 +1358,9 @@ static void strands_calc_curve_bending_forces(Strands *strands, float space[4][4
 			float target_state[3];
 			mul_v3_m3v3(target_state, mat, target);
 			
+			const float stiffness = strands_bending_stiffness(strands, params, it_bend.vertex1, t * length_inv);
+			const float damping = stiffness * params->bend_damping;
+			
 			int vi = BKE_strand_bend_iter_vertex0_offset(strands

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list