Merge branch 'master' into blender2.8
[blender.git] / source / blender / makesrna / intern / rna_depsgraph.c
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  * Contributor(s): Blender Foundation (2014).
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_depsgraph.c
24  *  \ingroup RNA
25  */
26
27 #include <stdlib.h>
28
29 #include "BLI_utildefines.h"
30 #include "BLI_path_util.h"
31
32 #include "RNA_define.h"
33 #include "RNA_enum_types.h"
34
35 #include "rna_internal.h"
36
37 #include "DEG_depsgraph.h"
38
39 #include "DNA_object_types.h"
40
41 #define STATS_MAX_SIZE 16384
42
43 #ifdef RNA_RUNTIME
44
45 #include "BLI_iterator.h"
46
47 #include "DEG_depsgraph_build.h"
48 #include "DEG_depsgraph_debug.h"
49 #include "DEG_depsgraph_query.h"
50
51 #include "MEM_guardedalloc.h"
52
53 /* **************** Depsgraph **************** */
54
55 static PointerRNA rna_DepsgraphIter_object_get(PointerRNA *ptr)
56 {
57         BLI_Iterator *iterator = ptr->data;
58         return rna_pointer_inherit_refine(ptr, &RNA_Object, iterator->current);
59 }
60
61 static PointerRNA rna_DepsgraphIter_instance_object_get(PointerRNA *ptr)
62 {
63         BLI_Iterator *iterator = ptr->data;
64         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
65         Object *instance_object = NULL;
66         if (deg_iter->dupli_object_current != NULL) {
67                 instance_object = deg_iter->dupli_object_current->ob;
68         }
69         return rna_pointer_inherit_refine(ptr, &RNA_Object, instance_object);
70 }
71
72 static PointerRNA rna_DepsgraphIter_parent_get(PointerRNA *ptr)
73 {
74         BLI_Iterator *iterator = ptr->data;
75         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
76         Object *dupli_parent = NULL;
77         if (deg_iter->dupli_object_current != NULL) {
78                 dupli_parent = deg_iter->dupli_parent;
79         }
80         return rna_pointer_inherit_refine(ptr, &RNA_Object, dupli_parent);
81 }
82
83 static void rna_DepsgraphIter_persistent_id_get(PointerRNA *ptr, int *persistent_id)
84 {
85         BLI_Iterator *iterator = ptr->data;
86         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
87         memcpy(persistent_id, deg_iter->dupli_object_current->persistent_id,
88                sizeof(deg_iter->dupli_object_current->persistent_id));
89 }
90
91 static void rna_DepsgraphIter_orco_get(PointerRNA *ptr, float *orco)
92 {
93         BLI_Iterator *iterator = ptr->data;
94         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
95         memcpy(orco, deg_iter->dupli_object_current->orco,
96                sizeof(deg_iter->dupli_object_current->orco));
97 }
98
99 static unsigned int rna_DepsgraphIter_random_id_get(PointerRNA *ptr)
100 {
101         BLI_Iterator *iterator = ptr->data;
102         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
103         return deg_iter->dupli_object_current->random_id;
104 }
105
106 static void rna_DepsgraphIter_uv_get(PointerRNA *ptr, float *uv)
107 {
108         BLI_Iterator *iterator = ptr->data;
109         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
110         memcpy(uv, deg_iter->dupli_object_current->uv,
111                sizeof(deg_iter->dupli_object_current->uv));
112 }
113
114 static int rna_DepsgraphIter_is_instance_get(PointerRNA *ptr)
115 {
116         BLI_Iterator *iterator = ptr->data;
117         DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
118         return (deg_iter->dupli_object_current != NULL);
119 }
120
121 /* **************** Depsgraph **************** */
122
123 static void rna_Depsgraph_debug_relations_graphviz(Depsgraph *depsgraph,
124                                                    const char *filename)
125 {
126         FILE *f = fopen(filename, "w");
127         if (f == NULL) {
128                 return;
129         }
130         DEG_debug_relations_graphviz(depsgraph, f, "Depsgraph");
131         fclose(f);
132 }
133
134 static void rna_Depsgraph_debug_stats_gnuplot(Depsgraph *depsgraph,
135                                               const char *filename,
136                                               const char *output_filename)
137 {
138         FILE *f = fopen(filename, "w");
139         if (f == NULL) {
140                 return;
141         }
142         DEG_debug_stats_gnuplot(depsgraph, f, "Timing Statistics", output_filename);
143         fclose(f);
144 }
145
146 static void rna_Depsgraph_debug_tag_update(Depsgraph *depsgraph)
147 {
148         DEG_graph_tag_relations_update(depsgraph);
149 }
150
151 static void rna_Depsgraph_debug_stats(Depsgraph *depsgraph, char *result)
152 {
153         size_t outer, ops, rels;
154         DEG_stats_simple(depsgraph, &outer, &ops, &rels);
155         BLI_snprintf(result, STATS_MAX_SIZE,
156                     "Approx %lu Operations, %lu Relations, %lu Outer Nodes",
157                      ops, rels, outer);
158 }
159
160 /* Iteration over objects, simple version */
161
162 static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
163 {
164         iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
165         DEGObjectIterData *data = MEM_callocN(sizeof(DEGObjectIterData), __func__);
166
167         data->graph = (Depsgraph *)ptr->data;
168         data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
169                      DEG_ITER_OBJECT_FLAG_VISIBLE |
170                      DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
171         data->mode = DEG_ITER_OBJECT_MODE_RENDER;
172
173         ((BLI_Iterator *)iter->internal.custom)->valid = true;
174         DEG_iterator_objects_begin(iter->internal.custom, data);
175         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
176 }
177
178 static void rna_Depsgraph_objects_next(CollectionPropertyIterator *iter)
179 {
180         DEG_iterator_objects_next(iter->internal.custom);
181         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
182 }
183
184 static void rna_Depsgraph_objects_end(CollectionPropertyIterator *iter)
185 {
186         DEG_iterator_objects_end(iter->internal.custom);
187         MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
188         MEM_freeN(iter->internal.custom);
189 }
190
191 static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter)
192 {
193         Object *ob = ((BLI_Iterator *)iter->internal.custom)->current;
194         return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ob);
195 }
196
197 /* Iteration over objects, extended version
198  *
199  * Contains extra information about duplicator and persistent ID.
200  */
201
202 static void rna_Depsgraph_duplis_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
203 {
204         iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
205         DEGObjectIterData *data = MEM_callocN(sizeof(DEGObjectIterData), __func__);
206
207         data->graph = (Depsgraph *)ptr->data;
208         data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
209                      DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
210                      DEG_ITER_OBJECT_FLAG_VISIBLE |
211                      DEG_ITER_OBJECT_FLAG_DUPLI;
212         data->mode = DEG_ITER_OBJECT_MODE_RENDER;
213
214         ((BLI_Iterator *)iter->internal.custom)->valid = true;
215         DEG_iterator_objects_begin(iter->internal.custom, data);
216         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
217 }
218
219 static void rna_Depsgraph_duplis_next(CollectionPropertyIterator *iter)
220 {
221         DEG_iterator_objects_next(iter->internal.custom);
222         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
223 }
224
225 static void rna_Depsgraph_duplis_end(CollectionPropertyIterator *iter)
226 {
227         DEG_iterator_objects_end(iter->internal.custom);
228         MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
229         MEM_freeN(iter->internal.custom);
230 }
231
232 static PointerRNA rna_Depsgraph_duplis_get(CollectionPropertyIterator *iter)
233 {
234         BLI_Iterator *iterator = (BLI_Iterator *)iter->internal.custom;
235         return rna_pointer_inherit_refine(&iter->parent, &RNA_DepsgraphIter, iterator);
236 }
237
238 static ID *rna_Depsgraph_evaluated_id_get(Depsgraph *depsgraph, ID *id_orig)
239 {
240         return DEG_get_evaluated_id(depsgraph, id_orig);
241 }
242
243 #else
244
245 static void rna_def_depsgraph_iter(BlenderRNA *brna)
246 {
247         StructRNA *srna;
248         PropertyRNA *prop;
249
250         srna = RNA_def_struct(brna, "DepsgraphIter", NULL);
251         RNA_def_struct_ui_text(srna, "Dependency Graph Iterator",
252                                "Extended information about dependency graph object iterator");
253
254         prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
255         RNA_def_property_struct_type(prop, "Object");
256         RNA_def_property_ui_text(prop, "Object", "Object the iterator points to");
257         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
258         RNA_def_property_pointer_funcs(prop, "rna_DepsgraphIter_object_get", NULL, NULL, NULL);
259
260         prop = RNA_def_property(srna, "instance_object", PROP_POINTER, PROP_NONE);
261         RNA_def_property_struct_type(prop, "Object");
262         RNA_def_property_ui_text(prop, "Instance Object", "Object which is being instanced by this iterator");
263         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
264         RNA_def_property_pointer_funcs(prop, "rna_DepsgraphIter_instance_object_get", NULL, NULL, NULL);
265
266         prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
267         RNA_def_property_struct_type(prop, "Object");
268         RNA_def_property_ui_text(prop, "Parent", "Parent of the duplication list");
269         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
270         RNA_def_property_pointer_funcs(prop, "rna_DepsgraphIter_parent_get", NULL, NULL, NULL);
271
272         prop = RNA_def_property(srna, "persistent_id", PROP_INT, PROP_NONE);
273         RNA_def_property_ui_text(prop, "Persistent ID",
274                                  "Persistent identifier for inter-frame matching of objects with motion blur");
275         RNA_def_property_array(prop, 2 * MAX_DUPLI_RECUR);
276         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
277         RNA_def_property_int_funcs(prop, "rna_DepsgraphIter_persistent_id_get", NULL, NULL);
278
279         prop = RNA_def_property(srna, "orco", PROP_FLOAT, PROP_TRANSLATION);
280         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
281         /* Seems system is not smart enough to figure that getter function should return
282          * array for PROP_TRANSLATION.
283          */
284         RNA_def_property_array(prop, 3);
285         RNA_def_property_ui_text(prop, "Generated Coordinates", "Generated coordinates in parent object space");
286         RNA_def_property_float_funcs(prop, "rna_DepsgraphIter_orco_get", NULL, NULL);
287
288         prop = RNA_def_property(srna, "random_id", PROP_INT, PROP_UNSIGNED);
289         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
290         RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this dupli object");
291         RNA_def_property_int_funcs(prop, "rna_DepsgraphIter_random_id_get", NULL, NULL);
292
293         prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
294         RNA_def_property_ui_text(prop, "UV Coordinates", "UV coordinates in parent object space");
295         RNA_def_property_array(prop, 2);
296         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
297         RNA_def_property_float_funcs(prop, "rna_DepsgraphIter_uv_get", NULL, NULL);
298
299         prop = RNA_def_property(srna, "is_instance", PROP_BOOLEAN, PROP_NONE);
300         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
301         RNA_def_property_ui_text(prop, "Is Instance", "Denotes whether the object is ocming from dupli-list");
302         RNA_def_property_boolean_funcs(prop, "rna_DepsgraphIter_is_instance_get", NULL);
303 }
304
305 static void rna_def_depsgraph(BlenderRNA *brna)
306 {
307         StructRNA *srna;
308         FunctionRNA *func;
309         PropertyRNA *parm;
310         PropertyRNA *prop;
311
312         srna = RNA_def_struct(brna, "Depsgraph", NULL);
313         RNA_def_struct_ui_text(srna, "Dependency Graph", "");
314
315         func = RNA_def_function(srna, "debug_relations_graphviz", "rna_Depsgraph_debug_relations_graphviz");
316         parm = RNA_def_string_file_path(func, "filename", NULL, FILE_MAX, "File Name",
317                                         "File in which to store graphviz debug output");
318         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
319
320         func = RNA_def_function(srna, "debug_stats_gnuplot", "rna_Depsgraph_debug_stats_gnuplot");
321         parm = RNA_def_string_file_path(func, "filename", NULL, FILE_MAX, "File Name",
322                                         "File in which to store graphviz debug output");
323         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
324         parm = RNA_def_string_file_path(func, "output_filename", NULL, FILE_MAX, "Output File Name",
325                                         "File name where gnuplot script will save the result");
326         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
327
328         func = RNA_def_function(srna, "debug_tag_update", "rna_Depsgraph_debug_tag_update");
329
330         func = RNA_def_function(srna, "debug_stats", "rna_Depsgraph_debug_stats");
331         RNA_def_function_ui_description(func, "Report the number of elements in the Dependency Graph");
332         /* weak!, no way to return dynamic string type */
333         parm = RNA_def_string(func, "result", NULL, STATS_MAX_SIZE, "result", "");
334         RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0); /* needed for string return value */
335         RNA_def_function_output(func, parm);
336
337         prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
338         RNA_def_property_struct_type(prop, "Object");
339         RNA_def_property_collection_funcs(prop,
340                                           "rna_Depsgraph_objects_begin",
341                                           "rna_Depsgraph_objects_next",
342                                           "rna_Depsgraph_objects_end",
343                                           "rna_Depsgraph_objects_get",
344                                           NULL, NULL, NULL, NULL);
345
346         func = RNA_def_function(srna, "evaluated_id_get", "rna_Depsgraph_evaluated_id_get");
347         parm = RNA_def_pointer(func, "id", "ID", "", "Original ID to get evaluated complementary part for");
348         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
349         parm = RNA_def_pointer(func, "evaluated_id", "ID", "", "Evaluated ID for the given original one");
350         RNA_def_function_return(func, parm);
351
352         /* TODO(sergey): Find a better name. */
353         prop = RNA_def_property(srna, "duplis", PROP_COLLECTION, PROP_NONE);
354         RNA_def_property_struct_type(prop, "DepsgraphIter");
355         RNA_def_property_collection_funcs(prop,
356                                           "rna_Depsgraph_duplis_begin",
357                                           "rna_Depsgraph_duplis_next",
358                                           "rna_Depsgraph_duplis_end",
359                                           "rna_Depsgraph_duplis_get",
360                                           NULL, NULL, NULL, NULL);
361 }
362
363 void RNA_def_depsgraph(BlenderRNA *brna)
364 {
365         rna_def_depsgraph_iter(brna);
366         rna_def_depsgraph(brna);
367 }
368
369 #endif