diff options
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_context.c | 35 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_group.c | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 42 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_api.c | 73 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_force.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 846 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 18 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_userdef.c | 28 |
10 files changed, 1012 insertions, 51 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 66e6f30feeb..9c45e34f211 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -317,6 +317,8 @@ extern StructRNA RNA_LaplacianSmoothModifier; extern StructRNA RNA_Lattice; extern StructRNA RNA_LatticeModifier; extern StructRNA RNA_LatticePoint; +extern StructRNA RNA_LayerCollection; +extern StructRNA RNA_LayerCollectionOverride; extern StructRNA RNA_Library; extern StructRNA RNA_LimitDistanceConstraint; extern StructRNA RNA_LimitLocationConstraint; @@ -504,6 +506,7 @@ extern StructRNA RNA_RigidBodyJointConstraint; extern StructRNA RNA_SPHFluidSettings; extern StructRNA RNA_Scene; extern StructRNA RNA_SceneGameData; +extern StructRNA RNA_SceneLayer; extern StructRNA RNA_SceneRenderLayer; extern StructRNA RNA_SceneSequence; extern StructRNA RNA_SceneObjects; @@ -573,6 +576,7 @@ extern StructRNA RNA_SpaceFileBrowser; extern StructRNA RNA_SpaceGraphEditor; extern StructRNA RNA_SpaceImageEditor; extern StructRNA RNA_SpaceInfo; +extern StructRNA RNA_SpaceCollectionManager; extern StructRNA RNA_SpaceLogicEditor; extern StructRNA RNA_SpaceNLA; extern StructRNA RNA_SpaceNodeEditor; @@ -641,6 +645,7 @@ extern StructRNA RNA_ThemeFontStyle; extern StructRNA RNA_ThemeGraphEditor; extern StructRNA RNA_ThemeImageEditor; extern StructRNA RNA_ThemeInfo; +extern StructRNA RNA_ThemeCollectionManager; extern StructRNA RNA_ThemeLogicEditor; extern StructRNA RNA_ThemeNLAEditor; extern StructRNA RNA_ThemeNodeEditor; diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index d7a679e9702..27e88f592ab 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -107,6 +107,26 @@ static PointerRNA rna_Context_scene_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_Scene, CTX_data_scene(C)); } +static PointerRNA rna_Context_scene_layer_get(PointerRNA *ptr) +{ + bContext *C = (bContext *)ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, CTX_data_scene_layer(C)); +} + +static PointerRNA rna_Context_scene_collection_get(PointerRNA *ptr) +{ + bContext *C = (bContext *)ptr->data; + ptr->id.data = CTX_data_scene(C); + return rna_pointer_inherit_refine(ptr, &RNA_SceneCollection, CTX_data_scene_collection(C)); +} + +static PointerRNA rna_Context_layer_collection_get(PointerRNA *ptr) +{ + bContext *C = (bContext *)ptr->data; + ptr->id.data = CTX_data_scene(C); + return rna_pointer_inherit_refine(ptr, &RNA_LayerCollection, CTX_data_layer_collection(C)); +} + static PointerRNA rna_Context_tool_settings_get(PointerRNA *ptr) { bContext *C = (bContext *)ptr->data; @@ -203,6 +223,21 @@ void RNA_def_context(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Scene"); RNA_def_property_pointer_funcs(prop, "rna_Context_scene_get", NULL, NULL, NULL); + prop = RNA_def_property(srna, "render_layer", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "SceneLayer"); + RNA_def_property_pointer_funcs(prop, "rna_Context_scene_layer_get", NULL, NULL, NULL); + + prop = RNA_def_property(srna, "scene_collection", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "SceneCollection"); + RNA_def_property_pointer_funcs(prop, "rna_Context_scene_collection_get", NULL, NULL, NULL); + + prop = RNA_def_property(srna, "layer_collection", PROP_POINTER, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "LayerCollection"); + RNA_def_property_pointer_funcs(prop, "rna_Context_layer_collection_get", NULL, NULL, NULL); + prop = RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "ToolSettings"); diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index aa02a3c159d..2a5a0011279 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -53,9 +53,9 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter) return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((GroupObject *)internal->link)->ob); } -static void rna_Group_objects_link(Group *group, bContext *C, ReportList *reports, Object *object) +static void rna_Group_objects_link(Group *group, ReportList *reports, Object *object) { - if (!BKE_group_object_add(group, object, CTX_data_scene(C), NULL)) { + if (!BKE_group_object_add(group, object)) { BKE_reportf(reports, RPT_ERROR, "Object '%s' already in group '%s'", object->id.name + 2, group->id.name + 2); return; } @@ -63,9 +63,9 @@ static void rna_Group_objects_link(Group *group, bContext *C, ReportList *report WM_main_add_notifier(NC_OBJECT | ND_DRAW, &object->id); } -static void rna_Group_objects_unlink(Group *group, bContext *C, ReportList *reports, Object *object) +static void rna_Group_objects_unlink(Group *group, ReportList *reports, Object *object) { - if (!BKE_group_object_unlink(group, object, CTX_data_scene(C), NULL)) { + if (!BKE_group_object_unlink(group, object)) { BKE_reportf(reports, RPT_ERROR, "Object '%s' not in group '%s'", object->id.name + 2, group->id.name + 2); return; } @@ -91,7 +91,7 @@ static void rna_def_group_objects(BlenderRNA *brna, PropertyRNA *cprop) /* add object */ func = RNA_def_function(srna, "link", "rna_Group_objects_link"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Add this object to a group"); /* object to add */ parm = RNA_def_pointer(func, "object", "Object", "", "Object to add"); @@ -100,7 +100,7 @@ static void rna_def_group_objects(BlenderRNA *brna, PropertyRNA *cprop) /* remove object */ func = RNA_def_function(srna, "unlink", "rna_Group_objects_unlink"); RNA_def_function_ui_description(func, "Remove this object to a group"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_flag(func, FUNC_USE_REPORTS); /* object to remove */ parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 76455adbc78..b904b65a37a 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -279,7 +279,7 @@ void RNA_api_material(StructRNA *srna); void RNA_api_mesh(struct StructRNA *srna); void RNA_api_meta(struct StructRNA *srna); void RNA_api_object(struct StructRNA *srna); -void RNA_api_object_base(struct StructRNA *srna); +void RNA_api_object_base_legacy(struct StructRNA *srna); void RNA_api_pose(struct StructRNA *srna); void RNA_api_pose_channel(struct StructRNA *srna); void RNA_api_scene(struct StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 0cffba47f16..f8b3bdd62e9 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -297,23 +297,14 @@ static void rna_Object_dependency_update(Main *bmain, Scene *UNUSED(scene), Poin } /* when changing the selection flag the scene needs updating */ -static void rna_Object_select_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) -{ - if (scene) { - Object *ob = (Object *)ptr->id.data; - short mode = (ob->flag & SELECT) ? BA_SELECT : BA_DESELECT; - ED_base_object_select(BKE_scene_base_find(scene, ob), mode); - } -} - static void rna_Base_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { - Base *base = (Base *)ptr->data; - short mode = (base->flag & BA_SELECT) ? BA_SELECT : BA_DESELECT; + BaseLegacy *base = (BaseLegacy *)ptr->data; + short mode = (base->flag_legacy & BA_SELECT) ? BA_SELECT : BA_DESELECT; ED_base_object_select(base, mode); } -static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, Base *base, Object *ob) +static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, BaseLegacy *base, Object *ob) { /* try to avoid scene sort */ if (scene == NULL) { @@ -335,7 +326,7 @@ static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, Base *b static void rna_Object_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr) { Object *ob = (Object *)ptr->id.data; - Base *base; + BaseLegacy *base; base = scene ? BKE_scene_base_find(scene, ob) : NULL; if (!base) @@ -351,7 +342,7 @@ static void rna_Object_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr) static void rna_Base_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - Base *base = (Base *)ptr->data; + BaseLegacy *base = (BaseLegacy *)ptr->data; Object *ob = (Object *)base->object; rna_Object_layer_update__internal(bmain, scene, base, ob); @@ -1120,7 +1111,7 @@ static void rna_Object_layer_set(PointerRNA *ptr, const int *values) static void rna_Base_layer_set(PointerRNA *ptr, const int *values) { - Base *base = (Base *)ptr->data; + BaseLegacy *base = (BaseLegacy *)ptr->data; unsigned int lay; lay = rna_Object_layer_validate__internal(values, base->lay); @@ -2246,11 +2237,6 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Local View Layers", "3D local view layers the object is on"); - prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); - RNA_def_property_ui_text(prop, "Select", "Object selection state"); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_select_update"); - /* for data access */ prop = RNA_def_property(srna, "bound_box", PROP_FLOAT, PROP_NONE); RNA_def_property_multi_array(prop, 2, boundbox_dimsize); @@ -2895,14 +2881,14 @@ static void rna_def_dupli_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Dupli Type", "Duplicator type that generated this dupli object"); } -static void rna_def_object_base(BlenderRNA *brna) +static void rna_def_object_base_legacy(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "ObjectBase", NULL); + srna = RNA_def_struct(brna, "ObjectBaseLegacy", NULL); RNA_def_struct_sdna(srna, "Base"); - RNA_def_struct_ui_text(srna, "Object Base", "An object instance in a scene"); + RNA_def_struct_ui_text(srna, "Object Base Legacy", "An object instance in a scene (deprecated)"); RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA); prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); @@ -2922,13 +2908,13 @@ static void rna_def_object_base(BlenderRNA *brna) RNA_def_property_array(prop, 8); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Local View Layers", "3D local view layers the object base is on"); - + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", BA_SELECT); + RNA_def_property_boolean_sdna(prop, NULL, "flag_legacy", BA_SELECT); RNA_def_property_ui_text(prop, "Select", "Object base selection state"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Base_select_update"); - - RNA_api_object_base(srna); + + RNA_api_object_base_legacy(srna); } void RNA_def_object(BlenderRNA *brna) @@ -2937,7 +2923,7 @@ void RNA_def_object(BlenderRNA *brna) RNA_define_animate_sdna(false); rna_def_object_game_settings(brna); - rna_def_object_base(brna); + rna_def_object_base_legacy(brna); rna_def_vertex_group(brna); rna_def_material_slot(brna); rna_def_dupli_object(brna); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index c680abe71a4..c93f72e798f 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -40,10 +40,12 @@ #include "RNA_define.h" #include "DNA_constraint_types.h" +#include "DNA_layer_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "BKE_depsgraph.h" +#include "BKE_layer.h" #include "rna_internal.h" /* own include */ @@ -90,6 +92,49 @@ static EnumPropertyItem space_items[] = { #include "DEG_depsgraph.h" +static void rna_Object_select_set(Object *ob, bContext *C, ReportList *reports, int action) +{ + SceneLayer *sl = CTX_data_scene_layer(C); + Base *base = BKE_scene_layer_base_find(sl, ob); + + if (!base) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, sl->name); + return; + } + + if (action == 2) { /* TOGGLE */ + if ((base->flag & BASE_SELECTED) != 0) { + action = 1; /* DESELECT */ + } + else { + action = 0; /* SELECT */ + } + } + + switch (action) { + case 1: /* DESELECT */ + base->flag &= ~BASE_SELECTED; + break; + case 0: /* SELECT */ + default: + BKE_scene_layer_base_select(sl, base); + break; + } +} + +static int rna_Object_select_get(Object *ob, bContext *C, ReportList *reports) +{ + SceneLayer *sl = CTX_data_scene_layer(C); + Base *base = BKE_scene_layer_base_find(sl, ob); + + if (!base) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, sl->name); + return -1; + } + + return ((base->flag & BASE_SELECTED) != 0) ? 1 : 0; +} + /* Convert a given matrix from a space to another (using the object and/or a bone as reference). */ static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan, float *mat, float *mat_ret, int from, int to) @@ -413,9 +458,9 @@ finally: free_bvhtree_from_mesh(&treeData); } -/* ObjectBase */ +/* ObjectBaseLegacy */ -static void rna_ObjectBase_layers_from_view(Base *base, View3D *v3d) +static void rna_ObjectBaseLegacy_layers_from_view(BaseLegacy *base, View3D *v3d) { base->lay = base->object->lay = v3d->lay; } @@ -504,6 +549,26 @@ void RNA_api_object(StructRNA *srna) }; #endif + static EnumPropertyItem object_select_items[] = { + {0, "SELECT", 0, "Select", "Select object from the active render layer"}, + {1, "DESELECT", 0, "Deselect", "Deselect object from the active render layer"}, + {2, "TOGGLE", 0, "Toggle", "Toggle object selection from the active render layer"}, + {0, NULL, 0, NULL, NULL} + }; + + /* Special wrapper to access the base selection value */ + func = RNA_def_function(srna, "select_set", "rna_Object_select_set"); + RNA_def_function_ui_description(func, "Select the object (for the active render layer)"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + parm = RNA_def_enum(func, "action", object_select_items, 0, "Action", "Select mode"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "select_get", "rna_Object_select_get"); + RNA_def_function_ui_description(func, "Get the object selection for the active render layer"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + parm = RNA_def_boolean(func, "result", 0, "", "Object selected"); + RNA_def_function_return(func, parm); + /* Matrix space conversion */ func = RNA_def_function(srna, "convert_space", "rna_Scene_mat_convert_space"); RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another"); @@ -707,12 +772,12 @@ void RNA_api_object(StructRNA *srna) } -void RNA_api_object_base(StructRNA *srna) +void RNA_api_object_base_legacy(StructRNA *srna) { FunctionRNA *func; PropertyRNA *parm; - func = RNA_def_function(srna, "layers_from_view", "rna_ObjectBase_layers_from_view"); + func = RNA_def_function(srna, "layers_from_view", "rna_ObjectBaseLegacy_layers_from_view"); RNA_def_function_ui_description(func, "Sets the object layers from a 3D View (use when adding an object in local view)"); parm = RNA_def_pointer(func, "view", "SpaceView3D", "", ""); diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 1d89f7535c4..5fd4762e5be 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -605,7 +605,7 @@ static void rna_EffectorWeight_update(Main *UNUSED(bmain), Scene *UNUSED(scene), if (id && GS(id->name) == ID_SCE) { Scene *scene = (Scene *)id; - Base *base; + BaseLegacy *base; for (base = scene->base.first; base; base = base->next) { BKE_ptcache_object_reset(scene, base->object, PTCACHE_RESET_DEPSGRAPH); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 1166fb89a0a..8f36af96cf4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -32,6 +32,7 @@ #include "DNA_particle_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" +#include "DNA_layer_types.h" #include "DNA_linestyle_types.h" #include "DNA_userdef_types.h" #include "DNA_world_types.h" @@ -47,6 +48,8 @@ #include "BKE_editmesh.h" #include "BKE_paint.h" +#include "ED_object.h" + #include "GPU_extensions.h" #include "RNA_define.h" @@ -445,10 +448,12 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { #include "MEM_guardedalloc.h" #include "BKE_brush.h" +#include "BKE_collection.h" #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_node.h" #include "BKE_pointcache.h" @@ -606,11 +611,11 @@ static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain, Scene *scene, Poi static int rna_Scene_object_bases_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) { Scene *scene = (Scene *)ptr->data; - Base *base; + BaseLegacy *base; for (base = scene->base.first; base; base = base->next) { if (STREQLEN(base->object->id.name + 2, key, sizeof(base->object->id.name) - 2)) { - *r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBase, base); + *r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBaseLegacy, base); return true; } } @@ -623,13 +628,13 @@ static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter) ListBaseIterator *internal = &iter->internal.listbase; /* we are actually iterating a Base list, so override get */ - return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((Base *)internal->link)->object); + return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((BaseLegacy *)internal->link)->object); } -static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *reports, Object *ob) +static BaseLegacy *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *reports, Object *ob) { Scene *scene_act = CTX_data_scene(C); - Base *base; + BaseLegacy *base; if (BKE_scene_base_find(scene, ob)) { BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in scene '%s'", ob->id.name + 2, scene->id.name + 2); @@ -660,7 +665,7 @@ static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *report static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *ob) { - Base *base = BKE_scene_base_find(scene, ob); + BaseLegacy *base = BKE_scene_base_find(scene, ob); if (!base) { BKE_reportf(reports, RPT_ERROR, "Object '%s' is not in this scene '%s'", ob->id.name + 2, scene->id.name + 2); return; @@ -1707,7 +1712,7 @@ static void rna_Scene_use_nodes_update(bContext *C, PointerRNA *ptr) static void rna_Physics_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Scene *scene = (Scene *)ptr->id.data; - Base *base; + BaseLegacy *base; for (base = scene->base.first; base; base = base->next) BKE_ptcache_object_reset(scene, base->object, PTCACHE_RESET_DEPSGRAPH); @@ -1778,7 +1783,7 @@ static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), Poi { Scene *sce = ptr->id.data; Scene *sce_iter; - Base *base; + BaseLegacy *base; BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true); for (SETLOOPER(sce, sce_iter, base)) @@ -2185,6 +2190,442 @@ static int rna_gpu_is_hq_supported_get(PointerRNA *UNUSED(ptr)) return GPU_instanced_drawing_support() && GPU_geometry_shader_support(); } +static void rna_SceneCollection_name_set(PointerRNA *ptr, const char *value) +{ + Scene *scene = (Scene *)ptr->id.data; + SceneCollection *sc = (SceneCollection *)ptr->data; + SceneCollection *sc_master = BKE_collection_master(scene); + + BLI_strncpy_utf8(sc->name, value, sizeof(sc->name)); + BLI_uniquename(&sc_master->scene_collections, sc, DATA_("SceneCollection"), '.', offsetof(SceneCollection, name), sizeof(sc->name)); +} + +static void rna_SceneCollection_filter_set(PointerRNA *ptr, const char *value) +{ + Scene *scene = (Scene *)ptr->id.data; + SceneCollection *sc = (SceneCollection *)ptr->data; + BLI_strncpy_utf8(sc->filter, value, sizeof(sc->filter)); + + TODO_LAYER_SYNC_FILTER; + (void)scene; +} + +static PointerRNA rna_SceneCollection_objects_get(CollectionPropertyIterator *iter) +{ + ListBaseIterator *internal = &iter->internal.listbase; + + /* we are actually iterating a LinkData list, so override get */ + return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((LinkData *)internal->link)->data); +} + +static SceneCollection *rna_SceneCollection_new(ID *id, SceneCollection *sc_parent, const char *name) +{ + Scene *scene = (Scene *)id; + SceneCollection *sc = BKE_collection_add(scene, sc_parent, name); + + DAG_id_tag_update(&scene->id, 0); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return sc; +} + +static void rna_SceneCollection_remove( + ID *id, SceneCollection *sc_parent, ReportList *reports, PointerRNA *sc_ptr) +{ + Scene *scene = (Scene *)id; + SceneCollection *sc = sc_ptr->data; + + const int index = BLI_findindex(&sc_parent->scene_collections, sc); + if (index == -1) { + BKE_reportf(reports, RPT_ERROR, "Collection '%s' is not a sub-collection of '%s'", + sc->name, sc_parent->name); + return; + } + + if (!BKE_collection_remove(scene, sc)) { + BKE_reportf(reports, RPT_ERROR, "Collection '%s' could not be removed from collection '%s'", + sc->name, sc_parent->name); + return; + } + + RNA_POINTER_INVALIDATE(sc_ptr); + + DAG_id_tag_update(&scene->id, 0); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); +} + +static int rna_SceneCollection_objects_active_index_get(PointerRNA *ptr) +{ + SceneCollection *sc = (SceneCollection *)ptr->data; + return sc->active_object_index; +} + +static void rna_SceneCollection_objects_active_index_set(PointerRNA *ptr, int value) +{ + SceneCollection *sc = (SceneCollection *)ptr->data; + sc->active_object_index = value; +} + +static void rna_SceneCollection_objects_active_index_range( + PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) +{ + SceneCollection *sc = (SceneCollection *)ptr->data; + *min = 0; + *max = max_ii(0, BLI_listbase_count(&sc->objects) - 1); +} + +void rna_SceneCollection_object_link( + ID *id, SceneCollection *sc, Main *bmain, ReportList *reports, Object *ob) +{ + Scene *scene = (Scene *)id; + + if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in collection '%s'", ob->id.name + 2, sc->name); + return; + } + + BKE_collection_object_add(scene, sc, ob); + + /* TODO(sergey): Only update relations for the current scene. */ + DAG_relations_tag_update(bmain); + DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + + WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene); +} + +static void rna_SceneCollection_object_unlink( + ID *id, SceneCollection *sc, Main *bmain, ReportList *reports, Object *ob) +{ + Scene *scene = (Scene *)id; + + if (!BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' is not in collection '%s'", ob->id.name + 2, sc->name); + return; + } + + BKE_collection_object_remove(bmain, scene, sc, ob, false); + + /* needed otherwise the depgraph will contain freed objects which can crash, see [#20958] */ + DAG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene); +} + +static void rna_LayerCollection_name_get(PointerRNA *ptr, char *value) +{ + SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection; + strcpy(value, sc->name); +} + +static int rna_LayerCollection_name_length(PointerRNA *ptr) +{ + SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection; + return strnlen(sc->name, sizeof(sc->name)); +} + +static void rna_LayerCollection_name_set(PointerRNA *ptr, const char *value) +{ + Scene *scene = (Scene *)ptr->id.data; + SceneCollection *sc = ((LayerCollection *)ptr->data)->scene_collection; + SceneCollection *sc_master = BKE_collection_master(scene); + + BLI_strncpy_utf8(sc->name, value, sizeof(sc->name)); + BLI_uniquename(&sc_master->scene_collections, sc, DATA_("SceneCollection"), '.', offsetof(SceneCollection, name), sizeof(sc->name)); +} + +static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *iter) +{ + ListBaseIterator *internal = &iter->internal.listbase; + Base *base = ((LinkData *)internal->link)->data; + return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object); +} + +static void rna_LayerCollection_hide_update(bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + LayerCollection *lc = ptr->data; + SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc); + + /* hide and deselect bases that are directly influenced by this LayerCollection */ + BKE_scene_layer_base_flag_recalculate(sl); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); +} + +static void rna_LayerCollection_hide_select_update(bContext *C, PointerRNA *ptr) +{ + LayerCollection *lc = ptr->data; + + if ((lc->flag & COLLECTION_SELECTABLE) == 0) { + Scene *scene = CTX_data_scene(C); + SceneLayer *sl = BKE_scene_layer_find_from_collection(scene, lc); + + /* deselect bases that are directly influenced by this LayerCollection */ + BKE_scene_layer_base_flag_recalculate(sl); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); + } +} + +static int rna_LayerCollections_active_collection_index_get(PointerRNA *ptr) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + return sl->active_collection; +} + +static void rna_LayerCollections_active_collection_index_set(PointerRNA *ptr, int value) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + int num_collections = BKE_layer_collection_count(sl); + sl->active_collection = min_ff(value, num_collections - 1); +} + +static void rna_LayerCollections_active_collection_index_range( + PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + *min = 0; + *max = max_ii(0, BKE_layer_collection_count(sl) - 1); +} + +static PointerRNA rna_LayerCollections_active_collection_get(PointerRNA *ptr) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + LayerCollection *lc = BKE_layer_collection_active(sl); + return rna_pointer_inherit_refine(ptr, &RNA_LayerCollection, lc); +} + +static void rna_LayerCollections_active_collection_set(PointerRNA *ptr, PointerRNA value) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + LayerCollection *lc = (LayerCollection *)value.data; + const int index = BKE_layer_collection_findindex(sl, lc); + if (index != -1) sl->active_collection = index; +} + +LayerCollection * rna_SceneLayer_collection_link( + ID *id, SceneLayer *sl, Main *bmain, SceneCollection *sc) +{ + Scene *scene = (Scene *)id; + LayerCollection *lc = BKE_collection_link(sl, sc); + + /* TODO(sergey/dfelinto): Only update relations for the current scenelayer. */ + DAG_relations_tag_update(bmain); + WM_main_add_notifier(NC_SCENE | ND_LAYER, scene); + + return lc; +} + +static void rna_SceneLayer_collection_unlink( + ID *id, SceneLayer *sl, Main *bmain, ReportList *reports, LayerCollection *lc) +{ + Scene *scene = (Scene *)id; + + if (BLI_findindex(&sl->layer_collections, lc) == -1) { + BKE_reportf(reports, RPT_ERROR, "Layer collection '%s' is not in '%s'", lc->scene_collection->name, sl->name); + return; + } + + BKE_collection_unlink(sl, lc); + + /* needed otherwise the depgraph will contain freed objects which can crash, see [#20958] */ + /* TODO(sergey/dfelinto): Only update relations for the current scenelayer. */ + DAG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER | ND_OB_ACTIVE, scene); +} + +static PointerRNA rna_LayerObjects_active_object_get(PointerRNA *ptr) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_Object, sl->basact ? sl->basact->object : NULL); +} + +static void rna_LayerObjects_active_object_set(PointerRNA *ptr, PointerRNA value) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + if (value.data) + sl->basact = BKE_scene_layer_base_find(sl, (Object *)value.data); + else + sl->basact = NULL; +} + +static void rna_SceneLayer_name_set(PointerRNA *ptr, const char *value) +{ + Scene *scene = (Scene *)ptr->id.data; + SceneLayer *sl = (SceneLayer *)ptr->data; + char oldname[sizeof(sl->name)]; + + BLI_strncpy(oldname, sl->name, sizeof(sl->name)); + + BLI_strncpy_utf8(sl->name, value, sizeof(sl->name)); + BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name)); + + if (scene->nodetree) { + bNode *node; + int index = BLI_findindex(&scene->render_layers, sl); + + for (node = scene->nodetree->nodes.first; node; node = node->next) { + if (node->type == CMP_NODE_R_LAYERS && node->id == NULL) { + if (node->custom1 == index) + BLI_strncpy(node->name, sl->name, NODE_MAXSTR); + } + } + } +} + +static PointerRNA rna_SceneLayer_objects_get(CollectionPropertyIterator *iter) +{ + ListBaseIterator *internal = &iter->internal.listbase; + + /* we are actually iterating a ObjectBase list, so override get */ + Base *base = (Base *)internal->link; + return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object); +} + +static int rna_SceneLayer_objects_selected_skip(CollectionPropertyIterator *iter, void *UNUSED(data)) +{ + ListBaseIterator *internal = &iter->internal.listbase; + Base *base = (Base *)internal->link; + + if ((base->flag & BASE_SELECTED) != 0) { + return 0; + } + + return 1; +}; + +static void rna_LayerObjects_selected_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + rna_iterator_listbase_begin(iter, &sl->object_bases, rna_SceneLayer_objects_selected_skip); +} + +static void rna_SceneLayer_engine_set(PointerRNA *ptr, int value) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + RenderEngineType *type = BLI_findlink(&R_engines, value); + + if (type) + BKE_scene_layer_engine_set(sl, type->idname); +} + +static EnumPropertyItem *rna_SceneLayer_engine_itemf( + bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + RenderEngineType *type; + EnumPropertyItem *item = NULL; + EnumPropertyItem tmp = {0, "", 0, "", ""}; + int a = 0, totitem = 0; + + for (type = R_engines.first; type; type = type->next, a++) { + tmp.value = a; + tmp.identifier = type->idname; + tmp.name = type->name; + RNA_enum_item_add(&item, &totitem, &tmp); + } + + RNA_enum_item_end(&item, &totitem); + *r_free = true; + + return item; +} + +static int rna_SceneLayer_engine_get(PointerRNA *ptr) +{ + SceneLayer *sl = (SceneLayer *)ptr->data; + RenderEngineType *type; + int a = 0; + + for (type = R_engines.first; type; type = type->next, a++) + if (STREQ(type->idname, sl->engine)) + return a; + + return 0; +} + +static void rna_SceneLayer_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr)) +{ + ED_render_engine_changed(bmain); +} + +static int rna_SceneLayer_multiple_engines_get(PointerRNA *UNUSED(ptr)) +{ + return (BLI_listbase_count(&R_engines) > 1); +} + +static int rna_SceneLayer_active_layer_index_get(PointerRNA *ptr) +{ + Scene *scene = (Scene *)ptr->data; + return scene->active_layer; +} + +static void rna_SceneLayer_active_layer_index_set(PointerRNA *ptr, int value) +{ + Scene *scene = (Scene *)ptr->data; + int num_layers = BLI_listbase_count(&scene->render_layers); + scene->active_layer = min_ff(value, num_layers - 1); +} + +static void rna_SceneLayer_active_layer_index_range( + PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) +{ + Scene *scene = (Scene *)ptr->data; + + *min = 0; + *max = max_ii(0, BLI_listbase_count(&scene->render_layers) - 1); +} + +static PointerRNA rna_SceneLayer_active_layer_get(PointerRNA *ptr) +{ + Scene *scene = (Scene *)ptr->data; + SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer); + + return rna_pointer_inherit_refine(ptr, &RNA_SceneLayer, sl); +} + +static void rna_SceneLayer_active_layer_set(PointerRNA *ptr, PointerRNA value) +{ + Scene *scene = (Scene *)ptr->data; + SceneLayer *sl = (SceneLayer *)value.data; + const int index = BLI_findindex(&scene->render_layers, sl); + if (index != -1) scene->active_layer = index; +} + +static SceneLayer *rna_SceneLayer_new(ID *id, Scene *UNUSED(sce), const char *name) +{ + Scene *scene = (Scene *)id; + SceneLayer *sl = BKE_scene_layer_add(scene, name); + + DAG_id_tag_update(&scene->id, 0); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + + return sl; +} + +static void rna_SceneLayer_remove( + ID *id, Scene *UNUSED(sce), Main *bmain, ReportList *reports, PointerRNA *sl_ptr) +{ + Scene *scene = (Scene *)id; + SceneLayer *sl = sl_ptr->data; + + if (!BKE_scene_layer_remove(bmain, scene, sl)) { + BKE_reportf(reports, RPT_ERROR, "Render layer '%s' could not be removed from scene '%s'", + sl->name, scene->id.name + 2); + return; + } + + RNA_POINTER_INVALIDATE(sl_ptr); + + DAG_id_tag_update(&scene->id, 0); + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); +} + +static void rna_ObjectBase_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Base *base = (Base *)ptr->data; + short mode = (base->flag & BASE_SELECTED) ? BA_SELECT : BA_DESELECT; + ED_object_base_select(base, mode); +} + #else /* Grease Pencil Interpolation tool settings */ @@ -5046,6 +5487,371 @@ static void rna_def_gpu_fx(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUFXSettings_fx_update"); } +/* Render Layers and Collections */ + +static void rna_def_scene_collections(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "SceneCollections"); + srna = RNA_def_struct(brna, "SceneCollections", NULL); + RNA_def_struct_sdna(srna, "SceneCollection"); + RNA_def_struct_ui_text(srna, "Scene Collection", "Collection of scene collections"); + + func = RNA_def_function(srna, "new", "rna_SceneCollection_new"); + RNA_def_function_ui_description(func, "Add a collection to scene"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_string(func, "name", "SceneCollection", 0, "", "New name for the collection (not unique)"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_pointer(func, "result", "SceneCollection", "", "Newly created collection"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_SceneCollection_remove"); + RNA_def_function_ui_description(func, "Remove a collection layer"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); + parm = RNA_def_pointer(func, "layer", "SceneCollection", "", "Collection to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); +} + +static void rna_def_collection_objects(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + PropertyRNA *prop; + + RNA_def_property_srna(cprop, "CollectionObjects"); + srna = RNA_def_struct(brna, "CollectionObjects", NULL); + RNA_def_struct_sdna(srna, "SceneCollection"); + RNA_def_struct_ui_text(srna, "Collection Objects", "Objects of a collection"); + + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_funcs(prop, "rna_SceneCollection_objects_active_index_get", + "rna_SceneCollection_objects_active_index_set", + "rna_SceneCollection_objects_active_index_range"); + RNA_def_property_ui_text(prop, "Active Object Index", "Active index in collection objects array"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); + + func = RNA_def_function(srna, "link", "rna_SceneCollection_object_link"); + RNA_def_function_ui_description(func, "Link an object to collection"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "object", "Object", "", "Object to add to collection"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + + func = RNA_def_function(srna, "unlink", "rna_SceneCollection_object_unlink"); + RNA_def_function_ui_description(func, "Unlink object from collection"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove from collection"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); +} + +static void rna_def_scene_collection(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "SceneCollection", NULL); + RNA_def_struct_ui_text(srna, "Scene Collection", "Collection"); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneCollection_name_set"); + RNA_def_property_ui_text(prop, "Name", "Collection name"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); + + prop = RNA_def_property(srna, "filter", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneCollection_filter_set"); + RNA_def_property_ui_text(prop, "Filter", "Filter to dynamically include objects based on their names (e.g., CHAR_*)"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); + + prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "scene_collections", NULL); + RNA_def_property_struct_type(prop, "SceneCollection"); + RNA_def_property_ui_text(prop, "SceneCollections", ""); + rna_def_scene_collections(brna, prop); + + prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "objects", NULL); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SceneCollection_objects_get", NULL, NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Objects", "All the objects directly added to this collection (not including sub-collection objects)"); + rna_def_collection_objects(brna, prop); + + prop = RNA_def_property(srna, "filters_objects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "filter_objects", NULL); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SceneCollection_objects_get", NULL, NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Filter Objects", "All the objects dynamically added to this collection via the filter"); +} + +static void rna_def_layer_collection_override(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "LayerCollectionOverride", NULL); + RNA_def_struct_sdna(srna, "CollectionOverride"); + RNA_def_struct_ui_text(srna, "Collection Override", "Collection Override"); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", "Collection name"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); +} + +static void rna_def_layer_collection(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "LayerCollection", NULL); + RNA_def_struct_ui_text(srna, "Layer Collection", "Layer collection"); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_LayerCollection_name_get", "rna_LayerCollection_name_length", "rna_LayerCollection_name_set"); + RNA_def_property_ui_text(prop, "Name", "Collection name"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); + + prop = RNA_def_property(srna, "collection", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "scene_collection"); + RNA_def_property_struct_type(prop, "SceneCollection"); + RNA_def_property_ui_text(prop, "Collection", "Collection this layer collection is wrapping"); + + prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "layer_collections", NULL); + RNA_def_property_struct_type(prop, "LayerCollection"); + RNA_def_property_ui_text(prop, "Layer Collections", ""); + + prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_LayerCollection_objects_get", NULL, NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Objects", "All the objects directly or indirectly added to this collection (not including sub-collection objects)"); + + prop = RNA_def_property(srna, "overrides", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "overrides", NULL); + RNA_def_property_struct_type(prop, "LayerCollectionOverride"); + RNA_def_property_ui_text(prop, "Collection Overrides", ""); + + /* Flags */ + prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_VISIBLE); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); + RNA_def_property_ui_text(prop, "Hide", "Restrict visiblity"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_hide_update"); + + prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_SELECTABLE); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, 1); + RNA_def_property_ui_text(prop, "Hide Selectable", "Restrict selection"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_hide_select_update"); + + prop = RNA_def_property(srna, "is_unfolded", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", COLLECTION_FOLDED); + RNA_def_property_ui_icon(prop, ICON_RIGHTARROW, 1); + RNA_def_property_ui_text(prop, "Folded", "Folded collection"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); + + /* TODO_LAYER_OVERRIDE */ +} + +static void rna_def_layer_collections(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *prop; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "LayerCollections"); + srna = RNA_def_struct(brna, "LayerCollections", NULL); + RNA_def_struct_sdna(srna, "SceneLayer"); + RNA_def_struct_ui_text(srna, "Layer Collections", "Collections of render layer"); + + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "active_collection"); + RNA_def_property_int_funcs(prop, "rna_LayerCollections_active_collection_index_get", + "rna_LayerCollections_active_collection_index_set", + "rna_LayerCollections_active_collection_index_range"); + RNA_def_property_ui_text(prop, "Active Collection Index", "Active index in layer collection array"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL); + + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "LayerCollection"); + RNA_def_property_pointer_funcs(prop, "rna_LayerCollections_active_collection_get", + "rna_LayerCollections_active_collection_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Active Layer Collection", "Active Layer Collection"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL); + + func = RNA_def_function(srna, "link", "rna_SceneLayer_collection_link"); + RNA_def_function_ui_description(func, "Link a collection to render layer"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); + parm = RNA_def_pointer(func, "scene_collection", "SceneCollection", "", "Collection to add to render layer"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_pointer(func, "result", "LayerCollection", "", "Newly created layer collection"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "unlink", "rna_SceneLayer_collection_unlink"); + RNA_def_function_ui_description(func, "Unlink a collection from render layer"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "layer_collection", "LayerCollection", "", "Layer collection to remove from render layer"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); +} + +static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + + RNA_def_property_srna(cprop, "LayerObjects"); + srna = RNA_def_struct(brna, "LayerObjects", NULL); + RNA_def_struct_sdna(srna, "SceneLayer"); + RNA_def_struct_ui_text(srna, "Layer Objects", "Collections of objects"); + + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_pointer_funcs(prop, "rna_LayerObjects_active_object_get", "rna_LayerObjects_active_object_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Object", "Active object for this layer"); + /* Could call: ED_base_object_activate(C, rl->basact); + * but would be a bad level call and it seems the notifier is enough */ + RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL); + + prop = RNA_def_property(srna, "selected", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_collection_funcs(prop, "rna_LayerObjects_selected_begin", "rna_iterator_listbase_next", + "rna_iterator_listbase_end", "rna_SceneLayer_objects_get", + NULL, NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Selected Objects", "All the selected objects of this layer"); +} + +static void rna_def_scene_layer(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem engine_items[] = { + {0, "BLENDER_RENDER", 0, "Blender Render", "Use the Blender internal rendering engine for rendering"}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "SceneLayer", NULL); + RNA_def_struct_ui_text(srna, "Render Layer", "Render layer"); + RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneLayer_name_set"); + RNA_def_property_ui_text(prop, "Name", "Render layer name"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL); + + prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "layer_collections", NULL); + RNA_def_property_struct_type(prop, "LayerCollection"); + RNA_def_property_ui_text(prop, "Layer Collections", ""); + rna_def_layer_collections(brna, prop); + + prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "object_bases", NULL); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_SceneLayer_objects_get", NULL, NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Objects", "All the objects in this layer"); + rna_def_layer_objects(brna, prop); + + /* layer options */ + prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SCENE_LAYER_RENDER); + RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the render layer"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL); + + /* engine */ + prop = RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, engine_items); + RNA_def_property_enum_funcs(prop, "rna_SceneLayer_engine_get", "rna_SceneLayer_engine_set", + "rna_SceneLayer_engine_itemf"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering"); + RNA_def_property_update(prop, NC_WINDOW, "rna_SceneLayer_engine_update"); + + prop = RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_SceneLayer_multiple_engines_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available"); +} + +static void rna_def_scene_layers(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + PropertyRNA *prop; + + RNA_def_property_srna(cprop, "SceneLayers"); + srna = RNA_def_struct(brna, "SceneLayers", NULL); + RNA_def_struct_sdna(srna, "Scene"); + RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers"); + + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "active_layer"); + RNA_def_property_int_funcs(prop, "rna_SceneLayer_active_layer_index_get", + "rna_SceneLayer_active_layer_index_set", + "rna_SceneLayer_active_layer_index_range"); + RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL); + + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "SceneLayer"); + RNA_def_property_pointer_funcs(prop, "rna_SceneLayer_active_layer_get", + "rna_SceneLayer_active_layer_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Active Render Layer", "Active Render Layer"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, NULL); + + func = RNA_def_function(srna, "new", "rna_SceneLayer_new"); + RNA_def_function_ui_description(func, "Add a render layer to scene"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_string(func, "name", "SceneLayer", 0, "", "New name for the render layer (not unique)"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_pointer(func, "result", "SceneLayer", "", "Newly created render layer"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_SceneLayer_remove"); + RNA_def_function_ui_description(func, "Remove a render layer"); + RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS | FUNC_USE_SELF_ID); + parm = RNA_def_pointer(func, "layer", "SceneLayer", "", "Render layer to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); +} + +static void rna_def_object_base(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ObjectBase", NULL); + RNA_def_struct_sdna(srna, "Base"); + RNA_def_struct_ui_text(srna, "Object Base", "An object instance in a render layer"); + RNA_def_struct_ui_icon(srna, ICON_OBJECT_DATA); + + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object"); + RNA_def_property_ui_text(prop, "Object", "Object this base links to"); + + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", BASE_SELECTED); + RNA_def_property_ui_text(prop, "Select", "Object base selection state"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ObjectBase_select_update"); +} + +/* TODO LAYERS: legacy SceneRenderLayers, to be removed */ static void rna_def_scene_render_layer(BlenderRNA *brna) { @@ -6760,7 +7566,7 @@ static void rna_def_scene_objects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "object", "Object", "", "Object to add to scene"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - parm = RNA_def_pointer(func, "base", "ObjectBase", "", "The newly created base"); + parm = RNA_def_pointer(func, "base", "ObjectBaseLegacy", "", "The newly created base"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "unlink", "rna_Scene_object_unlink"); @@ -6795,7 +7601,7 @@ static void rna_def_scene_bases(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_struct_ui_text(srna, "Scene Bases", "Collection of scene bases"); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "ObjectBase"); + RNA_def_property_struct_type(prop, "ObjectBaseLegacy"); RNA_def_property_pointer_sdna(prop, NULL, "basact"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Active Base", "Active object base in the scene"); @@ -7039,7 +7845,7 @@ void RNA_def_scene(BlenderRNA *brna) /* Bases/Objects */ prop = RNA_def_property(srna, "object_bases", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "base", NULL); - RNA_def_property_struct_type(prop, "ObjectBase"); + RNA_def_property_struct_type(prop, "ObjectBaseLegacy"); RNA_def_property_ui_text(prop, "Bases", ""); RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, "rna_Scene_object_bases_lookup_string", NULL); @@ -7385,6 +8191,19 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Depsgraph"); RNA_def_property_ui_text(prop, "Dependency Graph", "Dependencies in the scene data"); + /* Layer and Collections */ + prop = RNA_def_property(srna, "render_layers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "render_layers", NULL); + RNA_def_property_struct_type(prop, "SceneLayer"); + RNA_def_property_ui_text(prop, "Render Layers", ""); + rna_def_scene_layers(brna, prop); + + prop = RNA_def_property(srna, "master_collection", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "collection"); + RNA_def_property_struct_type(prop, "SceneCollection"); + RNA_def_property_ui_text(prop, "Master Collection", "Collection that contains all other collections"); + /* Nestled Data */ /* *** Non-Animated *** */ RNA_define_animate_sdna(false); @@ -7400,6 +8219,11 @@ void RNA_def_scene(BlenderRNA *brna) rna_def_transform_orientation(brna); rna_def_selected_uv_element(brna); rna_def_display_safe_areas(brna); + rna_def_scene_collection(brna); + rna_def_layer_collection(brna); + rna_def_layer_collection_override(brna); + rna_def_scene_layer(brna); + rna_def_object_base(brna); RNA_define_animate_sdna(true); /* *** Animated *** */ rna_def_scene_render_data(brna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index af4fb9d0d8a..9bfe70a7faa 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -79,6 +79,7 @@ EnumPropertyItem rna_enum_space_type_items[] = { {0, "", ICON_NONE, NULL, NULL}, {SPACE_BUTS, "PROPERTIES", ICON_BUTS, "Properties", "Edit properties of active object and related data-blocks"}, {SPACE_OUTLINER, "OUTLINER", ICON_OOPS, "Outliner", "Overview of scene graph and all available data-blocks"}, + {SPACE_COLLECTIONS, "COLLECTION_MANAGER", ICON_COLLAPSEMENU, "Collections", "Edit collections of active render layer"}, {SPACE_USERPREF, "USER_PREFERENCES", ICON_PREFERENCES, "User Preferences", "Edit persistent configuration settings"}, {SPACE_INFO, "INFO", ICON_INFO, "Info", "Main menu bar and list of error messages (drag down to expand and display)"}, {0, "", ICON_NONE, NULL, NULL}, @@ -208,6 +209,7 @@ static EnumPropertyItem buttons_context_items[] = { {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"}, {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, + {BCONTEXT_COLLECTION, "COLLECTION", ICON_COLLAPSEMENU, "Collection", "Collection"}, {0, NULL, 0, NULL, NULL} }; @@ -315,6 +317,8 @@ static StructRNA *rna_Space_refine(struct PointerRNA *ptr) return &RNA_SpaceUserPreferences; case SPACE_CLIP: return &RNA_SpaceClipEditor; + case SPACE_COLLECTIONS: + return &RNA_SpaceCollectionManager; default: return &RNA_Space; } @@ -1076,6 +1080,10 @@ static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSED(C), RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE); } + if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_COLLECTION); + } + if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) { RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD); } @@ -4812,6 +4820,15 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); } +static void rna_def_space_collections(BlenderRNA *brna) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, "SpaceCollectionManager", "Space"); + RNA_def_struct_sdna(srna, "SpaceCollections"); + RNA_def_struct_ui_text(srna, "Space Collection Manager", "Layer Collection space data"); +} + void RNA_def_space(BlenderRNA *brna) { @@ -4838,6 +4855,7 @@ void RNA_def_space(BlenderRNA *brna) rna_def_space_node(brna); rna_def_space_logic(brna); rna_def_space_clip(brna); + rna_def_space_collections(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index e68e67586e9..29cb76f5029 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2956,6 +2956,26 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna) rna_def_userdef_theme_spaces_curves(srna, false, false, false, true); } +static void rna_def_userdef_theme_space_collections(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ThemeCollectionManager", NULL); + RNA_def_struct_sdna(srna, "ThemeSpace"); + RNA_def_struct_clear_flag(srna, STRUCT_UNDO); + RNA_def_struct_ui_text(srna, "Theme Collection Manager", "Theme settings for the Collection Manager"); + + rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_list_main(srna); + + prop = RNA_def_property(srna, "selected_collection", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "hilite"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Selected Collection", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +} + static void rna_def_userdef_themes(BlenderRNA *brna) { StructRNA *srna; @@ -2982,6 +3002,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna) {16, "FILE_BROWSER", ICON_FILESEL, "File Browser", ""}, {17, "CONSOLE", ICON_CONSOLE, "Python Console", ""}, {20, "CLIP_EDITOR", ICON_CLIP, "Movie Clip Editor", ""}, + {21, "COLLECTION_MANAGER", ICON_COLLAPSEMENU, "Collection Manager", ""}, {0, NULL, 0, NULL, NULL} }; @@ -3115,6 +3136,12 @@ static void rna_def_userdef_themes(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "tclip"); RNA_def_property_struct_type(prop, "ThemeClipEditor"); RNA_def_property_ui_text(prop, "Clip Editor", ""); + + prop = RNA_def_property(srna, "collection_manager", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "tcollections"); + RNA_def_property_struct_type(prop, "ThemeCollectionManager"); + RNA_def_property_ui_text(prop, "Collection Manager", ""); } static void rna_def_userdef_addon(BlenderRNA *brna) @@ -3205,6 +3232,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna) rna_def_userdef_theme_space_console(brna); rna_def_userdef_theme_space_logic(brna); rna_def_userdef_theme_space_clip(brna); + rna_def_userdef_theme_space_collections(brna); rna_def_userdef_theme_colorset(brna); rna_def_userdef_themes(brna); } |