Depsgraph fix for editing linked Objects with the other instances being
authorTon Roosendaal <ton@blender.org>
Sun, 27 Nov 2005 20:49:25 +0000 (20:49 +0000)
committerTon Roosendaal <ton@blender.org>
Sun, 27 Nov 2005 20:49:25 +0000 (20:49 +0000)
in other layers (or hidden with local view).

In my search for the absolute minimum of recalculations, changes are only
flushed when they're visible. On changing layers, the tags then are just
set again (for everything that potentially moves) to ensure proper state.

However, it didn't work proper for linked Mesh objects that changed in
editmode, the Derivedmesh callback then accessed memory out of bounds.

The current dependency code was more designed for animation systems...
updating display data should work too, but might need some more tests!

(Thanks Andrea for clear error sample!)

source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/object.c
source/blender/src/header_view3d.c

index a7e37425da750475ba3892f4c40d65208e766209..2e4e4917de2647bb51703cf437d3a33d163a6cdf 100644 (file)
@@ -50,8 +50,11 @@ void copy_baseflags(void);
 void copy_objectflags(void);
 struct SoftBody *copy_softbody(struct SoftBody *sb);
 void update_base_layer(struct Object *ob);
+
 void free_object(struct Object *ob);
+void object_free_display(struct Object *ob);
 void object_free_modifiers(struct Object *ob);
+
 void unlink_object(struct Object *ob);
 int exist_object(struct Object *obtest);
 void *add_camera(void);
index 617a3dcdb6830d86edcbed72db4993b5abc08e41..50ca6bc4fe628a99e86274a50dbccdfec0718902 100644 (file)
@@ -67,6 +67,7 @@
 #include "BKE_key.h"
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
+#include "BKE_object.h"
 #include "BKE_utildefines.h"
 
 #include "MEM_guardedalloc.h"
@@ -1390,9 +1391,13 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
                        }
                }
                /* even nicer, we can clear recalc flags...  */
-               if((all_layer & layer)==0)
+               if((all_layer & layer)==0) {
+                       /* but existing displaylists or derivedmesh should be freed */
+                       if(ob->recalc & OB_RECALC_DATA)
+                               object_free_display(ob);
+                       
                        ob->recalc &= ~OB_RECALC;
-               
+               }
        }
        
        /* check case where child changes and parent forcing obdata to change */
index d97211b3125a39e7de72cd3c79836d5c66435a32..957d76d786b9fd05ba9571f1b2e8ed4ea3fbeeae 100644 (file)
@@ -161,14 +161,29 @@ void object_free_modifiers(Object *ob)
        }
 }
 
+/* here we will collect all local displist stuff */
+/* also (ab)used in depsgraph */
+void object_free_display(Object *ob)
+{
+       if(ob->derivedDeform) {
+               ob->derivedDeform->release(ob->derivedDeform);
+               ob->derivedDeform= NULL;
+       }
+       if(ob->derivedFinal) {
+               ob->derivedFinal->release(ob->derivedFinal);
+               ob->derivedFinal= NULL;
+       }
+       
+       freedisplist(&ob->disp);
+}
+
 /* do not free object itself */
 void free_object(Object *ob)
 {
        int a;
        
-       if(ob->derivedDeform) ob->derivedDeform->release(ob->derivedDeform);
-       if(ob->derivedFinal) ob->derivedFinal->release(ob->derivedFinal);
-
+       object_free_display(ob);
+       
        /* disconnect specific data */
        if(ob->data) {
                ID *id= ob->data;
@@ -211,8 +226,6 @@ void free_object(Object *ob)
        free_constraint_channels(&ob->constraintChannels);
        free_nlastrips(&ob->nlastrips);
        
-       freedisplist(&ob->disp);
-       
        BPY_free_scriptlink(&ob->scriptlink);
        
        if(ob->pd) MEM_freeN(ob->pd);
index 05a792e46902598b5bff675996b66c420b1cb328..2b448348034c3a03222d8396f022da5f1219670b 100644 (file)
@@ -3881,7 +3881,11 @@ void do_view3d_buttons(short event)
                
        case B_LOCALVIEW:
                if(G.vd->localview) initlocalview();
-               else endlocalview(curarea);
+               else {
+                       endlocalview(curarea);
+                       /* new layers might need unflushed events events */
+                       DAG_scene_update_flags(G.scene, G.vd->lay);     // tags all that moves and flushes
+               }
                scrarea_queue_headredraw(curarea);
                break;