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
20 /** \file
21 * \ingroup depsgraph
22 *
23 * Implementation of Querying API
24 */
25
26 #include "MEM_guardedalloc.h"
27
28 #include <string.h> /* 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"
47 #include "intern/eval/deg_eval_copy_on_write.h"
48 #include "intern/node/deg_node_id.h"
49
50 namespace deg = blender::deg;
51
DEG_get_input_scene(const Depsgraph * graph)52 struct Scene *DEG_get_input_scene(const Depsgraph *graph)
53 {
54 const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
55 return deg_graph->scene;
56 }
57
DEG_get_input_view_layer(const Depsgraph * graph)58 struct ViewLayer *DEG_get_input_view_layer(const Depsgraph *graph)
59 {
60 const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
61 return deg_graph->view_layer;
62 }
63
DEG_get_bmain(const Depsgraph * graph)64 struct Main *DEG_get_bmain(const Depsgraph *graph)
65 {
66 const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
67 return deg_graph->bmain;
68 }
69
DEG_get_mode(const Depsgraph * graph)70 eEvaluationMode DEG_get_mode(const Depsgraph *graph)
71 {
72 const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
73 return deg_graph->mode;
74 }
75
DEG_get_ctime(const Depsgraph * graph)76 float DEG_get_ctime(const Depsgraph *graph)
77 {
78 const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
79 return deg_graph->ctime;
80 }
81
DEG_id_type_updated(const Depsgraph * graph,short id_type)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
DEG_id_type_any_updated(const Depsgraph * graph)88 bool DEG_id_type_any_updated(const Depsgraph *graph)
89 {
90 const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
91
92 /* Loop over all ID types. */
93 for (int id_type_index = 0; id_type_index < MAX_LIBARRAY; id_type_index++) {
94 if (deg_graph->id_type_updated[id_type_index]) {
95 return true;
96 }
97 }
98
99 return false;
100 }
101
DEG_id_type_any_exists(const Depsgraph * depsgraph,short id_type)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
DEG_get_eval_flags_for_id(const Depsgraph * graph,ID * id)108 uint32_t DEG_get_eval_flags_for_id(const Depsgraph *graph, ID *id)
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
DEG_get_customdata_mask_for_object(const Depsgraph * graph,Object * ob,CustomData_MeshMasks * r_mask)129 void DEG_get_customdata_mask_for_object(const Depsgraph *graph,
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
DEG_get_evaluated_scene(const Depsgraph * graph)156 Scene *DEG_get_evaluated_scene(const Depsgraph *graph)
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
DEG_get_evaluated_view_layer(const Depsgraph * graph)166 ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph)
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
DEG_get_evaluated_object(const Depsgraph * depsgraph,Object * object)182 Object *DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
183 {
184 return (Object *)DEG_get_evaluated_id(depsgraph, &object->id);
185 }
186
DEG_get_evaluated_id(const Depsgraph * depsgraph,ID * id)187 ID *DEG_get_evaluated_id(const Depsgraph *depsgraph, ID *id)
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 */
DEG_get_evaluated_rna_pointer(const Depsgraph * depsgraph,PointerRNA * ptr,PointerRNA * r_ptr_eval)204 void DEG_get_evaluated_rna_pointer(const Depsgraph *depsgraph,
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__,
255 RNA_struct_identifier(ptr->type),
256 orig_id->name);
257 }
258 }
259 }
260
DEG_get_original_object(Object * object)261 Object *DEG_get_original_object(Object *object)
262 {
263 return (Object *)DEG_get_original_id(&object->id);
264 }
265
DEG_get_original_id(ID * id)266 ID *DEG_get_original_id(ID *id)
267 {
268 if (id == nullptr) {
269 return nullptr;
270 }
271 if (id->orig_id == nullptr) {
272 return id;
273 }
274 BLI_assert((id->tag & LIB_TAG_COPIED_ON_WRITE) != 0);
275 return (ID *)id->orig_id;
276 }
277
DEG_is_original_id(const ID * id)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 &
297 (LIB_TAG_COPIED_ON_WRITE | LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_LOCALIZED)) {
298 return false;
299 }
300 return true;
301 }
302
DEG_is_original_object(const Object * object)303 bool DEG_is_original_object(const Object *object)
304 {
305 return DEG_is_original_id(&object->id);
306 }
307
DEG_is_evaluated_id(const ID * id)308 bool DEG_is_evaluated_id(const ID *id)
309 {
310 return !DEG_is_original_id(id);
311 }
312
DEG_is_evaluated_object(const Object * object)313 bool DEG_is_evaluated_object(const Object *object)
314 {
315 return !DEG_is_original_object(object);
316 }
317
DEG_is_fully_evaluated(const struct Depsgraph * depsgraph)318 bool DEG_is_fully_evaluated(const struct Depsgraph *depsgraph)
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 }
331