Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-11-14 18:27:43 +0300
committerTon Roosendaal <ton@blender.org>2006-11-14 18:27:43 +0300
commitc0e9d77188680dbd0c464cddd494fbebe14c1e1f (patch)
tree856464de453eed3aa34b8307b3fe772b646951c5 /source
parent5a609daa7575dd3bda39d07d7704e7dcfd3e7ef4 (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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_object.h13
-rw-r--r--source/blender/blenkernel/intern/group.c2
-rw-r--r--source/blender/blenkernel/intern/object.c50
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-rw-r--r--source/blender/makesdna/DNA_object_types.h3
-rw-r--r--source/blender/src/editobject.c83
-rwxr-xr-xsource/blender/src/transform_generics.c3
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);
}
}