Animation System: Handling Updates
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 Dec 2009 18:28:09 +0000 (18:28 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 Dec 2009 18:28:09 +0000 (18:28 +0000)
* Added ANIM_list_elem_update and ANIM_id_update functions to call when
  changing animation curves, which will then call the RNA property update
  functions for those curves.

  This is to replace just calling DAG_id_flush_update, that may not always
  be the right thing to do, and doesn't send proper notifiers for redraw.

  Still only used/usable when transforming in the graph editor, not sure
  how this do this with NLA for example, .. needs to be improved.

* Added function wm_data_handle_update function to contain the object
  update function, and also added scene animation update there. Actually
  it should be doing all datablocks, this makes it work for sequencer.

Joshua, do you agree this is the right direction to go in? I can revert or
change the code if you think it should be done differently. Mainly wanted
to get this working well for sequencer now.

source/blender/editors/animation/anim_deps.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/transform/transform_generics.c
source/blender/windowmanager/intern/wm_event_system.c

index 7a96c3b32a3d349752cb3da757c9cfd816db2807..0e81dab380c13c992b8f5ecee42b80d3ee55cca5 100644 (file)
@@ -32,6 +32,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_action_types.h"
+#include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "BLI_blenlib.h"
 
 #include "BKE_action.h"
+#include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
+#include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
 #include "WM_api.h"
 #include "WM_types.h"
 
+/* tags the given anim list element for refreshes (if applicable)
+ * due to Animation Editor editing */
+void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
+{
+       ID *id;
+       FCurve *fcu;
+       AnimData *adt;
+
+       id= ale->id;
+       if(!id)
+               return;
+       
+       /* tag AnimData for refresh so that other views will update in realtime with these changes */
+       adt= BKE_animdata_from_id(id);
+       if(adt)
+               adt->recalc |= ADT_RECALC_ANIM;
+
+       /* update data */
+       fcu= (ale->datatype == ALE_FCURVE)? ale->key_data: NULL;
+               
+       if(fcu && fcu->rna_path) {
+               /* if we have an fcurve, call the update for the property we
+                  are editing, this is then expected to do the proper redraws
+                  and depsgraph updates  */
+               PointerRNA id_ptr, ptr;
+               PropertyRNA *prop;
+
+               RNA_id_pointer_create(id, &id_ptr);
+                       
+               if(RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop))
+                       RNA_property_update_main(G.main, scene, &ptr, prop);
+       }
+       else {
+               /* in other case we do standard depsgaph update, ideally
+                  we'd be calling property update functions here too ... */
+               DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
+       }
+}
+
+/* tags the given ID block for refreshes (if applicable) due to 
+ * Animation Editor editing */
+void ANIM_id_update(Scene *scene, ID *id)
+{
+       if(id) {
+               AnimData *adt= BKE_animdata_from_id(id);
+               
+               /* tag AnimData for refresh so that other views will update in realtime with these changes */
+               if (adt)
+                       adt->recalc |= ADT_RECALC_ANIM;
+                       
+               /* set recalc flags */
+               DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
+       }
+}
+
 /* **************************** pose <-> action syncing ******************************** */
 /* Summary of what needs to be synced between poses and actions:
  *     1) Flags
index c9c4c7af18cf479965c170dfaf5814b1cc777a40..9989589cf239f7d70dc96bec4793e9e2dbedf048 100644 (file)
@@ -496,6 +496,9 @@ void ED_nla_postop_refresh(bAnimContext *ac);
 
 /* --------- anim_deps.c, animation updates -------- */
 
+void ANIM_id_update(struct Scene *scene, struct ID *id);
+void ANIM_list_elem_update(struct Scene *scene, bAnimListElem *ale);
+
 /* pose <-> action syncing */
 void ANIM_action_to_pose_sync(struct Object *ob);
 void ANIM_pose_to_action_sync(struct Object *ob, struct ScrArea *sa);
index 0340475a1d13ee14f1d1bf8334673e95198425c5..7951b0021743d1a5f1d4dba660b4c93872c69b57 100644 (file)
@@ -273,23 +273,6 @@ static void editmesh_apply_to_mirror(TransInfo *t)
        }
 }
 
-/* tags the given ID block for refreshes (if applicable) due to 
- * Animation Editor editing
- */
-static void animedit_refresh_id_tags (Scene *scene, ID *id)
-{
-       if (id) {
-               AnimData *adt= BKE_animdata_from_id(id);
-               
-               /* tag AnimData for refresh so that other views will update in realtime with these changes */
-               if (adt)
-                       adt->recalc |= ADT_RECALC_ANIM;
-                       
-               /* set recalc flags */
-               DAG_id_flush_update(id, OB_RECALC); // XXX or do we want something more restrictive?
-       }
-}
-
 /* for the realtime animation recording feature, handle overlapping data */
 static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer)
 {
@@ -378,7 +361,7 @@ void recalcData(TransInfo *t)
                /* just tag these animdata-blocks to recalc, assuming that some data there changed */
                for (ale= anim_data.first; ale; ale= ale->next) {
                        /* set refresh tags for objects using this animation */
-                       animedit_refresh_id_tags(t->scene, ale->id);
+                       ANIM_list_elem_update(t->scene, ale);
                }
                
                /* now free temp channels */
@@ -426,7 +409,7 @@ void recalcData(TransInfo *t)
                                calchandles_fcurve(fcu);
                                
                        /* set refresh tags for objects using this animation */
-                       animedit_refresh_id_tags(t->scene, ale->id);
+                       ANIM_list_elem_update(t->scene, ale);
                }
                
                /* do resort and other updates? */
@@ -457,7 +440,7 @@ void recalcData(TransInfo *t)
                                continue;
                        
                        /* set refresh tags for objects using this animation */
-                       animedit_refresh_id_tags(t->scene, tdn->id);
+                       ANIM_id_update(t->scene, tdn->id);
                        
                        /* if cancelling transform, just write the values without validating, then move on */
                        if (t->state == TRANS_CANCEL) {
index 8e187eea93cfbaad0ec7857bbd7f799dbccebf31..76ab00e19a593e4cf76badbe515655c1820ec420 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "DNA_anim_types.h"
 #include "DNA_listBase.h"
 #include "DNA_screen_types.h"
 #include "DNA_scene_types.h"
@@ -41,6 +42,7 @@
 
 #include "BLI_blenlib.h"
 
+#include "BKE_animsys.h"
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_idprop.h"
@@ -147,6 +149,40 @@ static wmNotifier *wm_notifier_next(wmWindowManager *wm)
        return note;
 }
 
+static void wm_data_handle_update(Scene *scene)
+{
+       Scene *sce;
+       Base *base;
+
+       /* XXX make lock in future, or separated derivedmesh users in scene */
+       if(G.rendering)
+               return;
+
+       /* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual, 
+               no layer check here, gets correct flushed */
+       /* sets first, we allow per definition current scene to have dependencies on sets */
+       if(scene->set) {
+               for(SETLOOPER(scene->set, base))
+                       object_handle_update(scene, base->object);
+       }
+       
+       for(base= scene->base.first; base; base= base->next) {
+               object_handle_update(scene, base->object);
+       }
+
+       /* recalc scene animation data here (for sequencer). actually
+          this should be doing all datablocks including e.g. materials,
+          but for now this solves some update issues - brecht. */
+       {
+               AnimData *adt= BKE_animdata_from_id(&scene->id);
+
+               if(adt && (adt->recalc & ADT_RECALC_ANIM))
+                       BKE_animsys_evaluate_animdata(&scene->id, adt, scene->r.cfra, 0);
+       }
+
+       BKE_ptcache_quick_cache_all(scene);
+}
+
 /* called in mainloop */
 void wm_event_do_notifiers(bContext *C)
 {
@@ -246,9 +282,7 @@ void wm_event_do_notifiers(bContext *C)
        
        /* cached: editor refresh callbacks now, they get context */
        for(win= wm->windows.first; win; win= win->next) {
-               Scene *sce, *scene= win->screen->scene;
                ScrArea *sa;
-               Base *base;
                
                CTX_wm_window_set(C, win);
                for(sa= win->screen->areabase.first; sa; sa= sa->next) {
@@ -258,23 +292,9 @@ void wm_event_do_notifiers(bContext *C)
                        }
                }
                
-               if(G.rendering==0) { // XXX make lock in future, or separated derivedmesh users in scene
-                       
-                       /* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual, 
-                               no layer check here, gets correct flushed */
-                       /* sets first, we allow per definition current scene to have dependencies on sets */
-                       if(scene->set) {
-                               for(SETLOOPER(scene->set, base))
-                                       object_handle_update(scene, base->object);
-                       }
-                       
-                       for(base= scene->base.first; base; base= base->next) {
-                               object_handle_update(scene, base->object);
-                       }
-
-                       BKE_ptcache_quick_cache_all(scene);
-               }               
+               wm_data_handle_update(win->screen->scene);
        }
+
        CTX_wm_window_set(C, NULL);
 }