[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