Blender V5.0
deg_builder.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include <cstring>
12
13#include "DNA_ID.h"
14#include "DNA_armature_types.h"
15#include "DNA_layer_types.h"
16#include "DNA_modifier_types.h"
17#include "DNA_object_types.h"
18
19#include "BLI_string.h"
20
21#include "BKE_action.hh"
22#include "BKE_collection.hh"
23#include "BKE_lib_id.hh"
24
25#include "RNA_prototypes.hh"
26
29#include "intern/depsgraph.hh"
37
38#include "DEG_depsgraph.hh"
39
40namespace blender::deg {
41
42bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig)
43{
44 IDNode *id_node = graph->find_id_node(id_orig);
45 return id_node != nullptr;
46}
47
49{
50 Object *object_orig = base->base_orig->object;
51 IDNode *id_node = graph->find_id_node(&object_orig->id);
52 if (id_node == nullptr) {
53 return false;
54 }
55 return id_node->has_base;
56}
57
58/* -------------------------------------------------------------------- */
61
63 : bmain_(bmain), graph_(graph), cache_(cache)
64{
65}
66
68{
69 /* Simple check: enabled bases are always part of dependency graph. */
70 const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
72
73 if (!graph_->use_visibility_optimization || (base->flag & base_flag)) {
74 return true;
75 }
76
77 /* More involved check: since we don't support dynamic changes in dependency graph topology and
78 * all visible objects are to be part of dependency graph, we pull all objects which has animated
79 * visibility. */
81}
82
84{
85 AnimatedPropertyID property_id;
86 if (graph_->mode == DAG_EVAL_VIEWPORT) {
87 property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_viewport");
88 }
89 else if (graph_->mode == DAG_EVAL_RENDER) {
90 property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_render");
91 }
92 else {
93 BLI_assert_msg(0, "Unknown evaluation mode.");
94 return false;
95 }
96 return cache_->isPropertyAnimated(&object->id, property_id);
97}
98
100 const ModifierData *modifier)
101{
102 AnimatedPropertyID property_id;
103 if (graph_->mode == DAG_EVAL_VIEWPORT) {
104 property_id = AnimatedPropertyID(
105 &object->id, &RNA_Modifier, (void *)modifier, "show_viewport");
106 }
107 else if (graph_->mode == DAG_EVAL_RENDER) {
108 property_id = AnimatedPropertyID(&object->id, &RNA_Modifier, (void *)modifier, "show_render");
109 }
110 else {
111 BLI_assert_msg(0, "Unknown evaluation mode.");
112 return false;
113 }
114 return cache_->isPropertyAnimated(&object->id, property_id);
115}
116
118{
119 BLI_assert(object->type == OB_ARMATURE);
120 if (pchan == nullptr || pchan->bone == nullptr) {
121 return false;
122 }
123 /* We don't really care whether segments are higher than 1 due to static user input (as in,
124 * rigger entered value like 3 manually), or due to animation. In either way we need to create
125 * special evaluation. */
126 if (pchan->bone->segments > 1) {
127 return true;
128 }
129 bArmature *armature = static_cast<bArmature *>(object->data);
130 AnimatedPropertyID property_id(&armature->id, &RNA_Bone, pchan->bone, "bbone_segments");
131 /* Check both Object and Armature animation data, because drivers modifying Armature
132 * state could easily be created in the Object AnimData. */
133 return cache_->isPropertyAnimated(&object->id, property_id) ||
134 cache_->isPropertyAnimated(&armature->id, property_id);
135}
136
138 const bPoseChannel *pchan)
139{
140 return check_pchan_has_bbone(object, pchan);
141}
142
143bool DepsgraphBuilder::check_pchan_has_bbone_segments(const Object *object, const char *bone_name)
144{
145 const bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name);
146 return check_pchan_has_bbone_segments(object, pchan);
147}
148
150 const PointerRNA &target_prop,
151 const char *rna_path)
152{
153 if (rna_path == nullptr || target_prop.data != scene || target_prop.type != &RNA_Scene ||
154 !BLI_str_startswith(rna_path, "camera"))
155 {
156 return nullptr;
157 }
158
159 /* Return the part of the path relative to the camera. */
160 switch (rna_path[6]) {
161 case '.':
162 return rna_path + 7;
163 case '[':
164 return rna_path + 6;
165 default:
166 return nullptr;
167 }
168}
169
171
172/* -------------------------------------------------------------------- */
175
177{
180
181 /* Re-tag IDs for update if it was tagged before the relations
182 * update tag. */
183 for (IDNode *id_node : graph->id_nodes) {
184 const ID_Type id_type = id_node->id_type;
185 ID *id_orig = id_node->id_orig;
186 id_node->finalize_build(graph);
187 int flag = 0;
188 /* Tag rebuild if special evaluation flags changed. */
189 if (id_node->eval_flags != id_node->previous_eval_flags) {
191 }
192 /* Tag rebuild if the custom data mask changed. */
193 if (id_node->customdata_masks != id_node->previous_customdata_masks) {
195 }
196 const bool is_expanded = deg_eval_copy_is_expanded(id_node->id_cow);
197 if (!is_expanded) {
199 /* This means ID is being added to the dependency graph first
200 * time, which is similar to "ob-visible-change" */
201 if (id_type == ID_OB) {
203 }
204 if (id_type == ID_NT) {
206 }
207 }
208 else {
209 if (id_type == ID_GR) {
210 /* Collection content might have changed (children collection might have been added or
211 * removed from the graph based on their inclusion and visibility flags). */
213 nullptr, reinterpret_cast<Collection *>(id_node->id_cow), LIB_ID_CREATE_NO_DEG_TAG);
214 }
215 else if (id_type == ID_SCE) {
216 /* During undo the sequence strips might obtain a new session ID, which will disallow the
217 * audio handles to be re-used. Tag for the audio and sequence update to ensure the audio
218 * handles are open.
219 * NOTE: This is not something that should be required, and perhaps indicates a weakness in
220 * design somewhere else. For the cause of the problem check #117760. */
222 }
223 }
224 /* Restore recalc flags from original ID, which could possibly contain recalc flags set by
225 * an operator and then were carried on by the undo system.
226 *
227 * Only do it for active dependency graph, because otherwise modifications to the original
228 * objects might keep affecting the render pipeline. For example, when a Python script is
229 * executed in headless mode it will tag original objects for recalculation, and the flag
230 * will never be reset to 0 because there is no active dependency graph (since the
231 * DEG_ids_clear_recalc() only clears original ID recalc flags for the active depsgraph.
232 *
233 * A bit of a safety is to also consider the accumulated recalc flags from the original
234 * data-block for the first evaluation of the data-block within an inactive graph. */
235 if (graph->is_active || !is_expanded) {
236 flag |= id_orig->recalc;
237 }
238 if (flag != 0) {
240 }
241 }
242}
243
245
246} // namespace blender::deg
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_collection_object_cache_free(const Main *bmain, Collection *collection, const int id_create_flag)
@ LIB_ID_CREATE_NO_DEG_TAG
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
int bool BLI_str_startswith(const char *__restrict str, const char *__restrict start) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
@ DAG_EVAL_RENDER
@ DAG_EVAL_VIEWPORT
ID and Library types, which are fundamental for SDNA.
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1054
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1132
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1122
@ ID_RECALC_NTREE_OUTPUT
Definition DNA_ID.h:1155
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
ID_Type
@ ID_NT
@ ID_SCE
@ ID_GR
@ ID_OB
@ BASE_ENABLED_RENDER
@ BASE_ENABLED_VIEWPORT
Object is a sort of wrapper for general info.
@ OB_ARMATURE
DepsgraphBuilderCache * cache_
Definition deg_builder.h:53
virtual bool check_pchan_has_bbone_segments(const Object *object, const bPoseChannel *pchan)
virtual bool need_pull_base_into_graph(const Base *base)
virtual bool check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan)
virtual bool is_object_visibility_animated(const Object *object)
static const char * get_rna_path_relative_to_scene_camera(const Scene *scene, const PointerRNA &target_prop, const char *rna_path)
DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
virtual bool is_modifier_visibility_animated(const Object *object, const ModifierData *modifier)
void deg_graph_remove_unused_noops(Depsgraph *graph)
bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base)
bool deg_eval_copy_is_expanded(const ID *id_cow)
void deg_graph_flush_visibility_flags(Depsgraph *graph)
void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig)
void graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id, uint flags, eUpdateSource update_source)
short flag
struct Object * object
struct Base * base_orig
Definition DNA_ID.h:414
unsigned int recalc
Definition DNA_ID.h:445
struct bPose * pose
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
struct Bone * bone
IDNode * find_id_node(const ID *id) const
Definition depsgraph.cc:101
DEGCustomDataMeshMasks customdata_masks
DEGCustomDataMeshMasks previous_customdata_masks
void finalize_build(Depsgraph *graph)
uint32_t previous_eval_flags
uint8_t flag
Definition wm_window.cc:145