Rest shape key for cloth option, this makes it possible
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 30 Mar 2010 11:49:07 +0000 (11:49 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 30 Mar 2010 11:49:07 +0000 (11:49 +0000)
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)

12 files changed:
release/scripts/ui/properties_physics_cloth.py
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/modifier.c
source/blender/editors/space_image/image_buttons.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesrna/intern/rna_cloth.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_key.c

index 22a83e02ba70e3f8a140c2eb544f8d3a69f491fb..7ea9e60ebbb628f8efea30b5d5efee3dc65b4a18 100644 (file)
@@ -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"
index a8a0d7daa89f55a4e78ae61ff1c0cf4078831e45..d8b3fcfd0bb0e0b8d91287e0fb44a9dbe1e5d50f 100644 (file)
@@ -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 );
index 9d15ac3f348c5c672bc6228d6691d1a4fdafea00..f4e3a60803e296f492f54952e7fe675543f4cb15 100644 (file)
@@ -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);
index 33fe6212cd238318fcaa040bf4866b2bf7ff2d30..2b11c4bdfa02c33afcbdf0f93d7fc8df65769736 100644 (file)
@@ -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;
index a755170aae616008b3bf438a9bc5431c4fc22976..447c1e2f035fd700ccf38684690b0bcb2bbc37da 100644 (file)
@@ -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;
index 96877a9ae9e5f01fcb3370c37a022efe4ac73fd4..7dc6babba38d30129b2d073d5c3190e062409b97 100644 (file)
@@ -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;
 }
index c81f4d7d122af1faccfe18b21966b8b3de77a0a6..0a7c07bd1f1346c572cfa58a0fa3a8d6456f678e 100644 (file)
@@ -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");
index bd323c5821b1a23d6b7ed42cc22b6bb6102b53a3..9b9f0ede52630508178abd7e20f1d2ebf656337d 100644 (file)
@@ -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;
index 223147594f5dee2091d1c58c18d48bfbebcbd1ea..dc07b0f368ab419cd6bf5098067f526a60a10450 100644 (file)
@@ -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)
index 19718a3326508ea36d39ab2868edf37a861d3f0a..3518044a6018bfe1619671f59b0e52e26b238540 100644 (file)
@@ -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 */
 
index 68a7ca29a1ff51ac673825cd442412e6e59938ad..433d5ff29049b8da29765cfc659969f99701cc40 100644 (file)
@@ -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);
index 8c7e684b422f8a5394902cb1bb59e737fa9311e7..47accb86d8f4e7a49ee5c9dee1f0804e5eafcc4f 100644 (file)
@@ -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;
 }
 
-static void rna_ShapeKey_relative_key_set(PointerRNA *ptr, PointerRNA value)
+int rna_object_shapekey_index_set(ID *id, PointerRNA value, int current)
 {
-       Key *key= rna_ShapeKey_find_key(ptr->id.data);
-       KeyBlock *kb= (KeyBlock*)ptr->data, *kbrel;
+       Key *key= rna_ShapeKey_find_key(id);
+       KeyBlock *kb;
        int a;
 
        if(key)
-               for(a=0, kbrel=key->block.first; kbrel; kbrel=kbrel->next, a++)
-                       if(kbrel == value.data)
-                               kb->relative= a;
+               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)
+{
+       KeyBlock *kb= (KeyBlock*)ptr->data;
+
+       kb->relative= rna_object_shapekey_index_set(ptr->id.data, value, kb->relative);
 }
 
 static void rna_ShapeKeyPoint_co_get(PointerRNA *ptr, float *values)