Depsgraph: Keep objects which has animated visibility
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 27 Feb 2019 14:15:26 +0000 (15:15 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 28 Feb 2019 15:28:24 +0000 (16:28 +0100)
This allows dependency graph to evaluate drivers of those objects
and put them to a correct state. It will increase memory usage
since now we can no longer save it by skipping copy-on-write for
such objects. It will also currently make things slower, because
we do not have granular enough visibility update of components in
the dependency graph. Can do it later when the rest of the changes
are finished.

This commit does not update restriction flags on the base, since
that is somewhat tricky to do currently: need to somehow see whether
object is disabled due to flags on collection or due to own flags.

Differential Revision: https://developer.blender.org/D4419

source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/depsgraph/intern/builder/deg_builder.cc

index ddc1589..e9eea16 100644 (file)
@@ -162,6 +162,9 @@ void BKE_animdata_main_cb(struct Main *bmain, ID_AnimData_Edit_Callback func, vo
 /* Loop over all datablocks applying callback to all its F-Curves */
 void BKE_fcurves_main_cb(struct Main *bmain, ID_FCurve_Edit_Callback func, void *user_data);
 
+/* Look over all f-curves of a given ID. */
+void BKE_fcurves_id_cb(struct ID *id, ID_FCurve_Edit_Callback func, void *user_data);
+
 /* ************************************* */
 // TODO: overrides, remapping, and path-finding api's
 
index acbf006..7c1c269 100644 (file)
@@ -1088,6 +1088,15 @@ static void adt_apply_all_fcurves_cb(ID *id, AnimData *adt, void *wrapper_data)
        }
 }
 
+void BKE_fcurves_id_cb(ID *id, ID_FCurve_Edit_Callback func, void *user_data)
+{
+       AnimData *adt = BKE_animdata_from_id(id);
+       if (adt != NULL) {
+               AllFCurvesCbWrapper wrapper = {func, user_data};
+               adt_apply_all_fcurves_cb(id, adt, &wrapper);
+       }
+}
+
 /* apply the given callback function on all F-Curves attached to data in main database */
 void BKE_fcurves_main_cb(Main *bmain, ID_FCurve_Edit_Callback func, void *user_data)
 {
index f5cf433..e927d6c 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "intern/builder/deg_builder.h"
 
+#include <cstring>
+
 #include "DNA_anim_types.h"
 #include "DNA_layer_types.h"
 #include "DNA_ID.h"
@@ -53,6 +55,46 @@ namespace DEG {
  * Base class for builders.
  */
 
+namespace {
+
+struct VisibilityCheckData {
+       eEvaluationMode eval_mode;
+       bool is_visibility_animated;
+};
+
+void visibility_animated_check_cb(ID * /*id*/, FCurve *fcu, void *user_data)
+{
+       VisibilityCheckData *data =
+               reinterpret_cast<VisibilityCheckData *>(user_data);
+       if (data->is_visibility_animated) {
+               return;
+       }
+       if (data->eval_mode == DAG_EVAL_VIEWPORT) {
+               if (STREQ(fcu->rna_path, "hide_viewport")) {
+                       data->is_visibility_animated = true;
+               }
+       } else if (data->eval_mode == DAG_EVAL_RENDER) {
+               if (STREQ(fcu->rna_path, "hide_render")) {
+                       data->is_visibility_animated = true;
+               }
+       }
+}
+
+bool isObjectVisibilityAnimated(Depsgraph *graph, Object *object)
+{
+       AnimData* anim_data = BKE_animdata_from_id(&object->id);
+       if (anim_data == NULL) {
+               return false;
+       }
+       VisibilityCheckData data;
+       data.eval_mode = graph->mode;
+       data.is_visibility_animated = false;
+       BKE_fcurves_id_cb(&object->id, visibility_animated_check_cb, &data);
+       return data.is_visibility_animated;
+}
+
+}  // namespace
+
 DepsgraphBuilder::DepsgraphBuilder(Main *bmain, Depsgraph *graph)
         : bmain_(bmain),
           graph_(graph) {
@@ -65,6 +107,9 @@ bool DepsgraphBuilder::needPullBaseIntoGraph(struct Base *base)
        if (base->flag & base_flag) {
                return true;
        }
+       if (isObjectVisibilityAnimated(graph_, base->object)) {
+               return true;
+       }
        return false;
 }