Blender V4.3
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
10
11#include <cstring>
12
13#include "DNA_ID.h"
14#include "DNA_anim_types.h"
15#include "DNA_armature_types.h"
16#include "DNA_layer_types.h"
17#include "DNA_modifier_types.h"
18#include "DNA_object_types.h"
19
20#include "BLI_stack.h"
21#include "BLI_utildefines.h"
22
23#include "BKE_action.hh"
24#include "BKE_collection.hh"
25#include "BKE_lib_id.hh"
26
27#include "RNA_prototypes.hh"
28
31#include "intern/depsgraph.hh"
41
42#include "DEG_depsgraph.hh"
43
44namespace blender::deg {
45
46bool deg_check_id_in_depsgraph(const Depsgraph *graph, ID *id_orig)
47{
48 IDNode *id_node = graph->find_id_node(id_orig);
49 return id_node != nullptr;
50}
51
53{
54 Object *object_orig = base->base_orig->object;
55 IDNode *id_node = graph->find_id_node(&object_orig->id);
56 if (id_node == nullptr) {
57 return false;
58 }
59 return id_node->has_base;
60}
61
62/* -------------------------------------------------------------------- */
67 : bmain_(bmain), graph_(graph), cache_(cache)
68{
69}
70
72{
73 /* Simple check: enabled bases are always part of dependency graph. */
74 const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT :
76 if (base->flag & base_flag) {
77 return true;
78 }
79
80 /* More involved check: since we don't support dynamic changes in dependency graph topology and
81 * all visible objects are to be part of dependency graph, we pull all objects which has animated
82 * visibility. */
84}
85
87{
88 AnimatedPropertyID property_id;
90 property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_viewport");
91 }
92 else if (graph_->mode == DAG_EVAL_RENDER) {
93 property_id = AnimatedPropertyID(&object->id, &RNA_Object, "hide_render");
94 }
95 else {
96 BLI_assert_msg(0, "Unknown evaluation mode.");
97 return false;
98 }
99 return cache_->isPropertyAnimated(&object->id, property_id);
100}
101
103 const ModifierData *modifier)
104{
105 AnimatedPropertyID property_id;
106 if (graph_->mode == DAG_EVAL_VIEWPORT) {
107 property_id = AnimatedPropertyID(
108 &object->id, &RNA_Modifier, (void *)modifier, "show_viewport");
109 }
110 else if (graph_->mode == DAG_EVAL_RENDER) {
111 property_id = AnimatedPropertyID(&object->id, &RNA_Modifier, (void *)modifier, "show_render");
112 }
113 else {
114 BLI_assert_msg(0, "Unknown evaluation mode.");
115 return false;
116 }
117 return cache_->isPropertyAnimated(&object->id, property_id);
118}
119
121{
122 BLI_assert(object->type == OB_ARMATURE);
123 if (pchan == nullptr || pchan->bone == nullptr) {
124 return false;
125 }
126 /* We don't really care whether segments are higher than 1 due to static user input (as in,
127 * rigger entered value like 3 manually), or due to animation. In either way we need to create
128 * special evaluation. */
129 if (pchan->bone->segments > 1) {
130 return true;
131 }
132 bArmature *armature = static_cast<bArmature *>(object->data);
133 AnimatedPropertyID property_id(&armature->id, &RNA_Bone, pchan->bone, "bbone_segments");
134 /* Check both Object and Armature animation data, because drivers modifying Armature
135 * state could easily be created in the Object AnimData. */
136 return cache_->isPropertyAnimated(&object->id, property_id) ||
137 cache_->isPropertyAnimated(&armature->id, property_id);
138}
139
141 const bPoseChannel *pchan)
142{
143 return check_pchan_has_bbone(object, pchan);
144}
145
146bool DepsgraphBuilder::check_pchan_has_bbone_segments(const Object *object, const char *bone_name)
147{
148 const bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name);
149 return check_pchan_has_bbone_segments(object, pchan);
150}
151
153 const PointerRNA &target_prop,
154 const char *rna_path)
155{
156 if (rna_path == nullptr || target_prop.data != scene || target_prop.type != &RNA_Scene ||
157 !BLI_str_startswith(rna_path, "camera"))
158 {
159 return nullptr;
160 }
161
162 /* Return the part of the path relative to the camera. */
163 switch (rna_path[6]) {
164 case '.':
165 return rna_path + 7;
166 case '[':
167 return rna_path + 6;
168 default:
169 return nullptr;
170 }
171}
172
175/* -------------------------------------------------------------------- */
180{
183
184 /* Re-tag IDs for update if it was tagged before the relations
185 * update tag. */
186 for (IDNode *id_node : graph->id_nodes) {
187 const ID_Type id_type = id_node->id_type;
188 ID *id_orig = id_node->id_orig;
189 id_node->finalize_build(graph);
190 int flag = 0;
191 /* Tag rebuild if special evaluation flags changed. */
194 }
195 /* Tag rebuild if the custom data mask changed. */
198 }
199 const bool is_expanded = deg_eval_copy_is_expanded(id_node->id_cow);
200 if (!is_expanded) {
202 /* This means ID is being added to the dependency graph first
203 * time, which is similar to "ob-visible-change" */
204 if (id_type == ID_OB) {
206 }
207 if (id_type == ID_NT) {
209 }
210 }
211 else {
212 if (id_type == ID_GR) {
213 /* Collection content might have changed (children collection might have been added or
214 * removed from the graph based on their inclusion and visibility flags). */
216 nullptr, reinterpret_cast<Collection *>(id_node->id_cow), LIB_ID_CREATE_NO_DEG_TAG);
217 }
218 else if (id_type == ID_SCE) {
219 /* During undo the sequence strips might obtain a new session ID, which will disallow the
220 * audio handles to be re-used. Tag for the audio and sequence update to ensure the audio
221 * handles are open.
222 * NOTE: This is not something that should be required, and perhaps indicates a weakness in
223 * design somewhere else. For the cause of the problem check #117760. */
225 }
226 }
227 /* Restore recalc flags from original ID, which could possibly contain recalc flags set by
228 * an operator and then were carried on by the undo system.
229 *
230 * Only do it for active dependency graph, because otherwise modifications to the original
231 * objects might keep affecting the render pipeline. For example, when a Python script is
232 * executed in headless mode it will tag original objects for recalculation, and the flag
233 * will never be reset to 0 because there is no active dependency graph (since the
234 * DEG_ids_clear_recalc() only clears original ID recalc flags for the active depsgraph.
235 *
236 * A bit of a safety is to also consider the accumulated recalc flags from the original
237 * data-block for the first evaluation of the data-block within an inactive graph. */
238 if (graph->is_active || !is_expanded) {
239 flag |= id_orig->recalc;
240 }
241 if (flag != 0) {
243 }
244 }
245}
246
249} // 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:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
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:1021
@ ID_RECALC_AUDIO
Definition DNA_ID.h:1099
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1089
@ ID_RECALC_NTREE_OUTPUT
Definition DNA_ID.h:1122
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
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
bool isPropertyAnimated(const ID *id, Args... args)
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)
const IDNode * id_node
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:413
unsigned int recalc
Definition DNA_ID.h:437
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
struct Bone * bone
eEvaluationMode mode
Definition depsgraph.hh:136
DEGCustomDataMeshMasks customdata_masks
DEGCustomDataMeshMasks previous_customdata_masks
void finalize_build(Depsgraph *graph)
uint32_t previous_eval_flags
uint8_t flag
Definition wm_window.cc:138