Merge branch 'master' into blender2.8
[blender.git] / source / blender / depsgraph / intern / nodes / deg_node_component.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): None Yet
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/depsgraph/intern/nodes/deg_node_component.cc
28  *  \ingroup depsgraph
29  */
30
31 #include "intern/nodes/deg_node_component.h"
32
33 #include <stdio.h>
34 #include <cstring>  /* required for STREQ later on. */
35
36 #include "BLI_utildefines.h"
37 #include "BLI_ghash.h"
38
39 extern "C" {
40 #include "DNA_object_types.h"
41
42 #include "BKE_action.h"
43 } /* extern "C" */
44
45 #include "intern/nodes/deg_node_id.h"
46 #include "intern/nodes/deg_node_operation.h"
47 #include "intern/depsgraph_intern.h"
48 #include "util/deg_util_foreach.h"
49
50 namespace DEG {
51
52 /* *********** */
53 /* Outer Nodes */
54
55 /* Standard Component Methods ============================= */
56
57 ComponentDepsNode::OperationIDKey::OperationIDKey()
58         : opcode(DEG_OPCODE_OPERATION),
59           name(""),
60           name_tag(-1)
61 {
62 }
63
64 ComponentDepsNode::OperationIDKey::OperationIDKey(eDepsOperation_Code opcode)
65         : opcode(opcode),
66           name(""),
67           name_tag(-1)
68 {
69 }
70
71 ComponentDepsNode::OperationIDKey::OperationIDKey(eDepsOperation_Code opcode,
72                                                  const char *name,
73                                                  int name_tag)
74         : opcode(opcode),
75           name(name),
76           name_tag(name_tag)
77 {
78 }
79
80 string ComponentDepsNode::OperationIDKey::identifier() const
81 {
82         char codebuf[5];
83         BLI_snprintf(codebuf, sizeof(codebuf), "%d", opcode);
84         return string("OperationIDKey(") + codebuf + ", " + name + ")";
85 }
86
87 bool ComponentDepsNode::OperationIDKey::operator==(
88         const OperationIDKey &other) const
89 {
90         return (opcode == other.opcode) &&
91                (STREQ(name, other.name)) &&
92                (name_tag == other.name_tag);
93 }
94
95 static unsigned int comp_node_hash_key(const void *key_v)
96 {
97         const ComponentDepsNode::OperationIDKey *key =
98                 reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(key_v);
99         return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->opcode),
100                                           BLI_ghashutil_strhash_p(key->name));
101 }
102
103 static bool comp_node_hash_key_cmp(const void *a, const void *b)
104 {
105         const ComponentDepsNode::OperationIDKey *key_a =
106                 reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(a);
107         const ComponentDepsNode::OperationIDKey *key_b =
108                 reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(b);
109         return !(*key_a == *key_b);
110 }
111
112 static void comp_node_hash_key_free(void *key_v)
113 {
114         typedef ComponentDepsNode::OperationIDKey OperationIDKey;
115         OperationIDKey *key = reinterpret_cast<OperationIDKey *>(key_v);
116         OBJECT_GUARDED_DELETE(key, OperationIDKey);
117 }
118
119 static void comp_node_hash_value_free(void *value_v)
120 {
121         OperationDepsNode *op_node = reinterpret_cast<OperationDepsNode *>(value_v);
122         OBJECT_GUARDED_DELETE(op_node, OperationDepsNode);
123 }
124
125 ComponentDepsNode::ComponentDepsNode() :
126     entry_operation(NULL),
127     exit_operation(NULL)
128 {
129         operations_map = BLI_ghash_new(comp_node_hash_key,
130                                        comp_node_hash_key_cmp,
131                                        "Depsgraph id hash");
132 }
133
134 /* Initialize 'component' node - from pointer data given */
135 void ComponentDepsNode::init(const ID * /*id*/,
136                              const char * /*subdata*/)
137 {
138         /* hook up eval context? */
139         // XXX: maybe this needs a special API?
140 }
141
142 /* Free 'component' node */
143 ComponentDepsNode::~ComponentDepsNode()
144 {
145         clear_operations();
146         if (operations_map != NULL) {
147                 BLI_ghash_free(operations_map,
148                                comp_node_hash_key_free,
149                                comp_node_hash_value_free);
150         }
151 }
152
153 string ComponentDepsNode::identifier() const
154 {
155         string idname = this->owner->name;
156
157         char typebuf[16];
158         sprintf(typebuf, "(%d)", type);
159
160         return string(typebuf) + name + " : " + idname;
161 }
162
163 OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const
164 {
165         OperationDepsNode *node = NULL;
166         if (operations_map != NULL) {
167                 node = (OperationDepsNode *)BLI_ghash_lookup(operations_map, &key);
168         }
169         else {
170                 BLI_assert(key.name_tag == -1);
171                 foreach (OperationDepsNode *op_node, operations) {
172                         if (op_node->opcode == key.opcode &&
173                             STREQ(op_node->name, key.name))
174                         {
175                                 node = op_node;
176                                 break;
177                         }
178                 }
179         }
180         return node;
181 }
182
183 OperationDepsNode *ComponentDepsNode::find_operation(eDepsOperation_Code opcode,
184                                                     const char *name,
185                                                     int name_tag) const
186 {
187         OperationIDKey key(opcode, name, name_tag);
188         return find_operation(key);
189 }
190
191 OperationDepsNode *ComponentDepsNode::get_operation(OperationIDKey key) const
192 {
193         OperationDepsNode *node = find_operation(key);
194         if (node == NULL) {
195                 fprintf(stderr, "%s: find_operation(%s) failed\n",
196                         this->identifier().c_str(), key.identifier().c_str());
197                 BLI_assert(!"Request for non-existing operation, should not happen");
198                 return NULL;
199         }
200         return node;
201 }
202
203 OperationDepsNode *ComponentDepsNode::get_operation(eDepsOperation_Code opcode,
204                                                     const char *name,
205                                                     int name_tag) const
206 {
207         OperationIDKey key(opcode, name, name_tag);
208         return get_operation(key);
209 }
210
211 bool ComponentDepsNode::has_operation(OperationIDKey key) const
212 {
213         return find_operation(key) != NULL;
214 }
215
216 bool ComponentDepsNode::has_operation(eDepsOperation_Code opcode,
217                                       const char *name,
218                                       int name_tag) const
219 {
220         OperationIDKey key(opcode, name, name_tag);
221         return has_operation(key);
222 }
223
224 OperationDepsNode *ComponentDepsNode::add_operation(const DepsEvalOperationCb& op,
225                                                     eDepsOperation_Code opcode,
226                                                     const char *name,
227                                                     int name_tag)
228 {
229         OperationDepsNode *op_node = find_operation(opcode, name, name_tag);
230         if (!op_node) {
231                 DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_OPERATION);
232                 op_node = (OperationDepsNode *)factory->create_node(this->owner->id_orig, "", name);
233
234                 /* register opnode in this component's operation set */
235                 OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag);
236                 BLI_ghash_insert(operations_map, key, op_node);
237
238                 /* set backlink */
239                 op_node->owner = this;
240         }
241         else {
242                 fprintf(stderr, "add_operation: Operation already exists - %s has %s at %p\n",
243                         this->identifier().c_str(), op_node->identifier().c_str(), op_node);
244                 BLI_assert(!"Should not happen!");
245         }
246
247         /* attach extra data */
248         op_node->evaluate = op;
249         op_node->opcode = opcode;
250         op_node->name = name;
251
252         return op_node;
253 }
254
255 void ComponentDepsNode::set_entry_operation(OperationDepsNode *op_node)
256 {
257         BLI_assert(entry_operation == NULL);
258         entry_operation = op_node;
259 }
260
261 void ComponentDepsNode::set_exit_operation(OperationDepsNode *op_node)
262 {
263         BLI_assert(exit_operation == NULL);
264         exit_operation = op_node;
265 }
266
267 void ComponentDepsNode::clear_operations()
268 {
269         if (operations_map != NULL) {
270                 BLI_ghash_clear(operations_map,
271                                 comp_node_hash_key_free,
272                                 comp_node_hash_value_free);
273         }
274         foreach (OperationDepsNode *op_node, operations) {
275                 OBJECT_GUARDED_DELETE(op_node, OperationDepsNode);
276         }
277         operations.clear();
278 }
279
280 void ComponentDepsNode::tag_update(Depsgraph *graph)
281 {
282         OperationDepsNode *entry_op = get_entry_operation();
283         if (entry_op != NULL && entry_op->flag & DEPSOP_FLAG_NEEDS_UPDATE) {
284                 return;
285         }
286         foreach (OperationDepsNode *op_node, operations) {
287                 op_node->tag_update(graph);
288         }
289         // It is possible that tag happens before finalization.
290         if (operations_map != NULL) {
291                 GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map)
292                 {
293                         op_node->tag_update(graph);
294                 }
295                 GHASH_FOREACH_END();
296         }
297 }
298
299 OperationDepsNode *ComponentDepsNode::get_entry_operation()
300 {
301         if (entry_operation) {
302                 return entry_operation;
303         }
304         else if (operations_map != NULL && BLI_ghash_size(operations_map) == 1) {
305                 OperationDepsNode *op_node = NULL;
306                 /* TODO(sergey): This is somewhat slow. */
307                 GHASH_FOREACH_BEGIN(OperationDepsNode *, tmp, operations_map)
308                 {
309                         op_node = tmp;
310                 }
311                 GHASH_FOREACH_END();
312                 /* Cache for the subsequent usage. */
313                 entry_operation = op_node;
314                 return op_node;
315         }
316         else if (operations.size() == 1) {
317                 return operations[0];
318         }
319         return NULL;
320 }
321
322 OperationDepsNode *ComponentDepsNode::get_exit_operation()
323 {
324         if (exit_operation) {
325                 return exit_operation;
326         }
327         else if (operations_map != NULL && BLI_ghash_size(operations_map) == 1) {
328                 OperationDepsNode *op_node = NULL;
329                 /* TODO(sergey): This is somewhat slow. */
330                 GHASH_FOREACH_BEGIN(OperationDepsNode *, tmp, operations_map)
331                 {
332                         op_node = tmp;
333                 }
334                 GHASH_FOREACH_END();
335                 /* Cache for the subsequent usage. */
336                 exit_operation = op_node;
337                 return op_node;
338         }
339         else if (operations.size() == 1) {
340                 return operations[0];
341         }
342         return NULL;
343 }
344
345 void ComponentDepsNode::finalize_build(Depsgraph * /*graph*/)
346 {
347         operations.reserve(BLI_ghash_size(operations_map));
348         GHASH_FOREACH_BEGIN(OperationDepsNode *, op_node, operations_map)
349         {
350                 operations.push_back(op_node);
351         }
352         GHASH_FOREACH_END();
353         BLI_ghash_free(operations_map,
354                        comp_node_hash_key_free,
355                        NULL);
356         operations_map = NULL;
357 }
358
359 /* Bone Component ========================================= */
360
361 /* Initialize 'bone component' node - from pointer data given */
362 void BoneComponentDepsNode::init(const ID *id, const char *subdata)
363 {
364         /* generic component-node... */
365         ComponentDepsNode::init(id, subdata);
366
367         /* name of component comes is bone name */
368         /* TODO(sergey): This sets name to an empty string because subdata is
369          * empty. Is it a bug?
370          */
371         //this->name = subdata;
372
373         /* bone-specific node data */
374         Object *object = (Object *)id;
375         this->pchan = BKE_pose_channel_find_name(object->pose, subdata);
376 }
377
378 /* Register all components. =============================== */
379
380 DEG_COMPONENT_NODE_DEFINE(Animation,         ANIMATION,          ID_RECALC_ANIMATION);
381 DEG_COMPONENT_NODE_DEFINE(BatchCache,        BATCH_CACHE,        ID_RECALC_DRAW_CACHE);
382 DEG_COMPONENT_NODE_DEFINE(Bone,              BONE,               ID_RECALC_GEOMETRY);
383 DEG_COMPONENT_NODE_DEFINE(Cache,             CACHE,              ID_RECALC);
384 DEG_COMPONENT_NODE_DEFINE(CopyOnWrite,       COPY_ON_WRITE,      ID_RECALC);
385 DEG_COMPONENT_NODE_DEFINE(Geometry,          GEOMETRY,           ID_RECALC_GEOMETRY);
386 DEG_COMPONENT_NODE_DEFINE(LayerCollections,  LAYER_COLLECTIONS,  ID_RECALC_COLLECTIONS);
387 DEG_COMPONENT_NODE_DEFINE(Parameters,        PARAMETERS,         ID_RECALC);
388 DEG_COMPONENT_NODE_DEFINE(Particles,         EVAL_PARTICLES,     ID_RECALC_GEOMETRY);
389 DEG_COMPONENT_NODE_DEFINE(Proxy,             PROXY,              ID_RECALC_GEOMETRY);
390 DEG_COMPONENT_NODE_DEFINE(Pose,              EVAL_POSE,          ID_RECALC_GEOMETRY);
391 DEG_COMPONENT_NODE_DEFINE(Sequencer,         SEQUENCER,          ID_RECALC);
392 DEG_COMPONENT_NODE_DEFINE(Shading,           SHADING,            ID_RECALC_DRAW);
393 DEG_COMPONENT_NODE_DEFINE(ShadingParameters, SHADING_PARAMETERS, ID_RECALC_DRAW);
394 DEG_COMPONENT_NODE_DEFINE(Transform,         TRANSFORM,          ID_RECALC_TRANSFORM);
395
396 /* Node Types Register =================================== */
397
398 void deg_register_component_depsnodes()
399 {
400         deg_register_node_typeinfo(&DNTI_ANIMATION);
401         deg_register_node_typeinfo(&DNTI_BONE);
402         deg_register_node_typeinfo(&DNTI_CACHE);
403         deg_register_node_typeinfo(&DNTI_BATCH_CACHE);
404         deg_register_node_typeinfo(&DNTI_COPY_ON_WRITE);
405         deg_register_node_typeinfo(&DNTI_GEOMETRY);
406         deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS);
407         deg_register_node_typeinfo(&DNTI_PARAMETERS);
408         deg_register_node_typeinfo(&DNTI_EVAL_PARTICLES);
409         deg_register_node_typeinfo(&DNTI_PROXY);
410         deg_register_node_typeinfo(&DNTI_EVAL_POSE);
411         deg_register_node_typeinfo(&DNTI_SEQUENCER);
412         deg_register_node_typeinfo(&DNTI_SHADING);
413         deg_register_node_typeinfo(&DNTI_SHADING_PARAMETERS);
414         deg_register_node_typeinfo(&DNTI_TRANSFORM);
415 }
416
417 }  // namespace DEG