[Bf-blender-cvs] [c6f05db9122] cloth-improvements: Add support for external basemesh object

Luca Rood noreply at git.blender.org
Sun Mar 12 22:03:52 CET 2017


Commit: c6f05db9122ebc4f9943d0ab02bbea25e6b16ed2
Author: Luca Rood
Date:   Sun Mar 12 16:26:49 2017 -0300
Branches: cloth-improvements
https://developer.blender.org/rBc6f05db9122ebc4f9943d0ab02bbea25e6b16ed2

Add support for external basemesh object

This allows the usage of a different object as the rest shape, which
enables more flexibility regarding animated rest shapes.

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

M	release/scripts/startup/bl_ui/properties_physics_cloth.py
M	source/blender/blenkernel/BKE_cloth.h
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/makesdna/DNA_cloth_types.h
M	source/blender/makesrna/intern/rna_cloth.c
M	source/blender/modifiers/intern/MOD_cloth.c

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

diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index f12cc2374da..0fa77b4de52 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -203,13 +203,17 @@ class PHYSICS_PT_cloth_shape(PhysicButtonsPanel, Panel):
         row.prop(cloth, "shrinking", text="Shrinking")
         row.prop(cloth, "rest_planarity_factor", text="Flattening")
 
-        layout.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
+        row = layout.row()
+        sub = row.column()
+        sub.alert = not cloth.is_basemesh_target_valid
+        sub.prop(cloth, "basemesh_target")
+        row.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
 
         key = ob.data.shape_keys
 
         if key:
             sub = layout.column()
-            sub.active = not cloth.use_dynamic_mesh
+            sub.active = (not cloth.use_dynamic_mesh) and (cloth.basemesh_target is None)
             sub.prop_search(cloth, "rest_shape_key", key, "key_blocks")
 
 
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 0438128b41e..80860932b04 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -249,6 +249,8 @@ int cloth_add_spring (struct ClothModifierData *clmd, unsigned int indexA, unsig
 
 void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3]);
 
+bool is_basemesh_valid(struct Object *ob, struct Object *basemesh, struct ClothModifierData *clmd);
+
 ////////////////////////////////////////////////
 
 #endif
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 23b9fb5dc2e..f4262b961ba 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -43,6 +43,7 @@
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_cloth.h"
+#include "BKE_editmesh.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
 #include "BKE_modifier.h"
@@ -587,6 +588,37 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
 	}
 }
 
+bool is_basemesh_valid(Object *ob, Object *basemesh, ClothModifierData *clmd)
+{
+	DerivedMesh *basedm;
+	ModifierData *md;
+
+	if (!basemesh || (ob == basemesh)) {
+		return true;
+	}
+	else if (basemesh->type != OB_MESH) {
+		return false;
+	}
+
+	if (clmd) {
+		md = (ModifierData *)clmd;
+	}
+	else {
+		md = modifiers_findByType(ob, eModifierType_Cloth);
+		clmd = (ClothModifierData *)md;
+	}
+
+	if (basemesh == md->scene->obedit) {
+		BMEditMesh *em = BKE_editmesh_from_object(basemesh);
+		basedm = em->derivedFinal;
+	}
+	else {
+		basedm = basemesh->derivedFinal;
+	}
+
+	return clmd->clothObject->mvert_num == basedm->getNumVerts(basedm);
+}
+
 /******************************************************************************
  *
  * Internal functions.
@@ -727,6 +759,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
 {
 	int i = 0;
 	MVert *mvert = NULL;
+	MVert *basevert = NULL;
 	ClothVertex *verts = NULL;
 	float (*shapekey_rest)[3] = NULL;
 	float tnull[3] = {0, 0, 0};
@@ -762,10 +795,27 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
 	clmd->clothObject->springs = NULL;
 	clmd->clothObject->numsprings = -1;
 
-	if ( clmd->sim_parms->shapekey_rest && !(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH ) )
+	if (clmd->sim_parms->basemesh_target) {
+		if ((clmd->sim_parms->basemesh_target != ob) && is_basemesh_valid(ob, clmd->sim_parms->basemesh_target, clmd)) {
+			ModifierData *md = (ModifierData *)clmd;
+			DerivedMesh *basedm;
+
+			if (clmd->sim_parms->basemesh_target == md->scene->obedit) {
+				BMEditMesh *em = BKE_editmesh_from_object(clmd->sim_parms->basemesh_target);
+				basedm = em->derivedFinal;
+			}
+			else {
+				basedm = clmd->sim_parms->basemesh_target->derivedFinal;
+			}
+
+			basevert = basedm->getVertArray(basedm);
+		}
+	}
+	else if (clmd->sim_parms->shapekey_rest && !(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH)) {
 		shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO );
+	}
 
-	mvert = dm->getVertArray (dm);
+	mvert = dm->getVertArray(dm);
 
 	verts = clmd->clothObject->verts;
 
@@ -776,12 +826,17 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
 
 			mul_m4_v3(ob->obmat, verts->x);
 
-			if ( shapekey_rest ) {
+			if (basevert) {
+				copy_v3_v3(verts->xrest, basevert[i].co);
+				mul_m4_v3(clmd->sim_parms->basemesh_target->obmat, verts->xrest);
+			}
+			else if (shapekey_rest) {
 				copy_v3_v3(verts->xrest, shapekey_rest[i]);
 				mul_m4_v3(ob->obmat, verts->xrest);
 			}
-			else
+			else {
 				copy_v3_v3(verts->xrest, verts->x);
+			}
 		}
 		
 		/* no GUI interface yet */
@@ -1189,12 +1244,30 @@ static void cloth_update_springs( ClothModifierData *clmd )
 }
 
 /* Update rest verts, for dynamically deformable cloth */
-static void cloth_update_verts( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
+static void cloth_update_verts(Object *ob, ClothModifierData *clmd, DerivedMesh *dm)
 {
 	unsigned int i = 0;
-	MVert *mvert = dm->getVertArray (dm);
+	MVert *mvert;
 	ClothVertex *verts = clmd->clothObject->verts;
 
+	if (clmd->sim_parms->basemesh_target && (clmd->sim_parms->basemesh_target != ob) &&
+	    is_basemesh_valid(ob, clmd->sim_parms->basemesh_target, clmd))
+	{
+		ModifierData *md = (ModifierData *)clmd;
+
+		ob = clmd->sim_parms->basemesh_target;
+
+		if (ob == md->scene->obedit) {
+			BMEditMesh *em = BKE_editmesh_from_object(ob);
+			dm = em->derivedFinal;
+		}
+		else {
+			dm = ob->derivedFinal;
+		}
+	}
+
+	mvert = dm->getVertArray(dm);
+
 	/* vertex count is already ensured to match */
 	for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) {
 		copy_v3_v3(verts->xrest, mvert[i].co);
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 1d2ac6e6de3..cd83d8d5428 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -119,6 +119,8 @@ typedef struct ClothSimSettings {
 	float max_imp;
 	float imp_adj_factor;
 	char pad1[4];
+
+	struct Object *basemesh_target;	/* object to use for dynamic basemesh */
 } ClothSimSettings;
 
 
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index e7a5956aff3..c0c20726cdd 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -37,6 +37,7 @@
 
 #include "rna_internal.h"
 
+#include "BKE_cdderivedmesh.h"
 #include "BKE_cloth.h"
 #include "BKE_modifier.h"
 
@@ -392,6 +393,28 @@ static char *rna_ClothCollisionSettings_path(PointerRNA *ptr)
 	}
 }
 
+static void rna_ClothSettings_besemesh_target_set(PointerRNA *ptr, PointerRNA value)
+{
+	Object *target = (Object *)value.data;
+	ClothSimSettings *sim = (ClothSimSettings *)ptr->data;
+
+	if (is_basemesh_valid((Object *)ptr->id.data, target, NULL)) {
+		sim->basemesh_target = target;
+	}
+}
+
+static int rna_ClothSettings_besemesh_target_poll(PointerRNA *ptr, PointerRNA value)
+{
+	return is_basemesh_valid((Object *)ptr->id.data, (Object *)value.data, NULL);
+}
+
+static int rna_ClothSettings_besemesh_target_valid_get(PointerRNA *ptr)
+{
+	ClothSimSettings *sim = (ClothSimSettings *)ptr->data;
+
+	return is_basemesh_valid((Object *)ptr->id.data, sim->basemesh_target, NULL);
+}
+
 #else
 
 static void rna_def_cloth_solver_result(BlenderRNA *brna)
@@ -819,6 +842,17 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
 	RNA_def_property_update(prop, 0, "rna_cloth_update");
 	RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
 
+	prop = RNA_def_property(srna, "basemesh_target", PROP_POINTER, PROP_NONE);
+	RNA_def_property_ui_text(prop, "Basemesh", "Object mesh to use as rest shape");
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_ClothSettings_besemesh_target_set", NULL, "rna_ClothSettings_besemesh_target_poll");
+	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_update(prop, 0, "rna_cloth_dependency_update");
+
+	prop = RNA_def_property(srna, "is_basemesh_target_valid", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_funcs(prop, "rna_ClothSettings_besemesh_target_valid_get", NULL);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_ui_text(prop, "Basemesh Valid", "True if the set basemesh is valid");
+
 	/* unused */
 
 	/* unused still */
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index d15a6fcb1c8..dbd6d9bbec8 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -128,6 +128,12 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
 		dag_add_collision_relations(forest, scene, ob, obNode, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
 
 		dag_add_forcefield_relations(forest, scene, ob, obNode, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
+
+		if (clmd->sim_parms->basemesh_target && (clmd->sim_parms->basemesh_target != ob)) {
+			DagNode *curNode = dag_get_node(forest, clmd->sim_parms->basemesh_target);
+
+			dag_add_relation(forest, curNode, obNode, (DAG_RL_DATA_DATA | DAG_RL_OB_DATA), "Cloth Base Mesh Target");
+		}
 	}
 }
 
@@ -143,6 +149,11 @@ static void updateDepsgraph(ModifierData *md,
 		DEG_add_collision_relations(node, scene, ob, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
 
 		DEG_add_forcefield_relations(node, scene, ob, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
+
+		if (clmd->sim_parms->basemesh_target && (clmd->sim_parms->basemesh_target != ob)) {
+			DEG_add_object_relation(node, clmd->sim_parms->basemesh_target, DEG_OB_COMP_TRANSFORM, "Cloth Base Mesh Target");
+			DEG_add_object_relation(node, clmd->sim_parms->basemesh_target, DEG_OB_COMP_GEOMETRY, "Cloth Base Mesh Target");
+		}
 	}
 }
 
@@ -234,6 +245,10 @@ static void foreachIDLink(ModifierData *md, Object *ob,
 	if (clmd->sim_par

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list