diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 9ad20b6a586..13566be30b3 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -38,16 +38,6 @@ 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; diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index f7fa8436e4f..69ff6876acd 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -52,7 +52,7 @@ struct QuicktimeCodecData; if(seqar) MEM_freeN(seqar); \ } - +/* note; doesn't work when scene is empty */ #define SETLOOPER(s, b) sce= s, b= sce->base.first; b; b= (b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index fe586fa4d0f..9268f593970 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -665,7 +665,6 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, Mat4Invert(obinv, target->obmat); Mat4CpyMat4(premat, target->obmat); Mat4MulMat4(postmat, armOb->obmat, obinv); - Mat4Invert(premat, postmat); /* bone defmats are already in the channels, chan_mat */ @@ -967,21 +966,25 @@ void where_is_armature (bArmature *arm) } } -/* if bone layer is protected, copy the data from proxy->pose */ -static void pose_proxy_synchronize(Object *ob, Object *proxy, int layer_protected) +/* if bone layer is protected, copy the data from from->pose */ +static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected) { - bPose *pose= ob->pose, *proxypose= proxy->pose; + bPose *pose= ob->pose, *frompose= from->pose; bPoseChannel *pchan, *pchanp, pchanw; bConstraint *con; char *str; - if(proxypose==NULL) return; + if(frompose==NULL) return; + + /* exception, armature local layer should be proxied too */ + if(pose->proxy_layer) + ((bArmature *)ob->data)->layer= pose->proxy_layer; /* clear all transformation values from library */ - rest_pose(proxypose); + rest_pose(frompose); pchan= pose->chanbase.first; - pchanp= proxypose->chanbase.first; + pchanp= frompose->chanbase.first; for(; pchan && pchanp; pchan= pchan->next, pchanp= pchanp->next) { if(pchan->bone->layer & layer_protected) { @@ -997,7 +1000,7 @@ static void pose_proxy_synchronize(Object *ob, Object *proxy, int layer_protecte copy_constraints(&pchanw.constraints, &pchanp->constraints); for(con= pchanw.constraints.first; con; con= con->next) { - if(proxy==get_constraint_target(con, &str)) + if(from==get_constraint_target(con, &str)) set_constraint_target(con, ob, NULL); } @@ -1064,10 +1067,10 @@ void armature_rebuild_pose(Object *ob, bArmature *arm) BLI_freelinkN(&pose->chanbase, pchan); } } -// printf("rebuild pose %s, %d bones\n", ob->id.name, counter); + // printf("rebuild pose %s, %d bones\n", ob->id.name, counter); /* synchronize protected layers with proxy */ - if(OB_IS_PROXY(ob)) + if(ob->proxy) pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected); update_pose_constraint_flags(ob->pose); // for IK detection for example diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 1cc3c702a1a..ce441e26116 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -71,6 +71,7 @@ #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_utildefines.h" #include "MEM_guardedalloc.h" @@ -466,7 +467,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int dag_add_relation(dag,node2,node,DAG_RL_OB_OB); addtoroot = 0; } - if (ob->id.lib==NULL && ob->proxy) { + if (ob->proxy) { node2 = dag_get_node(dag, ob->proxy); dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA|DAG_RL_OB_OB); /* inverted relation, so addtoroot shouldn't be set to zero */ @@ -1792,15 +1793,16 @@ static void dag_object_time_update_flags(Object *ob) } /* flag all objects that need recalc, for changes in time for example */ -void DAG_scene_update_flags(Scene *sce, unsigned int lay) +void DAG_scene_update_flags(Scene *scene, unsigned int lay) { Base *base; Object *ob; Group *group; GroupObject *go; + Scene *sce; /* set ob flags where animated systems are */ - for(base= sce->base.first; base; base= base->next) { + for(SETLOOPER(scene, base)) { ob= base->object; /* now if DagNode were part of base, the node->lay could be checked... */ @@ -1810,8 +1812,7 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) /* handled in next loop */ if(ob->dup_group) ob->dup_group->id.flag |= LIB_DOIT; - - } + } /* we do groups each once */ for(group= G.main->group.first; group; group= group->id.next) { @@ -1822,25 +1823,26 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) } } - DAG_scene_flush_update(sce, lay); + for(sce= scene; sce; sce= sce->set) + DAG_scene_flush_update(sce, lay); /* test: set time flag, to disable baked systems to update */ - for(base= sce->base.first; base; base= base->next) { + for(SETLOOPER(scene, base)) { ob= base->object; if(ob->recalc) ob->recalc |= OB_RECALC_TIME; } /* hrmf... an exception to look at once, for invisible camera object we do it over */ - if(sce->camera) - dag_object_time_update_flags(sce->camera); + if(scene->camera) + dag_object_time_update_flags(scene->camera); /* and store the info in groupobject */ for(group= G.main->group.first; group; group= group->id.next) { if(group->id.flag & LIB_DOIT) { for(go= group->gobject.first; go; go= go->next) { go->recalc= go->ob->recalc; -// printf("ob %s recalc %d\n", go->ob->id.name, go->recalc); + // printf("ob %s recalc %d\n", go->ob->id.name, go->recalc); } group->id.flag &= ~LIB_DOIT; } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 129b5037346..ad12893ba28 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -753,8 +753,8 @@ static float eval_driver(IpoDriver *driver, float ipotime) Object *ob= driver->ob; if(ob==NULL) return 0.0f; - if(ob->id.lib && ob->proxy) - ob= ob->proxy; + if(ob->proxy_from) + ob= ob->proxy_from; if(driver->blocktype==ID_OB) { /* depsgraph failure; ob ipos are calculated in where_is_object, this might get called too late */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index abe7cd4d38d..af2d562b331 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -273,6 +273,10 @@ void unlink_object(Object *ob) while(obt) { if(obt->proxy==ob) obt->proxy= NULL; + if(obt->proxy_from==ob) { + obt->proxy_from= NULL; + obt->recalc |= OB_RECALC_OB; + } if(obt->proxy_group==ob) obt->proxy_group= NULL; @@ -992,7 +996,8 @@ void make_local_object(Object *ob) */ if(ob->id.lib==NULL) return; - if(ob->proxy) return; + + ob->proxy= ob->proxy_from= NULL; if(ob->id.us==1) { ob->id.lib= NULL; @@ -1047,7 +1052,7 @@ void make_local_object(Object *ob) /* *************** PROXY **************** */ -/* proxy rule: lib_object->proxy == the one we borrow from, set temporally while object_update */ +/* proxy rule: lib_object->proxy_from == 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 */ @@ -1499,7 +1504,7 @@ void where_is_object_time(Object *ob, float ctime) pushdata(par, sizeof(Object)); pop= 1; - if(par->id.lib && par->proxy); // was a copied matrix, no where_is! bad... + if(par->proxy_from); // was a copied matrix, no where_is! bad... else where_is_object_time(par, ctime); } @@ -1966,8 +1971,8 @@ void minmax_object(Object *ob, float *min, float *max) } } -/* 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 */ +/* proxy rule: lib_object->proxy_from == 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! */ @@ -1978,13 +1983,19 @@ void object_handle_update(Object *ob) if(ob->recalc & OB_RECALC) { if(ob->recalc & OB_RECALC_OB) { - 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); + + // printf("recalcob %s\n", ob->id.name+2); + + /* handle proxy copy for target */ + if(ob->id.lib && ob->proxy_from) { + // printf("ob proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name); + if(ob->proxy_from->proxy_group) {/* transform proxy into group space */ + Object *obg= ob->proxy_from->proxy_group; + Mat4Invert(obg->imat, obg->obmat); + Mat4MulMat4(ob->obmat, ob->proxy_from->obmat, obg->imat); } else - Mat4CpyMat4(ob->obmat, ob->proxy->obmat); + Mat4CpyMat4(ob->obmat, ob->proxy_from->obmat); } else where_is_object(ob); @@ -2012,8 +2023,10 @@ void object_handle_update(Object *ob) if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) armature_rebuild_pose(ob, ob->data); - if(OB_COPY_PROXY(ob)) - copy_pose_result(ob->pose, ob->proxy->pose); + if(ob->id.lib && ob->proxy_from) { + copy_pose_result(ob->pose, ob->proxy_from->pose); + // printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name); + } else { do_all_pose_actions(ob); where_is_pose(ob); @@ -2022,9 +2035,10 @@ void object_handle_update(Object *ob) } /* the no-group proxy case, we call update */ - if(OB_DO_PROXY(ob)) { + if(ob->proxy && ob->proxy_group==NULL) { /* set pointer in library proxy target, for copying, but restore it */ - ob->proxy->proxy= ob; + ob->proxy->proxy_from= ob; + // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name); object_handle_update(ob->proxy); } @@ -2032,9 +2046,9 @@ void object_handle_update(Object *ob) } /* 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); + if(ob->proxy) { + ob->proxy->proxy_from= ob; + // printf("set proxy pointer for later group stuff %s\n", ob->id.name); } } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6ea01013584..b5e41ec8514 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -277,29 +277,28 @@ void set_scene_bg(Scene *sce) scene_check_setscene(G.scene); /* deselect objects (for dataselect) */ - ob= G.main->object.first; - while(ob) { + for(ob= G.main->object.first; ob; ob= ob->id.next) ob->flag &= ~(SELECT|OB_FROMGROUP); - ob= ob->id.next; - } /* group flags again */ - group= G.main->group.first; - while(group) { + for(group= G.main->group.first; group; group= group->id.next) { go= group->gobject.first; while(go) { if(go->ob) go->ob->flag |= OB_FROMGROUP; go= go->next; } - group= group->id.next; } /* sort baselist */ DAG_scene_sort(sce); + + /* ensure dags are built for sets */ + for(sce= sce->set; sce; sce= sce->set) + if(sce->theDag==NULL) + DAG_scene_sort(sce); /* copy layers and flags from bases to objects */ - base= G.scene->base.first; - while(base) { + for(base= G.scene->base.first; base; base= base->next) { ob= base->object; ob->lay= base->lay; @@ -311,7 +310,6 @@ void set_scene_bg(Scene *sce) ob->flag= base->flag; ob->ctime= -1234567.0; /* force ipo to be calculated later */ - base= base->next; } /* no full animation update, this to enable render code to work (render code calls own animation updates) */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d33fa6334b4..04e57518d21 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -486,7 +486,7 @@ static Main *blo_find_main(ListBase *mainlist, const char *name, const char *rel char *libname= (m->curlib)?m->curlib->filename:m->name; if (BLI_streq(name1, libname)) { - printf("blo_find_main: found library %s\n", libname); + if(G.f & G_DEBUG) printf("blo_find_main: found library %s\n", libname); return m; } } @@ -500,7 +500,7 @@ static Main *blo_find_main(ListBase *mainlist, const char *name, const char *rel m->curlib= lib; - printf("blo_find_main: added new lib %s\n", name); + if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", name); return m; } @@ -2588,20 +2588,23 @@ static void lib_link_object(FileData *fd, Main *main) ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo); ob->action = newlibadr_us(fd, ob->id.lib, ob->action); ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group); - if(ob->id.lib) { - /* no proxy in library data, is default local data */ - ob->proxy= NULL; ob->proxy_group= NULL; - } - else { - ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy); - if(ob->proxy) { + + ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy); + if(ob->proxy) { + /* paranoia check, actually a proxy_from pointer should never be written... */ + if(ob->proxy->id.lib==NULL) { + ob->proxy->proxy_from= NULL; + ob->proxy= NULL; + } + else { /* this triggers object_update to always use a copy */ - ob->proxy->proxy= ob; + ob->proxy->proxy_from= ob; /* force proxy updates after load/undo, a bit weak */ ob->recalc= ob->proxy->recalc= OB_RECALC; } - ob->proxy_group= newlibadr(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); @@ -6335,13 +6338,13 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) if(id==0) { read_libblock(fd, mainvar, bhead, LIB_READ+LIB_INDIRECT, NULL); - printf("expand_doit: other lib %s\n", lib->name); + if(G.f & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name); } else { //oldnewmap_insert(fd->libmap, bhead->old, id, 1); change_idid_adr_fd(fd, bhead->old, id); - printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); + if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); } } } @@ -6727,6 +6730,11 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) if(ob->dup_group) expand_doit(fd, mainvar, ob->dup_group); + + if(ob->proxy) + expand_doit(fd, mainvar, ob->proxy); + if(ob->proxy_group) + expand_doit(fd, mainvar, ob->proxy_group); sens= ob->sensors.first; while(sens) { @@ -7246,7 +7254,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if(fd==NULL) { BlendReadError err; - printf("read_libraries: lib %s\n", mainptr->curlib->name); + printf("read library: lib %s\n", mainptr->curlib->name); fd= blo_openblenderfile(mainptr->curlib->filename, &err); if (fd) { if (fd->libmap) diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 30d1c5c7ab6..2c8711d10ba 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -82,12 +82,10 @@ typedef struct bPoseChannel { typedef struct bPose{ ListBase chanbase; - int flag; + short flag, proxy_layer; /* proxy layer: copy from armature, gets synced */ float ctime; /* local action time of this pose */ float stride_offset[3]; /* applied to object */ float cyclic_offset[3]; /* result of match and cycles, applied in where_is_pose() */ - short proxy_layer, pad1; - int pad2; } bPose; typedef struct bActionChannel { diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index e58e6d7aa79..3ecfafeddaf 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -90,7 +90,10 @@ typedef struct Object { int par1, par2, par3; /* can be vertexnrs */ char parsubstr[32]; /* String describing subobject info */ void *pardata; - struct Object *parent, *track, *proxy, *proxy_group; + struct Object *parent, *track; + /* if ob->proxy (or proxy_group), this object is proxy for object ob->proxy */ + /* proxy_from is set in target back to the proxy. */ + struct Object *proxy, *proxy_group, *proxy_from; struct Ipo *ipo; struct Path *path; struct BoundBox *bb; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 397d383edda..7e3a86f2dcb 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2768,7 +2768,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, no layer check here, gets correct flushed */ - for(base= G.scene->base.first; base; base= base->next) { + for(SETLOOPER(G.scene, base)) { object_handle_update(base->object); // bke_object.h } @@ -2857,8 +2857,6 @@ void drawview3dspace(ScrArea *sa, void *spacedata) for(SETLOOPER(G.scene->set, base)) { if(v3d->lay & base->lay) { - - object_handle_update(base->object); BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); draw_object(base, DRAW_CONSTCOLOR); diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index 178acf51b1d..2ee40396061 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -620,7 +620,7 @@ void add_constraint(int only_IK) if(pchanact==NULL) return; /* check protection */ - if(OB_IS_PROXY(ob) && (pchanact->bone->layer & arm->layer_protected)) { + if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) { error("Bone is Proxy protected"); return; } diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index 501c3977de1..aa82544217c 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -177,7 +177,7 @@ static int pose_has_protected_selected(Object *ob, int only_selected) { /* check protection */ - if(OB_IS_PROXY(ob)) { + if(ob->proxy) { bPoseChannel *pchan; bArmature *arm= ob->data;