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.
This commit is contained in:
2006-11-14 15:27:43 +00:00
parent 5a609daa75
commit c0e9d77188
7 changed files with 123 additions and 34 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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