diff options
author | Ton Roosendaal <ton@blender.org> | 2006-11-14 18:27:43 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-11-14 18:27:43 +0300 |
commit | c0e9d77188680dbd0c464cddd494fbebe14c1e1f (patch) | |
tree | 856464de453eed3aa34b8307b3fe772b646951c5 | |
parent | 5a609daa7575dd3bda39d07d7704e7dcfd3e7ef4 (diff) |
Next level of Proxy support for animation: Proxy for duplicated groups.
Notes:
- Only referenced groups (from other files)
- Only 1 group (no more duplicates using same group yet)
- Only Proxy working well for Armature or Empty
Is going to be reviewed in Plumiferos team; but target is that this will
solve a major animation pipeline bottleneck :)
Usage; select group, alt+ctrl+p, pick an object you want to proxify.
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/group.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 50 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 3 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 83 | ||||
-rwxr-xr-x | source/blender/src/transform_generics.c | 3 |
7 files changed, 123 insertions, 34 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 26f129ae2a5..fde33723cc4 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -38,12 +38,23 @@ extern "C" { #endif +/* defines now, might become functions */ + +/* proxy rule: lib_object->proxy == the one we borrow from, only set temporal and cleared here */ +/* local_object->proxy == pointer to library object, saved in files and read */ + +#define OB_COPY_PROXY(a) a->id.lib && a->proxy +#define OB_IS_PROXY(a) a->id.lib==NULL && a->proxy +#define OB_DO_PROXY(a) a->id.lib==NULL && a->proxy && a->proxy_group==NULL + + struct Base; struct Object; struct Camera; struct BoundBox; struct View3D; struct SoftBody; +struct Group; void clear_workob(void); void copy_baseflags(void); @@ -55,7 +66,7 @@ void free_object(struct Object *ob); void object_free_display(struct Object *ob); void object_free_modifiers(struct Object *ob); -void object_make_proxy(struct Object *ob, struct Object *target); +void object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob); void unlink_object(struct Object *ob); int exist_object(struct Object *obtest); diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 59293d3c48a..bf1b573afe5 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -183,7 +183,7 @@ void group_tag_recalc(Group *group) for(go= group->gobject.first; go; go= go->next) { if(go->ob) - go->ob->recalc= OB_RECALC; + go->ob->recalc= go->recalc; } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0e98d494c80..f2815d428f8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -893,7 +893,6 @@ Object *copy_object(Object *ob) if(ob->bb) obn->bb= MEM_dupallocN(ob->bb); obn->path= NULL; - obn->proxy= NULL; obn->flag &= ~OB_FROMGROUP; copy_effects(&obn->effect, &ob->effect); @@ -1047,8 +1046,9 @@ void make_local_object(Object *ob) /* proxy rule: lib_object->proxy == the one we borrow from, set temporally while object_update */ /* local_object->proxy == pointer to library object, saved in files and read */ +/* local_object->proxy_group == pointer to group dupli-object, saved in files and read */ -void object_make_proxy(Object *ob, Object *target) +void object_make_proxy(Object *ob, Object *target, Object *gob) { /* paranoia checks */ if(ob->id.lib || target->id.lib==NULL) { @@ -1057,14 +1057,22 @@ void object_make_proxy(Object *ob, Object *target) } ob->proxy= target; - target->proxy= ob; + ob->proxy_group= gob; + id_lib_extern(&target->id); ob->recalc= target->recalc= OB_RECALC; /* copy transform */ - VECCOPY(ob->loc, target->loc); - VECCOPY(ob->rot, target->rot); - VECCOPY(ob->size, target->size); + if(gob) { + VECCOPY(ob->loc, gob->loc); + VECCOPY(ob->rot, gob->rot); + VECCOPY(ob->size, gob->size); + } + else { + VECCOPY(ob->loc, target->loc); + VECCOPY(ob->rot, target->rot); + VECCOPY(ob->size, target->size); + } ob->parent= target->parent; /* libdata */ Mat4CpyMat4(ob->parentinv, target->parentinv); @@ -1649,7 +1657,6 @@ void solve_tracking (Object *ob, float targetmat[][4]) void where_is_object(Object *ob) { - where_is_object_time(ob, (float)G.scene->r.cfra); } @@ -1949,9 +1956,10 @@ void minmax_object(Object *ob, float *min, float *max) } } -/* proxy rule: lib_object->proxy == the one we borrow from, set on read */ +/* proxy rule: lib_object->proxy == the one we borrow from, only set temporal and cleared here */ /* local_object->proxy == pointer to library object, saved in files and read */ +/* function below is polluted with proxy exceptions, cleanup will follow! */ /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */ /* requires flags to be set! */ @@ -1960,8 +1968,14 @@ void object_handle_update(Object *ob) if(ob->recalc & OB_RECALC) { if(ob->recalc & OB_RECALC_OB) { - if(ob->id.lib && ob->proxy) - Mat4CpyMat4(ob->obmat, ob->proxy->obmat); + if(OB_COPY_PROXY(ob)) { + if(ob->proxy->proxy_group) {/* transform proxy into group space */ + Mat4Invert(ob->proxy->proxy_group->imat, ob->proxy->proxy_group->obmat); + Mat4MulMat4(ob->obmat, ob->proxy->obmat, ob->proxy->proxy_group->imat); + } + else + Mat4CpyMat4(ob->obmat, ob->proxy->obmat); + } else where_is_object(ob); } @@ -1988,7 +2002,7 @@ void object_handle_update(Object *ob) if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) armature_rebuild_pose(ob, ob->data); - if(ob->id.lib && ob->proxy) + if(OB_COPY_PROXY(ob)) copy_pose_result(ob->pose, ob->proxy->pose); else { do_all_pose_actions(ob); @@ -1997,11 +2011,21 @@ void object_handle_update(Object *ob) } } - if(ob->id.lib==NULL && ob->proxy) + /* the no-group proxy case, we call update */ + if(OB_DO_PROXY(ob)) { + /* set pointer in library proxy target, for copying, but restore it */ + ob->proxy->proxy= ob; object_handle_update(ob->proxy); - + } + ob->recalc &= ~OB_RECALC; } + + /* the case when this is a group proxy, object_update is called in group.c */ + if(OB_IS_PROXY(ob)) { + ob->proxy->proxy= ob; + //printf("set proxy pointer for later group stuff %s\n", ob->id.name); + } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fd80536dea1..24e8204ef95 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2425,11 +2425,12 @@ static void lib_link_object(FileData *fd, Main *main) else { ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy); if(ob->proxy) { + /* this triggers object_update to always use a copy */ ob->proxy->proxy= ob; /* force proxy updates after load/undo, a bit weak */ ob->recalc= ob->proxy->recalc= OB_RECALC; } - ob->proxy_group= newlibadr_us(fd, ob->id.lib, ob->proxy_group); + ob->proxy_group= newlibadr(fd, ob->id.lib, ob->proxy_group); } poin= ob->data; ob->data= newlibadr_us(fd, ob->id.lib, ob->data); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 8a4ef6cda37..78908a33faa 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -86,8 +86,7 @@ typedef struct Object { int par1, par2, par3; /* can be vertexnrs */ char parsubstr[32]; /* String describing subobject info */ void *pardata; - struct Object *parent, *track, *proxy; - struct Group *proxy_group; + struct Object *parent, *track, *proxy, *proxy_group; struct Ipo *ipo; struct Path *path; struct BoundBox *bb; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 5d578f47297..63dadb6e6c1 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -1245,24 +1245,71 @@ void make_vertex_parent(void) /* BIF_undo_push(str); not, conflicts with editmode undo... */ } +static Object *group_objects_menu(Group *group) +{ + GroupObject *go; + int len= 0; + short a, nr; + char *str; + + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) + len++; + } + if(len==0) return NULL; + + str= MEM_callocN(40+32*len, "menu"); + + strcpy(str, "Select a Group Object %t"); + a= strlen(str); + for(nr=1, go= group->gobject.first; go; go= go->next, nr++) { + a+= sprintf(str+a, "|%s %%x%d", go->ob->id.name+2, nr); + } + + a= pupmenu_col(str, 20); + MEM_freeN(str); + if(a>0) { + go= BLI_findlink(&group->gobject, a-1); + return go->ob; + } + return NULL; +} + + /* adds empty object to become local replacement data of a library-linked object */ void make_proxy(void) { Object *ob= OBACT; + Object *gob= NULL; if(G.scene->id.lib) return; if(ob==NULL) return; - if(ob->id.lib==NULL) { - error("Can not make proxy for non-linked object"); + + if(ob->dup_group && ob->dup_group->id.lib) { + gob= ob; + /* gives menu with list of objects in group */ + ob= group_objects_menu(ob->dup_group); } - else if(okee("Make Proxy Object")) { + else if(ob->id.lib) { + if(okee("Make Proxy Object")==0) + return; + } + else { + error("Can only make proxy for a referenced object or group"); + return; + } + + if(ob) { Object *newob; Base *newbase, *oldbase= BASACT; char name[32]; newob= add_object(OB_EMPTY); - strcpy(name, ob->id.name+2); + if(gob) + strcpy(name, gob->id.name+2); + else + strcpy(name, ob->id.name+2); strcat(name, "_proxy"); rename_id(&newob->id, name); @@ -1272,12 +1319,14 @@ void make_proxy(void) newob->lay= newbase->lay; /* remove base, leave user count of object, it gets linked in object_make_proxy */ - BLI_remlink(&G.scene->base, oldbase); - MEM_freeN(oldbase); - - object_make_proxy(newob, ob); + if(gob==NULL) { + BLI_remlink(&G.scene->base, oldbase); + MEM_freeN(oldbase); + } + object_make_proxy(newob, ob, gob); DAG_scene_sort(G.scene); + DAG_object_flush_update(G.scene, newob, OB_RECALC); allqueue(REDRAWALL, 0); BIF_undo_push("Make Proxy Object"); } @@ -4718,19 +4767,21 @@ void adduplicate(int mode, int dupflag) base= FIRSTBASE; while(base) { if TESTBASELIB(base) { - relink_constraints(&base->object->constraints); - if (base->object->pose){ + ob= base->object; + relink_constraints(&ob->constraints); + if (ob->pose){ bPoseChannel *chan; - for (chan = base->object->pose->chanbase.first; chan; chan=chan->next){ + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ relink_constraints(&chan->constraints); } } - modifiers_foreachIDLink(base->object, - adduplicate__forwardModifierLinks, NULL); - ID_NEW(base->object->parent); - ID_NEW(base->object->track); + modifiers_foreachIDLink(ob, adduplicate__forwardModifierLinks, NULL); + ID_NEW(ob->parent); + ID_NEW(ob->track); + ID_NEW(ob->proxy); + ID_NEW(ob->proxy_group); - for(strip= base->object->nlastrips.first; strip; strip= strip->next) { + for(strip= ob->nlastrips.first; strip; strip= strip->next) { bActionModifier *amod; for(amod= strip->modifiers.first; amod; amod= amod->next) ID_NEW(amod->ob); diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index f9e75d2336a..1435cbff47e 100755 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -72,6 +72,7 @@ #include "BKE_displist.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_ipo.h" #include "BKE_lattice.h" #include "BKE_mesh.h" @@ -355,6 +356,8 @@ void recalcData(TransInfo *t) /* proxy exception */ if(ob->proxy) ob->proxy->recalc |= ob->recalc; + if(ob->proxy_group) + group_tag_recalc(ob->proxy_group->dup_group); } } |