Depsgraph: Cleanup, make naming more understandable
[blender.git] / source / blender / depsgraph / intern / depsgraph.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * The Original Code is Copyright (C) 2013 Blender Foundation.
19  * All rights reserved.
20  *
21  * Original Author: Joshua Leung
22  * Contributor(s): Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/depsgraph.cc
28  *  \ingroup depsgraph
29  *
30  * Core routines for how the Depsgraph works.
31  */
32
33 #include "intern/depsgraph.h" /* own include */
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_utildefines.h"
38 #include "BLI_ghash.h"
39 #include "BLI_listbase.h"
40
41 extern "C" {
42 #include "DNA_action_types.h"
43 #include "DNA_armature_types.h"
44 #include "DNA_constraint_types.h"
45 #include "DNA_key_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_sequence_types.h"
48
49 #include "BKE_depsgraph.h"
50
51 #include "RNA_access.h"
52 }
53
54 #include <cstring>
55
56 #include "DEG_depsgraph.h"
57
58 #include "intern/nodes/deg_node.h"
59 #include "intern/nodes/deg_node_component.h"
60 #include "intern/nodes/deg_node_operation.h"
61
62 #include "intern/depsgraph_intern.h"
63 #include "util/deg_util_foreach.h"
64
65 namespace DEG {
66
67 static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
68 static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
69 static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
70
71 Depsgraph::Depsgraph()
72   : time_source(NULL),
73     need_update(false),
74     layers(0)
75 {
76         BLI_spin_init(&lock);
77         id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
78         entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags");
79 }
80
81 Depsgraph::~Depsgraph()
82 {
83         clear_id_nodes();
84         BLI_ghash_free(id_hash, NULL, NULL);
85         BLI_gset_free(entry_tags, NULL);
86         if (time_source != NULL) {
87                 OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
88         }
89         BLI_spin_end(&lock);
90 }
91
92 /* Query Conditions from RNA ----------------------- */
93
94 static bool pointer_to_component_node_criteria(
95         const PointerRNA *ptr,
96         const PropertyRNA *prop,
97         ID **id,
98         eDepsNode_Type *type,
99         const char **subdata,
100         eDepsOperation_Code *operation_code,
101         const char **operation_name,
102         int *operation_name_tag)
103 {
104         if (ptr->type == NULL) {
105                 return false;
106         }
107         /* Set default values for returns. */
108         *id = (ID *)ptr->id.data;
109         *subdata = "";
110         *operation_code = DEG_OPCODE_OPERATION;
111         *operation_name = "";
112         *operation_name_tag = -1;
113         /* Handling of commonly known scenarios. */
114         if (ptr->type == &RNA_PoseBone) {
115                 bPoseChannel *pchan = (bPoseChannel *)ptr->data;
116                 if (prop != NULL && RNA_property_is_idprop(prop)) {
117                         *type = DEG_NODE_TYPE_PARAMETERS;
118                         *subdata = "";
119                         *operation_code = DEG_OPCODE_PARAMETERS_EVAL;
120                         *operation_name = pchan->name;;
121                 }
122                 else {
123                         /* Bone - generally, we just want the bone component. */
124                         *type = DEG_NODE_TYPE_BONE;
125                         *subdata = pchan->name;
126                 }
127                 return true;
128         }
129         else if (ptr->type == &RNA_Bone) {
130                 Bone *bone = (Bone *)ptr->data;
131                 /* armature-level bone, but it ends up going to bone component anyway */
132                 // NOTE: the ID in thise case will end up being bArmature.
133                 *type = DEG_NODE_TYPE_BONE;
134                 *subdata = bone->name;
135                 return true;
136         }
137         else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
138                 Object *object = (Object *)ptr->id.data;
139                 bConstraint *con = (bConstraint *)ptr->data;
140                 /* Check whether is object or bone constraint. */
141                 if (BLI_findindex(&object->constraints, con) != -1) {
142                         /* Constraint is defining object transform. */
143                         *type = DEG_NODE_TYPE_TRANSFORM;
144                         return true;
145                 }
146                 else if (object->pose != NULL) {
147                         LINKLIST_FOREACH(bPoseChannel *, pchan, &object->pose->chanbase) {
148                                 if (BLI_findindex(&pchan->constraints, con) != -1) {
149                                         /* bone transforms */
150                                         *type = DEG_NODE_TYPE_BONE;
151                                         *subdata = pchan->name;
152                                         return true;
153                                 }
154                         }
155                 }
156         }
157         else if (RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
158                 *type = DEG_NODE_TYPE_GEOMETRY;
159                 return true;
160         }
161         else if (ptr->type == &RNA_Object) {
162                 /* Transforms props? */
163                 if (prop != NULL) {
164                         const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
165                         /* TODO(sergey): How to optimize this? */
166                         if (strstr(prop_identifier, "location") ||
167                             strstr(prop_identifier, "rotation") ||
168                             strstr(prop_identifier, "scale") ||
169                             strstr(prop_identifier, "matrix_"))
170                         {
171                                 *type = DEG_NODE_TYPE_TRANSFORM;
172                                 return true;
173                         }
174                         else if (strstr(prop_identifier, "data")) {
175                                 /* We access object.data, most likely a geometry.
176                                  * Might be a bone tho..
177                                  */
178                                 *type = DEG_NODE_TYPE_GEOMETRY;
179                                 return true;
180                         }
181                 }
182         }
183         else if (ptr->type == &RNA_ShapeKey) {
184                 Key *key = (Key *)ptr->id.data;
185                 /* ShapeKeys are currently handled as geometry on the geometry that
186                  * owns it.
187                  */
188                 *id = key->from;
189                 *type = DEG_NODE_TYPE_GEOMETRY;
190                 return true;
191         }
192         else if (ptr->type == &RNA_Key) {
193                 *id = (ID *)ptr->id.data;
194                 *type = DEG_NODE_TYPE_GEOMETRY;
195                 return true;
196         }
197         else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
198                 Sequence *seq = (Sequence *)ptr->data;
199                 /* Sequencer strip */
200                 *type = DEG_NODE_TYPE_SEQUENCER;
201                 *subdata = seq->name; // xxx?
202                 return true;
203         }
204         if (prop != NULL) {
205                 /* All unknown data effectively falls under "parameter evaluation". */
206                 *type = DEG_NODE_TYPE_PARAMETERS;
207                 *operation_code = DEG_OPCODE_PARAMETERS_EVAL;
208                 *operation_name = "";
209                 *operation_name_tag = -1;
210                 return true;
211         }
212         return false;
213 }
214
215 /* Convenience wrapper to find node given just pointer + property. */
216 DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr,
217                                             const PropertyRNA *prop) const
218 {
219         ID *id;
220         eDepsNode_Type node_type;
221         const char *component_name, *operation_name;
222         eDepsOperation_Code operation_code;
223         int operation_name_tag;
224
225         if (pointer_to_component_node_criteria(
226                          ptr, prop,
227                          &id, &node_type, &component_name,
228                          &operation_code, &operation_name, &operation_name_tag))
229         {
230                 IDDepsNode *id_node = find_id_node(id);
231                 if (id_node == NULL) {
232                         return NULL;
233                 }
234                 ComponentDepsNode *comp_node =
235                         id_node->find_component(node_type, component_name);
236                 if (comp_node == NULL) {
237                         return NULL;
238                 }
239                 if (operation_code == DEG_OPCODE_OPERATION) {
240                         return comp_node;
241                 }
242                 return comp_node->find_operation(operation_code,
243                                                  operation_name,
244                                                  operation_name_tag);
245         }
246         return NULL;
247 }
248
249 /* Node Management ---------------------------- */
250
251 static void id_node_deleter(void *value)
252 {
253         IDDepsNode *id_node = reinterpret_cast<IDDepsNode *>(value);
254         OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
255 }
256
257 TimeSourceDepsNode *Depsgraph::add_time_source()
258 {
259         if (time_source == NULL) {
260                 DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_TIMESOURCE);
261                 time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", "Time Source");
262         }
263         return time_source;
264 }
265
266 TimeSourceDepsNode *Depsgraph::find_time_source() const
267 {
268         return time_source;
269 }
270
271 IDDepsNode *Depsgraph::find_id_node(const ID *id) const
272 {
273         return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id));
274 }
275
276 IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name)
277 {
278         IDDepsNode *id_node = find_id_node(id);
279         if (!id_node) {
280                 DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_ID_REF);
281                 id_node = (IDDepsNode *)factory->create_node(id, "", name);
282                 id->tag |= LIB_TAG_DOIT;
283                 /* register */
284                 BLI_ghash_insert(id_hash, id, id_node);
285         }
286         return id_node;
287 }
288
289 void Depsgraph::clear_id_nodes()
290 {
291         BLI_ghash_clear(id_hash, NULL, id_node_deleter);
292 }
293
294 /* Add new relationship between two nodes. */
295 DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
296                                           OperationDepsNode *to,
297                                           const char *description,
298                                           bool check_unique)
299 {
300         DepsRelation *rel = NULL;
301         if (check_unique) {
302                 rel = check_nodes_connected(from, to, description);
303         }
304         if (rel != NULL) {
305                 return rel;
306         }
307         /* Create new relation, and add it to the graph. */
308         rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
309         /* TODO(sergey): Find a better place for this. */
310 #ifdef WITH_OPENSUBDIV
311         ComponentDepsNode *comp_node = from->owner;
312         if (comp_node->type == DEG_NODE_TYPE_GEOMETRY) {
313                 IDDepsNode *id_to = to->owner->owner;
314                 IDDepsNode *id_from = from->owner->owner;
315                 if (id_to != id_from && (id_to->id->recalc & ID_RECALC_ALL)) {
316                         if ((id_from->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
317                                 id_from->tag_update(this);
318                                 id_from->eval_flags |= DAG_EVAL_NEED_CPU;
319                         }
320                 }
321         }
322 #endif
323         return rel;
324 }
325
326 /* Add new relation between two nodes */
327 DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to,
328                                           const char *description,
329                                           bool check_unique)
330 {
331         DepsRelation *rel = NULL;
332         if (check_unique) {
333                 rel = check_nodes_connected(from, to, description);
334         }
335         if (rel != NULL) {
336                 return rel;
337         }
338         /* Create new relation, and add it to the graph. */
339         rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
340         return rel;
341 }
342
343 DepsRelation *Depsgraph::check_nodes_connected(const DepsNode *from,
344                                                const DepsNode *to,
345                                                const char *description)
346 {
347         foreach (DepsRelation *rel, from->outlinks) {
348                 BLI_assert(rel->from == from);
349                 if (rel->to != to) {
350                         continue;
351                 }
352                 if (description != NULL && !STREQ(rel->name, description)) {
353                         continue;
354                 }
355                 return rel;
356         }
357         return NULL;
358 }
359
360 /* ************************ */
361 /* Relationships Management */
362
363 DepsRelation::DepsRelation(DepsNode *from,
364                            DepsNode *to,
365                            const char *description)
366   : from(from),
367     to(to),
368     name(description),
369     flag(0)
370 {
371         /* Hook it up to the nodes which use it.
372          *
373          * NOTE: We register relation in the nodes which this link connects to here
374          * in constructor but we don't unregister it in the destructor.
375          *
376          * Reasoning:
377          *
378          * - Destructor is currently used on global graph destruction, so there's no
379          *   real need in avoiding dangling pointers, all the memory is to be freed
380          *   anyway.
381          *
382          * - Unregistering relation is not a cheap operation, so better to have it
383          *   as an explicit call if we need this.
384          */
385         from->outlinks.push_back(this);
386         to->inlinks.push_back(this);
387 }
388
389 DepsRelation::~DepsRelation()
390 {
391         /* Sanity check. */
392         BLI_assert(this->from && this->to);
393 }
394
395 /* Low level tagging -------------------------------------- */
396
397 /* Tag a specific node as needing updates. */
398 void Depsgraph::add_entry_tag(OperationDepsNode *node)
399 {
400         /* Sanity check. */
401         if (!node)
402                 return;
403
404         /* Add to graph-level set of directly modified nodes to start searching from.
405          * NOTE: this is necessary since we have several thousand nodes to play with...
406          */
407         BLI_gset_insert(entry_tags, node);
408 }
409
410 void Depsgraph::clear_all_nodes()
411 {
412         clear_id_nodes();
413         BLI_ghash_clear(id_hash, NULL, NULL);
414         if (time_source != NULL) {
415                 OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
416                 time_source = NULL;
417         }
418 }
419
420 void deg_editors_id_update(Main *bmain, ID *id)
421 {
422         if (deg_editor_update_id_cb != NULL) {
423                 deg_editor_update_id_cb(bmain, id);
424         }
425 }
426
427 void deg_editors_scene_update(Main *bmain, Scene *scene, bool updated)
428 {
429         if (deg_editor_update_scene_cb != NULL) {
430                 deg_editor_update_scene_cb(bmain, scene, updated);
431         }
432 }
433
434 }  // namespace DEG
435
436 /* **************** */
437 /* Public Graph API */
438
439 /* Initialize a new Depsgraph */
440 Depsgraph *DEG_graph_new()
441 {
442         DEG::Depsgraph *deg_depsgraph = OBJECT_GUARDED_NEW(DEG::Depsgraph);
443         return reinterpret_cast<Depsgraph *>(deg_depsgraph);
444 }
445
446 /* Free graph's contents and graph itself */
447 void DEG_graph_free(Depsgraph *graph)
448 {
449         using DEG::Depsgraph;
450         DEG::Depsgraph *deg_depsgraph = reinterpret_cast<DEG::Depsgraph *>(graph);
451         OBJECT_GUARDED_DELETE(deg_depsgraph, Depsgraph);
452 }
453
454 /* Set callbacks which are being called when depsgraph changes. */
455 void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func,
456                                DEG_EditorUpdateSceneCb scene_func,
457                                DEG_EditorUpdateScenePreCb scene_pre_func)
458 {
459         DEG::deg_editor_update_id_cb = id_func;
460         DEG::deg_editor_update_scene_cb = scene_func;
461         DEG::deg_editor_update_scene_pre_cb = scene_pre_func;
462 }
463
464 void DEG_editors_update_pre(Main *bmain, Scene *scene, bool time)
465 {
466         if (DEG::deg_editor_update_scene_pre_cb != NULL) {
467                 DEG::deg_editor_update_scene_pre_cb(bmain, scene, time);
468         }
469 }