2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2017 Blender Foundation.
19 * All rights reserved.
21 * Original Author: Dalai Felinto
22 * Contributor(s): Sergey Sharybin
24 * ***** END GPL LICENSE BLOCK *****
27 /** \file blender/depsgraph/intern/depsgraph_query_iter.cc
30 * Implementation of Querying and Filtering API's
33 #include "MEM_guardedalloc.h"
36 #include "BLI_utildefines.h"
39 #include "BKE_idprop.h"
40 #include "BKE_layer.h"
41 #include "BKE_object.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_query.h"
50 #include "intern/depsgraph_intern.h"
51 #include "util/deg_util_foreach.h"
53 #include "intern/nodes/deg_node_id.h"
56 # include "intern/eval/deg_eval_copy_on_write.h"
59 /* ************************ DEG ITERATORS ********************* */
61 static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
63 DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
64 while (data->dupli_object_next != NULL) {
65 DupliObject *dob = data->dupli_object_next;
66 Object *obd = dob->ob;
68 data->dupli_object_next = data->dupli_object_next->next;
70 /* Group duplis need to set ob matrices correct, for deform. so no_draw
73 if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) {
77 if (obd->type == OB_MBALL) {
81 data->dupli_object_current = dob;
83 /* Temporary object to evaluate. */
84 Object *dupli_parent = data->dupli_parent;
85 Object *temp_dupli_object = &data->temp_dupli_object;
86 *temp_dupli_object = *dob->ob;
87 temp_dupli_object->transflag &= ~OB_DUPLI;
88 temp_dupli_object->select_color = dupli_parent->select_color;
89 temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI;
91 if (dob->collection_properties != NULL) {
92 temp_dupli_object->base_collection_properties = dob->collection_properties;
93 IDP_MergeGroup(temp_dupli_object->base_collection_properties, dupli_parent->base_collection_properties, false);
96 temp_dupli_object->base_collection_properties = dupli_parent->base_collection_properties;
99 copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
100 iter->current = &data->temp_dupli_object;
102 DEG::deg_validate_copy_on_write_datablock(
103 &data->temp_dupli_object.id));
110 static void DEG_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_node)
112 /* Set it early in case we need to exit and we are running from within a loop. */
115 DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
116 const ID_Type id_type = GS(id_node->id_orig->name);
118 if (id_type != ID_OB) {
122 switch (id_node->linked_state) {
123 case DEG::DEG_ID_LINKED_DIRECTLY:
124 if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY) == 0) {
128 case DEG::DEG_ID_LINKED_VIA_SET:
129 if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) == 0) {
133 case DEG::DEG_ID_LINKED_INDIRECTLY:
134 if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY) == 0) {
140 Object *object = (Object *)id_node->id_cow;
141 BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id));
143 if ((BKE_object_is_visible(object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) &&
144 ((data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) != 0))
149 if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) && (object->transflag & OB_DUPLI)) {
150 data->dupli_parent = object;
151 data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object);
152 data->dupli_object_next = (DupliObject *)data->dupli_list->first;
154 const eObjectVisibilityCheck mode = (data->mode == DEG_ITER_OBJECT_MODE_RENDER) ?
155 OB_VISIBILITY_CHECK_FOR_RENDER :
156 OB_VISIBILITY_CHECK_FOR_VIEWPORT;
158 if (BKE_object_is_visible(object, mode) == false) {
163 iter->current = object;
167 void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
169 Depsgraph *depsgraph = data->graph;
170 DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
171 const size_t num_id_nodes = deg_graph->id_nodes.size();
173 if (num_id_nodes == 0) {
178 /* TODO(sergey): What evaluation type we want here? */
179 /* TODO(dfelinto): Get rid of evaluation context here, it's only used to do
180 * direct dupli-objects update in group.c. Which is terribly bad, and all
181 * objects are expected to be evaluated already. */
182 DEG_evaluation_context_init(&data->eval_ctx, DAG_EVAL_VIEWPORT);
183 data->eval_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
186 data->dupli_parent = NULL;
187 data->dupli_list = NULL;
188 data->dupli_object_next = NULL;
189 data->dupli_object_current = NULL;
190 data->scene = DEG_get_evaluated_scene(depsgraph);
191 data->id_node_index = 0;
192 data->num_id_nodes = num_id_nodes;
194 DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
195 DEG_iterator_objects_step(iter, id_node);
198 DEG_iterator_objects_next(iter);
202 void DEG_iterator_objects_next(BLI_Iterator *iter)
204 DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
205 Depsgraph *depsgraph = data->graph;
206 DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
209 if (data->dupli_list) {
210 if (deg_objects_dupli_iterator_next(iter)) {
214 free_object_duplilist(data->dupli_list);
215 data->dupli_parent = NULL;
216 data->dupli_list = NULL;
217 data->dupli_object_next = NULL;
218 data->dupli_object_current = NULL;
222 ++data->id_node_index;
223 if (data->id_node_index == data->num_id_nodes) {
228 DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
229 DEG_iterator_objects_step(iter, id_node);
230 } while (iter->skip);
233 void DEG_iterator_objects_end(BLI_Iterator *iter)
236 DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
237 /* Force crash in case the iterator data is referenced and accessed down the line. (T51718) */
238 memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));