Depsgraph: Use new animation cache for visibility check

Should be no functional changes, just switching code to use more
generic checks now.

One thing which goes a bit deeper than that is check for whether
base is a part of dependency graph. This is now done by explicitly
tagging corresponding ID node (of an object) rather than doing
animation check again.
This commit is contained in:
Sergey Sharybin 2019-04-29 14:11:32 +02:00
parent c8f3377d03
commit 6bbb82cf79
6 changed files with 39 additions and 54 deletions

View File

@ -41,6 +41,7 @@ extern "C" {
#include "intern/depsgraph.h"
#include "intern/depsgraph_tag.h"
#include "intern/depsgraph_type.h"
#include "intern/builder/deg_builder_cache.h"
#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_id.h"
@ -51,6 +52,16 @@ extern "C" {
namespace DEG {
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base)
{
Object *object_orig = base->base_orig->object;
IDNode *id_node = graph->find_id_node(&object_orig->id);
if (id_node == NULL) {
return false;
}
return id_node->has_base;
}
/*******************************************************************************
* Base class for builders.
*/
@ -60,62 +71,30 @@ DepsgraphBuilder::DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuild
{
}
namespace {
struct VisibilityCheckData {
eEvaluationMode eval_mode;
bool is_visibility_animated;
};
void visibility_animated_check_cb(ID * /*id*/, FCurve *fcu, void *user_data)
bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
{
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 is_object_visibility_animated(const 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
bool deg_check_base_available_for_build(const Depsgraph *graph, Base *base)
{
const int base_flag = (graph->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
BASE_ENABLED_RENDER;
/* Simple check: enabled bases are always part of dependency graph. */
const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
BASE_ENABLED_RENDER;
if (base->flag & base_flag) {
return true;
}
if (is_object_visibility_animated(graph, base->object)) {
return true;
/* More involved check: since we don't support dynamic changes in dependency graph topology and
* all visible objects are to be part of dependency graph, we pull all objects which has animated
* visibility. */
Object *object = base->object;
AnimatedPropertyID property_id;
if (graph_->mode == DAG_EVAL_VIEWPORT) {
property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_viewport");
}
return false;
}
bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
{
return deg_check_base_available_for_build(graph_, base);
else if (graph_->mode == DAG_EVAL_RENDER) {
property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_render");
}
else {
BLI_assert(!"Unknown evaluation mode.");
return false;
}
return cache_->isPropertyAnimated(&object->id, property_id);
}
/*******************************************************************************

View File

@ -33,7 +33,7 @@ class DepsgraphBuilderCache;
class DepsgraphBuilder {
public:
bool need_pull_base_into_graph(struct Base *base);
bool need_pull_base_into_graph(Base *base);
protected:
/* NOTE: The builder does NOT take ownership over any of those resources. */
@ -45,7 +45,7 @@ class DepsgraphBuilder {
DepsgraphBuilderCache *cache_;
};
bool deg_check_base_available_for_build(const Depsgraph *graph, Base *base);
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base);
void deg_graph_build_finalize(struct Main *bmain, struct Depsgraph *graph);
} // namespace DEG

View File

@ -528,6 +528,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) {
id_node->is_directly_visible |= is_visible;
}
id_node->has_base |= (base_index != -1);
return;
}
/* Create ID node for object and begin init. */
@ -540,6 +541,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
else {
id_node->is_directly_visible = is_visible;
}
id_node->has_base |= (base_index != -1);
/* Various flags, flushing from bases/collections. */
build_object_flags(base_index, object, linked_state);
/* Transform. */

View File

@ -380,7 +380,7 @@ void view_layer_remove_disabled_bases(const Depsgraph *depsgraph, ViewLayer *vie
* points to is not yet copied. This is dangerous access from evaluated
* domain to original one, but this is how the entire copy-on-write works:
* it does need to access original for an initial copy. */
const bool is_object_enabled = deg_check_base_available_for_build(depsgraph, base->base_orig);
const bool is_object_enabled = deg_check_base_in_depsgraph(depsgraph, base);
if (is_object_enabled) {
BLI_addtail(&enabled_bases, base);
}

View File

@ -111,6 +111,7 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata))
linked_state = DEG_ID_LINKED_INDIRECTLY;
is_directly_visible = true;
is_collection_fully_expanded = false;
has_base = false;
visible_components_mask = 0;
previously_visible_components_mask = 0;

View File

@ -96,6 +96,9 @@ struct IDNode : public Node {
* recursed into. */
bool is_collection_fully_expanded;
/* Is used to figure out whether object came to the dependency graph via a base. */
bool has_base;
IDComponentsMask visible_components_mask;
IDComponentsMask previously_visible_components_mask;