diff options
-rw-r--r-- | source/blender/blenkernel/BKE_key.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 184 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 94 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 285 |
8 files changed, 303 insertions, 281 deletions
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index d5bae00d32e..e80e57ae63c 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -59,7 +59,7 @@ void key_curve_normal_weights(float t, float *data, int type); float *do_ob_key(struct Scene *scene, struct Object *ob); struct Key *ob_get_key(struct Object *ob); -struct KeyBlock *add_keyblock(struct Scene *scene, struct Key *key); +struct KeyBlock *add_keyblock(struct Key *key); struct KeyBlock *ob_get_keyblock(struct Object *ob); struct KeyBlock *ob_get_reference_keyblock(struct Object *ob); struct KeyBlock *key_get_keyblock(struct Key *key, int index); @@ -68,6 +68,14 @@ char *key_get_curValue_rnaPath(struct Key *key, struct KeyBlock *kb); // needed for the GE void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, int mode); +/* conversion functions */ +void key_to_mesh(struct KeyBlock *kb, struct Mesh *me); +void mesh_to_key(struct Mesh *me, struct KeyBlock *kb); +void key_to_latt(struct KeyBlock *kb, struct Lattice *lt); +void latt_to_key(struct Lattice *lt, struct KeyBlock *kb); +void key_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb); +void curve_to_key(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb); + #ifdef __cplusplus }; #endif diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 3e239e91453..1dca3a597fe 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -120,6 +120,7 @@ int give_obdata_texspace(struct Object *ob, short **texflag, float **loc, float int object_insert_ptcache(struct Object *ob); // void object_delete_ptcache(struct Object *ob, int index); +int object_insert_shape_key(struct Scene *scene, struct Object *ob, int from_mix); #ifdef __cplusplus diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index c7b79756263..825dd7d441b 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1395,7 +1395,7 @@ Key *ob_get_key(Object *ob) return NULL; } -KeyBlock *add_keyblock(Scene *scene, Key *key) +KeyBlock *add_keyblock(Key *key) { KeyBlock *kb; float curpos= -0.1; @@ -1516,3 +1516,185 @@ char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb) /* return the path */ return RNA_path_from_ID_to_property(&ptr, prop); } + + +/* conversion functions */ + +/************************* Lattice ************************/ +void latt_to_key(Lattice *lt, KeyBlock *kb) +{ + BPoint *bp; + float *fp; + int a, tot; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + if(tot==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data"); + kb->totelem= tot; + + bp= lt->def; + fp= kb->data; + for(a=0; a<kb->totelem; a++, fp+=3, bp++) { + VECCOPY(fp, bp->vec); + } +} + +void key_to_latt(KeyBlock *kb, Lattice *lt) +{ + BPoint *bp; + float *fp; + int a, tot; + + bp= lt->def; + fp= kb->data; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + tot= MIN2(kb->totelem, tot); + + for(a=0; a<tot; a++, fp+=3, bp++) { + VECCOPY(bp->vec, fp); + } +} + +/************************* Curve ************************/ +void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, tot; + + /* count */ + tot= count_curveverts(nurb); + if(tot==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data"); + kb->totelem= tot; + + nu= nurb->first; + fp= kb->data; + while(nu) { + + if(nu->bezt) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + VECCOPY(fp, bezt->vec[0]); + fp+= 3; + VECCOPY(fp, bezt->vec[1]); + fp+= 3; + VECCOPY(fp, bezt->vec[2]); + fp+= 3; + fp[0]= bezt->alfa; + fp+= 3; /* alphas */ + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + VECCOPY(fp, bp->vec); + fp[3]= bp->alfa; + + fp+= 4; + bp++; + } + } + nu= nu->next; + } +} + +void key_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb) +{ + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + float *fp; + int a, tot; + + nu= nurb->first; + fp= kb->data; + + tot= count_curveverts(nurb); + + tot= MIN2(kb->totelem, tot); + + while(nu && tot>0) { + + if(nu->bezt) { + bezt= nu->bezt; + a= nu->pntsu; + while(a-- && tot>0) { + VECCOPY(bezt->vec[0], fp); + fp+= 3; + VECCOPY(bezt->vec[1], fp); + fp+= 3; + VECCOPY(bezt->vec[2], fp); + fp+= 3; + bezt->alfa= fp[0]; + fp+= 3; /* alphas */ + + tot-= 3; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a-- && tot>0) { + VECCOPY(bp->vec, fp); + bp->alfa= fp[3]; + + fp+= 4; + tot--; + bp++; + } + } + nu= nu->next; + } +} + +/************************* Mesh ************************/ +void mesh_to_key(Mesh *me, KeyBlock *kb) +{ + MVert *mvert; + float *fp; + int a; + + if(me->totvert==0) return; + + if(kb->data) MEM_freeN(kb->data); + + kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); + kb->totelem= me->totvert; + + mvert= me->mvert; + fp= kb->data; + for(a=0; a<kb->totelem; a++, fp+=3, mvert++) { + VECCOPY(fp, mvert->co); + + } +} + +void key_to_mesh(KeyBlock *kb, Mesh *me) +{ + MVert *mvert; + float *fp; + int a, tot; + + mvert= me->mvert; + fp= kb->data; + + tot= MIN2(kb->totelem, me->totvert); + + for(a=0; a<tot; a++, fp+=3, mvert++) { + VECCOPY(mvert->co, fp); + } +} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 06ae9874180..0a56bcff606 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -47,6 +47,7 @@ #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" +#include "DNA_key_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_material_types.h" @@ -2629,3 +2630,96 @@ void object_delete_ptcache(Object *ob, int index) BLI_freelinkN(&ob->pc_ids, link); } #endif + +/* shape key utility function */ + +/************************* Mesh ************************/ +static void insert_meshkey(Scene *scene, Object *ob, int from_mix) +{ + Mesh *me= ob->data; + Key *key= me->key; + KeyBlock *kb; + int newkey= 0; + + if(key == NULL) { + key= me->key= add_key((ID *)me); + key->type= KEY_RELATIVE; + newkey= 1; + } + + kb= add_keyblock(key); + + if(newkey || from_mix==FALSE) { + /* create from mesh */ + mesh_to_key(me, kb); + } + else { + /* copy from current values */ + kb->data= do_ob_key(scene, ob); + kb->totelem= me->totvert; + } +} +/************************* Lattice ************************/ +static void insert_lattkey(Scene *scene, Object *ob, int from_mix) +{ + Lattice *lt= ob->data; + Key *key= lt->key; + KeyBlock *kb; + int newkey= 0; + + if(key==NULL) { + key= lt->key= add_key( (ID *)lt); + key->type= KEY_RELATIVE; + newkey= 1; + } + + kb= add_keyblock(key); + + if(newkey || from_mix==FALSE) { + /* create from lattice */ + latt_to_key(lt, kb); + } + else { + /* copy from current values */ + kb->totelem= lt->pntsu*lt->pntsv*lt->pntsw; + kb->data= do_ob_key(scene, ob); + } +} +/************************* Curve ************************/ +static void insert_curvekey(Scene *scene, Object *ob, int from_mix) +{ + Curve *cu= ob->data; + Key *key= cu->key; + KeyBlock *kb; + ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb; + int newkey= 0; + + if(key==NULL) { + key= cu->key= add_key( (ID *)cu); + key->type = KEY_RELATIVE; + newkey= 1; + } + + kb= add_keyblock(key); + + if(newkey || from_mix==FALSE) { + /* create from curve */ + curve_to_key(cu, kb, lb); + } + else { + /* copy from current values */ + kb->totelem= count_curveverts(lb); + kb->data= do_ob_key(scene, ob); + } + +} + +int object_insert_shape_key(Scene *scene, Object *ob, int from_mix) +{ + if(ob->type==OB_MESH) insert_meshkey(scene, ob, from_mix); + else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob, from_mix); + else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob, from_mix); + else return 0; + return 1; +} + diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 0ba5c938377..272ee3b8699 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -110,7 +110,7 @@ void ED_object_constraint_dependency_update(struct Scene *scene, struct Object * int mouse_lattice(struct bContext *C, short mval[2], int extend); void undo_push_lattice(struct bContext *C, char *name); -/* object_shapekey.c */ +/* key.c */ void key_to_mesh(struct KeyBlock *kb, struct Mesh *me); void mesh_to_key(struct Mesh *me, struct KeyBlock *kb); void key_to_latt(struct KeyBlock *kb, struct Lattice *lt); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 02833bdf3f7..b004fcb0deb 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -588,7 +588,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) key->type= KEY_RELATIVE; /* first key added, so it was the basis. initialise it with the existing mesh */ - kb= add_keyblock(scene, key); + kb= add_keyblock(key); mesh_to_key(me, kb); } @@ -604,7 +604,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) if (!dm) continue; - kb= add_keyblock(scene, key); + kb= add_keyblock(key); strcpy(kb->name, base->object->id.name+2); BLI_uniquename(&key->block, kb, "Key", '.', offsetof(KeyBlock, name), 32); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 552de1f8f60..8bfc9a66690 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -370,11 +370,11 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M key->type= KEY_RELATIVE; /* if that was the first key block added, then it was the basis. * Initialise it with the mesh, and add another for the modifier */ - kb= add_keyblock(scene, key); + kb= add_keyblock(key); mesh_to_key(me, kb); } - kb= add_keyblock(scene, key); + kb= add_keyblock(key); DM_to_meshkey(dm, me, kb); dm->release(dm); diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index f8eff578839..5d839e60ca9 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -80,283 +80,16 @@ #include "object_intern.h" -/************************* Mesh ************************/ - -void mesh_to_key(Mesh *me, KeyBlock *kb) -{ - MVert *mvert; - float *fp; - int a; - - if(me->totvert==0) return; - - if(kb->data) MEM_freeN(kb->data); - - kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data"); - kb->totelem= me->totvert; - - mvert= me->mvert; - fp= kb->data; - for(a=0; a<kb->totelem; a++, fp+=3, mvert++) { - VECCOPY(fp, mvert->co); - - } -} - -void key_to_mesh(KeyBlock *kb, Mesh *me) -{ - MVert *mvert; - float *fp; - int a, tot; - - mvert= me->mvert; - fp= kb->data; - - tot= MIN2(kb->totelem, me->totvert); - - for(a=0; a<tot; a++, fp+=3, mvert++) { - VECCOPY(mvert->co, fp); - } -} - -static void insert_meshkey(Scene *scene, Object *ob) -{ - Mesh *me= ob->data; - Key *key= me->key; - KeyBlock *kb; - int newkey= 0; - - if(key == NULL) { - key= me->key= add_key((ID *)me); - key->type= KEY_RELATIVE; - newkey= 1; - } - - kb= add_keyblock(scene, key); - - if(newkey) { - /* create from mesh */ - mesh_to_key(me, kb); - } - else { - /* copy from current values */ - kb->data= do_ob_key(scene, ob); - kb->totelem= me->totvert; - } -} - -/************************* Lattice ************************/ - -void latt_to_key(Lattice *lt, KeyBlock *kb) -{ - BPoint *bp; - float *fp; - int a, tot; - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - if(tot==0) return; - - if(kb->data) MEM_freeN(kb->data); - - kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data"); - kb->totelem= tot; - - bp= lt->def; - fp= kb->data; - for(a=0; a<kb->totelem; a++, fp+=3, bp++) { - VECCOPY(fp, bp->vec); - } -} - -void key_to_latt(KeyBlock *kb, Lattice *lt) -{ - BPoint *bp; - float *fp; - int a, tot; - - bp= lt->def; - fp= kb->data; - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - tot= MIN2(kb->totelem, tot); - - for(a=0; a<tot; a++, fp+=3, bp++) { - VECCOPY(bp->vec, fp); - } -} - -static void insert_lattkey(Scene *scene, Object *ob) -{ - Lattice *lt= ob->data; - Key *key= lt->key; - KeyBlock *kb; - int newkey= 0; - - if(key==NULL) { - key= lt->key= add_key( (ID *)lt); - key->type= KEY_RELATIVE; - newkey= 1; - } - - kb= add_keyblock(scene, key); - - if(newkey) { - /* create from lattice */ - latt_to_key(lt, kb); - } - else { - /* copy from current values */ - kb->totelem= lt->pntsu*lt->pntsv*lt->pntsw; - kb->data= do_ob_key(scene, ob); - } -} - -/************************* Curve ************************/ - -void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - float *fp; - int a, tot; - - /* count */ - tot= count_curveverts(nurb); - if(tot==0) return; - - if(kb->data) MEM_freeN(kb->data); - - kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data"); - kb->totelem= tot; - - nu= nurb->first; - fp= kb->data; - while(nu) { - - if(nu->bezt) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - VECCOPY(fp, bezt->vec[0]); - fp+= 3; - VECCOPY(fp, bezt->vec[1]); - fp+= 3; - VECCOPY(fp, bezt->vec[2]); - fp+= 3; - fp[0]= bezt->alfa; - fp+= 3; /* alphas */ - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - VECCOPY(fp, bp->vec); - fp[3]= bp->alfa; - - fp+= 4; - bp++; - } - } - nu= nu->next; - } -} - -void key_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb) -{ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - float *fp; - int a, tot; - - nu= nurb->first; - fp= kb->data; - - tot= count_curveverts(nurb); - - tot= MIN2(kb->totelem, tot); - - while(nu && tot>0) { - - if(nu->bezt) { - bezt= nu->bezt; - a= nu->pntsu; - while(a-- && tot>0) { - VECCOPY(bezt->vec[0], fp); - fp+= 3; - VECCOPY(bezt->vec[1], fp); - fp+= 3; - VECCOPY(bezt->vec[2], fp); - fp+= 3; - bezt->alfa= fp[0]; - fp+= 3; /* alphas */ - - tot-= 3; - bezt++; - } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a-- && tot>0) { - VECCOPY(bp->vec, fp); - bp->alfa= fp[3]; - - fp+= 4; - tot--; - bp++; - } - } - nu= nu->next; - } -} - - -static void insert_curvekey(Scene *scene, Object *ob) -{ - Curve *cu= ob->data; - Key *key= cu->key; - KeyBlock *kb; - ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb; - int newkey= 0; - - if(key==NULL) { - key= cu->key= add_key( (ID *)cu); - key->type = KEY_RELATIVE; - newkey= 1; - } - - kb= add_keyblock(scene, key); - - if(newkey) { - /* create from curve */ - curve_to_key(cu, kb, lb); - } - else { - /* copy from current values */ - kb->totelem= count_curveverts(lb); - kb->data= do_ob_key(scene, ob); - } - -} - /*********************** add shape key ***********************/ -static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob) +static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob, int from_mix) { - Key *key; + if(object_insert_shape_key(scene, ob, from_mix)) { + Key *key= ob_get_key(ob); + ob->shapenr= BLI_countlist(&key->block); - if(ob->type==OB_MESH) insert_meshkey(scene, ob); - else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob); - else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob); - - key= ob_get_key(ob); - ob->shapenr= BLI_countlist(&key->block); - - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + } } /*********************** remove shape key ***********************/ @@ -505,8 +238,9 @@ static int shape_key_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + int from_mix = RNA_boolean_get(op->ptr, "from_mix"); - ED_object_shape_key_add(C, scene, ob); + ED_object_shape_key_add(C, scene, ob, from_mix); return OPERATOR_FINISHED; } @@ -524,6 +258,9 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "from_mix", 0, "From Mix", "Create the new shape key from the existing mix of keys."); } static int shape_key_remove_exec(bContext *C, wmOperator *op) |