/* SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup RNA */ #include #include "BLI_path_util.h" #include "BLI_utildefines.h" #include "RNA_define.h" #include "RNA_enum_types.h" #include "rna_internal.h" #include "DNA_object_types.h" #include "DEG_depsgraph.h" #define STATS_MAX_SIZE 16384 #ifdef RNA_RUNTIME # ifdef WITH_PYTHON # include "BPY_extern.h" # endif # include "BLI_iterator.h" # include "BLI_math.h" # include "RNA_access.h" # include "BKE_duplilist.h" # include "BKE_object.h" # include "BKE_scene.h" # include "DEG_depsgraph_build.h" # include "DEG_depsgraph_debug.h" # include "DEG_depsgraph_query.h" # include "MEM_guardedalloc.h" /* **************** Object Instance **************** */ typedef struct RNA_DepsgraphIterator { BLI_Iterator iter; # ifdef WITH_PYTHON /** * Store the Python instance so the #BPy_StructRNA can be set as invalid iteration is completed. * Otherwise accessing from Python (console auto-complete for e.g.) crashes, see: T100286. */ void *py_instance; # endif } RNA_DepsgraphIterator; # ifdef WITH_PYTHON void **rna_DepsgraphIterator_instance(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; return &di->py_instance; } # endif /* Temporary hack for Cycles until it is changed to work with the C API directly. */ DupliObject *rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; return deg_iter->dupli_object_current; } static PointerRNA rna_DepsgraphObjectInstance_object_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; return rna_pointer_inherit_refine(ptr, &RNA_Object, di->iter.current); } static bool rna_DepsgraphObjectInstance_is_instance_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; return (deg_iter->dupli_object_current != NULL); } static PointerRNA rna_DepsgraphObjectInstance_instance_object_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; Object *instance_object = NULL; if (deg_iter->dupli_object_current != NULL) { instance_object = deg_iter->dupli_object_current->ob; } return rna_pointer_inherit_refine(ptr, &RNA_Object, instance_object); } static bool rna_DepsgraphObjectInstance_show_self_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; int ob_visibility = BKE_object_visibility(di->iter.current, deg_iter->eval_mode); return (ob_visibility & OB_VISIBLE_SELF) != 0; } static bool rna_DepsgraphObjectInstance_show_particles_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; int ob_visibility = BKE_object_visibility(di->iter.current, deg_iter->eval_mode); return (ob_visibility & OB_VISIBLE_PARTICLES) != 0; } static PointerRNA rna_DepsgraphObjectInstance_parent_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; Object *dupli_parent = NULL; if (deg_iter->dupli_object_current != NULL) { dupli_parent = deg_iter->dupli_parent; } return rna_pointer_inherit_refine(ptr, &RNA_Object, dupli_parent); } static PointerRNA rna_DepsgraphObjectInstance_particle_system_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; struct ParticleSystem *particle_system = NULL; if (deg_iter->dupli_object_current != NULL) { particle_system = deg_iter->dupli_object_current->particle_system; } return rna_pointer_inherit_refine(ptr, &RNA_ParticleSystem, particle_system); } static void rna_DepsgraphObjectInstance_persistent_id_get(PointerRNA *ptr, int *persistent_id) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; if (deg_iter->dupli_object_current != NULL) { memcpy(persistent_id, deg_iter->dupli_object_current->persistent_id, sizeof(deg_iter->dupli_object_current->persistent_id)); } else { memset(persistent_id, 0, sizeof(deg_iter->dupli_object_current->persistent_id)); } } static int rna_DepsgraphObjectInstance_random_id_get(PointerRNA *ptr) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; if (deg_iter->dupli_object_current != NULL) { return (int)deg_iter->dupli_object_current->random_id; } else { return 0; } } static void rna_DepsgraphObjectInstance_matrix_world_get(PointerRNA *ptr, float *mat) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; if (deg_iter->dupli_object_current != NULL) { copy_m4_m4((float(*)[4])mat, deg_iter->dupli_object_current->mat); } else { /* We can return actual object's matrix here, no reason to return identity matrix * when this is not actually an instance... */ Object *ob = (Object *)di->iter.current; copy_m4_m4((float(*)[4])mat, ob->object_to_world); } } static void rna_DepsgraphObjectInstance_orco_get(PointerRNA *ptr, float *orco) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; if (deg_iter->dupli_object_current != NULL) { copy_v3_v3(orco, deg_iter->dupli_object_current->orco); } else { zero_v3(orco); } } static void rna_DepsgraphObjectInstance_uv_get(PointerRNA *ptr, float *uv) { RNA_DepsgraphIterator *di = ptr->data; DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data; if (deg_iter->dupli_object_current != NULL) { copy_v2_v2(uv, deg_iter->dupli_object_current->uv); } else { zero_v2(uv); } } /* ******************** Sorted ***************** */ static int rna_Depsgraph_mode_get(PointerRNA *ptr) { Depsgraph *depsgraph = ptr->data; return DEG_get_mode(depsgraph); } /* ******************** Updates ***************** */ static PointerRNA rna_DepsgraphUpdate_id_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_ID, ptr->data); } static bool rna_DepsgraphUpdate_is_updated_transform_get(PointerRNA *ptr) { ID *id = ptr->data; return ((id->recalc & ID_RECALC_TRANSFORM) != 0); } static bool rna_DepsgraphUpdate_is_updated_shading_get(PointerRNA *ptr) { /* Assume any animated parameters can affect shading, we don't have fine * grained enough updates to distinguish this. */ ID *id = ptr->data; return ((id->recalc & (ID_RECALC_SHADING | ID_RECALC_ANIMATION)) != 0); } static bool rna_DepsgraphUpdate_is_updated_geometry_get(PointerRNA *ptr) { ID *id = ptr->data; if (id->recalc & ID_RECALC_GEOMETRY) { return true; } if (GS(id->name) != ID_OB) { return false; } Object *object = (Object *)id; ID *data = object->data; if (data == NULL) { return false; } return ((data->recalc & ID_RECALC_ALL) != 0); } /* **************** Depsgraph **************** */ static void rna_Depsgraph_debug_relations_graphviz(Depsgraph *depsgraph, const char *filename) { FILE *f = fopen(filename, "w"); if (f == NULL) { return; } DEG_debug_relations_graphviz(depsgraph, f, "Depsgraph"); fclose(f); } static void rna_Depsgraph_debug_stats_gnuplot(Depsgraph *depsgraph, const char *filename, const char *output_filename) { FILE *f = fopen(filename, "w"); if (f == NULL) { return; } DEG_debug_stats_gnuplot(depsgraph, f, "Timing Statistics", output_filename); fclose(f); } static void rna_Depsgraph_debug_tag_update(Depsgraph *depsgraph) { DEG_graph_tag_relations_update(depsgraph); } static void rna_Depsgraph_debug_stats(Depsgraph *depsgraph, char *result) { size_t outer, ops, rels; DEG_stats_simple(depsgraph, &outer, &ops, &rels); BLI_snprintf(result, STATS_MAX_SIZE, "Approx %zu Operations, %zu Relations, %zu Outer Nodes", ops, rels, outer); } static void rna_Depsgraph_update(Depsgraph *depsgraph, Main *bmain, ReportList *reports) { if (DEG_is_evaluating(depsgraph)) { BKE_report(reports, RPT_ERROR, "Dependency graph update requested during evaluation"); return; } # ifdef WITH_PYTHON /* Allow drivers to be evaluated */ BPy_BEGIN_ALLOW_THREADS; # endif BKE_scene_graph_update_tagged(depsgraph, bmain); # ifdef WITH_PYTHON BPy_END_ALLOW_THREADS; # endif } /* Iteration over objects, simple version */ static void rna_Depsgraph_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__); DEGObjectIterData *data = MEM_callocN(sizeof(DEGObjectIterData), __func__); DEGObjectIterSettings *deg_iter_settings = MEM_callocN(sizeof(DEGObjectIterSettings), __func__); deg_iter_settings->depsgraph = (Depsgraph *)ptr->data; deg_iter_settings->flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; data->settings = deg_iter_settings; data->graph = deg_iter_settings->depsgraph; data->flag = deg_iter_settings->flags; ((BLI_Iterator *)iter->internal.custom)->valid = true; DEG_iterator_objects_begin(iter->internal.custom, data); iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid; } static void rna_Depsgraph_objects_next(CollectionPropertyIterator *iter) { DEG_iterator_objects_next(iter->internal.custom); iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid; } static void rna_Depsgraph_objects_end(CollectionPropertyIterator *iter) { DEGObjectIterData *data = (DEGObjectIterData *)((BLI_Iterator *)iter->internal.custom)->data; DEG_iterator_objects_end(iter->internal.custom); MEM_freeN(data->settings); MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data); MEM_freeN(iter->internal.custom); } static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter) { Object *ob = ((BLI_Iterator *)iter->internal.custom)->current; return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ob); } /* Iteration over objects, extended version * * Contains extra information about duplicator and persistent ID. */ /* XXX Ugly python seems to query next item of an iterator before using current one (see T57558). * This forces us to use that nasty ping-pong game between two sets of iterator data, * so that previous one remains valid memory for python to access to. Yuck. */ typedef struct RNA_Depsgraph_Instances_Iterator { RNA_DepsgraphIterator iterators[2]; DEGObjectIterData deg_data[2]; DupliObject dupli_object_current[2]; int counter; } RNA_Depsgraph_Instances_Iterator; static void rna_Depsgraph_object_instances_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { RNA_Depsgraph_Instances_Iterator *di_it = iter->internal.custom = MEM_callocN(sizeof(*di_it), __func__); DEGObjectIterSettings *deg_iter_settings = MEM_callocN(sizeof(DEGObjectIterSettings), __func__); deg_iter_settings->depsgraph = (Depsgraph *)ptr->data; deg_iter_settings->flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI; DEGObjectIterData *data = &di_it->deg_data[0]; data->settings = deg_iter_settings; data->graph = deg_iter_settings->depsgraph; data->flag = deg_iter_settings->flags; di_it->iterators[0].iter.valid = true; DEG_iterator_objects_begin(&di_it->iterators[0].iter, data); iter->valid = di_it->iterators[0].iter.valid; } static void rna_Depsgraph_object_instances_next(CollectionPropertyIterator *iter) { RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *) iter->internal.custom; /* We need to copy current iterator status to next one being worked on. */ di_it->iterators[(di_it->counter + 1) % 2].iter = di_it->iterators[di_it->counter % 2].iter; di_it->deg_data[(di_it->counter + 1) % 2] = di_it->deg_data[di_it->counter % 2]; di_it->counter++; di_it->iterators[di_it->counter % 2].iter.data = &di_it->deg_data[di_it->counter % 2]; DEG_iterator_objects_next(&di_it->iterators[di_it->counter % 2].iter); /* Dupli_object_current is also temp memory generated during the iterations, * it may be freed when last item has been iterated, * so we have same issue as with the iterator itself: * we need to keep a local copy, which memory remains valid a bit longer, * for Python accesses to work. */ if (di_it->deg_data[di_it->counter % 2].dupli_object_current != NULL) { di_it->dupli_object_current[di_it->counter % 2] = *di_it->deg_data[di_it->counter % 2].dupli_object_current; di_it->deg_data[di_it->counter % 2].dupli_object_current = &di_it->dupli_object_current[di_it->counter % 2]; } iter->valid = di_it->iterators[di_it->counter % 2].iter.valid; } static void rna_Depsgraph_object_instances_end(CollectionPropertyIterator *iter) { RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *) iter->internal.custom; for (int i = 0; i < ARRAY_SIZE(di_it->iterators); i++) { RNA_DepsgraphIterator *di = &di_it->iterators[i]; DEGObjectIterData *data = &di_it->deg_data[i]; if (i == 0) { /* Is shared between both iterators. */ MEM_freeN(data->settings); } DEG_iterator_objects_end(&di->iter); # ifdef WITH_PYTHON if (di->py_instance) { BPY_DECREF_RNA_INVALIDATE(di->py_instance); } # endif } MEM_freeN(di_it); } static PointerRNA rna_Depsgraph_object_instances_get(CollectionPropertyIterator *iter) { RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *) iter->internal.custom; RNA_DepsgraphIterator *di = &di_it->iterators[di_it->counter % 2]; return rna_pointer_inherit_refine(&iter->parent, &RNA_DepsgraphObjectInstance, di); } /* Iteration over evaluated IDs */ static void rna_Depsgraph_ids_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__); DEGIDIterData *data = MEM_callocN(sizeof(DEGIDIterData), __func__); data->graph = (Depsgraph *)ptr->data; ((BLI_Iterator *)iter->internal.custom)->valid = true; DEG_iterator_ids_begin(iter->internal.custom, data); iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid; } static void rna_Depsgraph_ids_next(CollectionPropertyIterator *iter) { DEG_iterator_ids_next(iter->internal.custom); iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid; } static void rna_Depsgraph_ids_end(CollectionPropertyIterator *iter) { DEG_iterator_ids_end(iter->internal.custom); MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data); MEM_freeN(iter->internal.custom); } static PointerRNA rna_Depsgraph_ids_get(CollectionPropertyIterator *iter) { ID *id = ((BLI_Iterator *)iter->internal.custom)->current; return rna_pointer_inherit_refine(&iter->parent, &RNA_ID, id); } static void rna_Depsgraph_updates_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__); DEGIDIterData *data = MEM_callocN(sizeof(DEGIDIterData), __func__); data->graph = (Depsgraph *)ptr->data; data->only_updated = true; ((BLI_Iterator *)iter->internal.custom)->valid = true; DEG_iterator_ids_begin(iter->internal.custom, data); iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid; } static PointerRNA rna_Depsgraph_updates_get(CollectionPropertyIterator *iter) { ID *id = ((BLI_Iterator *)iter->internal.custom)->current; return rna_pointer_inherit_refine(&iter->parent, &RNA_DepsgraphUpdate, id); } static ID *rna_Depsgraph_id_eval_get(Depsgraph *depsgraph, ID *id_orig) { return DEG_get_evaluated_id(depsgraph, id_orig); } static bool rna_Depsgraph_id_type_updated(Depsgraph *depsgraph, int id_type) { return DEG_id_type_updated(depsgraph, id_type); } static PointerRNA rna_Depsgraph_scene_get(PointerRNA *ptr) { Depsgraph *depsgraph = (Depsgraph *)ptr->data; Scene *scene = DEG_get_input_scene(depsgraph); PointerRNA newptr; RNA_pointer_create(&scene->id, &RNA_Scene, scene, &newptr); return newptr; } static PointerRNA rna_Depsgraph_view_layer_get(PointerRNA *ptr) { Depsgraph *depsgraph = (Depsgraph *)ptr->data; Scene *scene = DEG_get_input_scene(depsgraph); ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); PointerRNA newptr; RNA_pointer_create(&scene->id, &RNA_ViewLayer, view_layer, &newptr); return newptr; } static PointerRNA rna_Depsgraph_scene_eval_get(PointerRNA *ptr) { Depsgraph *depsgraph = (Depsgraph *)ptr->data; Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); PointerRNA newptr; RNA_pointer_create(&scene_eval->id, &RNA_Scene, scene_eval, &newptr); return newptr; } static PointerRNA rna_Depsgraph_view_layer_eval_get(PointerRNA *ptr) { Depsgraph *depsgraph = (Depsgraph *)ptr->data; Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph); PointerRNA newptr; RNA_pointer_create(&scene_eval->id, &RNA_ViewLayer, view_layer_eval, &newptr); return newptr; } #else static void rna_def_depsgraph_instance(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, "DepsgraphObjectInstance", NULL); RNA_def_struct_ui_text(srna, "Dependency Graph Object Instance", "Extended information about dependency graph object iterator " "(Warning: All data here is 'evaluated' one, not original .blend IDs)"); # ifdef WITH_PYTHON RNA_def_struct_register_funcs(srna, NULL, NULL, "rna_DepsgraphIterator_instance"); # endif prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Object", "Evaluated object the iterator points to"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_DepsgraphObjectInstance_object_get", NULL, NULL, NULL); prop = RNA_def_property(srna, "show_self", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text( prop, "Show Self", "The object geometry itself should be visible in the render"); RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_show_self_get", NULL); prop = RNA_def_property(srna, "show_particles", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text( prop, "Show Particles", "Particles part of the object should be visible in the render"); RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_show_particles_get", NULL); prop = RNA_def_property(srna, "is_instance", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text( prop, "Is Instance", "Denotes if the object is generated by another object"); RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_is_instance_get", NULL); prop = RNA_def_property(srna, "instance_object", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text( prop, "Instance Object", "Evaluated object which is being instanced by this iterator"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_pointer_funcs( prop, "rna_DepsgraphObjectInstance_instance_object_get", NULL, NULL, NULL); prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text( prop, "Parent", "If the object is an instance, the parent object that generated it"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_DepsgraphObjectInstance_parent_get", NULL, NULL, NULL); prop = RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ParticleSystem"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text( prop, "Particle System", "Evaluated particle system that this object was instanced from"); RNA_def_property_pointer_funcs( prop, "rna_DepsgraphObjectInstance_particle_system_get", NULL, NULL, NULL); prop = RNA_def_property(srna, "persistent_id", PROP_INT, PROP_NONE); RNA_def_property_ui_text( prop, "Persistent ID", "Persistent identifier for inter-frame matching of objects with motion blur"); RNA_def_property_array(prop, MAX_DUPLI_RECUR); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_int_funcs(prop, "rna_DepsgraphObjectInstance_persistent_id_get", NULL, NULL); prop = RNA_def_property(srna, "random_id", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text( prop, "Instance Random ID", "Random id for this instance, typically for randomized shading"); RNA_def_property_int_funcs(prop, "rna_DepsgraphObjectInstance_random_id_get", NULL, NULL); prop = RNA_def_property(srna, "matrix_world", PROP_FLOAT, PROP_MATRIX); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); RNA_def_property_ui_text(prop, "Generated Matrix", "Generated transform matrix in world space"); RNA_def_property_float_funcs(prop, "rna_DepsgraphObjectInstance_matrix_world_get", NULL, NULL); prop = RNA_def_property(srna, "orco", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_array(prop, 3); RNA_def_property_ui_text( prop, "Generated Coordinates", "Generated coordinates in parent object space"); RNA_def_property_float_funcs(prop, "rna_DepsgraphObjectInstance_orco_get", NULL, NULL); prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "UV Coordinates", "UV coordinates in parent object space"); RNA_def_property_array(prop, 2); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_float_funcs(prop, "rna_DepsgraphObjectInstance_uv_get", NULL, NULL); } static void rna_def_depsgraph_update(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, "DepsgraphUpdate", NULL); RNA_def_struct_ui_text(srna, "Dependency Graph Update", "Information about ID that was updated"); prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ID"); RNA_def_property_ui_text(prop, "ID", "Updated data-block"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_DepsgraphUpdate_id_get", NULL, NULL, NULL); /* Use term 'is_updated' instead of 'is_dirty' here because this is a signal * that users of the depsgraph may want to update their data (render engines for eg). */ prop = RNA_def_property(srna, "is_updated_transform", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text(prop, "Transform", "Object transformation is updated"); RNA_def_property_boolean_funcs(prop, "rna_DepsgraphUpdate_is_updated_transform_get", NULL); prop = RNA_def_property(srna, "is_updated_geometry", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text(prop, "Geometry", "Object geometry is updated"); RNA_def_property_boolean_funcs(prop, "rna_DepsgraphUpdate_is_updated_geometry_get", NULL); prop = RNA_def_property(srna, "is_updated_shading", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE); RNA_def_property_ui_text(prop, "Shading", "Object shading is updated"); RNA_def_property_boolean_funcs(prop, "rna_DepsgraphUpdate_is_updated_shading_get", NULL); } static void rna_def_depsgraph(BlenderRNA *brna) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; PropertyRNA *prop; static EnumPropertyItem enum_depsgraph_mode_items[] = { {DAG_EVAL_VIEWPORT, "VIEWPORT", 0, "Viewport", "Viewport non-rendered mode"}, {DAG_EVAL_RENDER, "RENDER", 0, "Render", "Render"}, {0, NULL, 0, NULL, NULL}, }; srna = RNA_def_struct(brna, "Depsgraph", NULL); RNA_def_struct_ui_text(srna, "Dependency Graph", ""); prop = RNA_def_enum(srna, "mode", enum_depsgraph_mode_items, 0, "Mode", "Evaluation mode"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_enum_funcs(prop, "rna_Depsgraph_mode_get", NULL, NULL); /* Debug helpers. */ func = RNA_def_function( srna, "debug_relations_graphviz", "rna_Depsgraph_debug_relations_graphviz"); parm = RNA_def_string_file_path( func, "filename", NULL, FILE_MAX, "File Name", "Output path for the graphviz debug file"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "debug_stats_gnuplot", "rna_Depsgraph_debug_stats_gnuplot"); parm = RNA_def_string_file_path( func, "filename", NULL, FILE_MAX, "File Name", "Output path for the gnuplot debug file"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_string_file_path(func, "output_filename", NULL, FILE_MAX, "Output File Name", "File name where gnuplot script will save the result"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "debug_tag_update", "rna_Depsgraph_debug_tag_update"); func = RNA_def_function(srna, "debug_stats", "rna_Depsgraph_debug_stats"); RNA_def_function_ui_description(func, "Report the number of elements in the Dependency Graph"); /* weak!, no way to return dynamic string type */ parm = RNA_def_string(func, "result", NULL, STATS_MAX_SIZE, "result", ""); RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0); /* needed for string return value */ RNA_def_function_output(func, parm); /* Updates. */ func = RNA_def_function(srna, "update", "rna_Depsgraph_update"); RNA_def_function_ui_description( func, "Re-evaluate any modified data-blocks, for example for animation or modifiers. " "This invalidates all references to evaluated data-blocks from this dependency graph."); RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); /* Queries for original data-blocks (the ones depsgraph is built for). */ prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Scene"); RNA_def_property_pointer_funcs(prop, "rna_Depsgraph_scene_get", NULL, NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Scene", "Original scene dependency graph is built for"); prop = RNA_def_property(srna, "view_layer", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ViewLayer"); RNA_def_property_pointer_funcs(prop, "rna_Depsgraph_view_layer_get", NULL, NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( prop, "View Layer", "Original view layer dependency graph is built for"); /* Queries for evaluated data-blocks (the ones depsgraph is evaluating). */ func = RNA_def_function(srna, "id_eval_get", "rna_Depsgraph_id_eval_get"); parm = RNA_def_pointer( func, "id", "ID", "", "Original ID to get evaluated complementary part for"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_pointer(func, "id_eval", "ID", "", "Evaluated ID for the given original one"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "id_type_updated", "rna_Depsgraph_id_type_updated"); parm = RNA_def_enum(func, "id_type", rna_enum_id_type_items, 0, "ID Type", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_boolean(func, "updated", false, "Updated", "True if any datablock with this type was added, updated or removed"); RNA_def_function_return(func, parm); prop = RNA_def_property(srna, "scene_eval", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Scene"); RNA_def_property_pointer_funcs(prop, "rna_Depsgraph_scene_eval_get", NULL, NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Scene", "Scene at its evaluated state"); prop = RNA_def_property(srna, "view_layer_eval", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ViewLayer"); RNA_def_property_pointer_funcs(prop, "rna_Depsgraph_view_layer_eval_get", NULL, NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "View Layer", "View layer at its evaluated state"); /* Iterators. */ prop = RNA_def_property(srna, "ids", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "ID"); RNA_def_property_collection_funcs(prop, "rna_Depsgraph_ids_begin", "rna_Depsgraph_ids_next", "rna_Depsgraph_ids_end", "rna_Depsgraph_ids_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "IDs", "All evaluated data-blocks"); prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_collection_funcs(prop, "rna_Depsgraph_objects_begin", "rna_Depsgraph_objects_next", "rna_Depsgraph_objects_end", "rna_Depsgraph_objects_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Objects", "Evaluated objects in the dependency graph"); prop = RNA_def_property(srna, "object_instances", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "DepsgraphObjectInstance"); RNA_def_property_collection_funcs(prop, "rna_Depsgraph_object_instances_begin", "rna_Depsgraph_object_instances_next", "rna_Depsgraph_object_instances_end", "rna_Depsgraph_object_instances_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Object Instances", "All object instances to display or render " "(Warning: Only use this as an iterator, never as a sequence, " "and do not keep any references to its items)"); prop = RNA_def_property(srna, "updates", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "DepsgraphUpdate"); RNA_def_property_collection_funcs(prop, "rna_Depsgraph_updates_begin", "rna_Depsgraph_ids_next", "rna_Depsgraph_ids_end", "rna_Depsgraph_updates_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Updates", "Updates to data-blocks"); } void RNA_def_depsgraph(BlenderRNA *brna) { rna_def_depsgraph_instance(brna); rna_def_depsgraph_update(brna); rna_def_depsgraph(brna); } #endif