Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2010-03-30 15:49:07 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2010-03-30 15:49:07 +0400
commit052cb2afd22b9f54fdb1528066e6e3cba6db6e99 (patch)
tree6e499a7e0ec79fab64dd0467aa2380355f6e9556 /source/blender/blenkernel
parent19fb497d139991ec759f3be3db53a27492c62877 (diff)
Rest shape key for cloth option, this makes it possible
to specify different spring lengths. Implementation is quite ugly because the shape key has to be pulled through the modifier stack somehow, need a more flexible data mask system to solve this properly. (commits 27773,27775,27778 by Brecht from render25 branch)
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c166
-rw-r--r--source/blender/blenkernel/intern/cloth.c40
-rw-r--r--source/blender/blenkernel/intern/customdata.c5
-rw-r--r--source/blender/blenkernel/intern/modifier.c8
5 files changed, 156 insertions, 65 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index a8a0d7daa89..d8b3fcfd0bb 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -126,6 +126,7 @@ typedef struct ClothVertex
float mass; /* mass / weight of the vertex */
float goal; /* goal, from SB */
float impulse[3]; /* used in collision.c */
+ float *xrest; /* temporary valid for building springs */
unsigned int impulse_count; /* same as above */
float avg_spring_len; /* average length of connected springs */
float struct_stiff;
@@ -240,6 +241,7 @@ void cloth_init ( ClothModifierData *clmd );
DerivedMesh *clothModifier_do ( ClothModifierData *clmd, struct Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc );
void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
+int cloth_uses_vgroup(ClothModifierData *clmd);
// needed for collision.c
void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving );
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 9d15ac3f348..f4e3a60803e 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_cloth_types.h"
#include "DNA_key_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -49,6 +50,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_displist.h"
+#include "BKE_key.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
@@ -1450,55 +1452,88 @@ static float *get_editmesh_orco_verts(EditMesh *em)
/* orco custom data layer */
-static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em)
+static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
+{
+ *free= 0;
+
+ if(layer == CD_ORCO) {
+ /* get original coordinates */
+ *free= 1;
+
+ if(em)
+ return (float(*)[3])get_editmesh_orco_verts(em);
+ else
+ return (float(*)[3])get_mesh_orco_verts(ob);
+ }
+ else if(layer == CD_CLOTH_ORCO) {
+ /* apply shape key for cloth, this should really be solved
+ by a more flexible customdata system, but not simple */
+ if(!em) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
+
+ if(kb->data)
+ return kb->data;
+ }
+
+ return NULL;
+ }
+
+ return NULL;
+}
+
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer)
{
DerivedMesh *dm;
float (*orco)[3];
+ int free;
- if(em) {
- dm= CDDM_from_editmesh(em, me);
- orco= (float(*)[3])get_editmesh_orco_verts(em);
- }
- else {
- dm= CDDM_from_mesh(me, ob);
- orco= (float(*)[3])get_mesh_orco_verts(ob);
+ if(em) dm= CDDM_from_editmesh(em, me);
+ else dm= CDDM_from_mesh(me, ob);
+
+ orco= get_orco_coords_dm(ob, em, layer, &free);
+
+ if(orco) {
+ CDDM_apply_vert_coords(dm, orco);
+ if(free) MEM_freeN(orco);
}
- CDDM_apply_vert_coords(dm, orco);
CDDM_calc_normals(dm);
- MEM_freeN(orco);
return dm;
}
-static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm)
+static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer)
{
float (*orco)[3], (*layerorco)[3];
- int totvert;
+ int totvert, free;
totvert= dm->getNumVerts(dm);
if(orcodm) {
orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
+ free= 1;
if(orcodm->getNumVerts(orcodm) == totvert)
orcodm->getVertCos(orcodm, orco);
else
dm->getVertCos(dm, orco);
}
- else {
- if(em) orco= (float(*)[3])get_editmesh_orco_verts(em);
- else orco= (float(*)[3])get_mesh_orco_verts(ob);
- }
+ else
+ orco= get_orco_coords_dm(ob, em, layer, &free);
- transform_mesh_orco_verts(ob->data, orco, totvert, 0);
+ if(orco) {
+ if(layer == CD_ORCO)
+ transform_mesh_orco_verts(ob->data, orco, totvert, 0);
+
+ if(!(layerorco = DM_get_vert_data_layer(dm, layer))) {
+ DM_add_vert_layer(dm, layer, CD_CALLOC, NULL);
+ layerorco = DM_get_vert_data_layer(dm, layer);
+ }
- if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
- memcpy(layerorco, orco, sizeof(float)*totvert);
- MEM_freeN(orco);
+ memcpy(layerorco, orco, sizeof(float)*3*totvert);
+ if(free) MEM_freeN(orco);
}
- else
- DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
/* weight paint colors */
@@ -1604,9 +1639,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
Mesh *me = ob->data;
ModifierData *firstmd, *md;
LinkNode *datamasks, *curr;
- CustomDataMask mask;
+ CustomDataMask mask, nextmask;
float (*deformedVerts)[3] = NULL;
- DerivedMesh *dm, *orcodm, *finaldm;
+ DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
int required_mode;
@@ -1679,6 +1714,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
dm = NULL;
orcodm = NULL;
+ clothorcodm = NULL;
for(;md; md = md->next, curr = curr->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1695,11 +1731,13 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
/* add an orco layer if needed by this modifier */
- if(dm && mti->requiredDataMask) {
+ if(mti->requiredDataMask)
mask = mti->requiredDataMask(ob, md);
- if(mask & CD_MASK_ORCO)
- add_orco_dm(ob, NULL, dm, orcodm);
- }
+ else
+ mask = 0;
+
+ if(dm && (mask & CD_MASK_ORCO))
+ add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO);
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
@@ -1766,26 +1804,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
}
- /* create an orco derivedmesh in parallel */
- mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
- if(mask & CD_MASK_ORCO) {
- if(!orcodm)
- orcodm= create_orco_dm(ob, me, NULL);
-
- mask &= ~CD_MASK_ORCO;
- DM_set_only_copy(orcodm, mask);
- ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0);
-
- if(ndm) {
- /* if the modifier returned a new dm, release the old one */
- if(orcodm && orcodm != ndm) orcodm->release(orcodm);
- orcodm = ndm;
- }
- }
-
+ /* determine which data layers are needed by following modifiers */
+ if(curr->next)
+ nextmask= (CustomDataMask)GET_INT_FROM_POINTER(curr->next->link);
+ else
+ nextmask= dataMask;
+
/* set the DerivedMesh to only copy needed data */
+ mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
DM_set_only_copy(dm, mask);
+ /* add cloth rest shape key if need */
+ if(mask & CD_MASK_CLOTH_ORCO)
+ add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO);
+
/* add an origspace layer if needed */
if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
@@ -1806,6 +1838,38 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
deformedVerts = NULL;
}
}
+
+ /* create an orco derivedmesh in parallel */
+ if(nextmask & CD_MASK_ORCO) {
+ if(!orcodm)
+ orcodm= create_orco_dm(ob, me, NULL, CD_ORCO);
+
+ nextmask &= ~CD_MASK_ORCO;
+ DM_set_only_copy(orcodm, nextmask);
+ ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(orcodm && orcodm != ndm) orcodm->release(orcodm);
+ orcodm = ndm;
+ }
+ }
+
+ /* create cloth orco derivedmesh in parallel */
+ if(nextmask & CD_MASK_CLOTH_ORCO) {
+ if(!clothorcodm)
+ clothorcodm= create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO);
+
+ nextmask &= ~CD_MASK_CLOTH_ORCO;
+ DM_set_only_copy(clothorcodm, nextmask);
+ ndm = mti->applyModifier(md, ob, clothorcodm, useRenderParams, 0);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(clothorcodm && clothorcodm != ndm) clothorcodm->release(clothorcodm);
+ clothorcodm = ndm;
+ }
+ }
}
/* grab modifiers until index i */
@@ -1846,16 +1910,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO) {
- add_orco_dm(ob, NULL, finaldm, orcodm);
+ add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO);
if(deform_r && *deform_r)
- add_orco_dm(ob, NULL, *deform_r, NULL);
+ add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO);
}
*final_r = finaldm;
if(orcodm)
orcodm->release(orcodm);
+ if(clothorcodm)
+ clothorcodm->release(clothorcodm);
if(deformedVerts && deformedVerts != inputVertexCos)
MEM_freeN(deformedVerts);
@@ -1930,7 +1996,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
if(dm && mti->requiredDataMask) {
mask = mti->requiredDataMask(ob, md);
if(mask & CD_MASK_ORCO)
- add_orco_dm(ob, em, dm, orcodm);
+ add_orco_dm(ob, em, dm, orcodm, CD_ORCO);
}
/* How to apply modifier depends on (a) what we already have as
@@ -1987,7 +2053,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
if(mask & CD_MASK_ORCO) {
if(!orcodm)
- orcodm= create_orco_dm(ob, ob->data, em);
+ orcodm= create_orco_dm(ob, ob->data, em, CD_ORCO);
mask &= ~CD_MASK_ORCO;
DM_set_only_copy(orcodm, mask);
@@ -2060,7 +2126,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO)
- add_orco_dm(ob, em, *final_r, orcodm);
+ add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO);
if(orcodm)
orcodm->release(orcodm);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 33fe6212cd2..2b11c4bdfa0 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -721,6 +721,15 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *
}
+int cloth_uses_vgroup(ClothModifierData *clmd)
+{
+ return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) ||
+ (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) &&
+ ((clmd->sim_parms->vgroup_mass>0) ||
+ (clmd->sim_parms->vgroup_struct>0)||
+ (clmd->sim_parms->vgroup_bend>0)));
+}
+
/**
* cloth_apply_vgroup - applies a vertex group as specified by type
*
@@ -744,11 +753,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
verts = clothObj->verts;
- if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) ||
- (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) &&
- ((clmd->sim_parms->vgroup_mass>0) ||
- (clmd->sim_parms->vgroup_struct>0)||
- (clmd->sim_parms->vgroup_bend>0)))
+ if (cloth_uses_vgroup(clmd))
{
for ( i = 0; i < numverts; i++, verts++ )
{
@@ -805,6 +810,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
int i = 0;
MVert *mvert = NULL;
ClothVertex *verts = NULL;
+ float (*shapekey_rest)[3]= NULL;
float tnull[3] = {0,0,0};
Cloth *cloth = NULL;
float maxdist = 0;
@@ -842,7 +848,11 @@ 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 )
+ shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO );
+
mvert = dm->getVertArray ( dm );
+
verts = clmd->clothObject->verts;
// set initial values
@@ -850,8 +860,16 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
{
if(first)
{
- VECCOPY ( verts->x, mvert[i].co );
+ copy_v3_v3( verts->x, mvert[i].co );
+
mul_m4_v3( ob->obmat, verts->x );
+
+ if( shapekey_rest ) {
+ verts->xrest= shapekey_rest[i];
+ mul_m4_v3( ob->obmat, verts->xrest );
+ }
+ else
+ verts->xrest = verts->x;
}
/* no GUI interface yet */
@@ -1070,7 +1088,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
{
spring->ij = MIN2(medge[i].v1, medge[i].v2);
spring->kl = MAX2(medge[i].v2, medge[i].v1);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
clmd->sim_parms->avg_spring_len += spring->restlen;
cloth->verts[spring->ij].avg_spring_len += spring->restlen;
@@ -1116,7 +1134,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(mface[i].v1, mface[i].v3);
spring->kl = MAX2(mface[i].v3, mface[i].v1);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_SHEAR;
spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
@@ -1139,7 +1157,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(mface[i].v2, mface[i].v4);
spring->kl = MAX2(mface[i].v4, mface[i].v2);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_SHEAR;
spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
@@ -1181,7 +1199,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(tspring2->ij, index2);
spring->kl = MAX2(tspring2->ij, index2);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
@@ -1221,7 +1239,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = tspring2->ij;
spring->kl = tspring->kl;
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index a755170aae6..447c1e2f035 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -794,13 +794,14 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
+ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
- "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"};
+ "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDClothOrco"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -813,7 +814,7 @@ const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
- CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
+ CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 96877a9ae9e..7dc6babba38 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -6978,9 +6978,13 @@ static void clothModifier_updateDepgraph(
static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
{
CustomDataMask dataMask = 0;
+ ClothModifierData *clmd = (ClothModifierData*)md;
- /* ask for vertexgroups if we need them */
- dataMask |= (1 << CD_MDEFORMVERT);
+ if(cloth_uses_vgroup(clmd))
+ dataMask |= (1 << CD_MDEFORMVERT);
+
+ if(clmd->sim_parms->shapekey_rest != 0)
+ dataMask |= (1 << CD_CLOTH_ORCO);
return dataMask;
}