Blender  V2.93
depsgraph_query.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2013 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include "MEM_guardedalloc.h"
27 
28 #include <cstring> /* XXX: memcpy */
29 
30 #include "BLI_listbase.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BKE_action.h" /* XXX: BKE_pose_channel_find_name */
34 #include "BKE_customdata.h"
35 #include "BKE_idtype.h"
36 #include "BKE_main.h"
37 
38 #include "DNA_object_types.h"
39 #include "DNA_scene_types.h"
40 
41 #include "RNA_access.h"
42 
43 #include "DEG_depsgraph.h"
44 #include "DEG_depsgraph_query.h"
45 
46 #include "intern/depsgraph.h"
49 
50 namespace deg = blender::deg;
51 
53 {
54  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
55  return deg_graph->scene;
56 }
57 
59 {
60  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
61  return deg_graph->view_layer;
62 }
63 
65 {
66  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
67  return deg_graph->bmain;
68 }
69 
71 {
72  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
73  return deg_graph->mode;
74 }
75 
77 {
78  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
79  return deg_graph->ctime;
80 }
81 
82 bool DEG_id_type_updated(const Depsgraph *graph, short id_type)
83 {
84  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
85  return deg_graph->id_type_updated[BKE_idtype_idcode_to_index(id_type)] != 0;
86 }
87 
89 {
90  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
91 
92  /* Loop over all ID types. */
93  for (char id_type_index : deg_graph->id_type_updated) {
94  if (id_type_index) {
95  return true;
96  }
97  }
98 
99  return false;
100 }
101 
102 bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
103 {
104  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(depsgraph);
105  return deg_graph->id_type_exist[BKE_idtype_idcode_to_index(id_type)] != 0;
106 }
107 
109 {
110  if (graph == nullptr) {
111  /* Happens when converting objects to mesh from a python script
112  * after modifying scene graph.
113  *
114  * Currently harmless because it's only called for temporary
115  * objects which are out of the DAG anyway. */
116  return 0;
117  }
118 
119  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
120  const deg::IDNode *id_node = deg_graph->find_id_node(DEG_get_original_id(id));
121  if (id_node == nullptr) {
122  /* TODO(sergey): Does it mean we need to check set scene? */
123  return 0;
124  }
125 
126  return id_node->eval_flags;
127 }
128 
130  Object *ob,
131  CustomData_MeshMasks *r_mask)
132 {
133  if (graph == nullptr) {
134  /* Happens when converting objects to mesh from a python script
135  * after modifying scene graph.
136  *
137  * Currently harmless because it's only called for temporary
138  * objects which are out of the DAG anyway. */
139  return;
140  }
141 
142  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
143  const deg::IDNode *id_node = deg_graph->find_id_node(DEG_get_original_id(&ob->id));
144  if (id_node == nullptr) {
145  /* TODO(sergey): Does it mean we need to check set scene? */
146  return;
147  }
148 
149  r_mask->vmask |= id_node->customdata_masks.vert_mask;
150  r_mask->emask |= id_node->customdata_masks.edge_mask;
151  r_mask->fmask |= id_node->customdata_masks.face_mask;
152  r_mask->lmask |= id_node->customdata_masks.loop_mask;
153  r_mask->pmask |= id_node->customdata_masks.poly_mask;
154 }
155 
157 {
158  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
159  Scene *scene_cow = deg_graph->scene_cow;
160  /* TODO(sergey): Shall we expand data-block here? Or is it OK to assume
161  * that caller is OK with just a pointer in case scene is not updated yet? */
162  BLI_assert(scene_cow != nullptr && deg::deg_copy_on_write_is_expanded(&scene_cow->id));
163  return scene_cow;
164 }
165 
167 {
168  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
169  Scene *scene_cow = DEG_get_evaluated_scene(graph);
170  if (scene_cow == nullptr) {
171  return nullptr; /* Happens with new, not-yet-built/evaluated graphes. */
172  }
173  /* Do name-based lookup. */
174  /* TODO(sergey): Can this be optimized? */
175  ViewLayer *view_layer_orig = deg_graph->view_layer;
176  ViewLayer *view_layer_cow = (ViewLayer *)BLI_findstring(
177  &scene_cow->view_layers, view_layer_orig->name, offsetof(ViewLayer, name));
178  BLI_assert(view_layer_cow != nullptr);
179  return view_layer_cow;
180 }
181 
183 {
184  return (Object *)DEG_get_evaluated_id(depsgraph, &object->id);
185 }
186 
188 {
189  if (id == nullptr) {
190  return nullptr;
191  }
192  /* TODO(sergey): This is a duplicate of Depsgraph::get_cow_id(),
193  * but here we never do assert, since we don't know nature of the
194  * incoming ID data-block. */
195  const deg::Depsgraph *deg_graph = (const deg::Depsgraph *)depsgraph;
196  const deg::IDNode *id_node = deg_graph->find_id_node(id);
197  if (id_node == nullptr) {
198  return id;
199  }
200  return id_node->id_cow;
201 }
202 
203 /* Get evaluated version of data pointed to by RNA pointer */
205  PointerRNA *ptr,
206  PointerRNA *r_ptr_eval)
207 {
208  if ((ptr == nullptr) || (r_ptr_eval == nullptr)) {
209  return;
210  }
211  ID *orig_id = ptr->owner_id;
212  ID *cow_id = DEG_get_evaluated_id(depsgraph, orig_id);
213  if (ptr->owner_id == ptr->data) {
214  /* For ID pointers, it's easy... */
215  r_ptr_eval->owner_id = cow_id;
216  r_ptr_eval->data = (void *)cow_id;
217  r_ptr_eval->type = ptr->type;
218  }
219  else if (ptr->type == &RNA_PoseBone) {
220  /* HACK: Since bone keyframing is quite commonly used,
221  * speed things up for this case by doing a special lookup
222  * for bones */
223  const Object *ob_eval = (Object *)cow_id;
224  bPoseChannel *pchan = (bPoseChannel *)ptr->data;
225  const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
226  r_ptr_eval->owner_id = cow_id;
227  r_ptr_eval->data = (void *)pchan_eval;
228  r_ptr_eval->type = ptr->type;
229  }
230  else {
231  /* For everything else, try to get RNA Path of the BMain-pointer,
232  * then use that to look up what the COW-domain one should be
233  * given the COW ID pointer as the new lookup point */
234  /* TODO: Find a faster alternative, or implement support for other
235  * common types too above (e.g. modifiers) */
236  char *path = RNA_path_from_ID_to_struct(ptr);
237  if (path) {
238  PointerRNA cow_id_ptr;
239  RNA_id_pointer_create(cow_id, &cow_id_ptr);
240  if (!RNA_path_resolve(&cow_id_ptr, path, r_ptr_eval, nullptr)) {
241  /* Couldn't find COW copy of data */
242  fprintf(stderr,
243  "%s: Couldn't resolve RNA path ('%s') relative to COW ID (%p) for '%s'\n",
244  __func__,
245  path,
246  (void *)cow_id,
247  orig_id->name);
248  }
249  }
250  else {
251  /* Path resolution failed - XXX: Hide this behind a debug flag */
252  fprintf(stderr,
253  "%s: Couldn't get RNA path for %s relative to %s\n",
254  __func__,
256  orig_id->name);
257  }
258  }
259 }
260 
262 {
263  return (Object *)DEG_get_original_id(&object->id);
264 }
265 
267 {
268  if (id == nullptr) {
269  return nullptr;
270  }
271  if (id->orig_id == nullptr) {
272  return id;
273  }
275  return (ID *)id->orig_id;
276 }
277 
278 bool DEG_is_original_id(const ID *id)
279 {
280  /* Some explanation of the logic.
281  *
282  * What we want here is to be able to tell whether given ID is a result of dependency graph
283  * evaluation or not.
284  *
285  * All the data-blocks which are created by copy-on-write mechanism will have will be tagged with
286  * LIB_TAG_COPIED_ON_WRITE tag. Those data-blocks can not be original.
287  *
288  * Modifier stack evaluation might create special data-blocks which have all the modifiers
289  * applied, and those will be tagged with LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT. Such data-blocks
290  * can not be original as well.
291  *
292  * Localization is usually happening from evaluated data-block, or will have some special pointer
293  * magic which will make them to act as evaluated.
294  *
295  * NOTE: We consider ID evaluated if ANY of those flags is set. We do NOT require ALL of them. */
296  if (id->tag &
298  return false;
299  }
300  return true;
301 }
302 
303 bool DEG_is_original_object(const Object *object)
304 {
305  return DEG_is_original_id(&object->id);
306 }
307 
308 bool DEG_is_evaluated_id(const ID *id)
309 {
310  return !DEG_is_original_id(id);
311 }
312 
313 bool DEG_is_evaluated_object(const Object *object)
314 {
315  return !DEG_is_original_object(object);
316 }
317 
319 {
320  const deg::Depsgraph *deg_graph = (const deg::Depsgraph *)depsgraph;
321  /* Check whether relations are up to date. */
322  if (deg_graph->need_update) {
323  return false;
324  }
325  /* Check whether IDs are up to date. */
326  if (!deg_graph->entry_tags.is_empty()) {
327  return false;
328  }
329  return true;
330 }
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
CustomData interface, see also DNA_customdata_types.h.
int BKE_idtype_idcode_to_index(const short idcode)
Definition: idtype.c:345
#define BLI_assert(a)
Definition: BLI_assert.h:58
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
eEvaluationMode
Definition: DEG_depsgraph.h:60
@ LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT
Definition: DNA_ID.h:567
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:565
@ LIB_TAG_LOCALIZED
Definition: DNA_ID.h:568
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
StructRNA RNA_PoseBone
Depsgraph * graph
const IDNode * id_node
const Depsgraph * depsgraph
float DEG_get_ctime(const Depsgraph *graph)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
struct Scene * DEG_get_input_scene(const Depsgraph *graph)
ID * DEG_get_evaluated_id(const Depsgraph *depsgraph, ID *id)
uint32_t DEG_get_eval_flags_for_id(const Depsgraph *graph, ID *id)
bool DEG_is_fully_evaluated(const struct Depsgraph *depsgraph)
bool DEG_is_evaluated_id(const ID *id)
void DEG_get_customdata_mask_for_object(const Depsgraph *graph, Object *ob, CustomData_MeshMasks *r_mask)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
bool DEG_is_original_id(const ID *id)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
ID * DEG_get_original_id(ID *id)
struct Main * DEG_get_bmain(const Depsgraph *graph)
bool DEG_is_original_object(const Object *object)
struct ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
void DEG_get_evaluated_rna_pointer(const Depsgraph *depsgraph, PointerRNA *ptr, PointerRNA *r_ptr_eval)
Object * DEG_get_original_object(Object *object)
bool DEG_id_type_updated(const Depsgraph *graph, short id_type)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
bool DEG_is_evaluated_object(const Object *object)
bool DEG_id_type_any_updated(const Depsgraph *graph)
bool deg_copy_on_write_is_expanded(const ID *id_cow)
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:723
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
char * RNA_path_from_ID_to_struct(PointerRNA *ptr)
Definition: rna_access.c:5876
bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: rna_access.c:5400
unsigned int uint32_t
Definition: stdint.h:83
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
struct ID * orig_id
Definition: DNA_ID.h:324
char name[66]
Definition: DNA_ID.h:283
Definition: BKE_main.h:116
char name[1024]
Definition: BKE_main.h:118
struct bPose * pose
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
ListBase view_layers
char name[64]
IDNode * find_id_node(const ID *id) const
Definition: depsgraph.cc:112
char id_type_updated[INDEX_ID_MAX]
Definition: depsgraph.h:112
eEvaluationMode mode
Definition: depsgraph.h:136
ViewLayer * view_layer
Definition: depsgraph.h:135
char id_type_exist[INDEX_ID_MAX]
Definition: depsgraph.h:115
Set< OperationNode * > entry_tags
Definition: depsgraph.h:120
PointerRNA * ptr
Definition: wm_files.c:3157