diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 166 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 40 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 8 |
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; } |