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 #ifdef RNA_RUNTIME
42
43 #include "BLI_iterator.h"
44 #include "BKE_report.h"
45
46 #include "DEG_depsgraph_build.h"
47 #include "DEG_depsgraph_debug.h"
48 #include "DEG_depsgraph_query.h"
49
50 #include "MEM_guardedalloc.h"
51
52 /* **************** Depsgraph **************** */
53
54 static PointerRNA rna_DepsgraphIter_object_get(PointerRNA *ptr)
55 {
56         BLI_Iterator *iterator = ptr->data;
57         return rna_pointer_inherit_refine(ptr, &RNA_Object, iterator->current);
58 }
59
60 static PointerRNA rna_DepsgraphIter_instance_object_get(PointerRNA *ptr)
61 {
62         BLI_Iterator *iterator = ptr->data;
63         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
64         Object *instance_object = NULL;
65         if (deg_iter->dupli_object_current != NULL) {
66                 instance_object = deg_iter->dupli_object_current->ob;
67         }
68         return rna_pointer_inherit_refine(ptr, &RNA_Object, instance_object);
69 }
70
71 static PointerRNA rna_DepsgraphIter_parent_get(PointerRNA *ptr)
72 {
73         BLI_Iterator *iterator = ptr->data;
74         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
75         Object *dupli_parent = NULL;
76         if (deg_iter->dupli_object_current != NULL) {
77                 dupli_parent = deg_iter->dupli_parent;
78         }
79         return rna_pointer_inherit_refine(ptr, &RNA_Object, dupli_parent);
80 }
81
82 static void rna_DepsgraphIter_persistent_id_get(PointerRNA *ptr, int *persistent_id)
83 {
84         BLI_Iterator *iterator = ptr->data;
85         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
86         memcpy(persistent_id, deg_iter->dupli_object_current->persistent_id,
87                sizeof(deg_iter->dupli_object_current->persistent_id));
88 }
89
90 static void rna_DepsgraphIter_orco_get(PointerRNA *ptr, float *orco)
91 {
92         BLI_Iterator *iterator = ptr->data;
93         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
94         memcpy(orco, deg_iter->dupli_object_current->orco,
95                sizeof(deg_iter->dupli_object_current->orco));
96 }
97
98 static unsigned int rna_DepsgraphIter_random_id_get(PointerRNA *ptr)
99 {
100         BLI_Iterator *iterator = ptr->data;
101         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
102         return deg_iter->dupli_object_current->random_id;
103 }
104
105 static void rna_DepsgraphIter_uv_get(PointerRNA *ptr, float *uv)
106 {
107         BLI_Iterator *iterator = ptr->data;
108         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
109         memcpy(uv, deg_iter->dupli_object_current->uv,
110                sizeof(deg_iter->dupli_object_current->uv));
111 }
112
113 static int rna_DepsgraphIter_is_instance_get(PointerRNA *ptr)
114 {
115         BLI_Iterator *iterator = ptr->data;
116         DEGObjectsIteratorData *deg_iter = (DEGObjectsIteratorData *)iterator->data;
117         return (deg_iter->dupli_object_current != NULL);
118 }
119
120 /* **************** Depsgraph **************** */
121
122 static void rna_Depsgraph_debug_graphviz(Depsgraph *graph, const char *filename)
123 {
124         FILE *f = fopen(filename, "w");
125         if (f == NULL)
126                 return;
127
128         DEG_debug_graphviz(graph, f, "Depsgraph", false);
129
130         fclose(f);
131 }
132
133 static void rna_Depsgraph_debug_rebuild(Depsgraph *UNUSED(graph), bContext *C)
134 {
135         Main *bmain = CTX_data_main(C);
136         EvaluationContext eval_ctx;
137         Scene *sce;
138
139         CTX_data_eval_ctx(C, &eval_ctx);
140
141         DEG_relations_tag_update(bmain);
142         for (sce = bmain->scene.first; sce; sce = sce->id.next) {
143                 DEG_scene_relations_rebuild(bmain, sce);
144                 DEG_graph_on_visible_update(bmain, sce);
145         }
146 }
147
148 static void rna_Depsgraph_debug_stats(Depsgraph *graph, ReportList *reports)
149 {
150         size_t outer, ops, rels;
151
152         DEG_stats_simple(graph, &outer, &ops, &rels);
153
154         // XXX: report doesn't seem to work
155         printf("Approx %lu Operations, %lu Relations, %lu Outer Nodes\n",
156                ops, rels, outer);
157
158         BKE_reportf(reports, RPT_WARNING, "Approx. %lu Operations, %lu Relations, %lu Outer Nodes",
159                     ops, rels, outer);
160 }
161
162 /* Iteration over objects, simple version */
163
164 static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
165 {
166         iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
167         DEGObjectsIteratorData *data = MEM_callocN(sizeof(DEGObjectsIteratorData), __func__);
168
169         data->graph = (Depsgraph *)ptr->data;
170         data->flag = DEG_OBJECT_ITER_FLAG_SET;
171
172         DEG_objects_iterator_begin(iter->internal.custom, data);
173         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
174 }
175
176 static void rna_Depsgraph_objects_next(CollectionPropertyIterator *iter)
177 {
178         DEG_objects_iterator_next(iter->internal.custom);
179         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
180 }
181
182 static void rna_Depsgraph_objects_end(CollectionPropertyIterator *iter)
183 {
184         DEG_objects_iterator_end(iter->internal.custom);
185         MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
186         MEM_freeN(iter->internal.custom);
187 }
188
189 static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter)
190 {
191         Object *ob = ((BLI_Iterator *)iter->internal.custom)->current;
192         return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ob);
193 }
194
195 /* Iteration over objects, extended version
196  *
197  * Contains extra information about duplicator and persistent ID.
198  */
199
200 static void rna_Depsgraph_duplis_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
201 {
202         iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
203         DEGObjectsIteratorData *data = MEM_callocN(sizeof(DEGObjectsIteratorData), __func__);
204
205         data->graph = (Depsgraph *)ptr->data;
206         data->flag = DEG_OBJECT_ITER_FLAG_ALL;
207
208         DEG_objects_iterator_begin(iter->internal.custom, data);
209         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
210 }
211
212 static void rna_Depsgraph_duplis_next(CollectionPropertyIterator *iter)
213 {
214         DEG_objects_iterator_next(iter->internal.custom);
215         iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
216 }
217
218 static void rna_Depsgraph_duplis_end(CollectionPropertyIterator *iter)
219 {
220         DEG_objects_iterator_end(iter->internal.custom);
221         MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
222         MEM_freeN(iter->internal.custom);
223 }
224
225 static PointerRNA rna_Depsgraph_duplis_get(CollectionPropertyIterator *iter)
226 {
227         BLI_Iterator *iterator = (BLI_Iterator *)iter->internal.custom;
228         return rna_pointer_inherit_refine(&iter->parent, &RNA_DepsgraphIter, iterator);
229 }
230
231 static ID *rna_Depsgraph_evaluated_id_get(Depsgraph *depsgraph, ID *id_orig)
232 {
233         return DEG_get_evaluated_id(depsgraph, id_orig);
234 }
235
236 #else
237
238 static void rna_def_depsgraph_iter(BlenderRNA *brna)
239 {
240         StructRNA *srna;
241         PropertyRNA *prop;
242
243         srna = RNA_def_struct(brna, "DepsgraphIter", NULL);
244         RNA_def_struct_ui_text(srna, "Dependency Graph Iterator",
245                                "Extended information about dependency graph object iterator");
246
247         prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
248         RNA_def_property_struct_type(prop, "Object");
249         RNA_def_property_ui_text(prop, "Object", "Object the iterator points to");
250         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
251         RNA_def_property_pointer_funcs(prop, "rna_DepsgraphIter_object_get", NULL, NULL, NULL);
252
253         prop = RNA_def_property(srna, "instance_object", PROP_POINTER, PROP_NONE);
254         RNA_def_property_struct_type(prop, "Object");
255         RNA_def_property_ui_text(prop, "Instance Object", "Object which is being instanced by this iterator");
256         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
257         RNA_def_property_pointer_funcs(prop, "rna_DepsgraphIter_instance_object_get", NULL, NULL, NULL);
258
259         prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
260         RNA_def_property_struct_type(prop, "Object");
261         RNA_def_property_ui_text(prop, "Parent", "Parent of the duplication list");
262         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
263         RNA_def_property_pointer_funcs(prop, "rna_DepsgraphIter_parent_get", NULL, NULL, NULL);
264
265         prop = RNA_def_property(srna, "persistent_id", PROP_INT, PROP_NONE);
266         RNA_def_property_ui_text(prop, "Persistent ID",
267                                  "Persistent identifier for inter-frame matching of objects with motion blur");
268         RNA_def_property_array(prop, 2 * MAX_DUPLI_RECUR);
269         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
270         RNA_def_property_int_funcs(prop, "rna_DepsgraphIter_persistent_id_get", NULL, NULL);
271
272         prop = RNA_def_property(srna, "orco", PROP_FLOAT, PROP_TRANSLATION);
273         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
274         /* Seems system is not smart enough to figure that getter function should return
275          * array for PROP_TRANSLATION.
276          */
277         RNA_def_property_array(prop, 3);
278         RNA_def_property_ui_text(prop, "Generated Coordinates", "Generated coordinates in parent object space");
279         RNA_def_property_float_funcs(prop, "rna_DepsgraphIter_orco_get", NULL, NULL);
280
281         prop = RNA_def_property(srna, "random_id", PROP_INT, PROP_UNSIGNED);
282         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
283         RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this dupli object");
284         RNA_def_property_int_funcs(prop, "rna_DepsgraphIter_random_id_get", NULL, NULL);
285
286         prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
287         RNA_def_property_ui_text(prop, "UV Coordinates", "UV coordinates in parent object space");
288         RNA_def_property_array(prop, 2);
289         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
290         RNA_def_property_float_funcs(prop, "rna_DepsgraphIter_uv_get", NULL, NULL);
291
292         prop = RNA_def_property(srna, "is_instance", PROP_BOOLEAN, PROP_NONE);
293         RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
294         RNA_def_property_ui_text(prop, "Is Instance", "Denotes whether the object is ocming from dupli-list");
295         RNA_def_property_boolean_funcs(prop, "rna_DepsgraphIter_is_instance_get", NULL);
296 }
297
298 static void rna_def_depsgraph(BlenderRNA *brna)
299 {
300         StructRNA *srna;
301         FunctionRNA *func;
302         PropertyRNA *parm;
303         PropertyRNA *prop;
304
305         srna = RNA_def_struct(brna, "Depsgraph", NULL);
306         RNA_def_struct_ui_text(srna, "Dependency Graph", "");
307
308         func = RNA_def_function(srna, "debug_graphviz", "rna_Depsgraph_debug_graphviz");
309         parm = RNA_def_string_file_path(func, "filename", NULL, FILE_MAX, "File Name",
310                                         "File in which to store graphviz debug output");
311         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
312
313         func = RNA_def_function(srna, "debug_rebuild", "rna_Depsgraph_debug_rebuild");
314         RNA_def_function_flag(func, FUNC_USE_CONTEXT);
315
316         func = RNA_def_function(srna, "debug_stats", "rna_Depsgraph_debug_stats");
317         RNA_def_function_ui_description(func, "Report the number of elements in the Dependency Graph");
318         RNA_def_function_flag(func, FUNC_USE_REPORTS);
319
320         prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
321         RNA_def_property_struct_type(prop, "Object");
322         RNA_def_property_collection_funcs(prop,
323                                           "rna_Depsgraph_objects_begin",
324                                           "rna_Depsgraph_objects_next",
325                                           "rna_Depsgraph_objects_end",
326                                           "rna_Depsgraph_objects_get",
327                                           NULL, NULL, NULL, NULL);
328
329         func = RNA_def_function(srna, "evaluated_id_get", "rna_Depsgraph_evaluated_id_get");
330         parm = RNA_def_pointer(func, "id", "ID", "", "Original ID to get evaluated complementary part for");
331         RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
332         parm = RNA_def_pointer(func, "evaluated_id", "ID", "", "Evaluated ID for the given original one");
333         RNA_def_function_return(func, parm);
334
335         /* TODO(sergey): Find a better name. */
336         prop = RNA_def_property(srna, "duplis", PROP_COLLECTION, PROP_NONE);
337         RNA_def_property_struct_type(prop, "DepsgraphIter");
338         RNA_def_property_collection_funcs(prop,
339                                           "rna_Depsgraph_duplis_begin",
340                                           "rna_Depsgraph_duplis_next",
341                                           "rna_Depsgraph_duplis_end",
342                                           "rna_Depsgraph_duplis_get",
343                                           NULL, NULL, NULL, NULL);
344 }
345
346 void RNA_def_depsgraph(BlenderRNA *brna)
347 {
348         rna_def_depsgraph_iter(brna);
349         rna_def_depsgraph(brna);
350 }
351
352 #endif