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