Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/CMakeLists.txt5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc182
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h12
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc24
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc29
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc367
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h30
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc57
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc35
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc120
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_transitive.cc1
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug.cc40
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug.h33
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc6
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc2
-rw-r--r--source/blender/depsgraph/intern/debug/deg_time_average.h71
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc79
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h49
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc11
-rw-r--r--source/blender/depsgraph/intern/depsgraph_debug.cc15
-rw-r--r--source/blender/depsgraph/intern/depsgraph_physics.cc28
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc32
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_foreach.cc5
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc30
-rw-r--r--source/blender/depsgraph/intern/depsgraph_relation.cc73
-rw-r--r--source/blender/depsgraph/intern/depsgraph_relation.h63
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc58
-rw-r--r--source/blender/depsgraph/intern/depsgraph_update.cc8
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc226
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc165
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h4
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc19
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc17
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h4
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc144
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h65
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc8
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc30
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc20
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc12
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.cc1
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.h4
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc40
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_factory.cc4
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc12
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc4
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_time.cc1
62 files changed, 1485 insertions, 838 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 4abeec19645..fad8bc22e08 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -59,6 +59,7 @@ set(SRC
intern/eval/deg_eval_copy_on_write.cc
intern/eval/deg_eval_flush.cc
intern/eval/deg_eval_runtime_backup.cc
+ intern/eval/deg_eval_runtime_backup_animation.cc
intern/eval/deg_eval_runtime_backup_modifier.cc
intern/eval/deg_eval_runtime_backup_movieclip.cc
intern/eval/deg_eval_runtime_backup_object.cc
@@ -82,6 +83,7 @@ set(SRC
intern/depsgraph_query.cc
intern/depsgraph_query_foreach.cc
intern/depsgraph_query_iter.cc
+ intern/depsgraph_relation.cc
intern/depsgraph_registry.cc
intern/depsgraph_tag.cc
intern/depsgraph_type.cc
@@ -104,10 +106,12 @@ set(SRC
intern/builder/deg_builder_rna.h
intern/builder/deg_builder_transitive.h
intern/debug/deg_debug.h
+ intern/debug/deg_time_average.h
intern/eval/deg_eval.h
intern/eval/deg_eval_copy_on_write.h
intern/eval/deg_eval_flush.h
intern/eval/deg_eval_runtime_backup.h
+ intern/eval/deg_eval_runtime_backup_animation.h
intern/eval/deg_eval_runtime_backup_modifier.h
intern/eval/deg_eval_runtime_backup_movieclip.h
intern/eval/deg_eval_runtime_backup_object.h
@@ -127,6 +131,7 @@ set(SRC
intern/depsgraph.h
intern/depsgraph_physics.h
intern/depsgraph_registry.h
+ intern/depsgraph_relation.h
intern/depsgraph_tag.h
intern/depsgraph_type.h
intern/depsgraph_update.h
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 4ca7240abd1..7eca04112e7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -42,6 +42,7 @@ extern "C" {
}
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
#include "intern/depsgraph_tag.h"
#include "intern/depsgraph_type.h"
#include "intern/builder/deg_builder_cache.h"
@@ -55,11 +56,17 @@ extern "C" {
namespace DEG {
+bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig)
+{
+ IDNode *id_node = graph->find_id_node(id_orig);
+ return id_node != nullptr;
+}
+
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) {
+ if (id_node == nullptr) {
return false;
}
return id_node->has_base;
@@ -107,7 +114,7 @@ bool DepsgraphBuilder::need_pull_base_into_graph(Base *base)
bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel *pchan)
{
BLI_assert(object->type == OB_ARMATURE);
- if (pchan == NULL || pchan->bone == NULL) {
+ if (pchan == nullptr || pchan->bone == nullptr) {
return false;
}
/* We don't really care whether segments are higher than 1 due to static user input (as in,
@@ -127,7 +134,7 @@ bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel
bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan)
{
/* Proxies don't have BONE_SEGMENTS */
- if (ID_IS_LINKED(object) && object->proxy_from != NULL) {
+ if (ID_IS_LINKED(object) && object->proxy_from != nullptr) {
return false;
}
return check_pchan_has_bbone(object, pchan);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h
index 97e12e9ceb2..2db861b6fca 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder.h
@@ -24,6 +24,7 @@
#pragma once
struct Base;
+struct ID;
struct Main;
struct Object;
struct bPoseChannel;
@@ -53,6 +54,7 @@ class DepsgraphBuilder {
DepsgraphBuilderCache *cache_;
};
+bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig);
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base);
void deg_graph_build_finalize(Main *bmain, Depsgraph *graph);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index 3cfb4f95e5e..fe1886c67e8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -37,7 +37,7 @@ namespace DEG {
/* Animated property storage. */
-AnimatedPropertyID::AnimatedPropertyID() : data(NULL), property_rna(NULL)
+AnimatedPropertyID::AnimatedPropertyID() : data(nullptr), property_rna(nullptr)
{
}
@@ -89,13 +89,13 @@ struct AnimatedPropertyCallbackData {
void animated_property_cb(ID * /*id*/, FCurve *fcurve, void *data_v)
{
- if (fcurve->rna_path == NULL || fcurve->rna_path[0] == '\0') {
+ if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') {
return;
}
AnimatedPropertyCallbackData *data = static_cast<AnimatedPropertyCallbackData *>(data_v);
/* Resolve property. */
PointerRNA pointer_rna;
- PropertyRNA *property_rna = NULL;
+ PropertyRNA *property_rna = nullptr;
if (!RNA_path_resolve_property(
&data->pointer_rna, fcurve->rna_path, &pointer_rna, &property_rna)) {
return;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
index bea59eceea2..e0d162a49c5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
@@ -35,6 +35,7 @@
#include "intern/node/deg_node_operation.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
namespace DEG {
@@ -99,8 +100,8 @@ void schedule_node_to_stack(CyclesSolverState *state, OperationNode *node)
{
StackEntry entry;
entry.node = node;
- entry.from = NULL;
- entry.via_relation = NULL;
+ entry.from = nullptr;
+ entry.via_relation = nullptr;
BLI_stack_push(state->traversal_stack, &entry);
set_node_visited_state(node, NODE_IN_STACK);
}
@@ -186,7 +187,7 @@ void solve_cycles(CyclesSolverState *state)
node->full_identifier() + " via '" + rel->name + "'\n";
StackEntry *current = entry;
while (current->node != to) {
- BLI_assert(current != NULL);
+ BLI_assert(current != nullptr);
cycle_str += " " + current->from->node->full_identifier() + " via '" +
current->via_relation->name + "'\n";
current = current->from;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index d0e40d49527..6382772c8db 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -47,6 +47,7 @@ extern "C" {
#include "DNA_gpencil_types.h"
#include "DNA_key_types.h"
#include "DNA_light_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
@@ -121,7 +122,7 @@ namespace {
void free_copy_on_write_datablock(void *id_info_v)
{
DepsgraphNodeBuilder::IDInfo *id_info = (DepsgraphNodeBuilder::IDInfo *)id_info_v;
- if (id_info->id_cow != NULL) {
+ if (id_info->id_cow != nullptr) {
deg_free_copy_on_write_datablock(id_info->id_cow);
MEM_freeN(id_info->id_cow);
}
@@ -139,37 +140,37 @@ DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain,
Depsgraph *graph,
DepsgraphBuilderCache *cache)
: DepsgraphBuilder(bmain, graph, cache),
- scene_(NULL),
- view_layer_(NULL),
+ scene_(nullptr),
+ view_layer_(nullptr),
view_layer_index_(-1),
- collection_(NULL),
+ collection_(nullptr),
is_parent_collection_visible_(true),
- id_info_hash_(NULL)
+ id_info_hash_(nullptr)
{
}
DepsgraphNodeBuilder::~DepsgraphNodeBuilder()
{
- if (id_info_hash_ != NULL) {
- BLI_ghash_free(id_info_hash_, NULL, free_copy_on_write_datablock);
+ if (id_info_hash_ != nullptr) {
+ BLI_ghash_free(id_info_hash_, nullptr, free_copy_on_write_datablock);
}
}
IDNode *DepsgraphNodeBuilder::add_id_node(ID *id)
{
- IDNode *id_node = NULL;
- ID *id_cow = NULL;
+ IDNode *id_node = nullptr;
+ ID *id_cow = nullptr;
IDComponentsMask previously_visible_components_mask = 0;
uint32_t previous_eval_flags = 0;
DEGCustomDataMeshMasks previous_customdata_masks;
IDInfo *id_info = (IDInfo *)BLI_ghash_lookup(id_info_hash_, id);
- if (id_info != NULL) {
+ if (id_info != nullptr) {
id_cow = id_info->id_cow;
previously_visible_components_mask = id_info->previously_visible_components_mask;
previous_eval_flags = id_info->previous_eval_flags;
previous_customdata_masks = id_info->previous_customdata_masks;
/* Tag ID info to not free the CoW ID pointer. */
- id_info->id_cow = NULL;
+ id_info->id_cow = nullptr;
}
id_node = graph_->add_id_node(id, id_cow);
id_node->previously_visible_components_mask = previously_visible_components_mask;
@@ -217,7 +218,7 @@ OperationNode *DepsgraphNodeBuilder::add_operation_node(ComponentNode *comp_node
int name_tag)
{
OperationNode *op_node = comp_node->find_operation(opcode, name, name_tag);
- if (op_node == NULL) {
+ if (op_node == nullptr) {
op_node = comp_node->add_operation(op, opcode, name, name_tag);
graph_->operations.push_back(op_node);
}
@@ -262,7 +263,7 @@ OperationNode *DepsgraphNodeBuilder::ensure_operation_node(ID *id,
int name_tag)
{
OperationNode *operation = find_operation_node(id, comp_type, opcode, name, name_tag);
- if (operation != NULL) {
+ if (operation != nullptr) {
return operation;
}
return add_operation_node(id, comp_type, opcode, op, name, name_tag);
@@ -275,7 +276,7 @@ bool DepsgraphNodeBuilder::has_operation_node(ID *id,
const char *name,
int name_tag)
{
- return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != NULL;
+ return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
}
OperationNode *DepsgraphNodeBuilder::find_operation_node(ID *id,
@@ -323,13 +324,13 @@ void DepsgraphNodeBuilder::begin_build()
id_info->id_cow = id_node->id_cow;
}
else {
- id_info->id_cow = NULL;
+ id_info->id_cow = nullptr;
}
id_info->previously_visible_components_mask = id_node->visible_components_mask;
id_info->previous_eval_flags = id_node->eval_flags;
id_info->previous_customdata_masks = id_node->customdata_masks;
BLI_ghash_insert(id_info_hash_, id_node->id_orig, id_info);
- id_node->id_cow = NULL;
+ id_node->id_cow = nullptr;
}
GSET_FOREACH_BEGIN (OperationNode *, op_node, graph_->entry_tags) {
@@ -349,23 +350,23 @@ void DepsgraphNodeBuilder::begin_build()
/* Make sure graph has no nodes left from previous state. */
graph_->clear_all_nodes();
graph_->operations.clear();
- BLI_gset_clear(graph_->entry_tags, NULL);
+ BLI_gset_clear(graph_->entry_tags, nullptr);
}
void DepsgraphNodeBuilder::end_build()
{
for (const SavedEntryTag &entry_tag : saved_entry_tags_) {
IDNode *id_node = find_id_node(entry_tag.id_orig);
- if (id_node == NULL) {
+ if (id_node == nullptr) {
continue;
}
ComponentNode *comp_node = id_node->find_component(entry_tag.component_type);
- if (comp_node == NULL) {
+ if (comp_node == nullptr) {
continue;
}
OperationNode *op_node = comp_node->find_operation(
entry_tag.opcode, entry_tag.name.c_str(), entry_tag.name_tag);
- if (op_node == NULL) {
+ if (op_node == nullptr) {
continue;
}
/* Since the tag is coming from a saved copy of entry tags, this means
@@ -376,7 +377,7 @@ void DepsgraphNodeBuilder::end_build()
void DepsgraphNodeBuilder::build_id(ID *id)
{
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
switch (GS(id->name)) {
@@ -390,7 +391,7 @@ void DepsgraphNodeBuilder::build_id(ID *id)
build_camera((Camera *)id);
break;
case ID_GR:
- build_collection(NULL, (Collection *)id);
+ build_collection(nullptr, (Collection *)id);
break;
case ID_OB:
/* TODO(sergey): Get visibility from a "parent" somehow.
@@ -432,6 +433,9 @@ void DepsgraphNodeBuilder::build_id(ID *id)
case ID_MSK:
build_mask((Mask *)id);
break;
+ case ID_LS:
+ build_freestyle_linestyle((FreestyleLineStyle *)id);
+ break;
case ID_MC:
build_movieclip((MovieClip *)id);
break;
@@ -483,7 +487,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
* objects are poked with the new visibility flag, since they
* might become visible too. */
}
- else if (from_layer_collection == NULL && !id_node->is_collection_fully_expanded) {
+ else if (from_layer_collection == nullptr && !id_node->is_collection_fully_expanded) {
/* Initially collection was built from layer now, and was requested
* to not recurs into object. But nw it's asked to recurs into all
* objects. */
@@ -497,7 +501,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
id_node = add_id_node(&collection->id);
id_node->is_directly_visible = is_collection_visible;
}
- if (from_layer_collection != NULL) {
+ if (from_layer_collection != nullptr) {
/* If we came from layer collection we don't go deeper, view layer
* builder takes care of going deeper. */
return;
@@ -514,7 +518,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
}
/* Build child collections. */
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- build_collection(NULL, child->collection);
+ build_collection(nullptr, child->collection);
}
/* Restore state. */
collection_ = current_state_collection;
@@ -527,7 +531,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
eDepsNode_LinkedState_Type linked_state,
bool is_visible)
{
- if (object->proxy != NULL) {
+ if (object->proxy != nullptr) {
object->proxy->proxy_from = object;
}
const bool has_object = built_map_.checkIsBuiltAndTag(object);
@@ -550,10 +554,10 @@ void DepsgraphNodeBuilder::build_object(int base_index,
IDNode *id_node = add_id_node(&object->id);
Object *object_cow = get_cow_datablock(object);
id_node->linked_state = linked_state;
- /* NOTE: Scene is NULL when building dependency graph for render pipeline.
- * Probably need to assign that to something non-NULL, but then the logic here will still be
+ /* NOTE: Scene is nullptr when building dependency graph for render pipeline.
+ * Probably need to assign that to something non-nullptr, but then the logic here will still be
* somewhat weird. */
- if (scene_ != NULL && object == scene_->camera) {
+ if (scene_ != nullptr && object == scene_->camera) {
id_node->is_directly_visible = true;
}
else {
@@ -565,32 +569,32 @@ void DepsgraphNodeBuilder::build_object(int base_index,
/* Transform. */
build_object_transform(object);
/* Parent. */
- if (object->parent != NULL) {
+ if (object->parent != nullptr) {
build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible);
}
/* Modifiers. */
- if (object->modifiers.first != NULL) {
+ if (object->modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
data.is_parent_visible = is_visible;
modifiers_foreachIDLink(object, modifier_walk, &data);
}
/* Grease Pencil Modifiers. */
- if (object->greasepencil_modifiers.first != NULL) {
+ if (object->greasepencil_modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
data.is_parent_visible = is_visible;
BKE_gpencil_modifiers_foreachIDLink(object, modifier_walk, &data);
}
/* Shader FX. */
- if (object->shader_fx.first != NULL) {
+ if (object->shader_fx.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
data.is_parent_visible = is_visible;
BKE_shaderfx_foreachIDLink(object, modifier_walk, &data);
}
/* Constraints. */
- if (object->constraints.first != NULL) {
+ if (object->constraints.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
data.is_parent_visible = is_visible;
@@ -608,17 +612,17 @@ void DepsgraphNodeBuilder::build_object(int base_index,
* pose for proxy. */
build_animdata(&object->id);
/* Particle systems. */
- if (object->particlesystem.first != NULL) {
+ if (object->particlesystem.first != nullptr) {
build_particle_systems(object, is_visible);
}
/* Proxy object to copy from. */
build_object_proxy_from(object, is_visible);
build_object_proxy_group(object, is_visible);
/* Object dupligroup. */
- if (object->instance_collection != NULL) {
+ if (object->instance_collection != nullptr) {
const bool is_current_parent_collection_visible = is_parent_collection_visible_;
is_parent_collection_visible_ = is_visible;
- build_collection(NULL, object->instance_collection);
+ build_collection(nullptr, object->instance_collection);
is_parent_collection_visible_ = is_current_parent_collection_visible;
add_operation_node(&object->id, NodeType::DUPLI, OperationCode::DUPLI);
}
@@ -654,7 +658,7 @@ void DepsgraphNodeBuilder::build_object_flags(int base_index,
void DepsgraphNodeBuilder::build_object_proxy_from(Object *object, bool is_visible)
{
- if (object->proxy_from == NULL) {
+ if (object->proxy_from == nullptr) {
return;
}
build_object(-1, object->proxy_from, DEG_ID_LINKED_INDIRECTLY, is_visible);
@@ -662,7 +666,7 @@ void DepsgraphNodeBuilder::build_object_proxy_from(Object *object, bool is_visib
void DepsgraphNodeBuilder::build_object_proxy_group(Object *object, bool is_visible)
{
- if (object->proxy_group == NULL) {
+ if (object->proxy_group == nullptr) {
return;
}
build_object(-1, object->proxy_group, DEG_ID_LINKED_INDIRECTLY, is_visible);
@@ -670,7 +674,7 @@ void DepsgraphNodeBuilder::build_object_proxy_group(Object *object, bool is_visi
void DepsgraphNodeBuilder::build_object_data(Object *object, bool is_object_visible)
{
- if (object->data == NULL) {
+ if (object->data == nullptr) {
return;
}
/* type-specific data. */
@@ -685,7 +689,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object, bool is_object_visi
build_object_data_geometry(object, is_object_visible);
break;
case OB_ARMATURE:
- if (ID_IS_LINKED(object) && object->proxy_from != NULL) {
+ if (ID_IS_LINKED(object) && object->proxy_from != nullptr) {
build_proxy_rig(object);
}
else {
@@ -714,7 +718,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object, bool is_object_visi
}
/* Materials. */
Material ***materials_ptr = give_matarar(object);
- if (materials_ptr != NULL) {
+ if (materials_ptr != nullptr) {
short *num_materials_ptr = give_totcolp(object);
build_materials(*materials_ptr, *num_materials_ptr);
}
@@ -759,14 +763,14 @@ void DepsgraphNodeBuilder::build_object_transform(Object *object)
OperationCode::TRANSFORM_LOCAL,
function_bind(BKE_object_eval_local_transform, _1, ob_cow));
/* Object parent. */
- if (object->parent != NULL) {
+ if (object->parent != nullptr) {
add_operation_node(&object->id,
NodeType::TRANSFORM,
OperationCode::TRANSFORM_PARENT,
function_bind(BKE_object_eval_parent, _1, ob_cow));
}
/* Object constraints. */
- if (object->constraints.first != NULL) {
+ if (object->constraints.first != nullptr) {
build_object_constraints(object);
}
/* Rest of transformation update. */
@@ -836,16 +840,16 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
build_animation_images(id);
/* Regular animation. */
AnimData *adt = BKE_animdata_from_id(id);
- if (adt == NULL) {
+ if (adt == nullptr) {
return;
}
- if (adt->action != NULL) {
+ if (adt->action != nullptr) {
build_action(adt->action);
}
/* Make sure ID node exists. */
(void)add_id_node(id);
ID *id_cow = get_cow_id(id);
- if (adt->action != NULL || !BLI_listbase_is_empty(&adt->nla_tracks)) {
+ if (adt->action != nullptr || !BLI_listbase_is_empty(&adt->nla_tracks)) {
OperationNode *operation_node;
/* Explicit entry operation. */
operation_node = add_operation_node(id, NodeType::ANIMATION, OperationCode::ANIMATION_ENTRY);
@@ -874,10 +878,10 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
void DepsgraphNodeBuilder::build_animdata_nlastrip_targets(ListBase *strips)
{
LISTBASE_FOREACH (NlaStrip *, strip, strips) {
- if (strip->act != NULL) {
+ if (strip->act != nullptr) {
build_action(strip->act);
}
- else if (strip->strips.first != NULL) {
+ else if (strip->strips.first != nullptr) {
build_animdata_nlastrip_targets(&strip->strips);
}
}
@@ -934,13 +938,13 @@ void DepsgraphNodeBuilder::build_driver_variables(ID *id, FCurve *fcurve)
build_driver_id_property(id, fcurve->rna_path);
LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) {
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- if (dtar->id == NULL) {
+ if (dtar->id == nullptr) {
continue;
}
build_id(dtar->id);
build_driver_id_property(dtar->id, dtar->rna_path);
/* Corresponds to dtar_id_ensure_proxy_from(). */
- if ((GS(dtar->id->name) == ID_OB) && (((Object *)dtar->id)->proxy_from != NULL)) {
+ if ((GS(dtar->id->name) == ID_OB) && (((Object *)dtar->id)->proxy_from != nullptr)) {
Object *proxy_from = ((Object *)dtar->id)->proxy_from;
build_id(&proxy_from->id);
build_driver_id_property(&proxy_from->id, dtar->rna_path);
@@ -952,7 +956,7 @@ void DepsgraphNodeBuilder::build_driver_variables(ID *id, FCurve *fcurve)
void DepsgraphNodeBuilder::build_driver_id_property(ID *id, const char *rna_path)
{
- if (id == NULL || rna_path == NULL) {
+ if (id == nullptr || rna_path == nullptr) {
return;
}
PointerRNA id_ptr, ptr;
@@ -962,7 +966,7 @@ void DepsgraphNodeBuilder::build_driver_id_property(ID *id, const char *rna_path
if (!RNA_path_resolve_full(&id_ptr, rna_path, &ptr, &prop, &index)) {
return;
}
- if (prop == NULL) {
+ if (prop == nullptr) {
return;
}
if (!RNA_property_is_idprop(prop)) {
@@ -970,7 +974,7 @@ void DepsgraphNodeBuilder::build_driver_id_property(ID *id, const char *rna_path
}
const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
ensure_operation_node(
- id, NodeType::PARAMETERS, OperationCode::ID_PROPERTY, NULL, prop_identifier);
+ id, NodeType::PARAMETERS, OperationCode::ID_PROPERTY, nullptr, prop_identifier);
}
void DepsgraphNodeBuilder::build_parameters(ID *id)
@@ -1049,8 +1053,8 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
sim_node->set_as_exit();
sim_node->owner->entry_operation = sim_node;
/* Objects - simulation participants. */
- if (rbw->group != NULL) {
- build_collection(NULL, rbw->group);
+ if (rbw->group != nullptr) {
+ build_collection(nullptr, rbw->group);
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
if (object->type != OB_MESH) {
continue;
@@ -1068,11 +1072,11 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
/* Constraints. */
- if (rbw->constraints != NULL) {
+ if (rbw->constraints != nullptr) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) {
RigidBodyCon *rbc = object->rigidbody_constraint;
- if (rbc == NULL || rbc->ob1 == NULL || rbc->ob2 == NULL) {
- /* When either ob1 or ob2 is NULL, the constraint doesn't work. */
+ if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) {
+ /* When either ob1 or ob2 is nullptr, the constraint doesn't work. */
continue;
}
/* Make sure indirectly linked objects are fully built. */
@@ -1116,11 +1120,11 @@ void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object
* NOTE: The call itself ensures settings are only build once. */
build_particle_settings(part);
/* Particle system evaluation. */
- add_operation_node(psys_comp, OperationCode::PARTICLE_SYSTEM_EVAL, NULL, psys->name);
+ add_operation_node(psys_comp, OperationCode::PARTICLE_SYSTEM_EVAL, nullptr, psys->name);
/* Keyed particle targets. */
if (part->phystype == PART_PHYS_KEYED) {
LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) {
- if (particle_target->ob == NULL || particle_target->ob == object) {
+ if (particle_target->ob == nullptr || particle_target->ob == object) {
continue;
}
build_object(-1, particle_target->ob, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
@@ -1129,13 +1133,13 @@ void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object
/* Visualization of particle system. */
switch (part->ren_as) {
case PART_DRAW_OB:
- if (part->instance_object != NULL) {
+ if (part->instance_object != nullptr) {
build_object(-1, part->instance_object, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
break;
case PART_DRAW_GR:
- if (part->instance_collection != NULL) {
- build_collection(NULL, part->instance_collection);
+ if (part->instance_collection != nullptr) {
+ build_collection(nullptr, part->instance_collection);
}
break;
}
@@ -1170,7 +1174,7 @@ void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *particle_se
/* Texture slots. */
for (int mtex_index = 0; mtex_index < MAX_MTEX; mtex_index++) {
MTex *mtex = particle_settings->mtex[mtex_index];
- if (mtex == NULL || mtex->tex == NULL) {
+ if (mtex == nullptr || mtex->tex == nullptr) {
continue;
}
build_texture(mtex->tex);
@@ -1192,7 +1196,7 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
* drivers evaluation. */
LISTBASE_FOREACH (KeyBlock *, key_block, &key->block) {
add_operation_node(
- &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, NULL, key_block->name);
+ &key->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, key_block->name);
}
}
@@ -1270,13 +1274,13 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
/* Make sure objects used for bevel.taper are in the graph.
* NOTE: This objects might be not linked to the scene. */
Curve *cu = (Curve *)obdata;
- if (cu->bevobj != NULL) {
+ if (cu->bevobj != nullptr) {
build_object(-1, cu->bevobj, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
- if (cu->taperobj != NULL) {
+ if (cu->taperobj != nullptr) {
build_object(-1, cu->taperobj, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
- if (cu->textoncurve != NULL) {
+ if (cu->textoncurve != nullptr) {
build_object(-1, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
break;
@@ -1334,7 +1338,7 @@ void DepsgraphNodeBuilder::build_camera(Camera *camera)
}
build_animdata(&camera->id);
build_parameters(&camera->id);
- if (camera->dof.focus_object != NULL) {
+ if (camera->dof.focus_object != nullptr) {
build_object(-1, camera->dof.focus_object, DEG_ID_LINKED_INDIRECTLY, false);
}
}
@@ -1352,7 +1356,7 @@ void DepsgraphNodeBuilder::build_light(Light *lamp)
void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
{
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
if (built_map_.checkIsBuiltAndTag(ntree)) {
@@ -1376,7 +1380,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
ID *id = bnode->id;
- if (id == NULL) {
+ if (id == nullptr) {
continue;
}
ID_Type id_type = GS(id->name);
@@ -1400,7 +1404,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
*
* On the one hand it's annoying to always pull it in, but on another hand it's also annoying
* to have hardcoded node-type exception here. */
- if (node_scene->camera != NULL) {
+ if (node_scene->camera != nullptr) {
/* TODO(sergey): Use visibility of owner of the node tree. */
build_object(-1, node_scene->camera, DEG_ID_LINKED_INDIRECTLY, true);
}
@@ -1450,7 +1454,7 @@ void DepsgraphNodeBuilder::build_material(Material *material)
void DepsgraphNodeBuilder::build_materials(Material **materials, int num_materials)
{
for (int i = 0; i < num_materials; i++) {
- if (materials[i] == NULL) {
+ if (materials[i] == nullptr) {
continue;
}
build_material(materials[i]);
@@ -1470,7 +1474,7 @@ void DepsgraphNodeBuilder::build_texture(Tex *texture)
build_nodetree(texture->nodetree);
/* Special cases for different IDs which texture uses. */
if (texture->type == TEX_IMAGE) {
- if (texture->ima != NULL) {
+ if (texture->ima != nullptr) {
build_image(texture->ima);
}
}
@@ -1548,7 +1552,7 @@ void DepsgraphNodeBuilder::build_mask(Mask *mask)
for (int i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point = &spline->points[i];
MaskParent *parent = &point->parent;
- if (parent == NULL || parent->id == NULL) {
+ if (parent == nullptr || parent->id == nullptr) {
continue;
}
build_id(parent->id);
@@ -1557,6 +1561,18 @@ void DepsgraphNodeBuilder::build_mask(Mask *mask)
}
}
+void DepsgraphNodeBuilder::build_freestyle_linestyle(FreestyleLineStyle *linestyle)
+{
+ if (built_map_.checkIsBuiltAndTag(linestyle)) {
+ return;
+ }
+
+ ID *linestyle_id = &linestyle->id;
+ build_parameters(linestyle_id);
+ build_animdata(linestyle_id);
+ build_nodetree(linestyle->nodetree);
+}
+
void DepsgraphNodeBuilder::build_movieclip(MovieClip *clip)
{
if (built_map_.checkIsBuiltAndTag(clip)) {
@@ -1599,7 +1615,7 @@ void DepsgraphNodeBuilder::build_speaker(Speaker *speaker)
add_operation_node(&speaker->id, NodeType::AUDIO, OperationCode::SPEAKER_EVAL);
build_animdata(&speaker->id);
build_parameters(&speaker->id);
- if (speaker->sound != NULL) {
+ if (speaker->sound != nullptr) {
build_sound(speaker->sound);
}
}
@@ -1621,7 +1637,7 @@ void DepsgraphNodeBuilder::build_sound(bSound *sound)
void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
{
- if (scene->ed == NULL) {
+ if (scene->ed == nullptr) {
return;
}
build_scene_audio(scene);
@@ -1633,13 +1649,13 @@ void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
/* Make sure data for sequences is in the graph. */
Sequence *seq;
SEQ_BEGIN (scene->ed, seq) {
- if (seq->sound != NULL) {
+ if (seq->sound != nullptr) {
build_sound(seq->sound);
}
- if (seq->scene != NULL) {
+ if (seq->scene != nullptr) {
build_scene_parameters(seq->scene);
}
- if (seq->type == SEQ_TYPE_SCENE && seq->scene != NULL) {
+ if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
if (seq->flag & SEQ_SCENE_STRIPS) {
build_scene_sequencer(seq->scene);
}
@@ -1680,7 +1696,7 @@ void DepsgraphNodeBuilder::modifier_walk(void *user_data,
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
ID *id = *idpoin;
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
switch (GS(id->name)) {
@@ -1703,7 +1719,7 @@ void DepsgraphNodeBuilder::constraint_walk(bConstraint * /*con*/,
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
ID *id = *idpoin;
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
switch (GS(id->name)) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 865f60432c1..54a4768d12a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -35,6 +35,8 @@ struct CacheFile;
struct Camera;
struct Collection;
struct FCurve;
+struct FreestyleLineSet;
+struct FreestyleLineStyle;
struct GHash;
struct ID;
struct Image;
@@ -104,27 +106,27 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
OperationNode *add_operation_node(ComponentNode *comp_node,
OperationCode opcode,
- const DepsEvalOperationCb &op = NULL,
+ const DepsEvalOperationCb &op = nullptr,
const char *name = "",
int name_tag = -1);
OperationNode *add_operation_node(ID *id,
NodeType comp_type,
const char *comp_name,
OperationCode opcode,
- const DepsEvalOperationCb &op = NULL,
+ const DepsEvalOperationCb &op = nullptr,
const char *name = "",
int name_tag = -1);
OperationNode *add_operation_node(ID *id,
NodeType comp_type,
OperationCode opcode,
- const DepsEvalOperationCb &op = NULL,
+ const DepsEvalOperationCb &op = nullptr,
const char *name = "",
int name_tag = -1);
OperationNode *ensure_operation_node(ID *id,
NodeType comp_type,
OperationCode opcode,
- const DepsEvalOperationCb &op = NULL,
+ const DepsEvalOperationCb &op = nullptr,
const char *name = "",
int name_tag = -1);
@@ -201,6 +203,8 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
virtual void build_nodetree(bNodeTree *ntree);
virtual void build_material(Material *ma);
virtual void build_materials(Material **materials, int num_materials);
+ virtual void build_freestyle_lineset(FreestyleLineSet *fls);
+ virtual void build_freestyle_linestyle(FreestyleLineStyle *linestyle);
virtual void build_texture(Tex *tex);
virtual void build_image(Image *image);
virtual void build_world(World *world);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 979e1a02e71..07010a5cbef 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -87,7 +87,7 @@ void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bC
/* Find the chain's root. */
bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
- if (rootchan == NULL) {
+ if (rootchan == nullptr) {
return;
}
@@ -154,12 +154,12 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
/* Armature. */
build_armature(armature);
/* Rebuild pose if not up to date. */
- if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) {
- /* By definition, no need to tag depsgraph as dirty from here, so we can pass NULL bmain. */
- BKE_pose_rebuild(NULL, object, armature, true);
+ if (object->pose == nullptr || (object->pose->flag & POSE_RECALC)) {
+ /* By definition, no need to tag depsgraph as dirty from here, so we can pass nullptr bmain. */
+ BKE_pose_rebuild(nullptr, object, armature, true);
}
/* Speed optimization for animation lookups. */
- if (object->pose != NULL) {
+ if (object->pose != nullptr) {
BKE_pose_channels_hash_make(object->pose);
if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
BKE_pose_update_constraint_flags(object->pose);
@@ -243,12 +243,12 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
op_node->set_as_exit();
/* Custom properties. */
- if (pchan->prop != NULL) {
+ if (pchan->prop != nullptr) {
add_operation_node(
- &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, NULL, pchan->name);
+ &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, pchan->name);
}
/* Build constraints. */
- if (pchan->constraints.first != NULL) {
+ if (pchan->constraints.first != nullptr) {
build_pose_constraints(object, pchan, pchan_index, is_object_visible);
}
/**
@@ -277,7 +277,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
}
}
/* Custom shape. */
- if (pchan->custom != NULL) {
+ if (pchan->custom != nullptr) {
/* TODO(sergey): Use own visibility. */
build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
}
@@ -291,7 +291,7 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
OperationNode *op_node;
Object *object_cow = get_cow_datablock(object);
/* Sanity check. */
- BLI_assert(object->pose != NULL);
+ BLI_assert(object->pose != nullptr);
/* Armature. */
build_armature(armature);
/* speed optimization for animation lookups */
@@ -322,9 +322,9 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
op_node->set_as_exit();
/* Custom properties. */
- if (pchan->prop != NULL) {
+ if (pchan->prop != nullptr) {
add_operation_node(
- &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, NULL, pchan->name);
+ &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, pchan->name);
}
pchan_index++;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
index 777512acf89..1edf9826208 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
@@ -46,7 +46,7 @@ void DepsgraphNodeBuilder::build_scene_render(Scene *scene, ViewLayer *view_laye
build_scene_sequencer(scene);
build_scene_speakers(scene, view_layer);
}
- if (scene->camera != NULL) {
+ if (scene->camera != nullptr) {
build_object(-1, scene->camera, DEG_ID_LINKED_DIRECTLY, true);
}
}
@@ -76,7 +76,7 @@ void DepsgraphNodeBuilder::build_scene_compositor(Scene *scene)
if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_SCENE_COMPOSITOR)) {
return;
}
- if (scene->nodetree == NULL) {
+ if (scene->nodetree == nullptr) {
return;
}
build_nodetree(scene->nodetree);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 88ebf1c9b50..d5e9c024812 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -37,6 +37,7 @@
extern "C" {
#include "DNA_freestyle_types.h"
#include "DNA_layer_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -74,6 +75,16 @@ void DepsgraphNodeBuilder::build_layer_collections(ListBase *lb)
}
}
+void DepsgraphNodeBuilder::build_freestyle_lineset(FreestyleLineSet *fls)
+{
+ if (fls->group != nullptr) {
+ build_collection(nullptr, fls->group);
+ }
+ if (fls->linestyle != nullptr) {
+ build_freestyle_linestyle(fls->linestyle);
+ }
+}
+
void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
ViewLayer *view_layer,
eDepsNode_LinkedState_Type linked_state)
@@ -109,19 +120,19 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
}
}
build_layer_collections(&view_layer->layer_collections);
- if (scene->camera != NULL) {
+ if (scene->camera != nullptr) {
build_object(-1, scene->camera, DEG_ID_LINKED_INDIRECTLY, true);
}
/* Rigidbody. */
- if (scene->rigidbody_world != NULL) {
+ if (scene->rigidbody_world != nullptr) {
build_rigidbody(scene);
}
/* Scene's animation and drivers. */
- if (scene->adt != NULL) {
+ if (scene->adt != nullptr) {
build_animdata(&scene->id);
}
/* World. */
- if (scene->world != NULL) {
+ if (scene->world != nullptr) {
build_world(scene->world);
}
/* Cache file. */
@@ -137,14 +148,12 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_movieclip(clip);
}
/* Material override. */
- if (view_layer->mat_override != NULL) {
+ if (view_layer->mat_override != nullptr) {
build_material(view_layer->mat_override);
}
- /* Freestyle collections. */
+ /* Freestyle linesets. */
LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
- if (fls->group != NULL) {
- build_collection(NULL, fls->group);
- }
+ build_freestyle_lineset(fls);
}
/* Sequencer. */
if (linked_state == DEG_ID_LINKED_DIRECTLY) {
@@ -161,7 +170,7 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
build_scene_compositor(scene);
build_scene_parameters(scene);
/* Build all set scenes. */
- if (scene->set != NULL) {
+ if (scene->set != nullptr) {
ViewLayer *set_view_layer = BKE_view_layer_default_render(scene->set);
build_view_layer(scene->set, set_view_layer, DEG_ID_LINKED_VIA_SET);
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
index 95c50c4f44e..5483ff9c030 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
@@ -35,7 +35,7 @@ static void free_rootpchanmap_valueset(void *val)
{
/* Just need to free the set itself - the names stored are all references. */
GSet *values = (GSet *)val;
- BLI_gset_free(values, NULL);
+ BLI_gset_free(values, nullptr);
}
RootPChanMap::RootPChanMap()
@@ -47,7 +47,7 @@ RootPChanMap::RootPChanMap()
RootPChanMap::~RootPChanMap()
{
/* Free the map, and all the value sets. */
- BLI_ghash_free(map_, NULL, free_rootpchanmap_valueset);
+ BLI_ghash_free(map_, nullptr, free_rootpchanmap_valueset);
}
/* Debug contents of map */
@@ -91,7 +91,7 @@ void RootPChanMap::add_bone(const char *bone, const char *root)
}
/* Check if there's a common root bone between two bones. */
-bool RootPChanMap::has_common_root(const char *bone1, const char *bone2)
+bool RootPChanMap::has_common_root(const char *bone1, const char *bone2) const
{
/* Ensure that both are in the map... */
if (BLI_ghash_haskey(map_, bone1) == false) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h
index 0c1d22f9345..1442f547b08 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.h
@@ -39,7 +39,7 @@ struct RootPChanMap {
void add_bone(const char *bone, const char *root);
/* Check if there's a common root bone between two bones. */
- bool has_common_root(const char *bone1, const char *bone2);
+ bool has_common_root(const char *bone1, const char *bone2) const;
protected:
/* The actual map:
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 3e0ab9684da..5214fdbd246 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -47,6 +47,7 @@ extern "C" {
#include "DNA_gpencil_types.h"
#include "DNA_key_types.h"
#include "DNA_light_types.h"
+#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
@@ -113,6 +114,7 @@ extern "C" {
#include "intern/node/deg_node_operation.h"
#include "intern/node/deg_node_time.h"
+#include "intern/depsgraph_relation.h"
#include "intern/depsgraph_type.h"
namespace DEG {
@@ -122,32 +124,10 @@ namespace DEG {
namespace {
-/* TODO(sergey): This is somewhat weak, but we don't want neither false-positive
- * time dependencies nor special exceptions in the depsgraph evaluation. */
-
-bool python_driver_exression_depends_on_time(const char *expression)
-{
- if (expression[0] == '\0') {
- /* Empty expression depends on nothing. */
- return false;
- }
- if (strchr(expression, '(') != NULL) {
- /* Function calls are considered dependent on a time. */
- return true;
- }
- if (strstr(expression, "frame") != NULL) {
- /* Variable `frame` depends on time. */
- /* TODO(sergey): This is a bit weak, but not sure about better way of handling this. */
- return true;
- }
- /* Possible indirect time relation s should be handled via variable targets. */
- return false;
-}
-
bool driver_target_depends_on_time(const DriverTarget *target)
{
if (target->idtype == ID_SCE &&
- (target->rna_path != NULL && STREQ(target->rna_path, "frame_current"))) {
+ (target->rna_path != nullptr && STREQ(target->rna_path, "frame_current"))) {
return true;
}
return false;
@@ -175,10 +155,8 @@ bool driver_variables_depends_on_time(const ListBase *variables)
bool driver_depends_on_time(ChannelDriver *driver)
{
- if (driver->type == DRIVER_TYPE_PYTHON) {
- if (python_driver_exression_depends_on_time(driver->expression)) {
- return true;
- }
+ if (BKE_driver_expression_depends_on_time(driver)) {
+ return true;
}
if (driver_variables_depends_on_time(&driver->variables)) {
return true;
@@ -217,10 +195,19 @@ bool object_particles_depends_on_time(Object *object)
bool check_id_has_anim_component(ID *id)
{
AnimData *adt = BKE_animdata_from_id(id);
- if (adt == NULL) {
+ if (adt == nullptr) {
return false;
}
- return (adt->action != NULL) || (!BLI_listbase_is_empty(&adt->nla_tracks));
+ return (adt->action != nullptr) || (!BLI_listbase_is_empty(&adt->nla_tracks));
+}
+
+bool check_id_has_driver_component(ID *id)
+{
+ AnimData *adt = BKE_animdata_from_id(id);
+ if (adt == nullptr) {
+ return false;
+ }
+ return !BLI_listbase_is_empty(&adt->drivers);
}
OperationCode bone_target_opcode(ID *target,
@@ -254,7 +241,7 @@ bool object_have_geometry_component(const Object *object)
DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain,
Depsgraph *graph,
DepsgraphBuilderCache *cache)
- : DepsgraphBuilder(bmain, graph, cache), scene_(NULL), rna_node_query_(graph, this)
+ : DepsgraphBuilder(bmain, graph, cache), scene_(nullptr), rna_node_query_(graph, this)
{
}
@@ -262,7 +249,7 @@ TimeSourceNode *DepsgraphRelationBuilder::get_node(const TimeSourceKey &key) con
{
if (key.id) {
/* XXX TODO */
- return NULL;
+ return nullptr;
}
else {
return graph_->time_source;
@@ -275,8 +262,8 @@ ComponentNode *DepsgraphRelationBuilder::get_node(const ComponentKey &key) const
if (!id_node) {
fprintf(stderr,
"find_node component: Could not find ID %s\n",
- (key.id != NULL) ? key.id->name : "<null>");
- return NULL;
+ (key.id != nullptr) ? key.id->name : "<null>");
+ return nullptr;
}
ComponentNode *node = id_node->find_component(key.type, key.name);
@@ -286,7 +273,7 @@ ComponentNode *DepsgraphRelationBuilder::get_node(const ComponentKey &key) const
OperationNode *DepsgraphRelationBuilder::get_node(const OperationKey &key) const
{
OperationNode *op_node = find_node(key);
- if (op_node == NULL) {
+ if (op_node == nullptr) {
fprintf(stderr,
"find_node_operation: Failed for (%s, '%s')\n",
operationCodeAsString(key.opcode),
@@ -304,18 +291,18 @@ OperationNode *DepsgraphRelationBuilder::find_node(const OperationKey &key) cons
{
IDNode *id_node = graph_->find_id_node(key.id);
if (!id_node) {
- return NULL;
+ return nullptr;
}
ComponentNode *comp_node = id_node->find_component(key.component_type, key.component_name);
if (!comp_node) {
- return NULL;
+ return nullptr;
}
return comp_node->find_operation(key.opcode, key.name, key.name_tag);
}
bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const
{
- return find_node(key) != NULL;
+ return find_node(key) != nullptr;
}
void DepsgraphRelationBuilder::add_modifier_to_transform_relation(const DepsNodeHandle *handle,
@@ -331,10 +318,11 @@ void DepsgraphRelationBuilder::add_modifier_to_transform_relation(const DepsNode
void DepsgraphRelationBuilder::add_customdata_mask(Object *object,
const DEGCustomDataMeshMasks &customdata_masks)
{
- if (customdata_masks != DEGCustomDataMeshMasks() && object != NULL && object->type == OB_MESH) {
+ if (customdata_masks != DEGCustomDataMeshMasks() && object != nullptr &&
+ object->type == OB_MESH) {
DEG::IDNode *id_node = graph_->find_id_node(&object->id);
- if (id_node == NULL) {
+ if (id_node == nullptr) {
BLI_assert(!"ID should always be valid");
}
else {
@@ -346,7 +334,7 @@ void DepsgraphRelationBuilder::add_customdata_mask(Object *object,
void DepsgraphRelationBuilder::add_special_eval_flag(ID *id, uint32_t flag)
{
DEG::IDNode *id_node = graph_->find_id_node(id);
- if (id_node == NULL) {
+ if (id_node == nullptr) {
BLI_assert(!"ID should always be valid");
}
else {
@@ -372,7 +360,7 @@ Relation *DepsgraphRelationBuilder::add_time_relation(TimeSourceNode *timesrc,
(node_to) ? node_to->identifier().c_str() : "<None>",
description);
}
- return NULL;
+ return nullptr;
}
Relation *DepsgraphRelationBuilder::add_operation_relation(OperationNode *node_from,
@@ -393,7 +381,7 @@ Relation *DepsgraphRelationBuilder::add_operation_relation(OperationNode *node_f
(node_to) ? node_to->identifier().c_str() : "<None>",
description);
}
- return NULL;
+ return nullptr;
}
void DepsgraphRelationBuilder::add_particle_collision_relations(const OperationKey &key,
@@ -453,7 +441,7 @@ void DepsgraphRelationBuilder::add_particle_forcefield_relations(const Operation
/* Absorption forces need collision relation. */
if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
- add_particle_collision_relations(key, object, NULL, "Force Absorption");
+ add_particle_collision_relations(key, object, nullptr, "Force Absorption");
}
}
@@ -490,7 +478,7 @@ void DepsgraphRelationBuilder::begin_build()
void DepsgraphRelationBuilder::build_id(ID *id)
{
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
switch (GS(id->name)) {
@@ -504,10 +492,10 @@ void DepsgraphRelationBuilder::build_id(ID *id)
build_camera((Camera *)id);
break;
case ID_GR:
- build_collection(NULL, NULL, (Collection *)id);
+ build_collection(nullptr, nullptr, (Collection *)id);
break;
case ID_OB:
- build_object(NULL, (Object *)id);
+ build_object(nullptr, (Object *)id);
break;
case ID_KE:
build_shapekeys((Key *)id);
@@ -536,6 +524,9 @@ void DepsgraphRelationBuilder::build_id(ID *id)
case ID_MSK:
build_mask((Mask *)id);
break;
+ case ID_LS:
+ build_freestyle_linestyle((FreestyleLineStyle *)id);
+ break;
case ID_MC:
build_movieclip((MovieClip *)id);
break;
@@ -571,7 +562,7 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
Object *object,
Collection *collection)
{
- if (from_layer_collection != NULL) {
+ if (from_layer_collection != nullptr) {
/* If we came from layer collection we don't go deeper, view layer
* builder takes care of going deeper.
*
@@ -581,18 +572,19 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
return;
}
const bool group_done = built_map_.checkIsBuiltAndTag(collection);
- OperationKey object_transform_final_key(
- object != NULL ? &object->id : NULL, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL);
- ComponentKey duplicator_key(object != NULL ? &object->id : NULL, NodeType::DUPLI);
+ OperationKey object_transform_final_key(object != nullptr ? &object->id : nullptr,
+ NodeType::TRANSFORM,
+ OperationCode::TRANSFORM_FINAL);
+ ComponentKey duplicator_key(object != nullptr ? &object->id : nullptr, NodeType::DUPLI);
if (!group_done) {
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
- build_object(NULL, cob->ob);
+ build_object(nullptr, cob->ob);
}
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- build_collection(NULL, NULL, child->collection);
+ build_collection(nullptr, nullptr, child->collection);
}
}
- if (object != NULL) {
+ if (object != nullptr) {
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, ob, graph_->mode) {
ComponentKey dupli_transform_key(&ob->id, NodeType::TRANSFORM);
add_relation(dupli_transform_key, object_transform_final_key, "Dupligroup");
@@ -612,7 +604,7 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
{
if (built_map_.checkIsBuiltAndTag(object)) {
- if (base != NULL) {
+ if (base != nullptr) {
build_object_flags(base, object);
}
return;
@@ -634,34 +626,34 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
/* Various flags, flushing from bases/collections. */
build_object_flags(base, object);
/* Parenting. */
- if (object->parent != NULL) {
+ if (object->parent != nullptr) {
/* Make sure parent object's relations are built. */
- build_object(NULL, object->parent);
+ build_object(nullptr, object->parent);
/* Parent relationship. */
build_object_parent(object);
/* Local -> parent. */
add_relation(local_transform_key, parent_transform_key, "ObLocal -> ObParent");
}
/* Modifiers. */
- if (object->modifiers.first != NULL) {
+ if (object->modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
modifiers_foreachIDLink(object, modifier_walk, &data);
}
/* Grease Pencil Modifiers. */
- if (object->greasepencil_modifiers.first != NULL) {
+ if (object->greasepencil_modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_gpencil_modifiers_foreachIDLink(object, modifier_walk, &data);
}
/* Shader FX. */
- if (object->shader_fx.first != NULL) {
+ if (object->shader_fx.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_shaderfx_foreachIDLink(object, modifier_walk, &data);
}
/* Constraints. */
- if (object->constraints.first != NULL) {
+ if (object->constraints.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_constraints_id_loop(&object->constraints, constraint_walk, &data);
@@ -669,11 +661,11 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
/* Object constraints. */
OperationKey object_transform_simulation_init_key(
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT);
- if (object->constraints.first != NULL) {
+ if (object->constraints.first != nullptr) {
OperationKey constraint_key(
&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_CONSTRAINTS);
/* Constraint relations. */
- build_constraints(&object->id, NodeType::TRANSFORM, "", &object->constraints, NULL);
+ build_constraints(&object->id, NodeType::TRANSFORM, "", &object->constraints, nullptr);
/* operation order */
add_relation(base_op_key, constraint_key, "ObBase-> Constraint Stack");
add_relation(constraint_key, final_transform_key, "ObConstraints -> Done");
@@ -697,15 +689,15 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
/* Object data. */
build_object_data(object);
/* Particle systems. */
- if (object->particlesystem.first != NULL) {
+ if (object->particlesystem.first != nullptr) {
build_particle_systems(object);
}
/* Proxy object to copy from. */
build_object_proxy_from(object);
build_object_proxy_group(object);
/* Object dupligroup. */
- if (object->instance_collection != NULL) {
- build_collection(NULL, object, object->instance_collection);
+ if (object->instance_collection != nullptr) {
+ build_collection(nullptr, object, object->instance_collection);
}
/* Point caches. */
build_object_pointcache(object);
@@ -719,11 +711,11 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
void DepsgraphRelationBuilder::build_object_proxy_from(Object *object)
{
- if (object->proxy_from == NULL) {
+ if (object->proxy_from == nullptr) {
return;
}
/* Object is linked here (comes from the library). */
- build_object(NULL, object->proxy_from);
+ build_object(nullptr, object->proxy_from);
ComponentKey ob_transform_key(&object->proxy_from->id, NodeType::TRANSFORM);
ComponentKey proxy_transform_key(&object->id, NodeType::TRANSFORM);
add_relation(ob_transform_key, proxy_transform_key, "Proxy Transform");
@@ -731,11 +723,11 @@ void DepsgraphRelationBuilder::build_object_proxy_from(Object *object)
void DepsgraphRelationBuilder::build_object_proxy_group(Object *object)
{
- if (object->proxy_group == NULL || object->proxy_group == object->proxy) {
+ if (object->proxy_group == nullptr || object->proxy_group == object->proxy) {
return;
}
/* Object is local here (local in .blend file, users interacts with it). */
- build_object(NULL, object->proxy_group);
+ build_object(nullptr, object->proxy_group);
OperationKey proxy_group_eval_key(
&object->proxy_group->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
OperationKey transform_eval_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
@@ -744,7 +736,7 @@ void DepsgraphRelationBuilder::build_object_proxy_group(Object *object)
void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object)
{
- if (base == NULL) {
+ if (base == nullptr) {
return;
}
OperationKey view_layer_done_key(
@@ -760,7 +752,7 @@ void DepsgraphRelationBuilder::build_object_flags(Base *base, Object *object)
void DepsgraphRelationBuilder::build_object_data(Object *object)
{
- if (object->data == NULL) {
+ if (object->data == nullptr) {
return;
}
ID *obdata_id = (ID *)object->data;
@@ -789,7 +781,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
break;
}
case OB_ARMATURE:
- if (ID_IS_LINKED(object) && object->proxy_from != NULL) {
+ if (ID_IS_LINKED(object) && object->proxy_from != nullptr) {
build_proxy_rig(object);
}
else {
@@ -810,7 +802,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
break;
}
Key *key = BKE_key_from_object(object);
- if (key != NULL) {
+ if (key != nullptr) {
ComponentKey geometry_key((ID *)object->data, NodeType::GEOMETRY);
ComponentKey key_key(&key->id, NodeType::GEOMETRY);
add_relation(key_key, geometry_key, "Shapekeys");
@@ -818,7 +810,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object)
}
/* Materials. */
Material ***materials_ptr = give_matarar(object);
- if (materials_ptr != NULL) {
+ if (materials_ptr != nullptr) {
short *num_materials_ptr = give_totcolp(object);
build_materials(*materials_ptr, *num_materials_ptr);
}
@@ -1040,7 +1032,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
for (bConstraint *con = (bConstraint *)constraints->first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
/* Invalid constraint type. */
- if (cti == NULL) {
+ if (cti == nullptr) {
continue;
}
/* Special case for camera tracking -- it doesn't use targets to
@@ -1067,7 +1059,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
depends_on_camera = true;
}
- if (depends_on_camera && scene_->camera != NULL) {
+ if (depends_on_camera && scene_->camera != nullptr) {
ComponentKey camera_key(&scene_->camera->id, NodeType::TRANSFORM);
add_relation(camera_key, constraint_op_key, cti->name);
}
@@ -1088,10 +1080,10 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
}
}
else if (cti->get_constraint_targets) {
- ListBase targets = {NULL, NULL};
+ ListBase targets = {nullptr, nullptr};
cti->get_constraint_targets(con, &targets);
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
- if (ct->tar == NULL) {
+ if (ct->tar == nullptr) {
continue;
}
if (ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK)) {
@@ -1219,13 +1211,13 @@ void DepsgraphRelationBuilder::build_animdata(ID *id)
void DepsgraphRelationBuilder::build_animdata_curves(ID *id)
{
AnimData *adt = BKE_animdata_from_id(id);
- if (adt == NULL) {
+ if (adt == nullptr) {
return;
}
- if (adt->action != NULL) {
+ if (adt->action != nullptr) {
build_action(adt->action);
}
- if (adt->action == NULL && BLI_listbase_is_empty(&adt->nla_tracks)) {
+ if (adt->action == nullptr && BLI_listbase_is_empty(&adt->nla_tracks)) {
return;
}
/* Ensure evaluation order from entry to exit. */
@@ -1237,20 +1229,20 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id)
/* Wire up dependency from action. */
ComponentKey adt_key(id, NodeType::ANIMATION);
/* Relation from action itself. */
- if (adt->action != NULL) {
+ if (adt->action != nullptr) {
ComponentKey action_key(&adt->action->id, NodeType::ANIMATION);
add_relation(action_key, adt_key, "Action -> Animation");
}
/* Get source operations. */
Node *node_from = get_node(adt_key);
- BLI_assert(node_from != NULL);
- if (node_from == NULL) {
+ BLI_assert(node_from != nullptr);
+ if (node_from == nullptr) {
return;
}
OperationNode *operation_from = node_from->get_exit_operation();
- BLI_assert(operation_from != NULL);
+ BLI_assert(operation_from != nullptr);
/* Build relations from animation operation to properties it changes. */
- if (adt->action != NULL) {
+ if (adt->action != nullptr) {
build_animdata_curves_targets(id, adt_key, operation_from, &adt->action->curves);
}
LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
@@ -1274,7 +1266,7 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id,
continue;
}
Node *node_to = rna_node_query_.find_node(&ptr, prop, RNAPointerSource::ENTRY);
- if (node_to == NULL) {
+ if (node_to == nullptr) {
continue;
}
OperationNode *operation_to = node_to->get_entry_operation();
@@ -1308,7 +1300,7 @@ void DepsgraphRelationBuilder::build_animdata_nlastrip_targets(ID *id,
ListBase *strips)
{
LISTBASE_FOREACH (NlaStrip *, strip, strips) {
- if (strip->act != NULL) {
+ if (strip->act != nullptr) {
build_action(strip->act);
ComponentKey action_key(&strip->act->id, NodeType::ANIMATION);
@@ -1316,7 +1308,7 @@ void DepsgraphRelationBuilder::build_animdata_nlastrip_targets(ID *id,
build_animdata_curves_targets(id, adt_key, operation_from, &strip->act->curves);
}
- else if (strip->strips.first != NULL) {
+ else if (strip->strips.first != nullptr) {
build_animdata_nlastrip_targets(id, adt_key, operation_from, &strip->strips);
}
}
@@ -1325,7 +1317,7 @@ void DepsgraphRelationBuilder::build_animdata_nlastrip_targets(ID *id,
void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
{
AnimData *adt = BKE_animdata_from_id(id);
- if (adt == NULL) {
+ if (adt == nullptr) {
return;
}
ComponentKey adt_key(id, NodeType::ANIMATION);
@@ -1350,7 +1342,7 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
*
* TODO(sergey): Avoid liner lookup somehow. */
if (fcu->array_index > 0) {
- FCurve *fcu_prev = NULL;
+ FCurve *fcu_prev = nullptr;
LISTBASE_FOREACH (FCurve *, fcu_candidate, &adt->drivers) {
/* Writing to different RNA paths is */
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
@@ -1362,11 +1354,11 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
continue;
}
/* Choose fcurve with highest possible array index. */
- if (fcu_prev == NULL || fcu_candidate->array_index > fcu_prev->array_index) {
+ if (fcu_prev == nullptr || fcu_candidate->array_index > fcu_prev->array_index) {
fcu_prev = fcu_candidate;
}
}
- if (fcu_prev != NULL) {
+ if (fcu_prev != nullptr) {
OperationKey prev_driver_key(id,
NodeType::PARAMETERS,
OperationCode::DRIVER,
@@ -1393,6 +1385,8 @@ void DepsgraphRelationBuilder::build_animation_images(ID *id)
/* TODO: can we check for existence of node for performance? */
if (BKE_image_user_id_has_animation(id)) {
OperationKey image_animation_key(id, NodeType::ANIMATION, OperationCode::IMAGE_ANIMATION);
+ ComponentKey cow_key(id, NodeType::COPY_ON_WRITE);
+ add_relation(cow_key, image_animation_key, "CoW -> Image Animation");
TimeSourceKey time_src_key;
add_relation(time_src_key, image_animation_key, "TimeSrc -> Image Animation");
}
@@ -1436,7 +1430,7 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
{
/* Validate the RNA path pointer just in case. */
const char *rna_path = fcu->rna_path;
- if (rna_path == NULL || rna_path[0] == '\0') {
+ if (rna_path == nullptr || rna_path[0] == '\0') {
return;
}
/* Parse the RNA path to find the target property pointer. */
@@ -1466,16 +1460,16 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
/* Drivers on armature-level bone settings (i.e. bbone stuff),
* which will affect the evaluation of corresponding pose bones. */
Bone *bone = (Bone *)property_entry_key.ptr.data;
- if (bone != NULL) {
+ if (bone != nullptr) {
/* Find objects which use this, and make their eval callbacks
* depend on this. */
for (IDNode *to_node : graph_->id_nodes) {
if (GS(to_node->id_orig->name) == ID_OB) {
Object *object = (Object *)to_node->id_orig;
/* We only care about objects with pose data which use this. */
- if (object->data == id_ptr && object->pose != NULL) {
+ if (object->data == id_ptr && object->pose != nullptr) {
bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone->name);
- if (pchan != NULL) {
+ if (pchan != nullptr) {
OperationKey bone_key(
&object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
add_relation(driver_key, bone_key, "Arm Bone -> Driver -> Bone");
@@ -1503,14 +1497,14 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
PointerRNA id_ptr;
PointerRNA ptr;
RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_full(&id_ptr, fcu->rna_path, &ptr, NULL, NULL)) {
+ if (RNA_path_resolve_full(&id_ptr, fcu->rna_path, &ptr, nullptr, nullptr)) {
if (id_ptr.owner_id != ptr.owner_id) {
ComponentKey cow_key(ptr.owner_id, NodeType::COPY_ON_WRITE);
add_relation(cow_key, driver_key, "Driven CoW -> Driver", RELATION_CHECK_BEFORE_ADD);
}
}
}
- if (property_entry_key.prop != NULL && RNA_property_is_idprop(property_entry_key.prop)) {
+ if (property_entry_key.prop != nullptr && RNA_property_is_idprop(property_entry_key.prop)) {
RNAPathKey property_exit_key(id, rna_path, RNAPointerSource::EXIT);
OperationKey parameters_key(id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL);
add_relation(property_exit_key, parameters_key, "Driven Property -> Properties");
@@ -1532,16 +1526,16 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
/* Only used targets. */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
ID *target_id = dtar->id;
- if (target_id == NULL) {
+ if (target_id == nullptr) {
continue;
}
build_id(target_id);
build_driver_id_property(target_id, dtar->rna_path);
/* Look up the proxy - matches dtar_id_ensure_proxy_from during evaluation. */
- Object *object = NULL;
+ Object *object = nullptr;
if (GS(target_id->name) == ID_OB) {
object = (Object *)target_id;
- if (object->proxy_from != NULL) {
+ if (object->proxy_from != nullptr) {
/* Redirect the target to the proxy, like in evaluation. */
object = object->proxy_from;
target_id = &object->id;
@@ -1554,7 +1548,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (object && object->type == OB_ARMATURE) &&
(dtar->pchan_name[0])) {
bPoseChannel *target_pchan = BKE_pose_channel_find_name(object->pose, dtar->pchan_name);
- if (target_pchan == NULL) {
+ if (target_pchan == nullptr) {
continue;
}
OperationKey variable_key(
@@ -1575,7 +1569,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
OperationKey target_key(target_id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL);
add_relation(target_key, driver_key, "Target -> Driver");
}
- else if (dtar->rna_path != NULL && dtar->rna_path[0] != '\0') {
+ else if (dtar->rna_path != nullptr && dtar->rna_path[0] != '\0') {
RNAPathKey variable_exit_key(target_id, dtar->rna_path, RNAPointerSource::EXIT);
if (RNA_pointer_is_null(&variable_exit_key.ptr)) {
continue;
@@ -1587,7 +1581,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
add_relation(variable_exit_key, driver_key, "RNA Target -> Driver");
}
else {
- /* If rna_path is NULL, and DTAR_FLAG_STRUCT_REF isn't set, this
+ /* If rna_path is nullptr, and DTAR_FLAG_STRUCT_REF isn't set, this
* is an incomplete target reference, so nothing to do here. */
}
}
@@ -1597,7 +1591,7 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
void DepsgraphRelationBuilder::build_driver_id_property(ID *id, const char *rna_path)
{
- if (id == NULL || rna_path == NULL) {
+ if (id == nullptr || rna_path == nullptr) {
return;
}
PointerRNA id_ptr, ptr;
@@ -1607,7 +1601,7 @@ void DepsgraphRelationBuilder::build_driver_id_property(ID *id, const char *rna_
if (!RNA_path_resolve_full(&id_ptr, rna_path, &ptr, &prop, &index)) {
return;
}
- if (prop == NULL) {
+ if (prop == nullptr) {
return;
}
if (!RNA_property_is_idprop(prop)) {
@@ -1639,7 +1633,7 @@ void DepsgraphRelationBuilder::build_world(World *world)
build_animdata(&world->id);
build_parameters(&world->id);
/* world's nodetree */
- if (world->nodetree != NULL) {
+ if (world->nodetree != nullptr) {
build_nodetree(world->nodetree);
OperationKey ntree_key(
&world->nodetree->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
@@ -1669,7 +1663,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
LISTBASE_FOREACH (EffectorRelation *, effector_relation, effector_relations) {
ComponentKey effector_transform_key(&effector_relation->ob->id, NodeType::TRANSFORM);
add_relation(effector_transform_key, rb_init_key, "RigidBody Field");
- if (effector_relation->pd != NULL) {
+ if (effector_relation->pd != nullptr) {
const short shape = effector_relation->pd->shape;
if (ELEM(shape, PFIELD_SHAPE_SURFACE, PFIELD_SHAPE_POINTS)) {
ComponentKey effector_geometry_key(&effector_relation->ob->id, NodeType::GEOMETRY);
@@ -1678,8 +1672,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
}
}
/* Objects. */
- if (rbw->group != NULL) {
- build_collection(NULL, NULL, rbw->group);
+ if (rbw->group != nullptr) {
+ build_collection(nullptr, nullptr, rbw->group);
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
if (object->type != OB_MESH) {
continue;
@@ -1699,7 +1693,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* Geometry must be known to create the rigid body. RBO_MESH_BASE
* uses the non-evaluated mesh, so then the evaluation is
* unnecessary. */
- if (object->rigidbody_object != NULL &&
+ if (object->rigidbody_object != nullptr &&
object->rigidbody_object->mesh_source != RBO_MESH_BASE) {
/* NOTE: We prefer this relation to be never killed, to avoid
* access partially evaluated mesh from solver. */
@@ -1718,18 +1712,18 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
/* Constraints. */
- if (rbw->constraints != NULL) {
+ if (rbw->constraints != nullptr) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) {
RigidBodyCon *rbc = object->rigidbody_constraint;
- if (rbc == NULL || rbc->ob1 == NULL || rbc->ob2 == NULL) {
- /* When either ob1 or ob2 is NULL, the constraint doesn't
+ if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) {
+ /* When either ob1 or ob2 is nullptr, the constraint doesn't
* work. */
continue;
}
/* Make sure indirectly linked objects are fully built. */
- build_object(NULL, object);
- build_object(NULL, rbc->ob1);
- build_object(NULL, rbc->ob2);
+ build_object(nullptr, object);
+ build_object(nullptr, rbc->ob1);
+ build_object(nullptr, rbc->ob2);
/* final result of the constraint object's transform controls how
* the constraint affects the physics sim for these objects. */
ComponentKey trans_key(&object->id, NodeType::TRANSFORM);
@@ -1785,8 +1779,8 @@ void DepsgraphRelationBuilder::build_particle_systems(Object *object)
add_particle_collision_relations(
psys_key, object, part->collision_group, "Particle Collision");
}
- else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd != NULL &&
- psys->clmd->coll_parms != NULL) {
+ else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd != nullptr &&
+ psys->clmd->coll_parms != nullptr) {
add_particle_collision_relations(
psys_key, object, psys->clmd->coll_parms->group, "Hair Collision");
}
@@ -1794,17 +1788,17 @@ void DepsgraphRelationBuilder::build_particle_systems(Object *object)
add_particle_forcefield_relations(
psys_key, object, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field");
/* Boids .*/
- if (part->boids != NULL) {
+ if (part->boids != nullptr) {
LISTBASE_FOREACH (BoidState *, state, &part->boids->states) {
LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
- Object *ruleob = NULL;
+ Object *ruleob = nullptr;
if (rule->type == eBoidRuleType_Avoid) {
ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
}
else if (rule->type == eBoidRuleType_FollowLeader) {
ruleob = ((BoidRuleFollowLeader *)rule)->ob;
}
- if (ruleob != NULL) {
+ if (ruleob != nullptr) {
ComponentKey ruleob_key(&ruleob->id, NodeType::TRANSFORM);
add_relation(ruleob_key, psys_key, "Boid Rule");
}
@@ -1814,11 +1808,11 @@ void DepsgraphRelationBuilder::build_particle_systems(Object *object)
/* Keyed particle targets. */
if (part->phystype == PART_PHYS_KEYED) {
LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) {
- if (particle_target->ob == NULL || particle_target->ob == object) {
+ if (particle_target->ob == nullptr || particle_target->ob == object) {
continue;
}
/* Make sure target object is pulled into the graph. */
- build_object(NULL, particle_target->ob);
+ build_object(nullptr, particle_target->ob);
/* Use geometry component, since that's where particles are
* actually evaluated. */
ComponentKey target_key(&particle_target->ob->id, NodeType::GEOMETRY);
@@ -1828,16 +1822,16 @@ void DepsgraphRelationBuilder::build_particle_systems(Object *object)
/* Visualization. */
switch (part->ren_as) {
case PART_DRAW_OB:
- if (part->instance_object != NULL) {
+ if (part->instance_object != nullptr) {
/* Make sure object's relations are all built. */
- build_object(NULL, part->instance_object);
+ build_object(nullptr, part->instance_object);
/* Build relation for the particle visualization. */
build_particle_system_visualization_object(object, psys, part->instance_object);
}
break;
case PART_DRAW_GR:
- if (part->instance_collection != NULL) {
- build_collection(NULL, NULL, part->instance_collection);
+ if (part->instance_collection != nullptr) {
+ build_collection(nullptr, nullptr, part->instance_collection);
LISTBASE_FOREACH (CollectionObject *, go, &part->instance_collection->gobject) {
build_particle_system_visualization_object(object, psys, go->ob);
}
@@ -1870,7 +1864,7 @@ void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
/* Texture slots. */
for (int mtex_index = 0; mtex_index < MAX_MTEX; mtex_index++) {
MTex *mtex = part->mtex[mtex_index];
- if (mtex == NULL || mtex->tex == NULL) {
+ if (mtex == nullptr || mtex->tex == nullptr) {
continue;
}
build_texture(mtex->tex);
@@ -1881,7 +1875,7 @@ void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
RELATION_FLAG_FLUSH_USER_EDIT_ONLY);
/* TODO(sergey): Consider moving texture space handling to an own
* function. */
- if (mtex->texco == TEXCO_OBJECT && mtex->object != NULL) {
+ if (mtex->texco == TEXCO_OBJECT && mtex->object != nullptr) {
ComponentKey object_key(&mtex->object->id, NodeType::TRANSFORM);
add_relation(object_key, particle_settings_eval_key, "Particle Texture Space");
}
@@ -1965,7 +1959,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
Relation *rel = add_relation(scene_key, obdata_ubereval_key, "CoW Relation");
rel->flag |= RELATION_FLAG_NO_FLUSH;
/* Modifiers */
- if (object->modifiers.first != NULL) {
+ if (object->modifiers.first != nullptr) {
ModifierUpdateDepsgraphContext ctx = {};
ctx.scene = scene_;
ctx.object = object;
@@ -1983,7 +1977,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
}
}
/* Grease Pencil Modifiers. */
- if (object->greasepencil_modifiers.first != NULL) {
+ if (object->greasepencil_modifiers.first != nullptr) {
ModifierUpdateDepsgraphContext ctx = {};
ctx.scene = scene_;
ctx.object = object;
@@ -2002,7 +1996,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
}
}
/* Shader FX. */
- if (object->shader_fx.first != NULL) {
+ if (object->shader_fx.first != nullptr) {
ModifierUpdateDepsgraphContext ctx = {};
ctx.scene = scene_;
ctx.object = object;
@@ -2062,8 +2056,8 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
/* Object data data-block. */
build_object_data_geometry_datablock((ID *)object->data);
Key *key = BKE_key_from_object(object);
- if (key != NULL) {
- if (key->adt != NULL) {
+ if (key != nullptr) {
+ if (key->adt != nullptr) {
if (key->adt->action || key->adt->nla_tracks.first) {
ComponentKey obdata_key((ID *)object->data, NodeType::GEOMETRY);
ComponentKey adt_key(&key->id, NodeType::ANIMATION);
@@ -2096,7 +2090,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
build_parameters(obdata);
/* ShapeKeys. */
Key *key = BKE_key_from_id(obdata);
- if (key != NULL) {
+ if (key != nullptr) {
build_shapekeys(key);
}
/* Link object data evaluation node to exit operation. */
@@ -2112,22 +2106,22 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
break;
case ID_CU: {
Curve *cu = (Curve *)obdata;
- if (cu->bevobj != NULL) {
+ if (cu->bevobj != nullptr) {
ComponentKey bevob_geom_key(&cu->bevobj->id, NodeType::GEOMETRY);
add_relation(bevob_geom_key, obdata_geom_eval_key, "Curve Bevel Geometry");
ComponentKey bevob_key(&cu->bevobj->id, NodeType::TRANSFORM);
add_relation(bevob_key, obdata_geom_eval_key, "Curve Bevel Transform");
- build_object(NULL, cu->bevobj);
+ build_object(nullptr, cu->bevobj);
}
- if (cu->taperobj != NULL) {
+ if (cu->taperobj != nullptr) {
ComponentKey taperob_key(&cu->taperobj->id, NodeType::GEOMETRY);
add_relation(taperob_key, obdata_geom_eval_key, "Curve Taper");
- build_object(NULL, cu->taperobj);
+ build_object(nullptr, cu->taperobj);
}
- if (cu->textoncurve != NULL) {
+ if (cu->textoncurve != nullptr) {
ComponentKey textoncurve_key(&cu->textoncurve->id, NodeType::GEOMETRY);
add_relation(textoncurve_key, obdata_geom_eval_key, "Text on Curve");
- build_object(NULL, cu->textoncurve);
+ build_object(nullptr, cu->textoncurve);
}
break;
}
@@ -2150,7 +2144,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
* we need to rebuild the bGPDstroke->triangles caches). */
for (int i = 0; i < gpd->totcol; i++) {
Material *ma = gpd->mat[i];
- if ((ma != NULL) && (ma->gp_style != NULL)) {
+ if ((ma != nullptr) && (ma->gp_style != nullptr)) {
OperationKey material_key(&ma->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
add_relation(material_key, geometry_key, "Material -> GP Data");
}
@@ -2179,8 +2173,8 @@ void DepsgraphRelationBuilder::build_camera(Camera *camera)
}
build_animdata(&camera->id);
build_parameters(&camera->id);
- if (camera->dof.focus_object != NULL) {
- build_object(NULL, camera->dof.focus_object);
+ if (camera->dof.focus_object != nullptr) {
+ build_object(nullptr, camera->dof.focus_object);
ComponentKey camera_parameters_key(&camera->id, NodeType::PARAMETERS);
ComponentKey dof_ob_key(&camera->dof.focus_object->id, NodeType::TRANSFORM);
add_relation(dof_ob_key, camera_parameters_key, "Camera DOF");
@@ -2196,7 +2190,7 @@ void DepsgraphRelationBuilder::build_light(Light *lamp)
build_animdata(&lamp->id);
build_parameters(&lamp->id);
/* light's nodetree */
- if (lamp->nodetree != NULL) {
+ if (lamp->nodetree != nullptr) {
build_nodetree(lamp->nodetree);
ComponentKey lamp_parameters_key(&lamp->id, NodeType::PARAMETERS);
ComponentKey nodetree_key(&lamp->nodetree->id, NodeType::SHADING);
@@ -2207,7 +2201,7 @@ void DepsgraphRelationBuilder::build_light(Light *lamp)
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
{
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
if (built_map_.checkIsBuiltAndTag(ntree)) {
@@ -2219,7 +2213,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
/* nodetree's nodes... */
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
ID *id = bnode->id;
- if (id == NULL) {
+ if (id == nullptr) {
continue;
}
ID_Type id_type = GS(id->name);
@@ -2239,7 +2233,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
add_relation(image_key, shading_key, "Image -> Node");
}
else if (id_type == ID_OB) {
- build_object(NULL, (Object *)id);
+ build_object(nullptr, (Object *)id);
ComponentKey object_transform_key(id, NodeType::TRANSFORM);
add_relation(object_transform_key, shading_key, "Object Transform -> Node");
if (object_have_geometry_component(reinterpret_cast<Object *>(id))) {
@@ -2254,8 +2248,8 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
*
* On the one hand it's annoying to always pull it in, but on another hand it's also annoying
* to have hardcoded node-type exception here. */
- if (node_scene->camera != NULL) {
- build_object(NULL, node_scene->camera);
+ if (node_scene->camera != nullptr) {
+ build_object(nullptr, node_scene->camera);
}
}
else if (id_type == ID_TXT) {
@@ -2305,7 +2299,7 @@ void DepsgraphRelationBuilder::build_material(Material *material)
build_animdata(&material->id);
build_parameters(&material->id);
/* material's nodetree */
- if (material->nodetree != NULL) {
+ if (material->nodetree != nullptr) {
build_nodetree(material->nodetree);
OperationKey ntree_key(
&material->nodetree->id, NodeType::SHADING, OperationCode::MATERIAL_UPDATE);
@@ -2318,7 +2312,7 @@ void DepsgraphRelationBuilder::build_material(Material *material)
void DepsgraphRelationBuilder::build_materials(Material **materials, int num_materials)
{
for (int i = 0; i < num_materials; i++) {
- if (materials[i] == NULL) {
+ if (materials[i] == nullptr) {
continue;
}
build_material(materials[i]);
@@ -2338,7 +2332,7 @@ void DepsgraphRelationBuilder::build_texture(Tex *texture)
build_nodetree(texture->nodetree);
/* Special cases for different IDs which texture uses. */
if (texture->type == TEX_IMAGE) {
- if (texture->ima != NULL) {
+ if (texture->ima != nullptr) {
build_image(texture->ima);
}
}
@@ -2383,6 +2377,11 @@ void DepsgraphRelationBuilder::build_cachefile(CacheFile *cache_file)
ComponentKey datablock_key(&cache_file->id, NodeType::CACHE);
add_relation(animation_key, datablock_key, "Datablock Animation");
}
+ if (check_id_has_driver_component(&cache_file->id)) {
+ ComponentKey animation_key(&cache_file->id, NodeType::PARAMETERS);
+ ComponentKey datablock_key(&cache_file->id, NodeType::CACHE);
+ add_relation(animation_key, datablock_key, "Drivers -> Cache Eval");
+ }
/* Cache file updates */
if (cache_file->is_sequence) {
@@ -2415,7 +2414,7 @@ void DepsgraphRelationBuilder::build_mask(Mask *mask)
for (int i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point = &spline->points[i];
MaskParent *parent = &point->parent;
- if (parent == NULL || parent->id == NULL) {
+ if (parent == nullptr || parent->id == nullptr) {
continue;
}
build_id(parent->id);
@@ -2429,6 +2428,18 @@ void DepsgraphRelationBuilder::build_mask(Mask *mask)
}
}
+void DepsgraphRelationBuilder::build_freestyle_linestyle(FreestyleLineStyle *linestyle)
+{
+ if (built_map_.checkIsBuiltAndTag(linestyle)) {
+ return;
+ }
+
+ ID *linestyle_id = &linestyle->id;
+ build_parameters(linestyle_id);
+ build_animdata(linestyle_id);
+ build_nodetree(linestyle->nodetree);
+}
+
void DepsgraphRelationBuilder::build_movieclip(MovieClip *clip)
{
if (built_map_.checkIsBuiltAndTag(clip)) {
@@ -2455,7 +2466,7 @@ void DepsgraphRelationBuilder::build_speaker(Speaker *speaker)
}
build_animdata(&speaker->id);
build_parameters(&speaker->id);
- if (speaker->sound != NULL) {
+ if (speaker->sound != nullptr) {
build_sound(speaker->sound);
ComponentKey speaker_key(&speaker->id, NodeType::AUDIO);
ComponentKey sound_key(&speaker->sound->id, NodeType::AUDIO);
@@ -2474,7 +2485,7 @@ void DepsgraphRelationBuilder::build_sound(bSound *sound)
void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
{
- if (scene->ed == NULL) {
+ if (scene->ed == nullptr) {
return;
}
build_scene_audio(scene);
@@ -2484,18 +2495,18 @@ void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
Sequence *seq;
bool has_audio_strips = false;
SEQ_BEGIN (scene->ed, seq) {
- if (seq->sound != NULL) {
+ if (seq->sound != nullptr) {
build_sound(seq->sound);
ComponentKey sound_key(&seq->sound->id, NodeType::AUDIO);
add_relation(sound_key, sequencer_key, "Sound -> Sequencer");
has_audio_strips = true;
}
- if (seq->scene != NULL) {
+ if (seq->scene != nullptr) {
build_scene_parameters(seq->scene);
/* This is to support 3D audio. */
has_audio_strips = true;
}
- if (seq->type == SEQ_TYPE_SCENE && seq->scene != NULL) {
+ if (seq->type == SEQ_TYPE_SCENE && seq->scene != nullptr) {
if (seq->flag & SEQ_SCENE_STRIPS) {
build_scene_sequencer(seq->scene);
ComponentKey sequence_scene_audio_key(&seq->scene->id, NodeType::AUDIO);
@@ -2525,7 +2536,7 @@ void DepsgraphRelationBuilder::build_scene_speakers(Scene * /*scene*/, ViewLayer
if (object->type != OB_SPEAKER || !need_pull_base_into_graph(base)) {
continue;
}
- build_object(NULL, base->object);
+ build_object(nullptr, base->object);
}
}
@@ -2551,7 +2562,7 @@ void DepsgraphRelationBuilder::build_nested_datablock(ID *owner, ID *id)
void DepsgraphRelationBuilder::build_nested_nodetree(ID *owner, bNodeTree *ntree)
{
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
build_nested_datablock(owner, &ntree->id);
@@ -2559,7 +2570,7 @@ void DepsgraphRelationBuilder::build_nested_nodetree(ID *owner, bNodeTree *ntree
void DepsgraphRelationBuilder::build_nested_shapekey(ID *owner, Key *key)
{
- if (key == NULL) {
+ if (key == nullptr) {
return;
}
build_nested_datablock(owner, &key->id);
@@ -2616,7 +2627,7 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
/* All entry operations of each component should wait for a proper
* copy of ID. */
OperationNode *op_entry = comp_node->get_entry_operation();
- if (op_entry != NULL) {
+ if (op_entry != nullptr) {
Relation *rel = graph_->add_new_relation(op_cow, op_entry, "CoW Dependency");
rel->flag |= rel_flag;
}
@@ -2662,7 +2673,7 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
if (GS(id_orig->name) == ID_OB) {
Object *object = (Object *)id_orig;
ID *object_data_id = (ID *)object->data;
- if (object_data_id != NULL) {
+ if (object_data_id != nullptr) {
if (deg_copy_on_write_is_needed(object_data_id)) {
OperationKey data_copy_on_write_key(
object_data_id, NodeType::COPY_ON_WRITE, OperationCode::COPY_ON_WRITE);
@@ -2674,6 +2685,26 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
BLI_assert(object->type == OB_EMPTY);
}
}
+
+#if 0
+ /* NOTE: Relation is disabled since AnimationBackup() is disabled.
+ * See comment in AnimationBackup:init_from_id(). */
+
+ /* Copy-on-write of write will iterate over f-curves to store current values corresponding
+ * to their RNA path. This means that action must be copied prior to the ID's copy-on-write,
+ * otherwise depsgraph might try to access freed data. */
+ AnimData *animation_data = BKE_animdata_from_id(id_orig);
+ if (animation_data != nullptr) {
+ if (animation_data->action != nullptr) {
+ OperationKey action_copy_on_write_key(
+ &animation_data->action->id, NodeType::COPY_ON_WRITE, OperationCode::COPY_ON_WRITE);
+ add_relation(action_copy_on_write_key,
+ copy_on_write_key,
+ "Eval Order",
+ RELATION_FLAG_GODMODE | RELATION_FLAG_NO_FLUSH);
+ }
+ }
+#endif
}
/* **** ID traversal callbacks functions **** */
@@ -2685,7 +2716,7 @@ void DepsgraphRelationBuilder::modifier_walk(void *user_data,
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
ID *id = *idpoin;
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
data->builder->build_id(id);
@@ -2698,7 +2729,7 @@ void DepsgraphRelationBuilder::constraint_walk(bConstraint * /*con*/,
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
ID *id = *idpoin;
- if (id == NULL) {
+ if (id == nullptr) {
return;
}
data->builder->build_id(id);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index c6a0014577f..11eb31c68f6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -51,6 +51,8 @@ struct Camera;
struct Collection;
struct EffectorWeights;
struct FCurve;
+struct FreestyleLineSet;
+struct FreestyleLineStyle;
struct ID;
struct Image;
struct Key;
@@ -255,6 +257,10 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
bPoseChannel *pchan,
bConstraint *con,
RootPChanMap *root_map);
+ virtual void build_inter_ik_chains(Object *object,
+ const OperationKey &solver_key,
+ const bPoseChannel *rootchan,
+ const RootPChanMap *root_map);
virtual void build_rig(Object *object);
virtual void build_proxy_rig(Object *object);
virtual void build_shapekeys(Key *key);
@@ -264,6 +270,8 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
virtual void build_nodetree(bNodeTree *ntree);
virtual void build_material(Material *ma);
virtual void build_materials(Material **materials, int num_materials);
+ virtual void build_freestyle_lineset(FreestyleLineSet *fls);
+ virtual void build_freestyle_linestyle(FreestyleLineStyle *linestyle);
virtual void build_texture(Tex *tex);
virtual void build_image(Image *image);
virtual void build_gpencil(bGPdata *gpd);
@@ -360,7 +368,7 @@ struct DepsNodeHandle {
const char *default_name = "")
: builder(builder), node(node), default_name(default_name)
{
- BLI_assert(node != NULL);
+ BLI_assert(node != nullptr);
}
DepsgraphRelationBuilder *builder;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
index 4412fa3fca3..eeeb58100b0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h
@@ -36,7 +36,7 @@ template<typename KeyType>
OperationNode *DepsgraphRelationBuilder::find_operation_node(const KeyType &key)
{
Node *node = get_node(key);
- return node != NULL ? node->get_exit_operation() : NULL;
+ return node != nullptr ? node->get_exit_operation() : nullptr;
}
template<typename KeyFrom, typename KeyTo>
@@ -47,8 +47,8 @@ Relation *DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
{
Node *node_from = get_node(key_from);
Node *node_to = get_node(key_to);
- OperationNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
- OperationNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
+ OperationNode *op_from = node_from ? node_from->get_exit_operation() : nullptr;
+ OperationNode *op_to = node_to ? node_to->get_entry_operation() : nullptr;
if (op_from && op_to) {
return add_operation_relation(op_from, op_to, description, flags);
}
@@ -80,7 +80,7 @@ Relation *DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
key_to.identifier().c_str());
}
}
- return NULL;
+ return nullptr;
}
template<typename KeyTo>
@@ -91,11 +91,11 @@ Relation *DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
{
TimeSourceNode *time_from = get_node(key_from);
Node *node_to = get_node(key_to);
- OperationNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
- if (time_from != NULL && op_to != NULL) {
+ OperationNode *op_to = node_to ? node_to->get_entry_operation() : nullptr;
+ if (time_from != nullptr && op_to != nullptr) {
return add_time_relation(time_from, op_to, description, flags);
}
- return NULL;
+ return nullptr;
}
template<typename KeyType>
@@ -105,9 +105,9 @@ Relation *DepsgraphRelationBuilder::add_node_handle_relation(const KeyType &key_
int flags)
{
Node *node_from = get_node(key_from);
- OperationNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
+ OperationNode *op_from = node_from ? node_from->get_exit_operation() : nullptr;
OperationNode *op_to = handle->node->get_entry_operation();
- if (op_from != NULL && op_to != NULL) {
+ if (op_from != nullptr && op_to != nullptr) {
return add_operation_relation(op_from, op_to, description, flags);
}
else {
@@ -124,7 +124,7 @@ Relation *DepsgraphRelationBuilder::add_node_handle_relation(const KeyType &key_
key_from.identifier().c_str());
}
}
- return NULL;
+ return nullptr;
}
template<typename KeyTo>
@@ -135,7 +135,7 @@ Relation *DepsgraphRelationBuilder::add_depends_on_transform_relation(ID *id,
{
if (GS(id->name) == ID_OB) {
Object *object = reinterpret_cast<Object *>(id);
- if (object->rigidbody_object != NULL) {
+ if (object->rigidbody_object != nullptr) {
OperationKey transform_key(&object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_EVAL);
return add_relation(transform_key, key_to, description, flags);
}
@@ -162,12 +162,12 @@ bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom &key_from,
/* Get operations for requested keys. */
Node *node_from = get_node(key_from);
Node *node_to = get_node(key_to);
- if (node_from == NULL || node_to == NULL) {
+ if (node_from == nullptr || node_to == nullptr) {
return false;
}
OperationNode *op_from = node_from->get_exit_operation();
OperationNode *op_to = node_to->get_entry_operation();
- if (op_from == NULL || op_to == NULL) {
+ if (op_from == nullptr || op_to == nullptr) {
return false;
}
/* Different armatures, bone can't be the same. */
@@ -193,12 +193,12 @@ bool DepsgraphRelationBuilder::is_same_nodetree_node_dependency(const KeyFrom &k
/* Get operations for requested keys. */
Node *node_from = get_node(key_from);
Node *node_to = get_node(key_to);
- if (node_from == NULL || node_to == NULL) {
+ if (node_from == nullptr || node_to == nullptr) {
return false;
}
OperationNode *op_from = node_from->get_exit_operation();
OperationNode *op_to = node_to->get_entry_operation();
- if (op_from == NULL || op_to == NULL) {
+ if (op_from == nullptr || op_to == nullptr) {
return false;
}
/* Check if this is actually a node tree. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
index 35af968d46e..6c449900f03 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
@@ -30,7 +30,7 @@ namespace DEG {
////////////////////////////////////////////////////////////////////////////////
// Time source.
-TimeSourceKey::TimeSourceKey() : id(NULL)
+TimeSourceKey::TimeSourceKey() : id(nullptr)
{
}
@@ -46,7 +46,7 @@ string TimeSourceKey::identifier() const
////////////////////////////////////////////////////////////////////////////////
// Component.
-ComponentKey::ComponentKey() : id(NULL), type(NodeType::UNDEFINED), name("")
+ComponentKey::ComponentKey() : id(nullptr), type(NodeType::UNDEFINED), name("")
{
}
@@ -72,7 +72,7 @@ string ComponentKey::identifier() const
// Operation.
OperationKey::OperationKey()
- : id(NULL),
+ : id(nullptr),
component_type(NodeType::UNDEFINED),
component_name(""),
opcode(OperationCode::OPERATION),
@@ -176,7 +176,7 @@ RNAPathKey::RNAPathKey(ID *id, const char *path, RNAPointerSource source) : id(i
int index;
if (!RNA_path_resolve_full(&id_ptr, path, &ptr, &prop, &index)) {
ptr = PointerRNA_NULL;
- prop = NULL;
+ prop = nullptr;
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index e254f8df0d2..12cd6936a13 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -58,6 +58,7 @@ extern "C" {
#include "intern/node/deg_node_operation.h"
#include "intern/depsgraph_type.h"
+#include "intern/depsgraph_relation.h"
namespace DEG {
@@ -70,7 +71,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
/* Attach owner to IK Solver to. */
bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
- if (rootchan == NULL) {
+ if (rootchan == nullptr) {
return;
}
OperationKey pchan_local_key(
@@ -90,7 +91,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
OperationKey target_dependent_key = is_itasc ? init_ik_key : solver_key;
/* IK target */
/* TODO(sergey): This should get handled as part of the constraint code. */
- if (data->tar != NULL) {
+ if (data->tar != nullptr) {
/* Different object - requires its transform. */
if (data->tar != object) {
ComponentKey target_key(&data->tar->id, NodeType::TRANSFORM);
@@ -119,7 +120,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
}
/* Pole Target. */
/* TODO(sergey): This should get handled as part of the constraint code. */
- if (data->poletar != NULL) {
+ if (data->poletar != nullptr) {
/* Different object - requires its transform. */
if (data->poletar != object) {
ComponentKey target_key(&data->poletar->id, NodeType::TRANSFORM);
@@ -146,7 +147,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
"\nStarting IK Build: pchan = %s, target = (%s, %s), "
"segcount = %d\n",
pchan->name,
- data->tar ? data->tar->id.name : "NULL",
+ data->tar ? data->tar->id.name : "nullptr",
data->subtarget,
data->rootbone);
bPoseChannel *parchan = pchan;
@@ -160,7 +161,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
add_relation(parchan_transforms_key, solver_key, "IK Solver Owner");
/* Walk to the chain's root. */
int segcount = 0;
- while (parchan != NULL) {
+ while (parchan != nullptr) {
/* Make IK-solver dependent on this bone's result, since it can only run
* after the standard results of the bone are know. Validate links step
* on the bone will ensure that users of this bone only grab the result
@@ -192,6 +193,9 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object,
}
OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
+
+ /* Add relation when the root of this IK chain is influenced by another IK chain. */
+ build_inter_ik_chains(object, solver_key, rootchan, root_map);
}
/* Spline IK Eval Steps */
@@ -214,7 +218,7 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
/* Attach owner to IK Solver. */
add_relation(transforms_key, solver_key, "Spline IK Solver Owner", RELATION_FLAG_GODMODE);
/* Attach path dependency to solver. */
- if (data->tar != NULL) {
+ if (data->tar != nullptr) {
ComponentKey target_geometry_key(&data->tar->id, NodeType::GEOMETRY);
add_relation(target_geometry_key, solver_key, "Curve.Path -> Spline IK");
ComponentKey target_transform_key(&data->tar->id, NodeType::TRANSFORM);
@@ -228,7 +232,7 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
root_map->add_bone(pchan->name, rootchan->name);
/* Walk to the chain's root/ */
int segcount = 1;
- for (bPoseChannel *parchan = pchan->parent; parchan != NULL && segcount < data->chainlen;
+ for (bPoseChannel *parchan = pchan->parent; parchan != nullptr && segcount < data->chainlen;
parchan = parchan->parent, segcount++) {
/* Make Spline IK solver dependent on this bone's result, since it can
* only run after the standard results of the bone are know. Validate
@@ -244,6 +248,33 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *object,
}
OperationKey pose_done_key(&object->id, NodeType::EVAL_POSE, OperationCode::POSE_DONE);
add_relation(solver_key, pose_done_key, "PoseEval Result-Bone Link");
+
+ /* Add relation when the root of this IK chain is influenced by another IK chain. */
+ build_inter_ik_chains(object, solver_key, rootchan, root_map);
+}
+
+void DepsgraphRelationBuilder::build_inter_ik_chains(Object *object,
+ const OperationKey &solver_key,
+ const bPoseChannel *rootchan,
+ const RootPChanMap *root_map)
+{
+ bPoseChannel *deepest_root = nullptr;
+ const char *root_name = rootchan->name;
+
+ /* Find shared IK chain root. */
+ for (bPoseChannel *parchan = rootchan->parent; parchan; parchan = parchan->parent) {
+ if (!root_map->has_common_root(root_name, parchan->name)) {
+ break;
+ }
+ deepest_root = parchan;
+ }
+ if (deepest_root == nullptr) {
+ return;
+ }
+
+ OperationKey other_bone_key(
+ &object->id, NodeType::BONE, deepest_root->name, OperationCode::BONE_DONE);
+ add_relation(other_bone_key, solver_key, "IK Chain Overlap");
}
/* Pose/Armature Bones Graph */
@@ -332,7 +363,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
/* Local to pose parenting operation. */
add_relation(bone_local_key, bone_pose_key, "Bone Local - Bone Pose");
/* Parent relation. */
- if (pchan->parent != NULL) {
+ if (pchan->parent != nullptr) {
OperationCode parent_key_opcode;
/* NOTE: this difference in handling allows us to prevent lockups
* while ensuring correct poses for separate chains. */
@@ -347,7 +378,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
add_relation(parent_key, bone_pose_key, "Parent Bone -> Child Bone");
}
/* Build constraints. */
- if (pchan->constraints.first != NULL) {
+ if (pchan->constraints.first != nullptr) {
/* Build relations for indirectly linked objects. */
BuilderWalkUserData data;
data.builder = this;
@@ -412,8 +443,8 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
add_relation(bone_ready_key, pose_cleanup_key, "Ready -> Cleanup");
}
/* Custom shape. */
- if (pchan->custom != NULL) {
- build_object(NULL, pchan->custom);
+ if (pchan->custom != nullptr) {
+ build_object(nullptr, pchan->custom);
}
}
}
@@ -456,13 +487,13 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object)
* the parent bone, some users expect the parent to be ready if the
* bone itself is (e.g. for computing the local space matrix).
*/
- if (pchan->parent != NULL) {
+ if (pchan->parent != nullptr) {
OperationKey parent_key(
&object->id, NodeType::BONE, pchan->parent->name, OperationCode::BONE_DONE);
add_relation(parent_key, bone_done_key, "Parent Bone -> Child Bone");
}
- if (pchan->prop != NULL) {
+ if (pchan->prop != nullptr) {
OperationKey bone_parameters(
&object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, pchan->name);
OperationKey from_bone_parameters(
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
index 4e0c2cbba0c..08191bcecc8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
@@ -42,8 +42,8 @@ void DepsgraphRelationBuilder::build_scene_render(Scene *scene, ViewLayer *view_
build_scene_sequencer(scene);
build_scene_speakers(scene, view_layer);
}
- if (scene->camera != NULL) {
- build_object(NULL, scene->camera);
+ if (scene->camera != nullptr) {
+ build_object(nullptr, scene->camera);
}
}
@@ -64,7 +64,7 @@ void DepsgraphRelationBuilder::build_scene_compositor(Scene *scene)
if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_SCENE_COMPOSITOR)) {
return;
}
- if (scene->nodetree == NULL) {
+ if (scene->nodetree == nullptr) {
return;
}
build_nodetree(scene->nodetree);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index 4c55e4a137a..41e91ba7286 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -35,6 +35,7 @@
#include "BLI_blenlib.h"
extern "C" {
+#include "DNA_linestyle_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -69,12 +70,22 @@ void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
continue;
}
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
- build_collection(lc, NULL, lc->collection);
+ build_collection(lc, nullptr, lc->collection);
}
build_layer_collections(&lc->layer_collections);
}
}
+void DepsgraphRelationBuilder::build_freestyle_lineset(FreestyleLineSet *fls)
+{
+ if (fls->group != nullptr) {
+ build_collection(nullptr, nullptr, fls->group);
+ }
+ if (fls->linestyle != nullptr) {
+ build_freestyle_linestyle(fls->linestyle);
+ }
+}
+
void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
ViewLayer *view_layer,
eDepsNode_LinkedState_Type linked_state)
@@ -84,7 +95,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
/* Scene objects. */
/* NOTE: Nodes builder requires us to pass CoW base because it's being
* passed to the evaluation functions. During relations builder we only
- * do NULL-pointer check of the base, so it's fine to pass original one. */
+ * do nullptr-pointer check of the base, so it's fine to pass original one. */
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (need_pull_base_into_graph(base)) {
build_object(base, base->object);
@@ -93,19 +104,19 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
build_layer_collections(&view_layer->layer_collections);
- if (scene->camera != NULL) {
- build_object(NULL, scene->camera);
+ if (scene->camera != nullptr) {
+ build_object(nullptr, scene->camera);
}
/* Rigidbody. */
- if (scene->rigidbody_world != NULL) {
+ if (scene->rigidbody_world != nullptr) {
build_rigidbody(scene);
}
/* Scene's animation and drivers. */
- if (scene->adt != NULL) {
+ if (scene->adt != nullptr) {
build_animdata(&scene->id);
}
/* World. */
- if (scene->world != NULL) {
+ if (scene->world != nullptr) {
build_world(scene->world);
}
/* Masks. */
@@ -117,14 +128,12 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
build_movieclip(clip);
}
/* Material override. */
- if (view_layer->mat_override != NULL) {
+ if (view_layer->mat_override != nullptr) {
build_material(view_layer->mat_override);
}
- /* Freestyle collections. */
+ /* Freestyle linesets. */
LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
- if (fls->group != NULL) {
- build_collection(NULL, NULL, fls->group);
- }
+ build_freestyle_lineset(fls);
}
/* Scene parameters, compositor and such. */
build_scene_compositor(scene);
@@ -140,7 +149,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
build_scene_sequencer(scene);
}
/* Build all set scenes. */
- if (scene->set != NULL) {
+ if (scene->set != nullptr) {
ViewLayer *set_view_layer = BKE_view_layer_default_render(scene->set);
build_view_layer(scene->set, set_view_layer, DEG_ID_LINKED_VIA_SET);
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 180499519f6..853f8995d68 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -57,14 +57,14 @@ namespace DEG {
class RNANodeQueryIDData {
public:
- explicit RNANodeQueryIDData(const ID *id) : id_(id), contraint_to_pchan_map_(NULL)
+ explicit RNANodeQueryIDData(const ID *id) : id_(id), contraint_to_pchan_map_(nullptr)
{
}
~RNANodeQueryIDData()
{
- if (contraint_to_pchan_map_ != NULL) {
- BLI_ghash_free(contraint_to_pchan_map_, NULL, NULL);
+ if (contraint_to_pchan_map_ != nullptr) {
+ BLI_ghash_free(contraint_to_pchan_map_, nullptr, nullptr);
}
}
@@ -76,13 +76,13 @@ class RNANodeQueryIDData {
void ensure_constraint_to_pchan_map()
{
- if (contraint_to_pchan_map_ != NULL) {
+ if (contraint_to_pchan_map_ != nullptr) {
return;
}
BLI_assert(GS(id_->name) == ID_OB);
const Object *object = reinterpret_cast<const Object *>(id_);
contraint_to_pchan_map_ = BLI_ghash_ptr_new("id data pchan constraint map");
- if (object->pose != NULL) {
+ if (object->pose != nullptr) {
LISTBASE_FOREACH (const bPoseChannel *, pchan, &object->pose->chanbase) {
LISTBASE_FOREACH (const bConstraint *, constraint, &pchan->constraints) {
BLI_ghash_insert(contraint_to_pchan_map_,
@@ -105,7 +105,7 @@ class RNANodeQueryIDData {
/* ***************************** Node Identifier **************************** */
RNANodeIdentifier::RNANodeIdentifier()
- : id(NULL),
+ : id(nullptr),
type(NodeType::UNDEFINED),
component_name(""),
operation_code(OperationCode::OPERATION),
@@ -116,7 +116,7 @@ RNANodeIdentifier::RNANodeIdentifier()
bool RNANodeIdentifier::is_valid() const
{
- return id != NULL && type != NodeType::UNDEFINED;
+ return id != nullptr && type != NodeType::UNDEFINED;
}
/* ********************************** Query ********************************* */
@@ -140,7 +140,7 @@ RNANodeQuery::RNANodeQuery(Depsgraph *depsgraph, DepsgraphBuilder *builder)
RNANodeQuery::~RNANodeQuery()
{
- BLI_ghash_free(id_data_map_, NULL, ghash_id_data_free_func);
+ BLI_ghash_free(id_data_map_, nullptr, ghash_id_data_free_func);
}
Node *RNANodeQuery::find_node(const PointerRNA *ptr,
@@ -149,16 +149,16 @@ Node *RNANodeQuery::find_node(const PointerRNA *ptr,
{
const RNANodeIdentifier node_identifier = construct_node_identifier(ptr, prop, source);
if (!node_identifier.is_valid()) {
- return NULL;
+ return nullptr;
}
IDNode *id_node = depsgraph_->find_id_node(node_identifier.id);
- if (id_node == NULL) {
- return NULL;
+ if (id_node == nullptr) {
+ return nullptr;
}
ComponentNode *comp_node = id_node->find_component(node_identifier.type,
node_identifier.component_name);
- if (comp_node == NULL) {
- return NULL;
+ if (comp_node == nullptr) {
+ return nullptr;
}
if (node_identifier.operation_code == OperationCode::OPERATION) {
return comp_node;
@@ -173,7 +173,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
RNAPointerSource source)
{
RNANodeIdentifier node_identifier;
- if (ptr->type == NULL) {
+ if (ptr->type == nullptr) {
return node_identifier;
}
/* Set default values for returns. */
@@ -183,44 +183,42 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
node_identifier.operation_name = "";
node_identifier.operation_name_tag = -1;
/* Handling of commonly known scenarios. */
- if (ptr->type == &RNA_PoseBone) {
+ if (prop != nullptr && RNA_property_is_idprop(prop)) {
+ node_identifier.type = NodeType::PARAMETERS;
+ node_identifier.operation_code = OperationCode::ID_PROPERTY;
+ node_identifier.operation_name = RNA_property_identifier(
+ reinterpret_cast<const PropertyRNA *>(prop));
+ return node_identifier;
+ }
+ else if (ptr->type == &RNA_PoseBone) {
const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr->data);
- if (prop != NULL && RNA_property_is_idprop(prop)) {
- node_identifier.type = NodeType::PARAMETERS;
- node_identifier.operation_code = OperationCode::ID_PROPERTY;
- node_identifier.operation_name = RNA_property_identifier(
- reinterpret_cast<const PropertyRNA *>(prop));
- node_identifier.operation_name_tag = -1;
- }
- else {
- /* Bone - generally, we just want the bone component. */
- node_identifier.type = NodeType::BONE;
- node_identifier.component_name = pchan->name;
- /* However check property name for special handling. */
- if (prop != NULL) {
- Object *object = reinterpret_cast<Object *>(node_identifier.id);
- const char *prop_name = RNA_property_identifier(prop);
- /* B-Bone properties should connect to the final operation. */
- if (STRPREFIX(prop_name, "bbone_")) {
- if (builder_->check_pchan_has_bbone_segments(object, pchan)) {
- node_identifier.operation_code = OperationCode::BONE_SEGMENTS;
- }
- else {
- node_identifier.operation_code = OperationCode::BONE_DONE;
- }
+ /* Bone - generally, we just want the bone component. */
+ node_identifier.type = NodeType::BONE;
+ node_identifier.component_name = pchan->name;
+ /* However check property name for special handling. */
+ if (prop != nullptr) {
+ Object *object = reinterpret_cast<Object *>(node_identifier.id);
+ const char *prop_name = RNA_property_identifier(prop);
+ /* B-Bone properties should connect to the final operation. */
+ if (STRPREFIX(prop_name, "bbone_")) {
+ if (builder_->check_pchan_has_bbone_segments(object, pchan)) {
+ node_identifier.operation_code = OperationCode::BONE_SEGMENTS;
}
- /* Final transform properties go to the Done node for the exit. */
- else if (STREQ(prop_name, "head") || STREQ(prop_name, "tail") ||
- STREQ(prop_name, "length") || STRPREFIX(prop_name, "matrix")) {
- if (source == RNAPointerSource::EXIT) {
- node_identifier.operation_code = OperationCode::BONE_DONE;
- }
- }
- /* And other properties can always go to the entry operation. */
else {
- node_identifier.operation_code = OperationCode::BONE_LOCAL;
+ node_identifier.operation_code = OperationCode::BONE_DONE;
+ }
+ }
+ /* Final transform properties go to the Done node for the exit. */
+ else if (STREQ(prop_name, "head") || STREQ(prop_name, "tail") ||
+ STREQ(prop_name, "length") || STRPREFIX(prop_name, "matrix")) {
+ if (source == RNAPointerSource::EXIT) {
+ node_identifier.operation_code = OperationCode::BONE_DONE;
}
}
+ /* And other properties can always go to the entry operation. */
+ else {
+ node_identifier.operation_code = OperationCode::BONE_LOCAL;
+ }
}
return node_identifier;
}
@@ -247,7 +245,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
* at a given constraint, but for rigging one might use constraint
* influence to be used to drive some corrective shape keys or so. */
const bPoseChannel *pchan = id_data->get_pchan_for_constraint(constraint);
- if (pchan == NULL) {
+ if (pchan == nullptr) {
node_identifier.type = NodeType::TRANSFORM;
node_identifier.operation_code = OperationCode::TRANSFORM_LOCAL;
}
@@ -262,10 +260,10 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
Object *object = reinterpret_cast<Object *>(ptr->owner_id);
bConstraintTarget *tgt = (bConstraintTarget *)ptr->data;
/* Check whether is object or bone constraint. */
- bPoseChannel *pchan = NULL;
+ bPoseChannel *pchan = nullptr;
bConstraint *con = BKE_constraint_find_from_target(object, tgt, &pchan);
- if (con != NULL) {
- if (pchan != NULL) {
+ if (con != nullptr) {
+ if (pchan != nullptr) {
node_identifier.type = NodeType::BONE;
node_identifier.operation_code = OperationCode::BONE_LOCAL;
node_identifier.component_name = pchan->name;
@@ -301,7 +299,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
}
else if (ptr->type == &RNA_Object) {
/* Transforms props? */
- if (prop != NULL) {
+ if (prop != nullptr) {
const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
/* TODO(sergey): How to optimize this? */
if (strstr(prop_identifier, "location") || strstr(prop_identifier, "rotation") ||
@@ -372,20 +370,12 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
node_identifier.type = NodeType::GEOMETRY;
return node_identifier;
}
- if (prop != NULL) {
+ if (prop != nullptr) {
/* All unknown data effectively falls under "parameter evaluation". */
- if (RNA_property_is_idprop(prop)) {
- node_identifier.type = NodeType::PARAMETERS;
- node_identifier.operation_code = OperationCode::ID_PROPERTY;
- node_identifier.operation_name = RNA_property_identifier((PropertyRNA *)prop);
- node_identifier.operation_name_tag = -1;
- }
- else {
- node_identifier.type = NodeType::PARAMETERS;
- node_identifier.operation_code = OperationCode::PARAMETERS_EVAL;
- node_identifier.operation_name = "";
- node_identifier.operation_name_tag = -1;
- }
+ node_identifier.type = NodeType::PARAMETERS;
+ node_identifier.operation_code = OperationCode::PARAMETERS_EVAL;
+ node_identifier.operation_name = "";
+ node_identifier.operation_name_tag = -1;
return node_identifier;
}
return node_identifier;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
index 13cf8e63832..fc7c546e294 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
@@ -30,6 +30,7 @@
#include "intern/node/deg_node_operation.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
#include "intern/debug/deg_debug.h"
namespace DEG {
diff --git a/source/blender/depsgraph/intern/debug/deg_debug.cc b/source/blender/depsgraph/intern/debug/deg_debug.cc
index b811f11f721..74a042989db 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug.cc
@@ -28,10 +28,50 @@
#include "BLI_hash.h"
#include "BLI_string.h"
+#include "PIL_time_utildefines.h"
+
#include "BKE_global.h"
namespace DEG {
+DepsgraphDebug::DepsgraphDebug()
+ : flags(G.debug), is_ever_evaluated(false), graph_evaluation_start_time_(0)
+{
+}
+
+bool DepsgraphDebug::do_time_debug() const
+{
+ return ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0);
+}
+
+void DepsgraphDebug::begin_graph_evaluation()
+{
+ if (!do_time_debug()) {
+ return;
+ }
+
+ const double current_time = PIL_check_seconds_timer();
+
+ if (is_ever_evaluated) {
+ fps_samples_.add_sample(current_time - graph_evaluation_start_time_);
+ }
+
+ graph_evaluation_start_time_ = current_time;
+}
+
+void DepsgraphDebug::end_graph_evaluation()
+{
+ if (!do_time_debug()) {
+ return;
+ }
+
+ const double graph_eval_end_time = PIL_check_seconds_timer();
+ printf("Depsgraph updated in %f seconds.\n", graph_eval_end_time - graph_evaluation_start_time_);
+ printf("Depsgraph evaluation FPS: %f\n", 1.0f / fps_samples_.get_averaged());
+
+ is_ever_evaluated = true;
+}
+
bool terminal_do_color(void)
{
return (G.debug & G_DEBUG_DEPSGRAPH_PRETTY) != 0;
diff --git a/source/blender/depsgraph/intern/debug/deg_debug.h b/source/blender/depsgraph/intern/debug/deg_debug.h
index 3e4da644641..21a802828dc 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug.h
+++ b/source/blender/depsgraph/intern/debug/deg_debug.h
@@ -24,6 +24,7 @@
#pragma once
#include "intern/depsgraph_type.h"
+#include "intern/debug/deg_time_average.h"
#include "BKE_global.h"
@@ -31,6 +32,38 @@
namespace DEG {
+class DepsgraphDebug {
+ public:
+ DepsgraphDebug();
+
+ bool do_time_debug() const;
+
+ void begin_graph_evaluation();
+ void end_graph_evaluation();
+
+ /* NOTE: Corresponds to G_DEBUG_DEPSGRAPH_* flags. */
+ int flags;
+
+ /* Name of this dependency graph (is used for debug prints, helping to distinguish graphs
+ * created for different view layer). */
+ string name;
+
+ /* Is true when dependency graph was evaluated at least once.
+ * This is NOT an indication that depsgraph is at its evaluated state. */
+ bool is_ever_evaluated;
+
+ protected:
+ /* Maximum number of counters used to calculate frame rate of depsgraph update. */
+ static const constexpr int MAX_FPS_COUNTERS = 64;
+
+ /* Point in time when last graph evaluation began.
+ * Is initialized from begin_graph_evaluation() when time debug is enabled.
+ */
+ double graph_evaluation_start_time_;
+
+ AveragedTimeSampler<MAX_FPS_COUNTERS> fps_samples_;
+};
+
#define DEG_DEBUG_PRINTF(depsgraph, type, ...) \
do { \
if (DEG_debug_flags_get(depsgraph) & G_DEBUG_DEPSGRAPH_##type) { \
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
index ee3959a0861..b2f2359a954 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
@@ -36,6 +36,8 @@ extern "C" {
#include "DEG_depsgraph_debug.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
+
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_operation.h"
@@ -553,7 +555,7 @@ static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgr
deg_debug_graphviz_node(ctx, node);
}
TimeSourceNode *time_source = graph->find_time_source();
- if (time_source != NULL) {
+ if (time_source != nullptr) {
deg_debug_graphviz_node(ctx, time_source);
}
}
@@ -570,7 +572,7 @@ static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const De
}
TimeSourceNode *time_source = graph->find_time_source();
- if (time_source != NULL) {
+ if (time_source != nullptr) {
deg_debug_graphviz_node_relations(ctx, time_source);
}
}
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
index 4a668e817fe..c37188bc3ca 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
@@ -156,7 +156,7 @@ void DEG_debug_stats_gnuplot(const Depsgraph *depsgraph,
const char *label,
const char *output_filename)
{
- if (depsgraph == NULL) {
+ if (depsgraph == nullptr) {
return;
}
DEG::DebugContext ctx;
diff --git a/source/blender/depsgraph/intern/debug/deg_time_average.h b/source/blender/depsgraph/intern/debug/deg_time_average.h
new file mode 100644
index 00000000000..9794e9a88c3
--- /dev/null
+++ b/source/blender/depsgraph/intern/debug/deg_time_average.h
@@ -0,0 +1,71 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+namespace DEG {
+
+// Utility class which takes care of calculating average of time series, such as
+// FPS counters.
+template<int MaxSamples> class AveragedTimeSampler {
+ public:
+ AveragedTimeSampler() : num_samples_(0), next_sample_index_(0)
+ {
+ }
+
+ void add_sample(double value)
+ {
+ samples_[next_sample_index_] = value;
+
+ // Move to the next index, keeping wrapping at the end of array into account.
+ ++next_sample_index_;
+ if (next_sample_index_ == MaxSamples) {
+ next_sample_index_ = 0;
+ }
+
+ // Update number of stored samples.
+ if (num_samples_ != MaxSamples) {
+ ++num_samples_;
+ }
+ }
+
+ double get_averaged() const
+ {
+ double sum = 0.0;
+ for (int i = 0; i < num_samples_; ++i) {
+ sum += samples_[i];
+ }
+ return sum / num_samples_;
+ }
+
+ protected:
+ double samples_[MaxSamples];
+
+ // Number of samples which are actually stored in the array.
+ int num_samples_;
+
+ // Index in the samples_ array under which next sample will be stored.
+ int next_sample_index_;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 292c3b361d8..ce6797939b5 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -46,6 +46,7 @@ extern "C" {
#include "intern/depsgraph_update.h"
#include "intern/depsgraph_physics.h"
+#include "intern/depsgraph_relation.h"
#include "intern/depsgraph_registry.h"
#include "intern/eval/deg_eval_copy_on_write.h"
@@ -66,7 +67,7 @@ template<typename T> static void remove_from_vector(vector<T> *vector, const T &
}
Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
- : time_source(NULL),
+ : time_source(nullptr),
need_update(true),
need_update_time(false),
bmain(bmain),
@@ -74,7 +75,7 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati
view_layer(view_layer),
mode(mode),
ctime(BKE_scene_frame_get(scene)),
- scene_cow(NULL),
+ scene_cow(nullptr),
is_active(false),
is_evaluating(false),
is_render_pipeline_depsgraph(false)
@@ -82,7 +83,6 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags");
- debug_flags = G.debug;
memset(id_type_updated, 0, sizeof(id_type_updated));
memset(id_type_exist, 0, sizeof(id_type_exist));
memset(physics_relations, 0, sizeof(physics_relations));
@@ -91,9 +91,9 @@ Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluati
Depsgraph::~Depsgraph()
{
clear_id_nodes();
- BLI_ghash_free(id_hash, NULL, NULL);
- BLI_gset_free(entry_tags, NULL);
- if (time_source != NULL) {
+ BLI_ghash_free(id_hash, nullptr, nullptr);
+ BLI_gset_free(entry_tags, nullptr);
+ if (time_source != nullptr) {
OBJECT_GUARDED_DELETE(time_source, TimeSourceNode);
}
BLI_spin_end(&lock);
@@ -103,9 +103,9 @@ Depsgraph::~Depsgraph()
TimeSourceNode *Depsgraph::add_time_source()
{
- if (time_source == NULL) {
+ if (time_source == nullptr) {
DepsNodeFactory *factory = type_get_factory(NodeType::TIMESOURCE);
- time_source = (TimeSourceNode *)factory->create_node(NULL, "", "Time Source");
+ time_source = (TimeSourceNode *)factory->create_node(nullptr, "", "Time Source");
}
return time_source;
}
@@ -143,7 +143,7 @@ IDNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint)
void Depsgraph::clear_id_nodes_conditional(const std::function<bool(ID_Type id_type)> &filter)
{
for (IDNode *id_node : id_nodes) {
- if (id_node->id_cow == NULL) {
+ if (id_node->id_cow == nullptr) {
/* This means builder "stole" ownership of the copy-on-written
* datablock for her own dirty needs. */
continue;
@@ -170,7 +170,7 @@ void Depsgraph::clear_id_nodes()
OBJECT_GUARDED_DELETE(id_node, IDNode);
}
/* Clear containers. */
- BLI_ghash_clear(id_hash, NULL, NULL);
+ BLI_ghash_clear(id_hash, nullptr, nullptr);
id_nodes.clear();
/* Clear physics relation caches. */
clear_physics_relations(this);
@@ -179,11 +179,11 @@ void Depsgraph::clear_id_nodes()
/* Add new relation between two nodes */
Relation *Depsgraph::add_new_relation(Node *from, Node *to, const char *description, int flags)
{
- Relation *rel = NULL;
+ Relation *rel = nullptr;
if (flags & RELATION_CHECK_BEFORE_ADD) {
rel = check_nodes_connected(from, to, description);
}
- if (rel != NULL) {
+ if (rel != nullptr) {
rel->flag |= flags;
return rel;
}
@@ -212,49 +212,12 @@ Relation *Depsgraph::check_nodes_connected(const Node *from,
if (rel->to != to) {
continue;
}
- if (description != NULL && !STREQ(rel->name, description)) {
+ if (description != nullptr && !STREQ(rel->name, description)) {
continue;
}
return rel;
}
- return NULL;
-}
-
-/* ************************ */
-/* Relationships Management */
-
-Relation::Relation(Node *from, Node *to, const char *description)
- : from(from), to(to), name(description), flag(0)
-{
- /* Hook it up to the nodes which use it.
- *
- * NOTE: We register relation in the nodes which this link connects to here
- * in constructor but we don't unregister it in the destructor.
- *
- * Reasoning:
- *
- * - Destructor is currently used on global graph destruction, so there's no
- * real need in avoiding dangling pointers, all the memory is to be freed
- * anyway.
- *
- * - Unregistering relation is not a cheap operation, so better to have it
- * as an explicit call if we need this. */
- from->outlinks.push_back(this);
- to->inlinks.push_back(this);
-}
-
-Relation::~Relation()
-{
- /* Sanity check. */
- BLI_assert(from != NULL && to != NULL);
-}
-
-void Relation::unlink()
-{
- /* Sanity check. */
- BLI_assert(from != NULL && to != NULL);
- remove_from_vector(&from->outlinks, this);
- remove_from_vector(&to->inlinks, this);
+ return nullptr;
}
/* Low level tagging -------------------------------------- */
@@ -263,7 +226,7 @@ void Relation::unlink()
void Depsgraph::add_entry_tag(OperationNode *node)
{
/* Sanity check. */
- if (node == NULL) {
+ if (node == nullptr) {
return;
}
/* Add to graph-level set of directly modified nodes to start searching
@@ -276,16 +239,16 @@ void Depsgraph::add_entry_tag(OperationNode *node)
void Depsgraph::clear_all_nodes()
{
clear_id_nodes();
- if (time_source != NULL) {
+ if (time_source != nullptr) {
OBJECT_GUARDED_DELETE(time_source, TimeSourceNode);
- time_source = NULL;
+ time_source = nullptr;
}
}
ID *Depsgraph::get_cow_id(const ID *id_orig) const
{
IDNode *id_node = find_id_node(id_orig);
- if (id_node == NULL) {
+ if (id_node == nullptr) {
/* This function is used from places where we expect ID to be either
* already a copy-on-write version or have a corresponding copy-on-write
* version.
@@ -325,7 +288,7 @@ Depsgraph *DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEval
/* Free graph's contents and graph itself */
void DEG_graph_free(Depsgraph *graph)
{
- if (graph == NULL) {
+ if (graph == nullptr) {
return;
}
using DEG::Depsgraph;
@@ -342,10 +305,10 @@ bool DEG_is_evaluating(struct Depsgraph *depsgraph)
bool DEG_is_active(const struct Depsgraph *depsgraph)
{
- if (depsgraph == NULL) {
+ if (depsgraph == nullptr) {
/* Happens for such cases as work object in what_does_obaction(),
* and sine render pipeline parts. Shouldn't really be accepting
- * NULL depsgraph, but is quite hard to get proper one in those
+ * nullptr depsgraph, but is quite hard to get proper one in those
* cases. */
return false;
}
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index 43829f4e045..7801f95e008 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -40,6 +40,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_physics.h"
+#include "intern/debug/deg_debug.h"
#include "intern/depsgraph_type.h"
struct GHash;
@@ -53,47 +54,9 @@ namespace DEG {
struct IDNode;
struct Node;
struct OperationNode;
+struct Relation;
struct TimeSourceNode;
-/* *************************** */
-/* Relationships Between Nodes */
-
-/* Settings/Tags on Relationship.
- * NOTE: Is a bitmask, allowing accumulation. */
-enum RelationFlag {
- /* "cyclic" link - when detecting cycles, this relationship was the one
- * which triggers a cyclic relationship to exist in the graph. */
- RELATION_FLAG_CYCLIC = (1 << 0),
- /* Update flush will not go through this relation. */
- RELATION_FLAG_NO_FLUSH = (1 << 1),
- /* Only flush along the relation is update comes from a node which was
- * affected by user input. */
- RELATION_FLAG_FLUSH_USER_EDIT_ONLY = (1 << 2),
- /* The relation can not be killed by the cyclic dependencies solver. */
- RELATION_FLAG_GODMODE = (1 << 4),
- /* Relation will check existence before being added. */
- RELATION_CHECK_BEFORE_ADD = (1 << 5),
-};
-
-/* B depends on A (A -> B) */
-struct Relation {
- Relation(Node *from, Node *to, const char *description);
- ~Relation();
-
- void unlink();
-
- /* the nodes in the relationship (since this is shared between the nodes) */
- Node *from; /* A */
- Node *to; /* B */
-
- /* relationship attributes */
- const char *name; /* label for debugging */
- int flag; /* Bitmask of RelationFlag) */
-};
-
-/* ********* */
-/* Depsgraph */
-
/* Dependency Graph object */
struct Depsgraph {
// TODO(sergey): Go away from C++ container and use some native BLI.
@@ -107,7 +70,7 @@ struct Depsgraph {
TimeSourceNode *find_time_source() const;
IDNode *find_id_node(const ID *id) const;
- IDNode *add_id_node(ID *id, ID *id_cow_hint = NULL);
+ IDNode *add_id_node(ID *id, ID *id_cow_hint = nullptr);
void clear_id_nodes();
void clear_id_nodes_conditional(const std::function<bool(ID_Type id_type)> &filter);
@@ -115,7 +78,7 @@ struct Depsgraph {
Relation *add_new_relation(Node *from, Node *to, const char *description, int flags = 0);
/* Check whether two nodes are connected by relation with given
- * description. Description might be NULL to check ANY relation between
+ * description. Description might be nullptr to check ANY relation between
* given nodes. */
Relation *check_nodes_connected(const Node *from, const Node *to, const char *description);
@@ -194,9 +157,7 @@ struct Depsgraph {
* to read stuff from. */
bool is_active;
- /* NOTE: Corresponds to G_DEBUG_DEPSGRAPH_* flags. */
- int debug_flags;
- string debug_name;
+ DepsgraphDebug debug;
bool is_evaluating;
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index f67ab381c79..a570e042c26 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -59,6 +59,7 @@ extern "C" {
#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_operation.h"
+#include "intern/depsgraph_relation.h"
#include "intern/depsgraph_registry.h"
#include "intern/depsgraph_type.h"
@@ -143,7 +144,7 @@ void DEG_add_object_pointcache_relation(struct DepsNodeHandle *node_handle,
ID *id = DEG_get_id_from_handle(node_handle);
DEG::ComponentKey point_cache_key(id, DEG::NodeType::POINT_CACHE);
DEG::Relation *rel = relation_builder->add_relation(comp_key, point_cache_key, "Point Cache");
- if (rel != NULL) {
+ if (rel != nullptr) {
rel->flag |= DEG::RELATION_FLAG_FLUSH_USER_EDIT_ONLY;
}
else {
@@ -345,7 +346,7 @@ class DepsgraphFromIDsFilter {
DepsgraphFromIDsFilter(ID **ids, const int num_ids)
{
for (int i = 0; i < num_ids; ++i) {
- ids_.insert(ids[0]);
+ ids_.insert(ids[i]);
}
}
@@ -376,7 +377,7 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
virtual void build_object_proxy_group(Object *object, bool is_visible) override
{
- if (object->proxy_group == NULL) {
+ if (object->proxy_group == nullptr) {
return;
}
if (!filter_.contains(&object->proxy_group->id)) {
@@ -407,7 +408,7 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
virtual void build_object_proxy_group(Object *object) override
{
- if (object->proxy_group == NULL) {
+ if (object->proxy_group == nullptr) {
return;
}
if (!filter_.contains(&object->proxy_group->id)) {
@@ -478,7 +479,7 @@ void DEG_graph_tag_relations_update(Depsgraph *graph)
* TODO(sergey): Try to make it so we don't flush updates
* to the whole depsgraph. */
DEG::IDNode *id_node = deg_graph->find_id_node(&deg_graph->scene->id);
- if (id_node != NULL) {
+ if (id_node != nullptr) {
id_node->tag_update(deg_graph, DEG::DEG_UPDATE_SOURCE_RELATIONS);
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc
index bb60db5209c..25f7e9117d1 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.cc
+++ b/source/blender/depsgraph/intern/depsgraph_debug.cc
@@ -38,6 +38,7 @@ extern "C" {
#include "DEG_depsgraph_query.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
#include "intern/depsgraph_type.h"
#include "intern/debug/deg_debug.h"
#include "intern/node/deg_node_component.h"
@@ -47,31 +48,31 @@ extern "C" {
void DEG_debug_flags_set(Depsgraph *depsgraph, int flags)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
- deg_graph->debug_flags = flags;
+ deg_graph->debug.flags = flags;
}
int DEG_debug_flags_get(const Depsgraph *depsgraph)
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(depsgraph);
- return deg_graph->debug_flags;
+ return deg_graph->debug.flags;
}
void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
- deg_graph->debug_name = name;
+ deg_graph->debug.name = name;
}
const char *DEG_debug_name_get(struct Depsgraph *depsgraph)
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(depsgraph);
- return deg_graph->debug_name.c_str();
+ return deg_graph->debug.name.c_str();
}
bool DEG_debug_compare(const struct Depsgraph *graph1, const struct Depsgraph *graph2)
{
- BLI_assert(graph1 != NULL);
- BLI_assert(graph2 != NULL);
+ BLI_assert(graph1 != nullptr);
+ BLI_assert(graph2 != nullptr);
const DEG::Depsgraph *deg_graph1 = reinterpret_cast<const DEG::Depsgraph *>(graph1);
const DEG::Depsgraph *deg_graph2 = reinterpret_cast<const DEG::Depsgraph *>(graph2);
if (deg_graph1->operations.size() != deg_graph2->operations.size()) {
@@ -233,7 +234,7 @@ void DEG_stats_simple(const Depsgraph *graph,
}
DEG::TimeSourceNode *time_source = deg_graph->find_time_source();
- if (time_source != NULL) {
+ if (time_source != nullptr) {
tot_rels += time_source->inlinks.size();
}
diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc
index f47081cd54e..cabb95fe732 100644
--- a/source/blender/depsgraph/intern/depsgraph_physics.cc
+++ b/source/blender/depsgraph/intern/depsgraph_physics.cc
@@ -67,8 +67,8 @@ static ePhysicsRelationType modifier_to_relation_type(unsigned int modifier_type
ListBase *DEG_get_effector_relations(const Depsgraph *graph, Collection *collection)
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
- if (deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR] == NULL) {
- return NULL;
+ if (deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR] == nullptr) {
+ return nullptr;
}
ID *collection_orig = DEG_get_original_id(&collection->id);
@@ -82,8 +82,8 @@ ListBase *DEG_get_collision_relations(const Depsgraph *graph,
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
- if (deg_graph->physics_relations[type] == NULL) {
- return NULL;
+ if (deg_graph->physics_relations[type] == nullptr) {
+ return nullptr;
}
ID *collection_orig = DEG_get_original_id(&collection->id);
return (ListBase *)BLI_ghash_lookup(deg_graph->physics_relations[type], collection_orig);
@@ -106,7 +106,7 @@ void DEG_add_collision_relations(DepsNodeHandle *handle,
if (ob1 == object) {
continue;
}
- if (filter_function == NULL ||
+ if (filter_function == nullptr ||
filter_function(ob1, modifiers_findByType(ob1, (ModifierType)modifier_type))) {
DEG_add_object_pointcache_relation(handle, ob1, DEG_OB_COMP_TRANSFORM, name);
DEG_add_object_pointcache_relation(handle, ob1, DEG_OB_COMP_GEOMETRY, name);
@@ -144,7 +144,7 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
}
/* Smoke flow relations. */
- if (relation->pd->forcefield == PFIELD_SMOKEFLOW && relation->pd->f_source != NULL) {
+ if (relation->pd->forcefield == PFIELD_SMOKEFLOW && relation->pd->f_source != nullptr) {
DEG_add_object_pointcache_relation(
handle, relation->pd->f_source, DEG_OB_COMP_TRANSFORM, "Smoke Force Domain");
DEG_add_object_pointcache_relation(
@@ -154,7 +154,7 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle,
/* Absorption forces need collision relation. */
if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
DEG_add_collision_relations(
- handle, object, NULL, eModifierType_Collision, NULL, "Force Absorption");
+ handle, object, nullptr, eModifierType_Collision, nullptr, "Force Absorption");
}
}
}
@@ -166,13 +166,13 @@ namespace DEG {
ListBase *build_effector_relations(Depsgraph *graph, Collection *collection)
{
GHash *hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR];
- if (hash == NULL) {
+ if (hash == nullptr) {
graph->physics_relations[DEG_PHYSICS_EFFECTOR] = BLI_ghash_ptr_new(
"Depsgraph physics relations hash");
hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR];
}
ListBase *relations = reinterpret_cast<ListBase *>(BLI_ghash_lookup(hash, collection));
- if (relations == NULL) {
+ if (relations == nullptr) {
::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph);
relations = BKE_effector_relations_create(depsgraph, graph->view_layer, collection);
BLI_ghash_insert(hash, &collection->id, relations);
@@ -186,12 +186,12 @@ ListBase *build_collision_relations(Depsgraph *graph,
{
const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
GHash *hash = graph->physics_relations[type];
- if (hash == NULL) {
+ if (hash == nullptr) {
graph->physics_relations[type] = BLI_ghash_ptr_new("Depsgraph physics relations hash");
hash = graph->physics_relations[type];
}
ListBase *relations = reinterpret_cast<ListBase *>(BLI_ghash_lookup(hash, collection));
- if (relations == NULL) {
+ if (relations == nullptr) {
::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph);
relations = BKE_collision_relations_create(depsgraph, collection, modifier_type);
BLI_ghash_insert(hash, &collection->id, relations);
@@ -221,17 +221,17 @@ void clear_physics_relations(Depsgraph *graph)
switch (type) {
case DEG_PHYSICS_EFFECTOR:
- BLI_ghash_free(graph->physics_relations[i], NULL, free_effector_relations);
+ BLI_ghash_free(graph->physics_relations[i], nullptr, free_effector_relations);
break;
case DEG_PHYSICS_COLLISION:
case DEG_PHYSICS_SMOKE_COLLISION:
case DEG_PHYSICS_DYNAMIC_BRUSH:
- BLI_ghash_free(graph->physics_relations[i], NULL, free_collision_relations);
+ BLI_ghash_free(graph->physics_relations[i], nullptr, free_collision_relations);
break;
case DEG_PHYSICS_RELATIONS_NUM:
break;
}
- graph->physics_relations[i] = NULL;
+ graph->physics_relations[i] = nullptr;
}
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 3b0f49e0150..4205f79b9c0 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -103,7 +103,7 @@ bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
uint32_t DEG_get_eval_flags_for_id(const Depsgraph *graph, ID *id)
{
- if (graph == NULL) {
+ if (graph == nullptr) {
/* Happens when converting objects to mesh from a python script
* after modifying scene graph.
*
@@ -114,7 +114,7 @@ uint32_t DEG_get_eval_flags_for_id(const Depsgraph *graph, ID *id)
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
const DEG::IDNode *id_node = deg_graph->find_id_node(DEG_get_original_id(id));
- if (id_node == NULL) {
+ if (id_node == nullptr) {
/* TODO(sergey): Does it mean we need to check set scene? */
return 0;
}
@@ -126,7 +126,7 @@ void DEG_get_customdata_mask_for_object(const Depsgraph *graph,
Object *ob,
CustomData_MeshMasks *r_mask)
{
- if (graph == NULL) {
+ if (graph == nullptr) {
/* Happens when converting objects to mesh from a python script
* after modifying scene graph.
*
@@ -137,7 +137,7 @@ void DEG_get_customdata_mask_for_object(const Depsgraph *graph,
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
const DEG::IDNode *id_node = deg_graph->find_id_node(DEG_get_original_id(&ob->id));
- if (id_node == NULL) {
+ if (id_node == nullptr) {
/* TODO(sergey): Does it mean we need to check set scene? */
return;
}
@@ -155,7 +155,7 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
Scene *scene_cow = deg_graph->scene_cow;
/* TODO(sergey): Shall we expand data-block here? Or is it OK to assume
* that caller is OK with just a pointer in case scene is not updated yet? */
- BLI_assert(scene_cow != NULL && DEG::deg_copy_on_write_is_expanded(&scene_cow->id));
+ BLI_assert(scene_cow != nullptr && DEG::deg_copy_on_write_is_expanded(&scene_cow->id));
return scene_cow;
}
@@ -163,15 +163,15 @@ ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
{
const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph);
Scene *scene_cow = DEG_get_evaluated_scene(graph);
- if (scene_cow == NULL) {
- return NULL; /* Happens with new, not-yet-built/evaluated graphes. */
+ if (scene_cow == nullptr) {
+ return nullptr; /* Happens with new, not-yet-built/evaluated graphes. */
}
/* Do name-based lookup. */
/* TODO(sergey): Can this be optimized? */
ViewLayer *view_layer_orig = deg_graph->view_layer;
ViewLayer *view_layer_cow = (ViewLayer *)BLI_findstring(
&scene_cow->view_layers, view_layer_orig->name, offsetof(ViewLayer, name));
- BLI_assert(view_layer_cow != NULL);
+ BLI_assert(view_layer_cow != nullptr);
return view_layer_cow;
}
@@ -182,15 +182,15 @@ Object *DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
ID *DEG_get_evaluated_id(const Depsgraph *depsgraph, ID *id)
{
- if (id == NULL) {
- return NULL;
+ if (id == nullptr) {
+ return nullptr;
}
/* TODO(sergey): This is a duplicate of Depsgraph::get_cow_id(),
* but here we never do assert, since we don't know nature of the
* incoming ID data-block. */
const DEG::Depsgraph *deg_graph = (const DEG::Depsgraph *)depsgraph;
const DEG::IDNode *id_node = deg_graph->find_id_node(id);
- if (id_node == NULL) {
+ if (id_node == nullptr) {
return id;
}
return id_node->id_cow;
@@ -201,7 +201,7 @@ void DEG_get_evaluated_rna_pointer(const Depsgraph *depsgraph,
PointerRNA *ptr,
PointerRNA *r_ptr_eval)
{
- if ((ptr == NULL) || (r_ptr_eval == NULL)) {
+ if ((ptr == nullptr) || (r_ptr_eval == nullptr)) {
return;
}
ID *orig_id = ptr->owner_id;
@@ -233,7 +233,7 @@ void DEG_get_evaluated_rna_pointer(const Depsgraph *depsgraph,
if (path) {
PointerRNA cow_id_ptr;
RNA_id_pointer_create(cow_id, &cow_id_ptr);
- if (!RNA_path_resolve(&cow_id_ptr, path, r_ptr_eval, NULL)) {
+ if (!RNA_path_resolve(&cow_id_ptr, path, r_ptr_eval, nullptr)) {
/* Couldn't find COW copy of data */
fprintf(stderr,
"%s: Couldn't resolve RNA path ('%s') relative to COW ID (%p) for '%s'\n",
@@ -261,10 +261,10 @@ Object *DEG_get_original_object(Object *object)
ID *DEG_get_original_id(ID *id)
{
- if (id == NULL) {
- return NULL;
+ if (id == nullptr) {
+ return nullptr;
}
- if (id->orig_id == NULL) {
+ if (id->orig_id == nullptr) {
return id;
}
BLI_assert((id->tag & LIB_TAG_COPIED_ON_WRITE) != 0);
diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
index b7a40fb69bd..0a28e379ef5 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
@@ -40,6 +40,7 @@ extern "C" {
#include "DEG_depsgraph_query.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_id.h"
@@ -87,7 +88,7 @@ void deg_foreach_dependent_operation(const Depsgraph *graph,
{
/* Start with getting ID node from the graph. */
IDNode *target_id_node = graph->find_id_node(id);
- if (target_id_node == NULL) {
+ if (target_id_node == nullptr) {
/* TODO(sergey): Shall we inform or assert here about attempt to start
* iterating over non-existing ID? */
return;
@@ -210,7 +211,7 @@ void deg_foreach_ancestor_ID(const Depsgraph *graph,
{
/* Start with getting ID node from the graph. */
IDNode *target_id_node = graph->find_id_node(id);
- if (target_id_node == NULL) {
+ if (target_id_node == nullptr) {
/* TODO(sergey): Shall we inform or assert here about attempt to start
* iterating over non-existing ID? */
return;
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index db469612f76..90ab7565f4a 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -67,7 +67,7 @@ namespace {
void deg_invalidate_iterator_work_data(DEGObjectIterData *data)
{
#ifdef INVALIDATE_WORK_DATA
- BLI_assert(data != NULL);
+ BLI_assert(data != nullptr);
memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));
#else
(void)data;
@@ -76,14 +76,14 @@ void deg_invalidate_iterator_work_data(DEGObjectIterData *data)
void verify_id_properties_freed(DEGObjectIterData *data)
{
- if (data->dupli_object_current == NULL) {
+ if (data->dupli_object_current == nullptr) {
// We didn't enter duplication yet, so we can't have any dangling
// pointers.
return;
}
const Object *dupli_object = data->dupli_object_current->ob;
Object *temp_dupli_object = &data->temp_dupli_object;
- if (temp_dupli_object->id.properties == NULL) {
+ if (temp_dupli_object->id.properties == nullptr) {
// No ID properties in temp datablock -- no leak is possible.
return;
}
@@ -94,7 +94,7 @@ void verify_id_properties_freed(DEGObjectIterData *data)
// Free memory which is owned by temporary storage which is about to
// get overwritten.
IDP_FreeProperty(temp_dupli_object->id.properties);
- temp_dupli_object->id.properties = NULL;
+ temp_dupli_object->id.properties = nullptr;
}
static bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject *dob)
@@ -120,7 +120,7 @@ static bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, Dupl
bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
{
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
- while (data->dupli_object_next != NULL) {
+ while (data->dupli_object_next != nullptr) {
DupliObject *dob = data->dupli_object_next;
Object *obd = dob->ob;
@@ -215,7 +215,7 @@ void deg_iterator_objects_step(BLI_Iterator *iter, DEG::IDNode *id_node)
if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
ob_visibility = BKE_object_visibility(object, data->eval_mode);
- if (deg_object_hide_original(data->eval_mode, object, NULL)) {
+ if (deg_object_hide_original(data->eval_mode, object, nullptr)) {
return;
}
}
@@ -249,10 +249,10 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
return;
}
- data->dupli_parent = NULL;
- data->dupli_list = NULL;
- data->dupli_object_next = NULL;
- data->dupli_object_current = NULL;
+ data->dupli_parent = nullptr;
+ data->dupli_list = nullptr;
+ data->dupli_object_next = nullptr;
+ data->dupli_object_current = nullptr;
data->scene = DEG_get_evaluated_scene(depsgraph);
data->id_node_index = 0;
data->num_id_nodes = num_id_nodes;
@@ -281,10 +281,10 @@ void DEG_iterator_objects_next(BLI_Iterator *iter)
else {
verify_id_properties_freed(data);
free_object_duplilist(data->dupli_list);
- data->dupli_parent = NULL;
- data->dupli_list = NULL;
- data->dupli_object_next = NULL;
- data->dupli_object_current = NULL;
+ data->dupli_parent = nullptr;
+ data->dupli_list = nullptr;
+ data->dupli_object_next = nullptr;
+ data->dupli_object_current = nullptr;
deg_invalidate_iterator_work_data(data);
}
}
@@ -303,7 +303,7 @@ void DEG_iterator_objects_next(BLI_Iterator *iter)
void DEG_iterator_objects_end(BLI_Iterator *iter)
{
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
- if (data != NULL) {
+ if (data != nullptr) {
/* Force crash in case the iterator data is referenced and accessed down
* the line. (T51718) */
deg_invalidate_iterator_work_data(data);
diff --git a/source/blender/depsgraph/intern/depsgraph_relation.cc b/source/blender/depsgraph/intern/depsgraph_relation.cc
new file mode 100644
index 00000000000..1b2de2cc807
--- /dev/null
+++ b/source/blender/depsgraph/intern/depsgraph_relation.cc
@@ -0,0 +1,73 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/depsgraph_relation.h" /* own include */
+
+#include "BLI_utildefines.h"
+
+#include "intern/depsgraph_type.h"
+#include "intern/node/deg_node.h"
+
+namespace DEG {
+
+/* TODO(sergey): Find a better place for this. */
+template<typename T> static void remove_from_vector(vector<T> *vector, const T &value)
+{
+ vector->erase(std::remove(vector->begin(), vector->end(), value), vector->end());
+}
+
+Relation::Relation(Node *from, Node *to, const char *description)
+ : from(from), to(to), name(description), flag(0)
+{
+ /* Hook it up to the nodes which use it.
+ *
+ * NOTE: We register relation in the nodes which this link connects to here
+ * in constructor but we don't unregister it in the destructor.
+ *
+ * Reasoning:
+ *
+ * - Destructor is currently used on global graph destruction, so there's no
+ * real need in avoiding dangling pointers, all the memory is to be freed
+ * anyway.
+ *
+ * - Unregistering relation is not a cheap operation, so better to have it
+ * as an explicit call if we need this. */
+ from->outlinks.push_back(this);
+ to->inlinks.push_back(this);
+}
+
+Relation::~Relation()
+{
+ /* Sanity check. */
+ BLI_assert(from != nullptr && to != nullptr);
+}
+
+void Relation::unlink()
+{
+ /* Sanity check. */
+ BLI_assert(from != nullptr && to != nullptr);
+ remove_from_vector(&from->outlinks, this);
+ remove_from_vector(&to->inlinks, this);
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/depsgraph_relation.h b/source/blender/depsgraph/intern/depsgraph_relation.h
new file mode 100644
index 00000000000..2f9f0249b1f
--- /dev/null
+++ b/source/blender/depsgraph/intern/depsgraph_relation.h
@@ -0,0 +1,63 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+namespace DEG {
+
+struct Node;
+
+/* Settings/Tags on Relationship.
+ * NOTE: Is a bitmask, allowing accumulation. */
+enum RelationFlag {
+ /* "cyclic" link - when detecting cycles, this relationship was the one
+ * which triggers a cyclic relationship to exist in the graph. */
+ RELATION_FLAG_CYCLIC = (1 << 0),
+ /* Update flush will not go through this relation. */
+ RELATION_FLAG_NO_FLUSH = (1 << 1),
+ /* Only flush along the relation is update comes from a node which was
+ * affected by user input. */
+ RELATION_FLAG_FLUSH_USER_EDIT_ONLY = (1 << 2),
+ /* The relation can not be killed by the cyclic dependencies solver. */
+ RELATION_FLAG_GODMODE = (1 << 4),
+ /* Relation will check existence before being added. */
+ RELATION_CHECK_BEFORE_ADD = (1 << 5),
+};
+
+/* B depends on A (A -> B) */
+struct Relation {
+ Relation(Node *from, Node *to, const char *description);
+ ~Relation();
+
+ void unlink();
+
+ /* the nodes in the relationship (since this is shared between the nodes) */
+ Node *from; /* A */
+ Node *to; /* B */
+
+ /* relationship attributes */
+ const char *name; /* label for debugging */
+ int flag; /* Bitmask of RelationFlag) */
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index ce5917110d6..b019c079dab 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -246,7 +246,7 @@ void id_tag_update_ntree_special(
Main *bmain, Depsgraph *graph, ID *id, int flag, eUpdateSource update_source)
{
bNodeTree *ntree = ntreeFromID(id);
- if (ntree == NULL) {
+ if (ntree == nullptr) {
return;
}
graph_id_tag_update(bmain, graph, &ntree->id, flag, update_source);
@@ -257,7 +257,7 @@ void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
/* NOTE: We handle this immediately, without delaying anything, to be
* sure we don't cause threading issues with OpenGL. */
/* TODO(sergey): Make sure this works for CoW-ed datablocks as well. */
- DEGEditorUpdateContext update_ctx = {NULL};
+ DEGEditorUpdateContext update_ctx = {nullptr};
update_ctx.bmain = bmain;
update_ctx.depsgraph = (::Depsgraph *)graph;
update_ctx.scene = graph->scene;
@@ -281,7 +281,7 @@ void depsgraph_tag_component(Depsgraph *graph,
/* NOTE: Animation component might not be existing yet (which happens when adding new driver or
* adding a new keyframe), so the required copy-on-write tag needs to be taken care explicitly
* here. */
- if (component_node == NULL) {
+ if (component_node == nullptr) {
if (component_type == NodeType::ANIMATION) {
depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
}
@@ -292,7 +292,7 @@ void depsgraph_tag_component(Depsgraph *graph,
}
else {
OperationNode *operation_node = component_node->find_operation(operation_code);
- if (operation_node != NULL) {
+ if (operation_node != nullptr) {
operation_node->tag_update(graph, update_source);
}
}
@@ -315,7 +315,7 @@ void deg_graph_id_tag_legacy_compat(
case ID_OB: {
Object *object = (Object *)id;
ID *data_id = (ID *)object->data;
- if (data_id != NULL) {
+ if (data_id != nullptr) {
graph_id_tag_update(bmain, depsgraph, data_id, 0, update_source);
}
break;
@@ -325,9 +325,9 @@ void deg_graph_id_tag_legacy_compat(
* tagging here. */
case ID_ME: {
Mesh *mesh = (Mesh *)id;
- if (mesh->key != NULL) {
+ if (mesh->key != nullptr) {
ID *key_id = &mesh->key->id;
- if (key_id != NULL) {
+ if (key_id != nullptr) {
graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
}
}
@@ -335,9 +335,9 @@ void deg_graph_id_tag_legacy_compat(
}
case ID_LT: {
Lattice *lattice = (Lattice *)id;
- if (lattice->key != NULL) {
+ if (lattice->key != nullptr) {
ID *key_id = &lattice->key->id;
- if (key_id != NULL) {
+ if (key_id != nullptr) {
graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
}
}
@@ -345,9 +345,9 @@ void deg_graph_id_tag_legacy_compat(
}
case ID_CU: {
Curve *curve = (Curve *)id;
- if (curve->key != NULL) {
+ if (curve->key != nullptr) {
ID *key_id = &curve->key->id;
- if (key_id != NULL) {
+ if (key_id != nullptr) {
graph_id_tag_update(bmain, depsgraph, key_id, 0, update_source);
}
}
@@ -367,13 +367,13 @@ static void graph_id_tag_update_single_flag(Main *bmain,
eUpdateSource update_source)
{
if (tag == ID_RECALC_EDITORS) {
- if (graph != NULL && graph->is_active) {
+ if (graph != nullptr && graph->is_active) {
depsgraph_update_editors_tag(bmain, graph, id);
}
return;
}
else if (tag == ID_RECALC_TIME) {
- if (graph != NULL) {
+ if (graph != nullptr) {
graph->need_update_time = true;
}
return;
@@ -389,14 +389,14 @@ static void graph_id_tag_update_single_flag(Main *bmain,
return;
}
/* Some sanity checks before moving forward. */
- if (id_node == NULL) {
+ if (id_node == nullptr) {
/* Happens when object is tagged for update and not yet in the
* dependency graph (but will be after relations update). */
return;
}
/* Tag ID recalc flag. */
DepsNodeFactory *factory = type_get_factory(component_type);
- BLI_assert(factory != NULL);
+ BLI_assert(factory != nullptr);
id_node->id_cow->recalc |= factory->id_recalc_tag();
/* Tag corresponding dependency graph operation for update. */
if (component_type == NodeType::ID_REF) {
@@ -413,7 +413,7 @@ static void graph_id_tag_update_single_flag(Main *bmain,
string stringify_append_bit(const string &str, IDRecalcFlag tag)
{
const char *tag_name = DEG_update_tag_as_string(tag);
- if (tag_name == NULL) {
+ if (tag_name == nullptr) {
return str;
}
string result = str;
@@ -468,7 +468,7 @@ int deg_recalc_flags_for_legacy_zero()
int deg_recalc_flags_effective(Depsgraph *graph, int flags)
{
- if (graph != NULL) {
+ if (graph != nullptr) {
if (!graph->is_active) {
return 0;
}
@@ -489,7 +489,7 @@ void deg_graph_node_tag_zero(Main *bmain,
IDNode *id_node,
eUpdateSource update_source)
{
- if (id_node == NULL) {
+ if (id_node == nullptr) {
return;
}
ID *id = id_node->id_orig;
@@ -514,7 +514,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph, const bool do_ti
const ID_Type id_type = GS(id_node->id_orig->name);
if (id_type == ID_OB) {
Object *object_orig = reinterpret_cast<Object *>(id_node->id_orig);
- if (object_orig->proxy != NULL) {
+ if (object_orig->proxy != nullptr) {
object_orig->proxy->proxy_from = object_orig;
}
}
@@ -528,7 +528,7 @@ void deg_graph_on_visible_update(Main *bmain, Depsgraph *graph, const bool do_ti
if (!DEG::deg_copy_on_write_is_expanded(id_node->id_cow)) {
flag |= ID_RECALC_COPY_ON_WRITE;
if (do_time) {
- if (BKE_animdata_from_id(id_node->id_orig) != NULL) {
+ if (BKE_animdata_from_id(id_node->id_orig) != nullptr) {
flag |= ID_RECALC_ANIMATION;
}
}
@@ -612,7 +612,7 @@ NodeType geometry_tag_to_component(const ID *id)
void id_tag_update(Main *bmain, ID *id, int flag, eUpdateSource update_source)
{
- graph_id_tag_update(bmain, NULL, id, flag, update_source);
+ graph_id_tag_update(bmain, nullptr, id, flag, update_source);
for (DEG::Depsgraph *depsgraph : DEG::get_all_registered_graphs(bmain)) {
graph_id_tag_update(bmain, depsgraph, id, flag, update_source);
}
@@ -621,8 +621,8 @@ void id_tag_update(Main *bmain, ID *id, int flag, eUpdateSource update_source)
void graph_id_tag_update(
Main *bmain, Depsgraph *graph, ID *id, int flag, eUpdateSource update_source)
{
- const int debug_flags = (graph != NULL) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug;
- if (graph != NULL && graph->is_evaluating) {
+ const int debug_flags = (graph != nullptr) ? DEG_debug_flags_get((::Depsgraph *)graph) : G.debug;
+ if (graph != nullptr && graph->is_evaluating) {
if (debug_flags & G_DEBUG_DEPSGRAPH) {
printf("ID tagged for update during dependency graph evaluation.");
}
@@ -635,8 +635,8 @@ void graph_id_tag_update(
stringify_update_bitfield(flag).c_str(),
update_source_as_string(update_source));
}
- IDNode *id_node = (graph != NULL) ? graph->find_id_node(id) : NULL;
- if (graph != NULL) {
+ IDNode *id_node = (graph != nullptr) ? graph->find_id_node(id) : nullptr;
+ if (graph != nullptr) {
DEG_graph_id_type_tag(reinterpret_cast<::Depsgraph *>(graph), GS(id->name));
}
if (flag == 0) {
@@ -644,7 +644,7 @@ void graph_id_tag_update(
}
/* Store original flag in the ID.
* Allows to have more granularity than a node-factory based flags. */
- if (id_node != NULL) {
+ if (id_node != nullptr) {
id_node->id_cow->recalc |= flag;
}
/* When ID is tagged for update based on an user edits store the recalc flags in the original ID.
@@ -730,7 +730,7 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
case ID_RECALC_ALL:
return "ALL";
}
- return NULL;
+ return nullptr;
}
/* Data-Based Tagging */
@@ -743,7 +743,7 @@ void DEG_id_tag_update(ID *id, int flag)
void DEG_id_tag_update_ex(Main *bmain, ID *id, int flag)
{
- if (id == NULL) {
+ if (id == nullptr) {
/* Ideally should not happen, but old depsgraph allowed this. */
return;
}
@@ -804,7 +804,7 @@ void DEG_ids_check_recalc(
{
bool updated = time || DEG_id_type_any_updated(depsgraph);
- DEGEditorUpdateContext update_ctx = {NULL};
+ DEGEditorUpdateContext update_ctx = {nullptr};
update_ctx.bmain = bmain;
update_ctx.depsgraph = depsgraph;
update_ctx.scene = scene;
diff --git a/source/blender/depsgraph/intern/depsgraph_update.cc b/source/blender/depsgraph/intern/depsgraph_update.cc
index ed4ec592fc7..d10bfaaace8 100644
--- a/source/blender/depsgraph/intern/depsgraph_update.cc
+++ b/source/blender/depsgraph/intern/depsgraph_update.cc
@@ -29,19 +29,19 @@
namespace DEG {
-static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
-static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
+static DEG_EditorUpdateIDCb deg_editor_update_id_cb = nullptr;
+static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = nullptr;
void deg_editors_id_update(const DEGEditorUpdateContext *update_ctx, ID *id)
{
- if (deg_editor_update_id_cb != NULL) {
+ if (deg_editor_update_id_cb != nullptr) {
deg_editor_update_id_cb(update_ctx, id);
}
}
void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx, bool updated)
{
- if (deg_editor_update_scene_cb != NULL) {
+ if (deg_editor_update_scene_cb != nullptr) {
deg_editor_update_scene_cb(update_ctx, updated);
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index d6b3c54a149..df61a1416bd 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -31,6 +31,7 @@
#include "BLI_utildefines.h"
#include "BLI_task.h"
#include "BLI_ghash.h"
+#include "BLI_gsqueue.h"
#include "BKE_global.h"
@@ -51,47 +52,86 @@
#include "intern/node/deg_node_operation.h"
#include "intern/node/deg_node_time.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
namespace DEG {
-/* ********************** */
-/* Evaluation Entrypoints */
+namespace {
-/* Forward declarations. */
-static void schedule_children(TaskPool *pool,
- Depsgraph *graph,
- OperationNode *node,
- const int thread_id);
+struct DepsgraphEvalState;
+
+void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id);
+
+template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
+void schedule_children(DepsgraphEvalState *state,
+ OperationNode *node,
+ const int thread_id,
+ ScheduleFunction *schedule_function,
+ ScheduleFunctionArgs... schedule_function_args);
+
+void schedule_node_to_pool(OperationNode *node, const int thread_id, TaskPool *pool)
+{
+ BLI_task_pool_push_from_thread(
+ pool, deg_task_run_func, node, false, TASK_PRIORITY_HIGH, thread_id);
+}
+
+/* Denotes which part of dependency graph is being evaluated. */
+enum class EvaluationStage {
+ /* Stage 1: Only Copy-on-Write operations are to be evaluated, prior to anything else.
+ * This allows other operations to access its dependencies when there is a dependency cycle
+ * involved. */
+ COPY_ON_WRITE,
+
+ /* Threaded evaluation of all possible operations. */
+ THREADED_EVALUATION,
+
+ /* Workaround for areas which can not be evaluated in threads.
+ *
+ * For example, metaballs, which are iterating over all bases and are requesting dupli-lists
+ * to see whether there are metaballs inside. */
+ SINGLE_THREADED_WORKAROUND,
+};
struct DepsgraphEvalState {
Depsgraph *graph;
bool do_stats;
- bool is_cow_stage;
+ EvaluationStage stage;
+ bool need_single_thread_pass;
};
-static void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id)
+void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_node)
{
- void *userdata_v = BLI_task_pool_userdata(pool);
- DepsgraphEvalState *state = (DepsgraphEvalState *)userdata_v;
- OperationNode *node = (OperationNode *)taskdata;
+ ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(state->graph);
+
/* Sanity checks. */
- BLI_assert(!node->is_noop() && "NOOP nodes should not actually be scheduled");
+ BLI_assert(!operation_node->is_noop() && "NOOP nodes should not actually be scheduled");
/* Perform operation. */
if (state->do_stats) {
const double start_time = PIL_check_seconds_timer();
- node->evaluate((::Depsgraph *)state->graph);
- node->stats.current_time += PIL_check_seconds_timer() - start_time;
+ operation_node->evaluate(depsgraph);
+ operation_node->stats.current_time += PIL_check_seconds_timer() - start_time;
}
else {
- node->evaluate((::Depsgraph *)state->graph);
+ operation_node->evaluate(depsgraph);
}
+}
+
+void deg_task_run_func(TaskPool *pool, void *taskdata, int thread_id)
+{
+ void *userdata_v = BLI_task_pool_userdata(pool);
+ DepsgraphEvalState *state = (DepsgraphEvalState *)userdata_v;
+
+ /* Evaluate node. */
+ OperationNode *operation_node = reinterpret_cast<OperationNode *>(taskdata);
+ evaluate_node(state, operation_node);
+
/* Schedule children. */
BLI_task_pool_delayed_push_begin(pool, thread_id);
- schedule_children(pool, state->graph, node, thread_id);
+ schedule_children(state, operation_node, thread_id, schedule_node_to_pool, pool);
BLI_task_pool_delayed_push_end(pool, thread_id);
}
-static bool check_operation_node_visible(OperationNode *op_node)
+bool check_operation_node_visible(OperationNode *op_node)
{
const ComponentNode *comp_node = op_node->owner;
/* Special exception, copy on write component is to be always evaluated,
@@ -102,7 +142,7 @@ static bool check_operation_node_visible(OperationNode *op_node)
return comp_node->affects_directly_visible;
}
-static void calculate_pending_parents_for_node(OperationNode *node)
+void calculate_pending_parents_for_node(OperationNode *node)
{
/* Update counters, applies for both visible and invisible IDs. */
node->num_links_pending = 0;
@@ -134,14 +174,14 @@ static void calculate_pending_parents_for_node(OperationNode *node)
}
}
-static void calculate_pending_parents(Depsgraph *graph)
+void calculate_pending_parents(Depsgraph *graph)
{
for (OperationNode *node : graph->operations) {
calculate_pending_parents_for_node(node);
}
}
-static void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph)
+void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph)
{
const bool do_stats = state->do_stats;
calculate_pending_parents(graph);
@@ -153,12 +193,54 @@ static void initialize_execution(DepsgraphEvalState *state, Depsgraph *graph)
}
}
+bool is_metaball_object_operation(const OperationNode *operation_node)
+{
+ const ComponentNode *component_node = operation_node->owner;
+ const IDNode *id_node = component_node->owner;
+ if (GS(id_node->id_cow->name) != ID_OB) {
+ return false;
+ }
+ const Object *object = reinterpret_cast<const Object *>(id_node->id_cow);
+ return object->type == OB_MBALL;
+}
+
+bool need_evaluate_operation_at_stage(DepsgraphEvalState *state,
+ const OperationNode *operation_node)
+{
+ const ComponentNode *component_node = operation_node->owner;
+ switch (state->stage) {
+ case EvaluationStage::COPY_ON_WRITE:
+ return (component_node->type == NodeType::COPY_ON_WRITE);
+
+ case EvaluationStage::THREADED_EVALUATION:
+ /* Sanity check: copy-on-write node should be evaluated already. This will be indicated by
+ * scheduled flag (we assume that scheduled operations have been actually handled by previous
+ * stage). */
+ BLI_assert(operation_node->scheduled || component_node->type != NodeType::COPY_ON_WRITE);
+ if (is_metaball_object_operation(operation_node)) {
+ state->need_single_thread_pass = true;
+ return false;
+ }
+ return true;
+
+ case EvaluationStage::SINGLE_THREADED_WORKAROUND:
+ return true;
+ }
+ BLI_assert(!"Unhandled evaluation stage, should never happen.");
+ return false;
+}
+
/* Schedule a node if it needs evaluation.
* dec_parents: Decrement pending parents count, true when child nodes are
* scheduled after a task has been completed.
*/
-static void schedule_node(
- TaskPool *pool, Depsgraph *graph, OperationNode *node, bool dec_parents, const int thread_id)
+template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
+void schedule_node(DepsgraphEvalState *state,
+ OperationNode *node,
+ bool dec_parents,
+ const int thread_id,
+ ScheduleFunction *schedule_function,
+ ScheduleFunctionArgs... schedule_function_args)
{
/* No need to schedule nodes of invisible ID. */
if (!check_operation_node_visible(node)) {
@@ -181,41 +263,39 @@ static void schedule_node(
return;
}
/* During the COW stage only schedule COW nodes. */
- DepsgraphEvalState *state = (DepsgraphEvalState *)BLI_task_pool_userdata(pool);
- if (state->is_cow_stage) {
- if (node->owner->type != NodeType::COPY_ON_WRITE) {
- return;
- }
- }
- else {
- BLI_assert(node->scheduled || node->owner->type != NodeType::COPY_ON_WRITE);
+ if (!need_evaluate_operation_at_stage(state, node)) {
+ return;
}
/* Actually schedule the node. */
bool is_scheduled = atomic_fetch_and_or_uint8((uint8_t *)&node->scheduled, (uint8_t) true);
if (!is_scheduled) {
if (node->is_noop()) {
/* skip NOOP node, schedule children right away */
- schedule_children(pool, graph, node, thread_id);
+ schedule_children(state, node, thread_id, schedule_function, schedule_function_args...);
}
else {
/* children are scheduled once this task is completed */
- BLI_task_pool_push_from_thread(
- pool, deg_task_run_func, node, false, TASK_PRIORITY_HIGH, thread_id);
+ schedule_function(node, thread_id, schedule_function_args...);
}
}
}
-static void schedule_graph(TaskPool *pool, Depsgraph *graph)
+template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
+void schedule_graph(DepsgraphEvalState *state,
+ ScheduleFunction *schedule_function,
+ ScheduleFunctionArgs... schedule_function_args)
{
- for (OperationNode *node : graph->operations) {
- schedule_node(pool, graph, node, false, -1);
+ for (OperationNode *node : state->graph->operations) {
+ schedule_node(state, node, false, -1, schedule_function, schedule_function_args...);
}
}
-static void schedule_children(TaskPool *pool,
- Depsgraph *graph,
- OperationNode *node,
- const int thread_id)
+template<typename ScheduleFunction, typename... ScheduleFunctionArgs>
+void schedule_children(DepsgraphEvalState *state,
+ OperationNode *node,
+ const int thread_id,
+ ScheduleFunction *schedule_function,
+ ScheduleFunctionArgs... schedule_function_args)
{
for (Relation *rel : node->outlinks) {
OperationNode *child = (OperationNode *)rel->to;
@@ -224,11 +304,39 @@ static void schedule_children(TaskPool *pool,
/* Happens when having cyclic dependencies. */
continue;
}
- schedule_node(pool, graph, child, (rel->flag & RELATION_FLAG_CYCLIC) == 0, thread_id);
+ schedule_node(state,
+ child,
+ (rel->flag & RELATION_FLAG_CYCLIC) == 0,
+ thread_id,
+ schedule_function,
+ schedule_function_args...);
+ }
+}
+
+void schedule_node_to_queue(OperationNode *node,
+ const int /*thread_id*/,
+ GSQueue *evaluation_queue)
+{
+ BLI_gsqueue_push(evaluation_queue, &node);
+}
+
+void evaluate_graph_single_threaded(DepsgraphEvalState *state)
+{
+ GSQueue *evaluation_queue = BLI_gsqueue_new(sizeof(OperationNode *));
+ schedule_graph(state, schedule_node_to_queue, evaluation_queue);
+
+ while (!BLI_gsqueue_is_empty(evaluation_queue)) {
+ OperationNode *operation_node;
+ BLI_gsqueue_pop(evaluation_queue, &operation_node);
+
+ evaluate_node(state, operation_node);
+ schedule_children(state, operation_node, 0, schedule_node_to_queue, evaluation_queue);
}
+
+ BLI_gsqueue_free(evaluation_queue);
}
-static void depsgraph_ensure_view_layer(Depsgraph *graph)
+void depsgraph_ensure_view_layer(Depsgraph *graph)
{
/* We update copy-on-write scene in the following cases:
* - It was not expanded yet.
@@ -242,6 +350,8 @@ static void depsgraph_ensure_view_layer(Depsgraph *graph)
}
}
+} // namespace
+
/**
* Evaluate all nodes tagged for updating,
* \warning This is usually done as part of main loop, but may also be
@@ -255,14 +365,16 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
if (BLI_gset_len(graph->entry_tags) == 0) {
return;
}
- const bool do_time_debug = ((G.debug & G_DEBUG_DEPSGRAPH_TIME) != 0);
- const double start_time = do_time_debug ? PIL_check_seconds_timer() : 0;
+
+ graph->debug.begin_graph_evaluation();
+
graph->is_evaluating = true;
depsgraph_ensure_view_layer(graph);
/* Set up evaluation state. */
DepsgraphEvalState state;
state.graph = graph;
- state.do_stats = do_time_debug;
+ state.do_stats = graph->debug.do_time_debug();
+ state.need_single_thread_pass = false;
/* Set up task scheduler and pull for threaded evaluation. */
TaskScheduler *task_scheduler;
bool need_free_scheduler;
@@ -277,16 +389,25 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
/* Prepare all nodes for evaluation. */
initialize_execution(&state, graph);
+
/* Do actual evaluation now. */
+
/* First, process all Copy-On-Write nodes. */
- state.is_cow_stage = true;
- schedule_graph(task_pool, graph);
+ state.stage = EvaluationStage::COPY_ON_WRITE;
+ schedule_graph(&state, schedule_node_to_pool, task_pool);
BLI_task_pool_work_wait_and_reset(task_pool);
+
/* After that, process all other nodes. */
- state.is_cow_stage = false;
- schedule_graph(task_pool, graph);
+ state.stage = EvaluationStage::THREADED_EVALUATION;
+ schedule_graph(&state, schedule_node_to_pool, task_pool);
BLI_task_pool_work_and_wait(task_pool);
BLI_task_pool_free(task_pool);
+
+ if (state.need_single_thread_pass) {
+ state.stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
+ evaluate_graph_single_threaded(&state);
+ }
+
/* Finalize statistics gathering. This is because we only gather single
* operation timing here, without aggregating anything to avoid any extra
* synchronization. */
@@ -299,9 +420,8 @@ void deg_evaluate_on_refresh(Depsgraph *graph)
BLI_task_scheduler_free(task_scheduler);
}
graph->is_evaluating = false;
- if (do_time_debug) {
- printf("Depsgraph updated in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+
+ graph->debug.end_graph_evaluation();
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 3a2cf35f4d5..b74e5715e14 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -120,13 +120,13 @@ union NestedIDHackTempStorage {
World world;
};
-/* Set nested owned ID pointers to NULL. */
+/* Set nested owned ID pointers to nullptr. */
void nested_id_hack_discard_pointers(ID *id_cow)
{
switch (GS(id_cow->name)) {
# define SPECIAL_CASE(id_type, dna_type, field) \
case id_type: { \
- ((dna_type *)id_cow)->field = NULL; \
+ ((dna_type *)id_cow)->field = nullptr; \
break; \
}
@@ -144,9 +144,9 @@ void nested_id_hack_discard_pointers(ID *id_cow)
Scene *scene_cow = (Scene *)id_cow;
/* Node trees always have their own ID node in the graph, and are
* being copied as part of their copy-on-write process. */
- scene_cow->nodetree = NULL;
+ scene_cow->nodetree = nullptr;
/* Tool settings pointer is shared with the original scene. */
- scene_cow->toolsettings = NULL;
+ scene_cow->toolsettings = nullptr;
break;
}
@@ -154,7 +154,7 @@ void nested_id_hack_discard_pointers(ID *id_cow)
/* Clear the ParticleSettings pointer to prevent doubly-freeing it. */
Object *ob = (Object *)id_cow;
LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
- psys->part = NULL;
+ psys->part = nullptr;
}
break;
}
@@ -165,7 +165,7 @@ void nested_id_hack_discard_pointers(ID *id_cow)
}
}
-/* Set ID pointer of nested owned IDs (nodetree, key) to NULL.
+/* Set ID pointer of nested owned IDs (nodetree, key) to nullptr.
*
* Return pointer to a new ID to be used. */
const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage, const ID *id)
@@ -174,7 +174,7 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage
# define SPECIAL_CASE(id_type, dna_type, field, variable) \
case id_type: { \
storage->variable = *(dna_type *)id; \
- storage->variable.field = NULL; \
+ storage->variable.field = nullptr; \
return &storage->variable.id; \
}
@@ -190,8 +190,8 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage
case ID_SCE: {
storage->scene = *(Scene *)id;
- storage->scene.toolsettings = NULL;
- storage->scene.nodetree = NULL;
+ storage->scene.toolsettings = nullptr;
+ storage->scene.nodetree = nullptr;
return &storage->scene.id;
}
@@ -206,7 +206,7 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage
/* Set ID pointer of nested owned IDs (nodetree, key) to the original value. */
void nested_id_hack_restore_pointers(const ID *old_id, ID *new_id)
{
- if (new_id == NULL) {
+ if (new_id == nullptr) {
return;
}
switch (GS(old_id->name)) {
@@ -240,9 +240,9 @@ void ntree_hack_remap_pointers(const Depsgraph *depsgraph, ID *id_cow)
# define SPECIAL_CASE(id_type, dna_type, field, field_type) \
case id_type: { \
dna_type *data = (dna_type *)id_cow; \
- if (data->field != NULL) { \
+ if (data->field != nullptr) { \
ID *ntree_id_cow = depsgraph->get_cow_id(&data->field->id); \
- if (ntree_id_cow != NULL) { \
+ if (ntree_id_cow != nullptr) { \
DEG_COW_PRINT(" Remapping datablock for %s: id_orig=%p id_cow=%p\n", \
data->field->id.name, \
data->field, \
@@ -287,7 +287,7 @@ bool id_copy_inplace_no_main(const ID *id, ID *newid)
#endif
bool result = BKE_id_copy_ex(
- NULL, (ID *)id_for_copy, &newid, (LIB_ID_COPY_LOCALIZE | LIB_ID_CREATE_NO_ALLOCATE));
+ nullptr, (ID *)id_for_copy, &newid, (LIB_ID_COPY_LOCALIZE | LIB_ID_CREATE_NO_ALLOCATE));
#ifdef NESTED_ID_NASTY_WORKAROUND
if (result) {
@@ -310,7 +310,7 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
#endif
bool result = BKE_id_copy_ex(
- NULL, id_for_copy, (ID **)&new_scene, LIB_ID_COPY_LOCALIZE | LIB_ID_CREATE_NO_ALLOCATE);
+ nullptr, id_for_copy, (ID **)&new_scene, LIB_ID_COPY_LOCALIZE | LIB_ID_CREATE_NO_ALLOCATE);
#ifdef NESTED_ID_NASTY_WORKAROUND
if (result) {
@@ -339,7 +339,7 @@ ViewLayer *get_original_view_layer(const Depsgraph *depsgraph, const IDNode *id_
* properly fixed.
*
* TODO(sergey): Support indirectly linked scene. */
- return NULL;
+ return nullptr;
}
/* Remove all view layers but the one which corresponds to an input one. */
@@ -359,27 +359,27 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
* NOTE: Need to keep view layers for all scenes, even indirect ones. This is because of
* render layer node possibly pointing to another scene. */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene_cow->view_layers) {
- view_layer->basact = NULL;
+ view_layer->basact = nullptr;
}
return;
}
else if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
/* Indirectly linked scenes means it's not an input scene and not a set scene, and is pulled
* via some driver. Such scenes should not have view layers after copy. */
- view_layer_input = NULL;
+ view_layer_input = nullptr;
}
else {
view_layer_input = get_original_view_layer(depsgraph, id_node);
}
- ViewLayer *view_layer_eval = NULL;
+ ViewLayer *view_layer_eval = nullptr;
/* Find evaluated view layer. At the same time we free memory used by
* all other of the view layers. */
for (ViewLayer *view_layer_cow = reinterpret_cast<ViewLayer *>(scene_cow->view_layers.first),
*view_layer_next;
- view_layer_cow != NULL;
+ view_layer_cow != nullptr;
view_layer_cow = view_layer_next) {
view_layer_next = view_layer_cow->next;
- if (view_layer_input != NULL && STREQ(view_layer_input->name, view_layer_cow->name)) {
+ if (view_layer_input != nullptr && STREQ(view_layer_input->name, view_layer_cow->name)) {
view_layer_eval = view_layer_cow;
}
else {
@@ -387,8 +387,8 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
}
}
/* Make evaluated view layer the only one in the evaluated scene (if it exists). */
- if (view_layer_eval != NULL) {
- view_layer_eval->prev = view_layer_eval->next = NULL;
+ if (view_layer_eval != nullptr) {
+ view_layer_eval->prev = view_layer_eval->next = nullptr;
}
scene_cow->view_layers.first = view_layer_eval;
scene_cow->view_layers.last = view_layer_eval;
@@ -405,10 +405,10 @@ void scene_remove_all_bases(Scene *scene_cow)
* objects. */
void view_layer_remove_disabled_bases(const Depsgraph *depsgraph, ViewLayer *view_layer)
{
- if (view_layer == NULL) {
+ if (view_layer == nullptr) {
return;
}
- ListBase enabled_bases = {NULL, NULL};
+ ListBase enabled_bases = {nullptr, nullptr};
LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
/* TODO(sergey): Would be cool to optimize this somehow, or make it so
* builder tags bases.
@@ -427,7 +427,7 @@ void view_layer_remove_disabled_bases(const Depsgraph *depsgraph, ViewLayer *vie
}
else {
if (base == view_layer->basact) {
- view_layer->basact = NULL;
+ view_layer->basact = nullptr;
}
MEM_freeN(base);
}
@@ -438,7 +438,7 @@ void view_layer_remove_disabled_bases(const Depsgraph *depsgraph, ViewLayer *vie
void view_layer_update_orig_base_pointers(const ViewLayer *view_layer_orig,
ViewLayer *view_layer_eval)
{
- if (view_layer_orig == NULL || view_layer_eval == NULL) {
+ if (view_layer_orig == nullptr || view_layer_eval == nullptr) {
/* Happens when scene is only used for parameters or compositor/sequencer. */
return;
}
@@ -478,7 +478,7 @@ void update_sequence_orig_pointers(const ListBase *sequences_orig, ListBase *seq
{
Sequence *sequence_orig = reinterpret_cast<Sequence *>(sequences_orig->first);
Sequence *sequence_cow = reinterpret_cast<Sequence *>(sequences_cow->first);
- while (sequence_orig != NULL) {
+ while (sequence_orig != nullptr) {
update_sequence_orig_pointers(&sequence_orig->seqbase, &sequence_cow->seqbase);
sequence_cow->orig_sequence = sequence_orig;
sequence_cow = sequence_cow->next;
@@ -488,7 +488,7 @@ void update_sequence_orig_pointers(const ListBase *sequences_orig, ListBase *seq
void update_scene_orig_pointers(const Scene *scene_orig, Scene *scene_cow)
{
- if (scene_orig->ed != NULL) {
+ if (scene_orig->ed != nullptr) {
update_sequence_orig_pointers(&scene_orig->ed->seqbase, &scene_cow->ed->seqbase);
}
}
@@ -499,21 +499,6 @@ BLI_INLINE bool check_datablock_expanded(const ID *id_cow)
return (id_cow->name[0] != '\0');
}
-/* Those are data-blocks which are not covered by dependency graph and hence
- * does not need any remapping or anything.
- *
- * TODO(sergey): How to make it more robust for the future, so we don't have
- * to maintain exception lists all over the code? */
-bool check_datablocks_copy_on_writable(const ID *id_orig)
-{
- const ID_Type id_type = GS(id_orig->name);
- /* We shouldn't bother if copied ID is same as original one. */
- if (!deg_copy_on_write_is_needed(id_orig)) {
- return false;
- }
- return !ELEM(id_type, ID_BR, ID_LS, ID_PAL);
-}
-
/* Callback for BKE_library_foreach_ID_link which remaps original ID pointer
* with the one created by CoW system. */
@@ -530,13 +515,13 @@ struct RemapCallbackUserData {
int foreach_libblock_remap_callback(void *user_data_v, ID *id_self, ID **id_p, int /*cb_flag*/)
{
- if (*id_p == NULL) {
+ if (*id_p == nullptr) {
return IDWALK_RET_NOP;
}
RemapCallbackUserData *user_data = (RemapCallbackUserData *)user_data_v;
const Depsgraph *depsgraph = user_data->depsgraph;
ID *id_orig = *id_p;
- if (check_datablocks_copy_on_writable(id_orig)) {
+ if (deg_copy_on_write_is_needed(id_orig)) {
ID *id_cow;
if (user_data->create_placeholders) {
/* Special workaround to stop creating temp datablocks for
@@ -550,7 +535,7 @@ int foreach_libblock_remap_callback(void *user_data_v, ID *id_self, ID **id_p, i
const ID_Type id_type_self = GS(id_self->name);
if (id_type == ID_OB && id_type_self == ID_SCE) {
IDNode *id_node = depsgraph->find_id_node(id_orig);
- if (id_node == NULL) {
+ if (id_node == nullptr) {
id_cow = id_orig;
}
else {
@@ -564,7 +549,7 @@ int foreach_libblock_remap_callback(void *user_data_v, ID *id_self, ID **id_p, i
else {
id_cow = depsgraph->get_cow_id(id_orig);
}
- BLI_assert(id_cow != NULL);
+ BLI_assert(id_cow != nullptr);
DEG_COW_PRINT(
" Remapping datablock for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
*id_p = id_cow;
@@ -610,7 +595,7 @@ void update_lattice_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
lt_cow->editlatt = lt_orig->editlatt;
}
-void update_mesh_edit_mode_pointers(const Depsgraph *depsgraph, const ID *id_orig, ID *id_cow)
+void update_mesh_edit_mode_pointers(const ID *id_orig, ID *id_cow)
{
/* For meshes we need to update edit_mesh to make it to point
* to the CoW version of object.
@@ -620,13 +605,12 @@ void update_mesh_edit_mode_pointers(const Depsgraph *depsgraph, const ID *id_ori
* edit_mesh to object. */
const Mesh *mesh_orig = (const Mesh *)id_orig;
Mesh *mesh_cow = (Mesh *)id_cow;
- if (mesh_orig->edit_mesh == NULL) {
+ if (mesh_orig->edit_mesh == nullptr) {
return;
}
mesh_cow->edit_mesh = (BMEditMesh *)MEM_dupallocN(mesh_orig->edit_mesh);
- mesh_cow->edit_mesh->ob = (Object *)depsgraph->get_cow_id(&mesh_orig->edit_mesh->ob->id);
- mesh_cow->edit_mesh->mesh_eval_cage = NULL;
- mesh_cow->edit_mesh->mesh_eval_final = NULL;
+ mesh_cow->edit_mesh->mesh_eval_cage = nullptr;
+ mesh_cow->edit_mesh->mesh_eval_final = nullptr;
}
/* Edit data is stored and owned by original datablocks, copied ones
@@ -639,7 +623,7 @@ void update_edit_mode_pointers(const Depsgraph *depsgraph, const ID *id_orig, ID
update_armature_edit_mode_pointers(depsgraph, id_orig, id_cow);
break;
case ID_ME:
- update_mesh_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ update_mesh_edit_mode_pointers(id_orig, id_cow);
break;
case ID_CU:
update_curve_edit_mode_pointers(depsgraph, id_orig, id_cow);
@@ -662,7 +646,7 @@ void update_list_orig_pointers(const ListBase *listbase_orig,
{
T *element_orig = reinterpret_cast<T *>(listbase_orig->first);
T *element_cow = reinterpret_cast<T *>(listbase->first);
- while (element_orig != NULL) {
+ while (element_orig != nullptr) {
element_cow->*orig_field = element_orig;
element_cow = element_cow->next;
element_orig = element_orig->next;
@@ -695,9 +679,9 @@ void reset_particle_system_edit_eval(const Depsgraph *depsgraph, Object *object_
}
LISTBASE_FOREACH (ParticleSystem *, psys, &object_cow->particlesystem) {
ParticleSystem *orig_psys = psys->orig_psys;
- if (orig_psys->edit != NULL) {
- orig_psys->edit->psys_eval = NULL;
- orig_psys->edit->psmd_eval = NULL;
+ if (orig_psys->edit != nullptr) {
+ orig_psys->edit->psys_eval = nullptr;
+ orig_psys->edit->psmd_eval = nullptr;
}
}
}
@@ -726,7 +710,7 @@ void update_nla_strips_orig_pointers(const ListBase *strips_orig, ListBase *stri
{
NlaStrip *strip_orig = reinterpret_cast<NlaStrip *>(strips_orig->first);
NlaStrip *strip_cow = reinterpret_cast<NlaStrip *>(strips_cow->first);
- while (strip_orig != NULL) {
+ while (strip_orig != nullptr) {
strip_cow->orig_strip = strip_orig;
update_nla_strips_orig_pointers(&strip_orig->strips, &strip_cow->strips);
strip_cow = strip_cow->next;
@@ -738,7 +722,7 @@ void update_nla_tracks_orig_pointers(const ListBase *tracks_orig, ListBase *trac
{
NlaTrack *track_orig = reinterpret_cast<NlaTrack *>(tracks_orig->first);
NlaTrack *track_cow = reinterpret_cast<NlaTrack *>(tracks_cow->first);
- while (track_orig != NULL) {
+ while (track_orig != nullptr) {
update_nla_strips_orig_pointers(&track_orig->strips, &track_cow->strips);
track_cow = track_cow->next;
track_orig = track_orig->next;
@@ -748,29 +732,29 @@ void update_nla_tracks_orig_pointers(const ListBase *tracks_orig, ListBase *trac
void update_animation_data_after_copy(const ID *id_orig, ID *id_cow)
{
const AnimData *anim_data_orig = BKE_animdata_from_id(const_cast<ID *>(id_orig));
- if (anim_data_orig == NULL) {
+ if (anim_data_orig == nullptr) {
return;
}
AnimData *anim_data_cow = BKE_animdata_from_id(id_cow);
- BLI_assert(anim_data_cow != NULL);
+ BLI_assert(anim_data_cow != nullptr);
update_nla_tracks_orig_pointers(&anim_data_orig->nla_tracks, &anim_data_cow->nla_tracks);
}
/* Some builders (like motion path one) will ignore proxies from being built. This code makes it so
* proxy and proxy_group pointers never point to an original objects, preventing evaluation code
* from assign evaluated pointer to an original proxy->proxy_from. */
-void update_proxy_pointers_after_copy(const Depsgraph * /*depsgraph*/,
- const Object * /*object_orig*/,
+void update_proxy_pointers_after_copy(const Depsgraph *depsgraph,
+ const Object *object_orig,
Object *object_cow)
{
- if (object_cow->proxy != NULL) {
- if ((object_cow->proxy->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
- object_cow->proxy = NULL;
+ if (object_cow->proxy != nullptr) {
+ if (!deg_check_id_in_depsgraph(depsgraph, &object_orig->proxy->id)) {
+ object_cow->proxy = nullptr;
}
}
- if (object_cow->proxy_group != NULL) {
- if ((object_cow->proxy_group->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
- object_cow->proxy_group = NULL;
+ if (object_cow->proxy_group != nullptr) {
+ if (!deg_check_id_in_depsgraph(depsgraph, &object_orig->proxy_group->id)) {
+ object_cow->proxy_group = nullptr;
}
}
}
@@ -801,7 +785,7 @@ void update_id_after_copy(const Depsgraph *depsgraph,
const bArmature *armature_orig = (bArmature *)object_orig->data;
bArmature *armature_cow = (bArmature *)object_cow->data;
BKE_pose_remap_bone_pointers(armature_cow, object_cow->pose);
- if (armature_orig->edbo == NULL) {
+ if (armature_orig->edbo == nullptr) {
update_pose_orig_pointers(object_orig->pose, object_cow->pose);
}
BKE_pose_pchan_index_rebuild(object_cow->pose);
@@ -835,7 +819,7 @@ int foreach_libblock_validate_callback(void *user_data,
int /*cb_flag*/)
{
ValidateData *data = (ValidateData *)user_data;
- if (*id_p != NULL) {
+ if (*id_p != nullptr) {
if (!check_datablock_expanded(*id_p)) {
data->is_valid = false;
/* TODO(sergey): Store which is not valid? */
@@ -922,12 +906,12 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
* is not to be remapped again. */
deg_tag_copy_on_write_id(id_cow, id_orig);
/* Perform remapping of the nodes. */
- RemapCallbackUserData user_data = {NULL};
+ RemapCallbackUserData user_data = {nullptr};
user_data.depsgraph = depsgraph;
user_data.node_builder = node_builder;
user_data.create_placeholders = create_placeholders;
BKE_library_foreach_ID_link(
- NULL, id_cow, foreach_libblock_remap_callback, (void *)&user_data, IDWALK_NOP);
+ nullptr, id_cow, foreach_libblock_remap_callback, (void *)&user_data, IDWALK_NOP);
/* Correct or tweak some pointers which are not taken care by foreach
* from above. */
update_id_after_copy(depsgraph, id_node, id_orig, id_cow);
@@ -942,7 +926,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
bool create_placeholders)
{
DEG::IDNode *id_node = depsgraph->find_id_node(id_orig);
- BLI_assert(id_node != NULL);
+ BLI_assert(id_node != nullptr);
return deg_expand_copy_on_write_datablock(depsgraph, id_node, node_builder, create_placeholders);
}
@@ -966,7 +950,7 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode
ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, ID *id_orig)
{
DEG::IDNode *id_node = depsgraph->find_id_node(id_orig);
- BLI_assert(id_node != NULL);
+ BLI_assert(id_node != nullptr);
return deg_update_copy_on_write_datablock(depsgraph, id_node);
}
@@ -975,47 +959,47 @@ namespace {
void discard_armature_edit_mode_pointers(ID *id_cow)
{
bArmature *armature_cow = (bArmature *)id_cow;
- armature_cow->edbo = NULL;
+ armature_cow->edbo = nullptr;
}
void discard_curve_edit_mode_pointers(ID *id_cow)
{
Curve *curve_cow = (Curve *)id_cow;
- curve_cow->editnurb = NULL;
- curve_cow->editfont = NULL;
+ curve_cow->editnurb = nullptr;
+ curve_cow->editfont = nullptr;
}
void discard_mball_edit_mode_pointers(ID *id_cow)
{
MetaBall *mball_cow = (MetaBall *)id_cow;
- mball_cow->editelems = NULL;
+ mball_cow->editelems = nullptr;
}
void discard_lattice_edit_mode_pointers(ID *id_cow)
{
Lattice *lt_cow = (Lattice *)id_cow;
- lt_cow->editlatt = NULL;
+ lt_cow->editlatt = nullptr;
}
void discard_mesh_edit_mode_pointers(ID *id_cow)
{
Mesh *mesh_cow = (Mesh *)id_cow;
- if (mesh_cow->edit_mesh == NULL) {
+ if (mesh_cow->edit_mesh == nullptr) {
return;
}
BKE_editmesh_free_derivedmesh(mesh_cow->edit_mesh);
MEM_freeN(mesh_cow->edit_mesh);
- mesh_cow->edit_mesh = NULL;
+ mesh_cow->edit_mesh = nullptr;
}
void discard_scene_pointers(ID *id_cow)
{
Scene *scene_cow = (Scene *)id_cow;
- scene_cow->toolsettings = NULL;
- scene_cow->eevee.light_cache = NULL;
+ scene_cow->toolsettings = nullptr;
+ scene_cow->eevee.light_cache = nullptr;
}
-/* NULL-ify all edit mode pointers which points to data from
+/* nullptr-ify all edit mode pointers which points to data from
* original object. */
void discard_edit_mode_pointers(ID *id_cow)
{
@@ -1069,8 +1053,8 @@ void deg_free_copy_on_write_datablock(ID *id_cow)
* caches from modifying object->data. This is currently happening
* due to mesh/curve datablock boundbox tagging dirty. */
Object *ob_cow = (Object *)id_cow;
- ob_cow->data = NULL;
- ob_cow->sculpt = NULL;
+ ob_cow->data = nullptr;
+ ob_cow->sculpt = nullptr;
break;
}
default:
@@ -1097,12 +1081,13 @@ void deg_evaluate_copy_on_write(struct ::Depsgraph *graph, const IDNode *id_node
bool deg_validate_copy_on_write_datablock(ID *id_cow)
{
- if (id_cow == NULL) {
+ if (id_cow == nullptr) {
return false;
}
ValidateData data;
data.is_valid = true;
- BKE_library_foreach_ID_link(NULL, id_cow, foreach_libblock_validate_callback, &data, IDWALK_NOP);
+ BKE_library_foreach_ID_link(
+ nullptr, id_cow, foreach_libblock_validate_callback, &data, IDWALK_NOP);
return data.is_valid;
}
@@ -1124,7 +1109,7 @@ bool deg_copy_on_write_is_expanded(const ID *id_cow)
bool deg_copy_on_write_is_needed(const ID *id_orig)
{
const ID_Type id_type = GS(id_orig->name);
- return !ELEM(id_type, ID_IM);
+ return ID_TYPE_IS_COW(id_type);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
index 2f83c2f54b9..1992c80e036 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.h
@@ -52,11 +52,11 @@ struct IDNode;
*/
ID *deg_expand_copy_on_write_datablock(const struct Depsgraph *depsgraph,
const IDNode *id_node,
- DepsgraphNodeBuilder *node_builder = NULL,
+ DepsgraphNodeBuilder *node_builder = nullptr,
bool create_placeholders = false);
ID *deg_expand_copy_on_write_datablock(const struct Depsgraph *depsgraph,
struct ID *id_orig,
- DepsgraphNodeBuilder *node_builder = NULL,
+ DepsgraphNodeBuilder *node_builder = nullptr,
bool create_placeholders = false);
/* Makes sure given CoW data-block is brought back to state of the original
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 96e2974a7ab..d99f6cccc69 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -49,6 +49,7 @@ extern "C" {
#include "intern/debug/deg_debug.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
#include "intern/depsgraph_update.h"
#include "intern/node/deg_node.h"
#include "intern/node/deg_node_component.h"
@@ -156,7 +157,7 @@ BLI_INLINE void flush_handle_component_node(IDNode *id_node,
* whole IK solver, otherwise result might be unpredictable. */
if (comp_node->type == NodeType::BONE) {
ComponentNode *pose_comp = id_node->find_component(NodeType::EVAL_POSE);
- BLI_assert(pose_comp != NULL);
+ BLI_assert(pose_comp != nullptr);
if (pose_comp->custom_flags == COMPONENT_STATE_NONE) {
queue->push_front(pose_comp->get_entry_operation());
pose_comp->custom_flags = COMPONENT_STATE_SCHEDULED;
@@ -172,7 +173,7 @@ BLI_INLINE void flush_handle_component_node(IDNode *id_node,
*/
BLI_INLINE OperationNode *flush_schedule_children(OperationNode *op_node, FlushQueue *queue)
{
- OperationNode *result = NULL;
+ OperationNode *result = nullptr;
for (Relation *rel : op_node->outlinks) {
/* Flush is forbidden, completely. */
if (rel->flag & RELATION_FLAG_NO_FLUSH) {
@@ -196,7 +197,7 @@ BLI_INLINE OperationNode *flush_schedule_children(OperationNode *op_node, FlushQ
if (to_node->scheduled) {
continue;
}
- if (result != NULL) {
+ if (result != nullptr) {
queue->push_front(to_node);
}
else {
@@ -210,7 +211,7 @@ BLI_INLINE OperationNode *flush_schedule_children(OperationNode *op_node, FlushQ
void flush_engine_data_update(ID *id)
{
DrawDataList *draw_data_list = DRW_drawdatalist_from_id(id);
- if (draw_data_list == NULL) {
+ if (draw_data_list == nullptr) {
return;
}
LISTBASE_FOREACH (DrawData *, draw_data, draw_data_list) {
@@ -235,7 +236,7 @@ void flush_editors_id_update(Depsgraph *graph, const DEGEditorUpdateContext *upd
continue;
}
DepsNodeFactory *factory = type_get_factory(comp_node->type);
- BLI_assert(factory != NULL);
+ BLI_assert(factory != nullptr);
id_cow->recalc |= factory->id_recalc_tag();
}
GHASH_FOREACH_END();
@@ -336,8 +337,8 @@ void invalidate_tagged_evaluated_data(Depsgraph *graph)
void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
{
/* Sanity checks. */
- BLI_assert(bmain != NULL);
- BLI_assert(graph != NULL);
+ BLI_assert(bmain != nullptr);
+ BLI_assert(graph != nullptr);
/* Nothing to update, early out. */
if (graph->need_update_time) {
const Scene *scene_orig = graph->scene;
@@ -364,7 +365,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
while (!queue.empty()) {
OperationNode *op_node = queue.front();
queue.pop_front();
- while (op_node != NULL) {
+ while (op_node != nullptr) {
/* Tag operation as required for update. */
op_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
/* Inform corresponding ID and component nodes about the change. */
@@ -392,7 +393,7 @@ void deg_graph_clear_tags(Depsgraph *graph)
DEPSOP_FLAG_USER_MODIFIED);
}
/* Clear any entry tags which haven't been flushed. */
- BLI_gset_clear(graph->entry_tags, NULL);
+ BLI_gset_clear(graph->entry_tags, nullptr);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
index 88390ab412f..40a17666880 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
@@ -32,13 +32,14 @@
namespace DEG {
RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
- : scene_backup(depsgraph),
+ : animation_backup(depsgraph),
+ scene_backup(depsgraph),
sound_backup(depsgraph),
object_backup(depsgraph),
- drawdata_ptr(NULL),
+ drawdata_ptr(nullptr),
movieclip_backup(depsgraph)
{
- drawdata_backup.first = drawdata_backup.last = NULL;
+ drawdata_backup.first = drawdata_backup.last = nullptr;
}
void RuntimeBackup::init_from_id(ID *id)
@@ -47,6 +48,8 @@ void RuntimeBackup::init_from_id(ID *id)
return;
}
+ animation_backup.init_from_id(id);
+
const ID_Type id_type = GS(id->name);
switch (id_type) {
case ID_OB:
@@ -68,14 +71,16 @@ void RuntimeBackup::init_from_id(ID *id)
/* Note that we never free GPU draw data from here since that's not
* safe for threading and draw data is likely to be re-used. */
drawdata_ptr = DRW_drawdatalist_from_id(id);
- if (drawdata_ptr != NULL) {
+ if (drawdata_ptr != nullptr) {
drawdata_backup = *drawdata_ptr;
- drawdata_ptr->first = drawdata_ptr->last = NULL;
+ drawdata_ptr->first = drawdata_ptr->last = nullptr;
}
}
void RuntimeBackup::restore_to_id(ID *id)
{
+ animation_backup.restore_to_id(id);
+
const ID_Type id_type = GS(id->name);
switch (id_type) {
case ID_OB:
@@ -93,7 +98,7 @@ void RuntimeBackup::restore_to_id(ID *id)
default:
break;
}
- if (drawdata_ptr != NULL) {
+ if (drawdata_ptr != nullptr) {
*drawdata_ptr = drawdata_backup;
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
index 31ae3164e37..cc8c6ae0d5b 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
@@ -25,6 +25,7 @@
#include "DNA_ID.h"
+#include "intern/eval/deg_eval_runtime_backup_animation.h"
#include "intern/eval/deg_eval_runtime_backup_movieclip.h"
#include "intern/eval/deg_eval_runtime_backup_object.h"
#include "intern/eval/deg_eval_runtime_backup_scene.h"
@@ -38,12 +39,13 @@ class RuntimeBackup {
public:
explicit RuntimeBackup(const Depsgraph *depsgraph);
- /* NOTE: Will reset all runtime fields which has been backed up to NULL. */
+ /* NOTE: Will reset all runtime fields which has been backed up to nullptr. */
void init_from_id(ID *id);
/* Restore fields to the given ID. */
void restore_to_id(ID *id);
+ AnimationBackup animation_backup;
SceneBackup scene_backup;
SoundBackup sound_backup;
ObjectRuntimeBackup object_backup;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc
new file mode 100644
index 00000000000..e3beeb52ab1
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.cc
@@ -0,0 +1,144 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_animation.h"
+
+#include "DNA_anim_types.h"
+
+#include "BKE_animsys.h"
+
+#include "RNA_access.h"
+#include "RNA_types.h"
+
+#include "intern/depsgraph.h"
+
+namespace DEG {
+
+namespace {
+
+struct AnimatedPropertyStoreCalbackData {
+ AnimationBackup *backup;
+
+ /* ID which needs to be stored.
+ * Is used to check possibly nested IDs which f-curves are pointing to. */
+ ID *id;
+
+ PointerRNA id_pointer_rna;
+};
+
+void animated_property_store_cb(ID *id, FCurve *fcurve, void *data_v)
+{
+ AnimatedPropertyStoreCalbackData *data = reinterpret_cast<AnimatedPropertyStoreCalbackData *>(
+ data_v);
+ if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') {
+ return;
+ }
+ if (id != data->id) {
+ return;
+ }
+
+ /* Resolve path to the property. */
+ PathResolvedRNA resolved_rna;
+ if (!BKE_animsys_store_rna_setting(
+ &data->id_pointer_rna, fcurve->rna_path, fcurve->array_index, &resolved_rna)) {
+ return;
+ }
+
+ /* Read property value. */
+ float value;
+ if (!BKE_animsys_read_rna_setting(&resolved_rna, &value)) {
+ return;
+ }
+
+ data->backup->values_backup.emplace_back(fcurve->rna_path, fcurve->array_index, value);
+}
+
+} // namespace
+
+AnimationValueBackup::AnimationValueBackup()
+{
+}
+
+AnimationValueBackup::AnimationValueBackup(const string &rna_path, int array_index, float value)
+ : rna_path(rna_path), array_index(array_index), value(value)
+{
+}
+
+AnimationValueBackup::~AnimationValueBackup()
+{
+}
+
+AnimationBackup::AnimationBackup(const Depsgraph *depsgraph)
+{
+ meed_value_backup = !depsgraph->is_active;
+ reset();
+}
+
+void AnimationBackup::reset()
+{
+}
+
+void AnimationBackup::init_from_id(ID *id)
+{
+ /* NOTE: This animation backup nicely preserves values which are animated and
+ * are not touched by frame/depsgraph post_update handler.
+ *
+ * But it makes it impossible to have user edits to animated properties: for
+ * example, translation of object with animated location will not work with
+ * the current version of backup. */
+ return;
+
+ AnimatedPropertyStoreCalbackData data;
+ data.backup = this;
+ data.id = id;
+ RNA_id_pointer_create(id, &data.id_pointer_rna);
+ BKE_fcurves_id_cb(id, animated_property_store_cb, &data);
+}
+
+void AnimationBackup::restore_to_id(ID *id)
+{
+ return;
+
+ PointerRNA id_pointer_rna;
+ RNA_id_pointer_create(id, &id_pointer_rna);
+ for (const AnimationValueBackup &value_backup : values_backup) {
+ /* Resolve path to the property.
+ *
+ * NOTE: Do it again (after storing), since the sub-data pointers might be
+ * changed after copy-on-write. */
+ PathResolvedRNA resolved_rna;
+ if (!BKE_animsys_store_rna_setting(&id_pointer_rna,
+ value_backup.rna_path.c_str(),
+ value_backup.array_index,
+ &resolved_rna)) {
+ return;
+ }
+
+ /* Write property value. */
+ if (!BKE_animsys_write_rna_setting(&resolved_rna, value_backup.value)) {
+ return;
+ }
+ }
+}
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h
new file mode 100644
index 00000000000..d97ee2b0556
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_animation.h
@@ -0,0 +1,65 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "BKE_modifier.h"
+
+#include "intern/depsgraph_type.h"
+
+namespace DEG {
+
+struct Depsgraph;
+
+class AnimationValueBackup {
+ public:
+ AnimationValueBackup();
+ AnimationValueBackup(const string &rna_path, int array_index, float value);
+ ~AnimationValueBackup();
+
+ AnimationValueBackup(const AnimationValueBackup &other) = default;
+ AnimationValueBackup(AnimationValueBackup &&other) noexcept = default;
+
+ AnimationValueBackup &operator=(const AnimationValueBackup &other) = default;
+ AnimationValueBackup &operator=(AnimationValueBackup &&other) = default;
+
+ string rna_path;
+ int array_index;
+ float value;
+};
+
+/* Backup of animated properties values. */
+class AnimationBackup {
+ public:
+ AnimationBackup(const Depsgraph *depsgraph);
+
+ void reset();
+
+ void init_from_id(ID *id);
+ void restore_to_id(ID *id);
+
+ bool meed_value_backup;
+ vector<AnimationValueBackup> values_backup;
+};
+
+} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
index c5744533083..3361c26a077 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
@@ -26,7 +26,7 @@
namespace DEG {
ModifierDataBackupID::ModifierDataBackupID(const Depsgraph * /*depsgraph*/)
- : ModifierDataBackupID(NULL, eModifierType_None)
+ : ModifierDataBackupID(nullptr, eModifierType_None)
{
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc
index 54838475bbf..d552c8da99a 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_movieclip.cc
@@ -36,8 +36,8 @@ MovieClipBackup::MovieClipBackup(const Depsgraph * /*depsgraph*/)
void MovieClipBackup::reset()
{
- anim = NULL;
- cache = NULL;
+ anim = nullptr;
+ cache = nullptr;
}
void MovieClipBackup::init_from_movieclip(MovieClip *movieclip)
@@ -46,8 +46,8 @@ void MovieClipBackup::init_from_movieclip(MovieClip *movieclip)
cache = movieclip->cache;
/* Clear pointers stored in the movie clip, so they are not freed when copied-on-written
* datablock is freed for re-allocation. */
- movieclip->anim = NULL;
- movieclip->cache = NULL;
+ movieclip->anim = nullptr;
+ movieclip->cache = nullptr;
}
void MovieClipBackup::restore_to_movieclip(MovieClip *movieclip)
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
index a6a042f3e7b..df7338e1076 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
@@ -52,7 +52,7 @@ void ObjectRuntimeBackup::init_from_object(Object *object)
/* Object update will override actual object->data to an evaluated version.
* Need to make sure we don't have data set to evaluated one before free
* anything. */
- if (mesh_eval != NULL && object->data == mesh_eval) {
+ if (mesh_eval != nullptr && object->data == mesh_eval) {
object->data = runtime.mesh_orig;
}
/* Make a backup of base flags. */
@@ -73,22 +73,22 @@ inline ModifierDataBackupID create_modifier_data_id(const ModifierData *modifier
void ObjectRuntimeBackup::backup_modifier_runtime_data(Object *object)
{
LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
- if (modifier_data->runtime == NULL) {
+ if (modifier_data->runtime == nullptr) {
continue;
}
- BLI_assert(modifier_data->orig_modifier_data != NULL);
+ BLI_assert(modifier_data->orig_modifier_data != nullptr);
ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
modifier_runtime_data.insert(make_pair(modifier_data_id, modifier_data->runtime));
- modifier_data->runtime = NULL;
+ modifier_data->runtime = nullptr;
}
}
void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
{
- if (object->pose != NULL) {
+ if (object->pose != nullptr) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- /* This is NULL in Edit mode. */
- if (pchan->orig_pchan != NULL) {
+ /* This is nullptr in Edit mode. */
+ if (pchan->orig_pchan != nullptr) {
pose_channel_runtime_data[pchan->orig_pchan] = pchan->runtime;
BKE_pose_channel_runtime_reset(&pchan->runtime);
}
@@ -103,7 +103,7 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
object->runtime = runtime;
object->runtime.mesh_orig = mesh_orig;
object->runtime.bb = bb;
- if (object->type == OB_MESH && object->runtime.mesh_eval != NULL) {
+ if (object->type == OB_MESH && object->runtime.mesh_eval != nullptr) {
if (object->id.recalc & ID_RECALC_GEOMETRY) {
/* If geometry is tagged for update it means, that part of
* evaluated mesh are not valid anymore. In this case we can not
@@ -138,33 +138,33 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
void ObjectRuntimeBackup::restore_modifier_runtime_data(Object *object)
{
LISTBASE_FOREACH (ModifierData *, modifier_data, &object->modifiers) {
- BLI_assert(modifier_data->orig_modifier_data != NULL);
+ BLI_assert(modifier_data->orig_modifier_data != nullptr);
ModifierDataBackupID modifier_data_id = create_modifier_data_id(modifier_data);
ModifierRuntimeDataBackup::iterator runtime_data_iterator = modifier_runtime_data.find(
modifier_data_id);
if (runtime_data_iterator != modifier_runtime_data.end()) {
modifier_data->runtime = runtime_data_iterator->second;
- runtime_data_iterator->second = NULL;
+ runtime_data_iterator->second = nullptr;
}
}
for (ModifierRuntimeDataBackup::value_type value : modifier_runtime_data) {
const ModifierDataBackupID modifier_data_id = value.first;
void *runtime = value.second;
- if (value.second == NULL) {
+ if (value.second == nullptr) {
continue;
}
const ModifierTypeInfo *modifier_type_info = modifierType_getInfo(modifier_data_id.type);
- BLI_assert(modifier_type_info != NULL);
+ BLI_assert(modifier_type_info != nullptr);
modifier_type_info->freeRuntimeData(runtime);
}
}
void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
{
- if (object->pose != NULL) {
+ if (object->pose != nullptr) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- /* This is NULL in Edit mode. */
- if (pchan->orig_pchan != NULL) {
+ /* This is nullptr in Edit mode. */
+ if (pchan->orig_pchan != nullptr) {
PoseChannelRuntimeDataBackup::iterator runtime_data_iterator =
pose_channel_runtime_data.find(pchan->orig_pchan);
if (runtime_data_iterator != pose_channel_runtime_data.end()) {
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
index a288fb6ab92..a1d6961cf5d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_scene.cc
@@ -35,10 +35,10 @@ SceneBackup::SceneBackup(const Depsgraph *depsgraph) : sequencer_backup(depsgrap
void SceneBackup::reset()
{
- sound_scene = NULL;
- playback_handle = NULL;
- sound_scrub_handle = NULL;
- speaker_handles = NULL;
+ sound_scene = nullptr;
+ playback_handle = nullptr;
+ sound_scrub_handle = nullptr;
+ speaker_handles = nullptr;
rigidbody_last_time = -1;
}
@@ -49,16 +49,16 @@ void SceneBackup::init_from_scene(Scene *scene)
sound_scrub_handle = scene->sound_scrub_handle;
speaker_handles = scene->speaker_handles;
- if (scene->rigidbody_world != NULL) {
+ if (scene->rigidbody_world != nullptr) {
rigidbody_last_time = scene->rigidbody_world->ltime;
}
/* Clear pointers stored in the scene, so they are not freed when copied-on-written datablock
* is freed for re-allocation. */
- scene->sound_scene = NULL;
- scene->playback_handle = NULL;
- scene->sound_scrub_handle = NULL;
- scene->speaker_handles = NULL;
+ scene->sound_scene = nullptr;
+ scene->playback_handle = nullptr;
+ scene->sound_scrub_handle = nullptr;
+ scene->speaker_handles = nullptr;
sequencer_backup.init_from_scene(scene);
}
@@ -70,7 +70,7 @@ void SceneBackup::restore_to_scene(Scene *scene)
scene->sound_scrub_handle = sound_scrub_handle;
scene->speaker_handles = speaker_handles;
- if (scene->rigidbody_world != NULL) {
+ if (scene->rigidbody_world != nullptr) {
scene->rigidbody_world->ltime = rigidbody_last_time;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc
index 0150281a4ef..f26d78d3138 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequence.cc
@@ -34,14 +34,14 @@ SequenceBackup::SequenceBackup(const Depsgraph * /*depsgraph*/)
void SequenceBackup::reset()
{
- scene_sound = NULL;
+ scene_sound = nullptr;
}
void SequenceBackup::init_from_sequence(Sequence *sequence)
{
scene_sound = sequence->scene_sound;
- sequence->scene_sound = NULL;
+ sequence->scene_sound = nullptr;
}
void SequenceBackup::restore_to_sequence(Sequence *sequence)
@@ -52,7 +52,7 @@ void SequenceBackup::restore_to_sequence(Sequence *sequence)
bool SequenceBackup::isEmpty() const
{
- return (scene_sound == NULL);
+ return (scene_sound == nullptr);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
index 08c2697aab3..adc7fd570e8 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
@@ -63,7 +63,7 @@ void SequencerBackup::restore_to_scene(Scene *scene)
/* Cleanup audio while the scene is still known. */
for (SequencesBackupMap::value_type &it : sequences_backup) {
SequenceBackup &sequence_backup = it.second;
- if (sequence_backup.scene_sound != NULL) {
+ if (sequence_backup.scene_sound != nullptr) {
BKE_sound_remove_scene_sound(scene, sequence_backup.scene_sound);
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc
index 0c54032e32c..f427d57a8ef 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sound.cc
@@ -36,9 +36,9 @@ SoundBackup::SoundBackup(const Depsgraph * /*depsgraph*/)
void SoundBackup::reset()
{
- cache = NULL;
- waveform = NULL;
- playback_handle = NULL;
+ cache = nullptr;
+ waveform = nullptr;
+ playback_handle = nullptr;
}
void SoundBackup::init_from_sound(bSound *sound)
@@ -47,9 +47,9 @@ void SoundBackup::init_from_sound(bSound *sound)
waveform = sound->waveform;
playback_handle = sound->playback_handle;
- sound->cache = NULL;
- sound->waveform = NULL;
- sound->playback_handle = NULL;
+ sound->cache = nullptr;
+ sound->waveform = nullptr;
+ sound->playback_handle = nullptr;
}
void SoundBackup::restore_to_sound(bSound *sound)
diff --git a/source/blender/depsgraph/intern/node/deg_node.cc b/source/blender/depsgraph/intern/node/deg_node.cc
index 16c934e72fe..5002f2890ae 100644
--- a/source/blender/depsgraph/intern/node/deg_node.cc
+++ b/source/blender/depsgraph/intern/node/deg_node.cc
@@ -28,6 +28,7 @@
#include "BLI_utildefines.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
#include "intern/eval/deg_eval_copy_on_write.h"
#include "intern/node/deg_node_component.h"
#include "intern/node/deg_node_factory.h"
diff --git a/source/blender/depsgraph/intern/node/deg_node.h b/source/blender/depsgraph/intern/node/deg_node.h
index acfc8d19bc7..3878362d936 100644
--- a/source/blender/depsgraph/intern/node/deg_node.h
+++ b/source/blender/depsgraph/intern/node/deg_node.h
@@ -191,11 +191,11 @@ struct Node {
virtual OperationNode *get_entry_operation()
{
- return NULL;
+ return nullptr;
}
virtual OperationNode *get_exit_operation()
{
- return NULL;
+ return nullptr;
}
virtual NodeClass get_class() const;
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index 830c53cfc76..334f55c0942 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -104,7 +104,7 @@ static void comp_node_hash_value_free(void *value_v)
}
ComponentNode::ComponentNode()
- : entry_operation(NULL), exit_operation(NULL), affects_directly_visible(false)
+ : entry_operation(nullptr), exit_operation(nullptr), affects_directly_visible(false)
{
operations_map = BLI_ghash_new(comp_node_hash_key, comp_node_hash_key_cmp, "Depsgraph id hash");
}
@@ -120,7 +120,7 @@ void ComponentNode::init(const ID * /*id*/, const char * /*subdata*/)
ComponentNode::~ComponentNode()
{
clear_operations();
- if (operations_map != NULL) {
+ if (operations_map != nullptr) {
BLI_ghash_free(operations_map, comp_node_hash_key_free, comp_node_hash_value_free);
}
}
@@ -135,8 +135,8 @@ string ComponentNode::identifier() const
OperationNode *ComponentNode::find_operation(OperationIDKey key) const
{
- OperationNode *node = NULL;
- if (operations_map != NULL) {
+ OperationNode *node = nullptr;
+ if (operations_map != nullptr) {
node = (OperationNode *)BLI_ghash_lookup(operations_map, &key);
}
else {
@@ -162,13 +162,13 @@ OperationNode *ComponentNode::find_operation(OperationCode opcode,
OperationNode *ComponentNode::get_operation(OperationIDKey key) const
{
OperationNode *node = find_operation(key);
- if (node == NULL) {
+ if (node == nullptr) {
fprintf(stderr,
"%s: find_operation(%s) failed\n",
this->identifier().c_str(),
key.identifier().c_str());
BLI_assert(!"Request for non-existing operation, should not happen");
- return NULL;
+ return nullptr;
}
return node;
}
@@ -183,7 +183,7 @@ OperationNode *ComponentNode::get_operation(OperationCode opcode,
bool ComponentNode::has_operation(OperationIDKey key) const
{
- return find_operation(key) != NULL;
+ return find_operation(key) != nullptr;
}
bool ComponentNode::has_operation(OperationCode opcode, const char *name, int name_tag) const
@@ -229,19 +229,19 @@ OperationNode *ComponentNode::add_operation(const DepsEvalOperationCb &op,
void ComponentNode::set_entry_operation(OperationNode *op_node)
{
- BLI_assert(entry_operation == NULL);
+ BLI_assert(entry_operation == nullptr);
entry_operation = op_node;
}
void ComponentNode::set_exit_operation(OperationNode *op_node)
{
- BLI_assert(exit_operation == NULL);
+ BLI_assert(exit_operation == nullptr);
exit_operation = op_node;
}
void ComponentNode::clear_operations()
{
- if (operations_map != NULL) {
+ if (operations_map != nullptr) {
BLI_ghash_clear(operations_map, comp_node_hash_key_free, comp_node_hash_value_free);
}
for (OperationNode *op_node : operations) {
@@ -253,14 +253,14 @@ void ComponentNode::clear_operations()
void ComponentNode::tag_update(Depsgraph *graph, eUpdateSource source)
{
OperationNode *entry_op = get_entry_operation();
- if (entry_op != NULL && entry_op->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
+ if (entry_op != nullptr && entry_op->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
return;
}
for (OperationNode *op_node : operations) {
op_node->tag_update(graph, source);
}
// It is possible that tag happens before finalization.
- if (operations_map != NULL) {
+ if (operations_map != nullptr) {
GHASH_FOREACH_BEGIN (OperationNode *, op_node, operations_map) {
op_node->tag_update(graph, source);
}
@@ -273,8 +273,8 @@ OperationNode *ComponentNode::get_entry_operation()
if (entry_operation) {
return entry_operation;
}
- else if (operations_map != NULL && BLI_ghash_len(operations_map) == 1) {
- OperationNode *op_node = NULL;
+ else if (operations_map != nullptr && BLI_ghash_len(operations_map) == 1) {
+ OperationNode *op_node = nullptr;
/* TODO(sergey): This is somewhat slow. */
GHASH_FOREACH_BEGIN (OperationNode *, tmp, operations_map) {
op_node = tmp;
@@ -287,7 +287,7 @@ OperationNode *ComponentNode::get_entry_operation()
else if (operations.size() == 1) {
return operations[0];
}
- return NULL;
+ return nullptr;
}
OperationNode *ComponentNode::get_exit_operation()
@@ -295,8 +295,8 @@ OperationNode *ComponentNode::get_exit_operation()
if (exit_operation) {
return exit_operation;
}
- else if (operations_map != NULL && BLI_ghash_len(operations_map) == 1) {
- OperationNode *op_node = NULL;
+ else if (operations_map != nullptr && BLI_ghash_len(operations_map) == 1) {
+ OperationNode *op_node = nullptr;
/* TODO(sergey): This is somewhat slow. */
GHASH_FOREACH_BEGIN (OperationNode *, tmp, operations_map) {
op_node = tmp;
@@ -309,7 +309,7 @@ OperationNode *ComponentNode::get_exit_operation()
else if (operations.size() == 1) {
return operations[0];
}
- return NULL;
+ return nullptr;
}
void ComponentNode::finalize_build(Depsgraph * /*graph*/)
@@ -319,8 +319,8 @@ void ComponentNode::finalize_build(Depsgraph * /*graph*/)
operations.push_back(op_node);
}
GHASH_FOREACH_END();
- BLI_ghash_free(operations_map, comp_node_hash_key_free, NULL);
- operations_map = NULL;
+ BLI_ghash_free(operations_map, comp_node_hash_key_free, nullptr);
+ operations_map = nullptr;
}
/* Bone Component ========================================= */
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h
index 53fbc6e617c..c25f0bbd7aa 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.h
+++ b/source/blender/depsgraph/intern/node/deg_node_component.h
@@ -65,7 +65,7 @@ struct ComponentNode : public Node {
virtual string identifier() const override;
/* Find an existing operation, if requested operation does not exist
- * NULL will be returned. */
+ * nullptr will be returned. */
OperationNode *find_operation(OperationIDKey key) const;
OperationNode *find_operation(OperationCode opcode, const char *name, int name_tag) const;
diff --git a/source/blender/depsgraph/intern/node/deg_node_factory.cc b/source/blender/depsgraph/intern/node/deg_node_factory.cc
index 4a11ed2a4fb..9dfd018b4fd 100644
--- a/source/blender/depsgraph/intern/node/deg_node_factory.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_factory.cc
@@ -26,11 +26,11 @@
namespace DEG {
/* Global type registry */
-static DepsNodeFactory *node_typeinfo_registry[static_cast<int>(NodeType::NUM_TYPES)] = {NULL};
+static DepsNodeFactory *node_typeinfo_registry[static_cast<int>(NodeType::NUM_TYPES)] = {nullptr};
void register_node_typeinfo(DepsNodeFactory *factory)
{
- BLI_assert(factory != NULL);
+ BLI_assert(factory != nullptr);
const int type_as_int = static_cast<int>(factory->type());
node_typeinfo_registry[type_as_int] = factory;
}
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index e14513a1aa2..853198109a2 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -101,7 +101,7 @@ static void id_deps_node_hash_value_free(void *value_v)
/* Initialize 'id' node - from pointer data given. */
void IDNode::init(const ID *id, const char *UNUSED(subdata))
{
- BLI_assert(id != NULL);
+ BLI_assert(id != nullptr);
/* Store ID-pointer. */
id_orig = (ID *)id;
eval_flags = 0;
@@ -126,7 +126,7 @@ void IDNode::init_copy_on_write(ID *id_cow_hint)
/* Create pointer as early as possible, so we can use it for function
* bindings. Rest of data we'll be copying to the new datablock when
* it is actually needed. */
- if (id_cow_hint != NULL) {
+ if (id_cow_hint != nullptr) {
// BLI_assert(deg_copy_on_write_is_needed(id_orig));
if (deg_copy_on_write_is_needed(id_orig)) {
id_cow = id_cow_hint;
@@ -154,22 +154,22 @@ IDNode::~IDNode()
void IDNode::destroy()
{
- if (id_orig == NULL) {
+ if (id_orig == nullptr) {
return;
}
BLI_ghash_free(components, id_deps_node_hash_key_free, id_deps_node_hash_value_free);
/* Free memory used by this CoW ID. */
- if (id_cow != id_orig && id_cow != NULL) {
+ if (id_cow != id_orig && id_cow != nullptr) {
deg_free_copy_on_write_datablock(id_cow);
MEM_freeN(id_cow);
- id_cow = NULL;
+ id_cow = nullptr;
DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
}
/* Tag that the node is freed. */
- id_orig = NULL;
+ id_orig = nullptr;
}
string IDNode::identifier() const
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index 35184253f5c..886c25b5a4e 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -57,7 +57,7 @@ struct IDNode : public Node {
};
virtual void init(const ID *id, const char *subdata) override;
- void init_copy_on_write(ID *id_cow_hint = NULL);
+ void init_copy_on_write(ID *id_cow_hint = nullptr);
~IDNode();
void destroy();
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 09a761d282f..e313b5ccee7 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -241,13 +241,13 @@ void OperationNode::tag_update(Depsgraph *graph, eUpdateSource source)
void OperationNode::set_as_entry()
{
- BLI_assert(owner != NULL);
+ BLI_assert(owner != nullptr);
owner->set_entry_operation(this);
}
void OperationNode::set_as_exit()
{
- BLI_assert(owner != NULL);
+ BLI_assert(owner != nullptr);
owner->set_exit_operation(this);
}
diff --git a/source/blender/depsgraph/intern/node/deg_node_time.cc b/source/blender/depsgraph/intern/node/deg_node_time.cc
index cae98ef56c0..ff3e950bb44 100644
--- a/source/blender/depsgraph/intern/node/deg_node_time.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_time.cc
@@ -26,6 +26,7 @@
#include "DNA_scene_types.h"
#include "intern/depsgraph.h"
+#include "intern/depsgraph_relation.h"
namespace DEG {