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)
This commit is contained in:
Brecht Van Lommel 2010-03-30 11:49:07 +00:00
parent 19fb497d13
commit 052cb2afd2
12 changed files with 238 additions and 96 deletions

@ -129,6 +129,11 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel):
col.prop(cloth, "goal_friction", text="Friction")
"""
key = ob.data.shape_keys
if key:
col.label(text="Rest Shape Key:")
col.prop_object(cloth, "rest_shape_key", key, "keys", text="")
class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
bl_label = "Cloth Cache"

@ -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 );

@ -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);
}
transform_mesh_orco_verts(ob->data, orco, totvert, 0);
if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
memcpy(layerorco, orco, sizeof(float)*totvert);
MEM_freeN(orco);
}
else
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
orco= get_orco_coords_dm(ob, em, layer, &free);
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);
}
memcpy(layerorco, orco, sizeof(float)*3*totvert);
if(free) MEM_freeN(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);

@ -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;

@ -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;

@ -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;
}

@ -110,7 +110,6 @@ static int simaUVSel_Check() {return 0;}
static void image_editvertex_buts(const bContext *C, uiBlock *block);
#if 0
static void do_image_panel_events(bContext *C, void *arg, int event)
{
SpaceImage *sima= CTX_wm_space_image(C);
@ -126,7 +125,6 @@ static void do_image_panel_events(bContext *C, void *arg, int event)
/* all events now */
WM_event_add_notifier(C, NC_IMAGE, sima->image);
}
#endif
static void image_info(Image *ima, ImBuf *ibuf, char *str)
{
@ -948,7 +946,6 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
}
}
#if 0
static int image_panel_uv_poll(const bContext *C, PanelType *pt)
{
Object *obedit= CTX_data_edit_object(C);
@ -964,20 +961,20 @@ static void image_panel_uv(const bContext *C, Panel *pa)
image_editvertex_buts(C, block);
}
#endif
void image_buttons_register(ARegionType *art)
{
PanelType *pt;
/* editvertex_buts not working atm
pt= MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
strcpy(pt->idname, "IMAGE_PT_uv");
strcpy(pt->label, "UV");
pt->draw= image_panel_uv;
pt->poll= image_panel_uv_poll;
BLI_addtail(&art->paneltypes, pt);
*/
/* editvertex_buts not working atm */
if(0) {
pt= MEM_callocN(sizeof(PanelType), "spacetype image panel uv");
strcpy(pt->idname, "IMAGE_PT_uv");
strcpy(pt->label, "UV");
pt->draw= image_panel_uv;
pt->poll= image_panel_uv_poll;
BLI_addtail(&art->paneltypes, pt);
}
pt= MEM_callocN(sizeof(PanelType), "spacetype image panel curves");
strcpy(pt->idname, "IMAGE_PT_curves");

@ -76,8 +76,10 @@ typedef struct ClothSimSettings
short vgroup_bend; /* vertex group for scaling bending stiffness */
short vgroup_mass; /* optional vertexgroup name for assigning weight.*/
short vgroup_struct; /* vertex group for scaling structural stiffness */
short shapekey_rest; /* vertex group for scaling structural stiffness */
short presets; /* used for presets on GUI */
short reset;
short reset;
short pad[3];
struct EffectorWeights *effector_weights;
} ClothSimSettings;

@ -83,7 +83,8 @@ typedef struct CustomData {
#define CD_WEIGHT_MCOL 20 /* for displaying weightpaint colors */
#define CD_ID_MCOL 21
#define CD_TEXTURE_MCOL 22
#define CD_NUMTYPES 23
#define CD_CLOTH_ORCO 23
#define CD_NUMTYPES 24
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@ -107,6 +108,7 @@ typedef struct CustomData {
#define CD_MASK_TANGENT (1 << CD_TANGENT)
#define CD_MASK_MDISPS (1 << CD_MDISPS)
#define CD_MASK_WEIGHT_MCOL (1 << CD_WEIGHT_MCOL)
#define CD_MASK_CLOTH_ORCO (1 << CD_CLOTH_ORCO)
/* derivedmesh wants CustomDataMask for weightpaint too, is not customdata though */
#define CD_MASK_WEIGHTPAINT (1 << CD_WEIGHTPAINT)

@ -140,6 +140,22 @@ static void rna_ClothSettings_bend_vgroup_set(PointerRNA *ptr, const char *value
rna_object_vgroup_name_index_set(ptr, value, &sim->vgroup_bend);
}
static PointerRNA rna_ClothSettings_rest_shape_key_get(PointerRNA *ptr)
{
Object *ob= (Object*)ptr->id.data;
ClothSimSettings *sim= (ClothSimSettings*)ptr->data;
return rna_object_shapekey_index_get(ob->data, sim->shapekey_rest);
}
static void rna_ClothSettings_rest_shape_key_set(PointerRNA *ptr, PointerRNA value)
{
Object *ob= (Object*)ptr->id.data;
ClothSimSettings *sim= (ClothSimSettings*)ptr->data;
sim->shapekey_rest= rna_object_shapekey_index_set(ob->data, value, sim->shapekey_rest);
}
static void rna_ClothSettings_gravity_get(PointerRNA *ptr, float *values)
{
ClothSimSettings *sim= (ClothSimSettings*)ptr->data;
@ -334,6 +350,12 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pre Roll", "Simulation starts on this frame");
RNA_def_property_update(prop, 0, "rna_cloth_reset");
prop= RNA_def_property(srna, "rest_shape_key", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "ShapeKey");
RNA_def_property_pointer_funcs(prop, "rna_ClothSettings_rest_shape_key_get", "rna_ClothSettings_rest_shape_key_set", NULL);
RNA_def_property_ui_text(prop, "Rest Shade Key", "Shape key to use the rest spring lengths from");
RNA_def_property_update(prop, 0, "rna_cloth_update");
/* unused */

@ -31,6 +31,7 @@
#define RNA_MAGIC ((int)~0)
struct ID;
struct IDProperty;
struct SDNA;
@ -200,6 +201,8 @@ void rna_object_vgroup_name_index_set(struct PointerRNA *ptr, const char *value,
void rna_object_vgroup_name_set(struct PointerRNA *ptr, const char *value, char *result, int maxlen);
void rna_object_uvlayer_name_set(struct PointerRNA *ptr, const char *value, char *result, int maxlen);
void rna_object_vcollayer_name_set(struct PointerRNA *ptr, const char *value, char *result, int maxlen);
PointerRNA rna_object_shapekey_index_get(struct ID *id, int value);
int rna_object_shapekey_index_set(struct ID *id, PointerRNA value, int current);
void rna_Object_update(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);
void rna_Object_update_data(struct Main *bmain, struct Scene *scene, struct PointerRNA *ptr);

@ -24,6 +24,7 @@
#include <stdlib.h>
#include "RNA_access.h"
#include "RNA_define.h"
#include "rna_internal.h"
@ -96,30 +97,49 @@ static void rna_ShapeKey_value_range(PointerRNA *ptr, float *min, float *max)
*max= data->slidermax;
}
static PointerRNA rna_ShapeKey_relative_key_get(PointerRNA *ptr)
PointerRNA rna_object_shapekey_index_get(ID *id, int value)
{
Key *key= rna_ShapeKey_find_key(ptr->id.data);
KeyBlock *kb= (KeyBlock*)ptr->data, *kbrel;
Key *key= rna_ShapeKey_find_key(id);
KeyBlock *kb= NULL;
PointerRNA ptr;
int a;
if(key && kb->relative < key->totkey)
for(a=0, kbrel=key->block.first; kbrel; kbrel=kbrel->next, a++)
if(a == kb->relative)
return rna_pointer_inherit_refine(ptr, &RNA_ShapeKey, kbrel);
if(key && value < key->totkey)
for(a=0, kb=key->block.first; kb; kb=kb->next, a++)
if(a == value)
break;
RNA_pointer_create(id, &RNA_ShapeKey, kb, &ptr);
return rna_pointer_inherit_refine(ptr, NULL, NULL);
return ptr;
}
int rna_object_shapekey_index_set(ID *id, PointerRNA value, int current)
{
Key *key= rna_ShapeKey_find_key(id);
KeyBlock *kb;
int a;
if(key)
for(a=0, kb=key->block.first; kb; kb=kb->next, a++)
if(kb == value.data)
return a;
return current;
}
static PointerRNA rna_ShapeKey_relative_key_get(PointerRNA *ptr)
{
KeyBlock *kb= (KeyBlock*)ptr->data;
return rna_object_shapekey_index_get(ptr->id.data, kb->relative);
}
static void rna_ShapeKey_relative_key_set(PointerRNA *ptr, PointerRNA value)
{
Key *key= rna_ShapeKey_find_key(ptr->id.data);
KeyBlock *kb= (KeyBlock*)ptr->data, *kbrel;
int a;
KeyBlock *kb= (KeyBlock*)ptr->data;
if(key)
for(a=0, kbrel=key->block.first; kbrel; kbrel=kbrel->next, a++)
if(kbrel == value.data)
kb->relative= a;
kb->relative= rna_object_shapekey_index_set(ptr->id.data, value, kb->relative);
}
static void rna_ShapeKeyPoint_co_get(PointerRNA *ptr, float *values)