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