Blender  V2.93
depsgraph_query_iter.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) 2017 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 /* Silence warnings from copying deprecated fields. */
27 #define DNA_DEPRECATED_ALLOW
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "BKE_duplilist.h"
32 #include "BKE_geometry_set.hh"
33 #include "BKE_idprop.h"
34 #include "BKE_layer.h"
35 #include "BKE_node.h"
36 #include "BKE_object.h"
37 
38 #include "BLI_math.h"
39 #include "BLI_utildefines.h"
40 
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 
44 #include "DEG_depsgraph.h"
45 #include "DEG_depsgraph_query.h"
46 
47 #include "intern/depsgraph.h"
49 
50 #ifndef NDEBUG
52 #endif
53 
54 // If defined, all working data will be set to an invalid state, helping
55 // to catch issues when areas accessing data which is considered to be no
56 // longer available.
57 #undef INVALIDATE_WORK_DATA
58 
59 #ifndef NDEBUG
60 # define INVALIDATE_WORK_DATA
61 #endif
62 
63 namespace deg = blender::deg;
64 
65 /* ************************ DEG ITERATORS ********************* */
66 
67 namespace {
68 
69 void deg_invalidate_iterator_work_data(DEGObjectIterData *data)
70 {
71 #ifdef INVALIDATE_WORK_DATA
72  BLI_assert(data != nullptr);
73  memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));
74 #else
75  (void)data;
76 #endif
77 }
78 
79 void verify_id_properties_freed(DEGObjectIterData *data)
80 {
81  if (data->dupli_object_current == nullptr) {
82  // We didn't enter duplication yet, so we can't have any dangling
83  // pointers.
84  return;
85  }
86  const Object *dupli_object = data->dupli_object_current->ob;
87  Object *temp_dupli_object = &data->temp_dupli_object;
88  if (temp_dupli_object->id.properties == nullptr) {
89  // No ID properties in temp data-block -- no leak is possible.
90  return;
91  }
92  if (temp_dupli_object->id.properties == dupli_object->id.properties) {
93  // Temp copy of object did not modify ID properties.
94  return;
95  }
96  // Free memory which is owned by temporary storage which is about to
97  // get overwritten.
98  IDP_FreeProperty(temp_dupli_object->id.properties);
99  temp_dupli_object->id.properties = nullptr;
100 }
101 
102 bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject *dob)
103 {
104  /* Automatic hiding if this object is being instanced on verts/faces/frames
105  * by its parent. Ideally this should not be needed, but due to the wrong
106  * dependency direction in the data design there is no way to keep the object
107  * visible otherwise. The better solution eventually would be for objects
108  * to specify which object they instance, instead of through parenting.
109  *
110  * This function should not be used for meta-balls. They have custom visibility rules, as hiding
111  * the base meta-ball will also hide all the other balls in the group. */
112  if (eval_mode == DAG_EVAL_RENDER || dob) {
113  const int hide_original_types = OB_DUPLIVERTS | OB_DUPLIFACES;
114 
115  if (!dob || !(dob->type & hide_original_types)) {
116  if (ob->parent && (ob->parent->transflag & hide_original_types)) {
117  return true;
118  }
119  }
120  }
121 
122  return false;
123 }
124 
125 void deg_iterator_components_init(DEGObjectIterData *data, Object *object)
126 {
127  data->geometry_component_owner = object;
128  data->geometry_component_id = 0;
129 }
130 
131 /* Returns false when iterator is exhausted. */
132 bool deg_iterator_components_step(BLI_Iterator *iter)
133 {
135  if (data->geometry_component_owner == nullptr) {
136  return false;
137  }
138 
139  if (data->geometry_component_owner->runtime.geometry_set_eval == nullptr) {
140  /* Return the object itself, if it does not have a geometry set yet. */
141  iter->current = data->geometry_component_owner;
142  data->geometry_component_owner = nullptr;
143  return true;
144  }
145 
146  GeometrySet *geometry_set = data->geometry_component_owner->runtime.geometry_set_eval;
147  if (geometry_set == nullptr) {
148  data->geometry_component_owner = nullptr;
149  return false;
150  }
151 
152  /* The mesh component. */
153  if (data->geometry_component_id == 0) {
154  data->geometry_component_id++;
155 
156  /* Don't use a temporary object for this component, when the owner is a mesh object. */
157  if (data->geometry_component_owner->type == OB_MESH) {
158  iter->current = data->geometry_component_owner;
159  return true;
160  }
161 
162  const Mesh *mesh = geometry_set->get_mesh_for_read();
163  if (mesh != nullptr) {
164  Object *temp_object = &data->temp_geometry_component_object;
165  *temp_object = *data->geometry_component_owner;
166  temp_object->type = OB_MESH;
167  temp_object->data = (void *)mesh;
168  temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
169  iter->current = temp_object;
170  return true;
171  }
172  }
173 
174  /* The pointcloud component. */
175  if (data->geometry_component_id == 1) {
176  data->geometry_component_id++;
177 
178  /* Don't use a temporary object for this component, when the owner is a point cloud object. */
179  if (data->geometry_component_owner->type == OB_POINTCLOUD) {
180  iter->current = data->geometry_component_owner;
181  return true;
182  }
183 
184  const PointCloud *pointcloud = geometry_set->get_pointcloud_for_read();
185  if (pointcloud != nullptr) {
186  Object *temp_object = &data->temp_geometry_component_object;
187  *temp_object = *data->geometry_component_owner;
188  temp_object->type = OB_POINTCLOUD;
189  temp_object->data = (void *)pointcloud;
190  temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
191  iter->current = temp_object;
192  return true;
193  }
194  }
195 
196  /* The volume component. */
197  if (data->geometry_component_id == 2) {
198  data->geometry_component_id++;
199 
200  /* Don't use a temporary object for this component, when the owner is a volume object. */
201  if (data->geometry_component_owner->type == OB_VOLUME) {
202  iter->current = data->geometry_component_owner;
203  return true;
204  }
205 
207  if (component != nullptr) {
208  const Volume *volume = component->get_for_read();
209 
210  if (volume != nullptr) {
211  Object *temp_object = &data->temp_geometry_component_object;
212  *temp_object = *data->geometry_component_owner;
213  temp_object->type = OB_VOLUME;
214  temp_object->data = (void *)volume;
215  temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
216  iter->current = temp_object;
217  return true;
218  }
219  }
220  }
221 
222  data->geometry_component_owner = nullptr;
223  return false;
224 }
225 
226 void deg_iterator_duplis_init(DEGObjectIterData *data, Object *object)
227 {
228  if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
229  ((object->transflag & OB_DUPLI) || object->runtime.geometry_set_eval != nullptr)) {
230  data->dupli_parent = object;
231  data->dupli_list = object_duplilist(data->graph, data->scene, object);
232  data->dupli_object_next = (DupliObject *)data->dupli_list->first;
233  }
234 }
235 
236 /* Returns false when iterator is exhausted. */
237 bool deg_iterator_duplis_step(DEGObjectIterData *data)
238 {
239  if (data->dupli_list == nullptr) {
240  return false;
241  }
242 
243  while (data->dupli_object_next != nullptr) {
244  DupliObject *dob = data->dupli_object_next;
245  Object *obd = dob->ob;
246 
247  data->dupli_object_next = data->dupli_object_next->next;
248 
249  if (dob->no_draw) {
250  continue;
251  }
252  if (obd->type == OB_MBALL) {
253  continue;
254  }
255  if (deg_object_hide_original(data->eval_mode, dob->ob, dob)) {
256  continue;
257  }
258 
259  verify_id_properties_freed(data);
260 
261  data->dupli_object_current = dob;
262 
263  /* Temporary object to evaluate. */
264  Object *dupli_parent = data->dupli_parent;
265  Object *temp_dupli_object = &data->temp_dupli_object;
266  *temp_dupli_object = *dob->ob;
267  temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI;
268  temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits;
269  temp_dupli_object->runtime.local_collections_bits =
270  dupli_parent->runtime.local_collections_bits;
271  temp_dupli_object->dt = MIN2(temp_dupli_object->dt, dupli_parent->dt);
272  copy_v4_v4(temp_dupli_object->color, dupli_parent->color);
273  temp_dupli_object->runtime.select_id = dupli_parent->runtime.select_id;
274 
275  /* Duplicated elements shouldn't care whether their original collection is visible or not. */
276  temp_dupli_object->base_flag |= BASE_VISIBLE_DEPSGRAPH;
277 
278  int ob_visibility = BKE_object_visibility(temp_dupli_object, data->eval_mode);
279  if ((ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) == 0) {
280  continue;
281  }
282 
283  /* This could be avoided by refactoring make_dupli() in order to track all negative scaling
284  * recursively. */
285  bool is_neg_scale = is_negative_m4(dob->mat);
286  SET_FLAG_FROM_TEST(data->temp_dupli_object.transflag, is_neg_scale, OB_NEG_SCALE);
287 
288  copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
289  invert_m4_m4(data->temp_dupli_object.imat, data->temp_dupli_object.obmat);
290  deg_iterator_components_init(data, &data->temp_dupli_object);
292  return true;
293  }
294 
295  verify_id_properties_freed(data);
296  free_object_duplilist(data->dupli_list);
297  data->dupli_parent = nullptr;
298  data->dupli_list = nullptr;
299  data->dupli_object_next = nullptr;
300  data->dupli_object_current = nullptr;
301  deg_invalidate_iterator_work_data(data);
302  return false;
303 }
304 
305 /* Returns false when iterator is exhausted. */
306 bool deg_iterator_objects_step(DEGObjectIterData *data)
307 {
308  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(data->graph);
309 
310  for (; data->id_node_index < data->num_id_nodes; data->id_node_index++) {
311  deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
312 
314  continue;
315  }
316 
317  const ID_Type id_type = GS(id_node->id_orig->name);
318 
319  if (id_type != ID_OB) {
320  continue;
321  }
322 
323  switch (id_node->linked_state) {
325  if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY) == 0) {
326  continue;
327  }
328  break;
330  if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) == 0) {
331  continue;
332  }
333  break;
335  if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY) == 0) {
336  continue;
337  }
338  break;
339  }
340 
341  Object *object = (Object *)id_node->id_cow;
343 
344  int ob_visibility = OB_VISIBLE_ALL;
345  if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
346  ob_visibility = BKE_object_visibility(object, data->eval_mode);
347 
348  if (object->type != OB_MBALL && deg_object_hide_original(data->eval_mode, object, nullptr)) {
349  continue;
350  }
351  }
352 
353  object->runtime.select_id = DEG_get_original_object(object)->runtime.select_id;
354  if (ob_visibility & OB_VISIBLE_INSTANCES) {
355  deg_iterator_duplis_init(data, object);
356  }
357 
358  if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
359  deg_iterator_components_init(data, object);
360  }
361  data->id_node_index++;
362  return true;
363  }
364  return false;
365 }
366 
367 } // namespace
368 
370 {
371  Depsgraph *depsgraph = data->graph;
372  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
373  const size_t num_id_nodes = deg_graph->id_nodes.size();
374 
375  iter->data = data;
376 
377  if (num_id_nodes == 0) {
378  iter->valid = false;
379  return;
380  }
381 
382  data->dupli_parent = nullptr;
383  data->dupli_list = nullptr;
384  data->dupli_object_next = nullptr;
385  data->dupli_object_current = nullptr;
387  data->id_node_index = 0;
388  data->num_id_nodes = num_id_nodes;
389  data->eval_mode = DEG_get_mode(depsgraph);
390  data->geometry_component_id = 0;
391  data->geometry_component_owner = nullptr;
392  deg_invalidate_iterator_work_data(data);
393 
395 }
396 
398 {
400  while (true) {
401  if (deg_iterator_components_step(iter)) {
402  return;
403  }
404  if (deg_iterator_duplis_step(data)) {
405  continue;
406  }
407  if (deg_iterator_objects_step(data)) {
408  continue;
409  }
410  iter->valid = false;
411  break;
412  }
413 }
414 
416 {
418  if (data != nullptr) {
419  /* Force crash in case the iterator data is referenced and accessed down
420  * the line. (T51718) */
421  deg_invalidate_iterator_work_data(data);
422  }
423 }
424 
425 /* ************************ DEG ID ITERATOR ********************* */
426 
427 static void DEG_iterator_ids_step(BLI_Iterator *iter, deg::IDNode *id_node, bool only_updated)
428 {
429  ID *id_cow = id_node->id_cow;
430 
431  if (!id_node->is_directly_visible) {
432  iter->skip = true;
433  return;
434  }
435  if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) {
436  bNodeTree *ntree = ntreeFromID(id_cow);
437 
438  /* Node-tree is considered part of the data-block. */
439  if (!(ntree && (ntree->id.recalc & ID_RECALC_ALL))) {
440  iter->skip = true;
441  return;
442  }
443  }
444 
445  iter->current = id_cow;
446  iter->skip = false;
447 }
448 
450 {
451  Depsgraph *depsgraph = data->graph;
452  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
453  const size_t num_id_nodes = deg_graph->id_nodes.size();
454 
455  iter->data = data;
456 
457  if ((num_id_nodes == 0) || (data->only_updated && !DEG_id_type_any_updated(depsgraph))) {
458  iter->valid = false;
459  return;
460  }
461 
462  data->id_node_index = 0;
463  data->num_id_nodes = num_id_nodes;
464 
465  deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
466  DEG_iterator_ids_step(iter, id_node, data->only_updated);
467 
468  if (iter->skip) {
469  DEG_iterator_ids_next(iter);
470  }
471 }
472 
474 {
475  DEGIDIterData *data = (DEGIDIterData *)iter->data;
476  Depsgraph *depsgraph = data->graph;
477  deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
478 
479  do {
480  iter->skip = false;
481 
482  ++data->id_node_index;
483  if (data->id_node_index == data->num_id_nodes) {
484  iter->valid = false;
485  return;
486  }
487 
488  deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
489  DEG_iterator_ids_step(iter, id_node, data->only_updated);
490  } while (iter->skip);
491 }
492 
494 {
495 }
struct ListBase * object_duplilist(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob)
void free_object_duplilist(struct ListBase *lb)
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1040
struct bNodeTree * ntreeFromID(struct ID *id)
Definition: node.cc:3147
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_INSTANCES
Definition: BKE_object.h:127
@ OB_VISIBLE_SELF
Definition: BKE_object.h:125
@ OB_VISIBLE_PARTICLES
Definition: BKE_object.h:126
@ OB_VISIBLE_ALL
Definition: BKE_object.h:128
int BKE_object_visibility(const struct Object *ob, const int dag_eval_mode)
#define BLI_assert(a)
Definition: BLI_assert.h:58
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2590
MINLINE void copy_v4_v4(float r[4], const float a[4])
#define UNUSED(x)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define MIN2(a, b)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:126
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
eEvaluationMode
Definition: DEG_depsgraph.h:60
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
bool DEG_id_type_any_updated(const struct Depsgraph *depsgraph)
struct Object * DEG_get_original_object(struct Object *object)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_VISIBLE
@ DEG_ITER_OBJECT_FLAG_DUPLI
@ DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY
@ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_ALL
Definition: DNA_ID.h:697
ID_Type
Definition: DNA_ID_enums.h:56
@ ID_OB
Definition: DNA_ID_enums.h:59
@ BASE_FROM_DUPLI
@ BASE_VISIBLE_DEPSGRAPH
Object is a sort of wrapper for general info.
@ OB_DUPLIFACES
@ OB_DUPLI
@ OB_NEG_SCALE
@ OB_DUPLIVERTS
@ OB_MBALL
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
Read Guarded memory(de)allocation.
int64_t size() const
Definition: BLI_vector.hh:662
const IDNode * id_node
const Depsgraph * depsgraph
void DEG_iterator_ids_begin(BLI_Iterator *iter, DEGIDIterData *data)
void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
void DEG_iterator_objects_end(BLI_Iterator *iter)
void DEG_iterator_objects_next(BLI_Iterator *iter)
void DEG_iterator_ids_next(BLI_Iterator *iter)
void DEG_iterator_ids_end(BLI_Iterator *UNUSED(iter))
static void DEG_iterator_ids_step(BLI_Iterator *iter, deg::IDNode *id_node, bool only_updated)
bNodeTree * ntree
#define GS(x)
Definition: iris.c:241
bool deg_validate_copy_on_write_datablock(ID *id_cow)
@ DEG_ID_LINKED_INDIRECTLY
Definition: deg_node_id.h:42
@ DEG_ID_LINKED_VIA_SET
Definition: deg_node_id.h:44
@ DEG_ID_LINKED_DIRECTLY
Definition: deg_node_id.h:46
void * current
Definition: BLI_iterator.h:28
float mat[4][4]
Definition: BKE_duplilist.h:46
struct Object * ob
Definition: BKE_duplilist.h:45
const PointCloud * get_pointcloud_for_read() const
const GeometryComponent * get_component_for_read(GeometryComponentType component_type) const
const Mesh * get_mesh_for_read() const
Definition: DNA_ID.h:273
int recalc
Definition: DNA_ID.h:295
IDProperty * properties
Definition: DNA_ID.h:314
char name[66]
Definition: DNA_ID.h:283
unsigned short local_collections_bits
struct GeometrySet * geometry_set_eval
short transflag
short base_flag
Object_Runtime runtime
float color[4]
struct Object * parent
unsigned short base_local_view_bits
void * data
IDDepsNodes id_nodes
Definition: depsgraph.h:103
eDepsNode_LinkedState_Type linked_state
Definition: deg_node_id.h:108