Depsgraph: Add evaluation callbacks for granular nodes update
[blender-staging.git] / source / blender / blenkernel / intern / anim_sys.c
index 3c98d11dbdb8d7a3a9e1ce5f115877c27f447632..d5a8b8f857cbd44bdd09970a4d0a32a6606c46f7 100644 (file)
@@ -1620,7 +1620,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
 }
 
 /* Simple replacement based data-setting of the FCurve using RNA */
-static bool animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
+bool BKE_animsys_execute_fcurve(PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
 {
        char *path = NULL;
        bool free_path = false;
@@ -1655,7 +1655,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, AnimMapper
                        /* check if this curve should be skipped */
                        if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
                                calculate_fcurve(fcu, ctime);
-                               animsys_execute_fcurve(ptr, remap, fcu); 
+                               BKE_animsys_execute_fcurve(ptr, remap, fcu); 
                        }
                }
        }
@@ -1685,7 +1685,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
                                 * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
                                 *       new to only be done when drivers only changed */
                                calculate_fcurve(fcu, ctime);
-                               ok = animsys_execute_fcurve(ptr, NULL, fcu);
+                               ok = BKE_animsys_execute_fcurve(ptr, NULL, fcu);
                                
                                /* clear recalc flag */
                                driver->flag &= ~DRIVER_FLAG_RECALC;
@@ -1754,7 +1754,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
                /* check if this curve should be skipped */
                if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
                        calculate_fcurve(fcu, ctime);
-                       animsys_execute_fcurve(ptr, remap, fcu); 
+                       BKE_animsys_execute_fcurve(ptr, remap, fcu); 
                }
        }
 }
@@ -2846,3 +2846,62 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
 }
 
 /* ***************************************** */ 
+
+/* ************** */
+/* Evaluation API */
+
+#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
+
+void BKE_animsys_eval_animdata(EvaluationContext *eval_ctx, ID *id)
+{
+       AnimData *adt = BKE_animdata_from_id(id);
+       Scene *scene = NULL; /* XXX: this is only needed for flushing RNA updates,
+                             * which should get handled as part of the graph instead...
+                             */
+       DEBUG_PRINT("%s on %s, time=%f\n\n", __func__, id->name, (double)eval_ctx->ctime);
+       BKE_animsys_evaluate_animdata(scene, id, adt, eval_ctx->ctime, ADT_RECALC_ANIM);
+}
+
+void BKE_animsys_eval_driver(EvaluationContext *eval_ctx,
+                             ID *id,
+                             FCurve *fcu)
+{
+       /* TODO(sergey): De-duplicate with BKE animsys. */
+       ChannelDriver *driver = fcu->driver;
+       PointerRNA id_ptr;
+       bool ok = false;
+
+       DEBUG_PRINT("%s on %s (%s[%d])\n",
+                   __func__,
+                   id->name,
+                   fcu->rna_path,
+                   fcu->array_index);
+
+       RNA_id_pointer_create(id, &id_ptr);
+
+       /* check if this driver's curve should be skipped */
+       if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
+               /* check if driver itself is tagged for recalculation */
+               /* XXX driver recalc flag is not set yet by depsgraph! */
+               if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) {
+                       /* evaluate this using values set already in other places
+                        * NOTE: for 'layering' option later on, we should check if we should remove old value before adding
+                        *       new to only be done when drivers only changed */
+                       //printf("\told val = %f\n", fcu->curval);
+                       calculate_fcurve(fcu, eval_ctx->ctime);
+                       ok = BKE_animsys_execute_fcurve(&id_ptr, NULL, fcu);
+                       //printf("\tnew val = %f\n", fcu->curval);
+
+                       /* clear recalc flag */
+                       driver->flag &= ~DRIVER_FLAG_RECALC;
+
+                       /* set error-flag if evaluation failed */
+                       if (ok == 0) {
+                               printf("invalid driver - %s[%d]\n", fcu->rna_path, fcu->array_index);
+                               driver->flag |= DRIVER_FLAG_INVALID;
+                       }
+               }
+       }
+}
+
+#undef DEBUG_PRINT