Depsgraph: New dependency graph integration commit
[blender.git] / source / blender / depsgraph / intern / depsgraph_build.h
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: Lukas Toenne
22  * Contributor(s): None Yet
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #ifndef __DEPSGRAPH_BUILD_H__
28 #define __DEPSGRAPH_BUILD_H__
29
30 struct Base;
31 struct bGPdata;
32 struct ListBase;
33 struct GHash;
34 struct ID;
35 struct FCurve;
36 struct Group;
37 struct Key;
38 struct Main;
39 struct Material;
40 struct MTex;
41 struct bNodeTree;
42 struct Object;
43 struct bPoseChannel;
44 struct bConstraint;
45 struct Scene;
46 struct Tex;
47 struct World;
48
49 struct PropertyRNA;
50
51 struct Depsgraph;
52 struct DepsNode;
53 struct DepsNodeHandle;
54 struct RootDepsNode;
55 struct SubgraphDepsNode;
56 struct IDDepsNode;
57 struct TimeSourceDepsNode;
58 struct ComponentDepsNode;
59 struct OperationDepsNode;
60 struct RootPChanMap;
61
62 struct DepsgraphNodeBuilder {
63         DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph);
64         ~DepsgraphNodeBuilder();
65
66         RootDepsNode *add_root_node();
67         IDDepsNode *add_id_node(ID *id);
68         TimeSourceDepsNode *add_time_source(ID *id);
69
70         ComponentDepsNode *add_component_node(ID *id, eDepsNode_Type comp_type, const string &comp_name = "");
71
72         OperationDepsNode *add_operation_node(ComponentDepsNode *comp_node, eDepsOperation_Type optype,
73                                               DepsEvalOperationCb op, eDepsOperation_Code opcode, const string &description = "");
74         OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, const string &comp_name, eDepsOperation_Type optype,
75                                               DepsEvalOperationCb op, eDepsOperation_Code opcode, const string &description = "");
76         OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, eDepsOperation_Type optype,
77                                               DepsEvalOperationCb op, eDepsOperation_Code opcode, const string &description = "")
78         {
79                 return add_operation_node(id, comp_type, "", optype, op, opcode, description);
80         }
81
82         bool has_operation_node(ID *id, eDepsNode_Type comp_type, const string &comp_name,
83                                 eDepsOperation_Code opcode, const string &description = "");
84
85         OperationDepsNode *find_operation_node(ID *id,
86                                                eDepsNode_Type comp_type,
87                                                const string &comp_name,
88                                                eDepsOperation_Code opcode,
89                                                const string &description = "");
90
91         OperationDepsNode *find_operation_node(ID *id,
92                                                eDepsNode_Type comp_type,
93                                                eDepsOperation_Code opcode,
94                                                const string &description = "")
95         {
96                 return find_operation_node(id, comp_type, "", opcode, description);
97         }
98
99         void build_scene(Main *bmain, Scene *scene);
100         SubgraphDepsNode *build_subgraph(Group *group);
101         void build_group(Scene *scene, Base *base, Group *group);
102         void build_object(Scene *scene, Base *base, Object *ob);
103         void build_object_transform(Scene *scene, Object *ob);
104         void build_object_constraints(Scene *scene, Object *ob);
105         void build_pose_constraints(Object *ob, bPoseChannel *pchan);
106         void build_rigidbody(Scene *scene);
107         void build_particles(Object *ob);
108         void build_animdata(ID *id);
109         OperationDepsNode *build_driver(ID *id, FCurve *fcurve);
110         void build_ik_pose(Scene *scene, Object *ob, bPoseChannel *pchan, bConstraint *con);
111         void build_splineik_pose(Scene *scene, Object *ob, bPoseChannel *pchan, bConstraint *con);
112         void build_rig(Scene *scene, Object *ob);
113         void build_proxy_rig(Object *ob);
114         void build_shapekeys(Key *key);
115         void build_obdata_geom(Scene *scene, Object *ob);
116         void build_camera(Object *ob);
117         void build_lamp(Object *ob);
118         void build_nodetree(DepsNode *owner_node, bNodeTree *ntree);
119         void build_material(DepsNode *owner_node, Material *ma);
120         void build_texture(DepsNode *owner_node, Tex *tex);
121         void build_texture_stack(DepsNode *owner_node, MTex **texture_stack);
122         void build_world(World *world);
123         void build_compositor(Scene *scene);
124         void build_gpencil(bGPdata *gpd);
125
126 private:
127         Main *m_bmain;
128         Depsgraph *m_graph;
129 };
130
131 struct RootKey
132 {
133         RootKey() {}
134 };
135
136 struct TimeSourceKey
137 {
138         TimeSourceKey() : id(NULL) {}
139         TimeSourceKey(ID *id) : id(id) {}
140
141         string identifier() const
142         {
143                 return string("TimeSourceKey");
144         }
145
146         ID *id;
147 };
148
149 struct ComponentKey
150 {
151         ComponentKey() :
152             id(NULL), type(DEPSNODE_TYPE_UNDEFINED), name("")
153         {}
154         ComponentKey(ID *id, eDepsNode_Type type, const string &name = "") :
155             id(id), type(type), name(name)
156         {}
157
158         string identifier() const
159         {
160                 const char *idname = (id) ? id->name : "<None>";
161
162                 char typebuf[5];
163                 sprintf(typebuf, "%d", type);
164
165                 return string("ComponentKey(") + idname + ", " + typebuf + ", '" + name + "')";
166         }
167
168         ID *id;
169         eDepsNode_Type type;
170         string name;
171 };
172
173 struct OperationKey
174 {
175         OperationKey() :
176             id(NULL), component_type(DEPSNODE_TYPE_UNDEFINED), component_name(""), opcode(DEG_OPCODE_OPERATION), name("")
177         {}
178
179         OperationKey(ID *id, eDepsNode_Type component_type, const string &name) :
180             id(id), component_type(component_type), component_name(""), opcode(DEG_OPCODE_OPERATION), name(name)
181         {}
182         OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, const string &name) :
183             id(id), component_type(component_type), component_name(component_name), opcode(DEG_OPCODE_OPERATION), name(name)
184         {}
185
186         OperationKey(ID *id, eDepsNode_Type component_type, eDepsOperation_Code opcode) :
187             id(id), component_type(component_type), component_name(""), opcode(opcode), name("")
188         {}
189         OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, eDepsOperation_Code opcode) :
190             id(id), component_type(component_type), component_name(component_name), opcode(opcode), name("")
191         {}
192
193         OperationKey(ID *id, eDepsNode_Type component_type, eDepsOperation_Code opcode, const string &name) :
194             id(id), component_type(component_type), component_name(""), opcode(opcode), name(name)
195         {}
196         OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, eDepsOperation_Code opcode, const string &name) :
197             id(id), component_type(component_type), component_name(component_name), opcode(opcode), name(name)
198         {}
199
200         string identifier() const
201         {
202                 char typebuf[5];
203                 sprintf(typebuf, "%d", component_type);
204
205                 return string("OperationKey(") + "t: " + typebuf + ", cn: '" + component_name + "', c: " + DEG_OPNAMES[opcode] + ", n: '" + name + "')";
206         }
207
208
209         ID *id;
210         eDepsNode_Type component_type;
211         string component_name;
212         eDepsOperation_Code opcode;
213         string name;
214 };
215
216 struct RNAPathKey
217 {
218         // Note: see depsgraph_build.cpp for implementation
219         RNAPathKey(ID *id, const string &path);
220
221         RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop) :
222             id(id), ptr(ptr), prop(prop)
223         {}
224
225         string identifier() const
226         {
227                 const char *id_name   = (id) ?  id->name : "<No ID>";
228                 const char *prop_name = (prop) ? RNA_property_identifier(prop) : "<No Prop>";
229
230                 return string("RnaPathKey(") + "id: " + id_name + ", prop: " + prop_name +  "')";
231         }
232
233
234         ID *id;
235         PointerRNA ptr;
236         PropertyRNA *prop;
237 };
238
239 struct DepsgraphRelationBuilder
240 {
241         DepsgraphRelationBuilder(Depsgraph *graph);
242
243         template <typename KeyFrom, typename KeyTo>
244         void add_relation(const KeyFrom &key_from, const KeyTo &key_to,
245                           eDepsRelation_Type type, const char *description);
246
247         template <typename KeyTo>
248         void add_relation(const TimeSourceKey &key_from, const KeyTo &key_to,
249                           eDepsRelation_Type type, const char *description);
250
251         template <typename KeyType>
252         void add_node_handle_relation(const KeyType &key_from, const DepsNodeHandle *handle,
253                                       eDepsRelation_Type type, const char *description);
254
255         void build_scene(Main *bmain, Scene *scene);
256         void build_group(Main *bmain, Scene *scene, Object *object, Group *group);
257         void build_object(Main *bmain, Scene *scene, Object *ob);
258         void build_object_parent(Object *ob);
259         void build_constraints(Scene *scene, ID *id, eDepsNode_Type component_type, const char *component_subdata,
260                                ListBase *constraints, RootPChanMap *root_map);
261         void build_animdata(ID *id);
262         void build_driver(ID *id, FCurve *fcurve);
263         void build_world(World *world);
264         void build_rigidbody(Scene *scene);
265         void build_particles(Scene *scene, Object *ob);
266         void build_ik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con, RootPChanMap *root_map);
267         void build_splineik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con, RootPChanMap *root_map);
268         void build_rig(Scene *scene, Object *ob);
269         void build_proxy_rig(Object *ob);
270         void build_shapekeys(ID *obdata, Key *key);
271         void build_obdata_geom(Main *bmain, Scene *scene, Object *ob);
272         void build_camera(Object *ob);
273         void build_lamp(Object *ob);
274         void build_nodetree(ID *owner, bNodeTree *ntree);
275         void build_material(ID *owner, Material *ma);
276         void build_texture(ID *owner, Tex *tex);
277         void build_texture_stack(ID *owner, MTex **texture_stack);
278         void build_compositor(Scene *scene);
279         void build_gpencil(ID *owner, bGPdata *gpd);
280
281 protected:
282         RootDepsNode *find_node(const RootKey &key) const;
283         TimeSourceDepsNode *find_node(const TimeSourceKey &key) const;
284         ComponentDepsNode *find_node(const ComponentKey &key) const;
285         OperationDepsNode *find_node(const OperationKey &key) const;
286         DepsNode *find_node(const RNAPathKey &key) const;
287         OperationDepsNode *has_node(const OperationKey &key) const;
288
289         void add_time_relation(TimeSourceDepsNode *timesrc, DepsNode *node_to, const char *description);
290         void add_operation_relation(OperationDepsNode *node_from, OperationDepsNode *node_to,
291                                     eDepsRelation_Type type, const char *description);
292
293         template <typename KeyType>
294         DepsNodeHandle create_node_handle(const KeyType &key, const string &default_name = "");
295
296         bool needs_animdata_node(ID *id);
297
298 private:
299         Depsgraph *m_graph;
300 };
301
302 struct DepsNodeHandle
303 {
304         DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const string &default_name = "") :
305             builder(builder),
306             node(node),
307             default_name(default_name)
308         {
309                 BLI_assert(node != NULL);
310         }
311
312         DepsgraphRelationBuilder *builder;
313         OperationDepsNode *node;
314         const string &default_name;
315 };
316
317 /* Utilities for Builders ----------------------------------------------------- */
318
319 /* Get unique identifier for FCurves and Drivers */
320 string deg_fcurve_id_name(const FCurve *fcu);
321
322 template <typename KeyFrom, typename KeyTo>
323 void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
324                                             const KeyTo &key_to,
325                                             eDepsRelation_Type type,
326                                             const char *description)
327 {
328         DepsNode *node_from = find_node(key_from);
329         DepsNode *node_to = find_node(key_to);
330         OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
331         OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
332         if (op_from && op_to) {
333                 add_operation_relation(op_from, op_to, type, description);
334         }
335         else {
336                 if (!op_from) {
337                         /* XXX TODO handle as error or report if needed */
338                         fprintf(stderr, "add_relation(%d, %s) - Could not find op_from (%s)\n",
339                                 type, description, key_from.identifier().c_str());
340                 }
341                 else {
342                         fprintf(stderr, "add_relation(%d, %s) - Failed, but op_from (%s) was ok\n",
343                                 type, description, key_from.identifier().c_str());
344                 }
345                 if (!op_to) {
346                         /* XXX TODO handle as error or report if needed */
347                         fprintf(stderr, "add_relation(%d, %s) - Could not find op_to (%s)\n",
348                                 type, description, key_to.identifier().c_str());
349                 }
350                 else {
351                         fprintf(stderr, "add_relation(%d, %s) - Failed, but op_to (%s) was ok\n",
352                                 type, description, key_to.identifier().c_str());
353                 }
354         }
355 }
356
357 template <typename KeyTo>
358 void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
359                                             const KeyTo &key_to,
360                                             eDepsRelation_Type type,
361                                             const char *description)
362 {
363         (void)type;  /* Ignored in release builds. */
364         BLI_assert(type == DEPSREL_TYPE_TIME);
365         TimeSourceDepsNode *time_from = find_node(key_from);
366         DepsNode *node_to = find_node(key_to);
367         OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
368         if (time_from && op_to) {
369                 add_time_relation(time_from, op_to, description);
370         }
371         else {
372         }
373 }
374
375 template <typename KeyType>
376 void DepsgraphRelationBuilder::add_node_handle_relation(const KeyType &key_from,
377                                                         const DepsNodeHandle *handle,
378                                                         eDepsRelation_Type type,
379                                                         const char *description)
380 {
381         DepsNode *node_from = find_node(key_from);
382         OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
383         OperationDepsNode *op_to = handle->node->get_entry_operation();
384         if (op_from && op_to) {
385                 add_operation_relation(op_from, op_to, type, description);
386         }
387         else {
388                 if (!op_from) {
389                         /* XXX TODO handle as error or report if needed */
390                 }
391                 if (!op_to) {
392                         /* XXX TODO handle as error or report if needed */
393                 }
394         }
395 }
396
397 template <typename KeyType>
398 DepsNodeHandle DepsgraphRelationBuilder::create_node_handle(const KeyType &key,
399                                                             const string &default_name)
400 {
401         return DepsNodeHandle(this, find_node(key), default_name);
402 }
403
404 #endif  /* __DEPSGRAPH_BUILD_H__ */