diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2022-04-02 01:11:11 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2022-04-02 07:14:27 +0300 |
commit | ad35453cd19b3db779b0b3a90feac2e93c7a73cf (patch) | |
tree | 3ad7893815bda3e34e18302422ad1f978e828603 /source | |
parent | 5387d33e5f954c4cecdb7ffd3d1042d8632d6c15 (diff) |
Cycles: Add support for light groups
Light groups are a type of pass that only contains lighting from a subset of light sources.
They are created in the View layer, and light sources (lamps, objects with emissive materials
and/or the environment) can be assigned to a group.
Currently, each light group ends up generating its own version of the Combined pass.
In the future, additional types of passes (e.g. shadowcatcher) might be getting their own
per-lightgroup versions.
The lightgroup creation and assignment is not Cycles-specific, so Eevee or external render
engines could make use of it in the future.
Note that Lightgroups are identified by their name - therefore, the name of the Lightgroup
in the View Layer and the name that's set in an object's settings must match for it to be
included.
Currently, changing a Lightgroup's name does not update objects - this is planned for the
future, along with other features such as denoising for light groups and viewing them in
preview renders.
Original patch by Alex Fuller (@mistaed), with some polishing by Lukas Stockner (@lukasstockner97).
Differential Revision: https://developer.blender.org/D12871
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_layer.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/layer.c | 148 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.cc | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/world.c | 12 | ||||
-rw-r--r-- | source/blender/editors/render/render_intern.hh | 2 | ||||
-rw-r--r-- | source/blender/editors/render/render_ops.cc | 2 | ||||
-rw-r--r-- | source/blender/editors/render/render_shading.cc | 80 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_layer_types.h | 19 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_world_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 24 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 104 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_world.c | 23 |
14 files changed, 454 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index c877035830c..4a3917dafee 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -8,6 +8,7 @@ #include "BKE_collection.h" +#include "DNA_layer_types.h" #include "DNA_listBase.h" #ifdef __cplusplus @@ -581,6 +582,21 @@ bool BKE_view_layer_has_valid_aov(struct ViewLayer *view_layer); struct ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV *view_layer_aov); +struct ViewLayerLightgroup *BKE_view_layer_add_lightgroup(struct ViewLayer *view_layer); +void BKE_view_layer_remove_lightgroup(struct ViewLayer *view_layer, + struct ViewLayerLightgroup *lightgroup); +void BKE_view_layer_set_active_lightgroup(struct ViewLayer *view_layer, + struct ViewLayerLightgroup *lightgroup); +struct ViewLayer *BKE_view_layer_find_with_lightgroup( + struct Scene *scene, struct ViewLayerLightgroup *view_layer_lightgroup); +void BKE_view_layer_rename_lightgroup(ViewLayer *view_layer, + ViewLayerLightgroup *lightgroup, + const char *name); + +void BKE_lightgroup_membership_get(struct LightgroupMembership *lgm, char *value); +int BKE_lightgroup_membership_length(struct LightgroupMembership *lgm); +void BKE_lightgroup_membership_set(struct LightgroupMembership **lgm, const char *value); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index ccff4dbed03..c99bf885074 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -266,6 +266,8 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user) BLI_freelistN(&view_layer->drawdata); BLI_freelistN(&view_layer->aovs); view_layer->active_aov = NULL; + BLI_freelistN(&view_layer->lightgroups); + view_layer->active_lightgroup = NULL; MEM_SAFE_FREE(view_layer->stats); @@ -428,6 +430,29 @@ static void layer_aov_copy_data(ViewLayer *view_layer_dst, } } +static void layer_lightgroup_copy_data(ViewLayer *view_layer_dst, + const ViewLayer *view_layer_src, + ListBase *lightgroups_dst, + const ListBase *lightgroups_src) +{ + if (lightgroups_src != NULL) { + BLI_duplicatelist(lightgroups_dst, lightgroups_src); + } + + ViewLayerLightgroup *lightgroup_dst = lightgroups_dst->first; + const ViewLayerLightgroup *lightgroup_src = lightgroups_src->first; + + while (lightgroup_dst != NULL) { + BLI_assert(lightgroup_src); + if (lightgroup_src == view_layer_src->active_lightgroup) { + view_layer_dst->active_lightgroup = lightgroup_dst; + } + + lightgroup_dst = lightgroup_dst->next; + lightgroup_src = lightgroup_src->next; + } +} + static void layer_collections_copy_data(ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, ListBase *layer_collections_dst, @@ -496,6 +521,10 @@ void BKE_view_layer_copy_data(Scene *scene_dst, layer_aov_copy_data( view_layer_dst, view_layer_src, &view_layer_dst->aovs, &view_layer_src->aovs); + BLI_listbase_clear(&view_layer_dst->lightgroups); + layer_lightgroup_copy_data( + view_layer_dst, view_layer_src, &view_layer_dst->lightgroups, &view_layer_src->lightgroups); + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { id_us_plus((ID *)view_layer_dst->mat_override); } @@ -2256,6 +2285,9 @@ void BKE_view_layer_blend_write(BlendWriter *writer, ViewLayer *view_layer) LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { BLO_write_struct(writer, ViewLayerAOV, aov); } + LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) { + BLO_write_struct(writer, ViewLayerLightgroup, lightgroup); + } write_layer_collections(writer, &view_layer->layer_collections); } @@ -2294,6 +2326,9 @@ void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_lay BLO_read_list(reader, &view_layer->aovs); BLO_read_data_address(reader, &view_layer->active_aov); + BLO_read_list(reader, &view_layer->lightgroups); + BLO_read_data_address(reader, &view_layer->active_lightgroup); + BLI_listbase_clear(&view_layer->drawdata); view_layer->object_bases_array = NULL; view_layer->object_bases_hash = NULL; @@ -2471,4 +2506,117 @@ ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV return NULL; } +/* -------------------------------------------------------------------- */ +/** \name Light Groups + * \{ */ + +static void viewlayer_lightgroup_make_name_unique(ViewLayer *view_layer, + ViewLayerLightgroup *lightgroup) +{ + /* Don't allow dots, it's incompatible with OpenEXR convention to store channels + * as "layer.pass.channel". */ + BLI_str_replace_char(lightgroup->name, '.', '_'); + BLI_uniquename(&view_layer->lightgroups, + lightgroup, + DATA_("Lightgroup"), + '_', + offsetof(ViewLayerLightgroup, name), + sizeof(lightgroup->name)); +} + +static void viewlayer_lightgroup_active_set(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup) +{ + if (lightgroup != NULL) { + BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1); + view_layer->active_lightgroup = lightgroup; + } + else { + view_layer->active_lightgroup = NULL; + } +} + +struct ViewLayerLightgroup *BKE_view_layer_add_lightgroup(struct ViewLayer *view_layer) +{ + ViewLayerLightgroup *lightgroup; + lightgroup = MEM_callocN(sizeof(ViewLayerLightgroup), __func__); + BLI_strncpy(lightgroup->name, DATA_("Lightgroup"), sizeof(lightgroup->name)); + BLI_addtail(&view_layer->lightgroups, lightgroup); + viewlayer_lightgroup_active_set(view_layer, lightgroup); + viewlayer_lightgroup_make_name_unique(view_layer, lightgroup); + return lightgroup; +} + +void BKE_view_layer_remove_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup) +{ + BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1); + BLI_assert(lightgroup != NULL); + if (view_layer->active_lightgroup == lightgroup) { + if (lightgroup->next) { + viewlayer_lightgroup_active_set(view_layer, lightgroup->next); + } + else { + viewlayer_lightgroup_active_set(view_layer, lightgroup->prev); + } + } + BLI_freelinkN(&view_layer->lightgroups, lightgroup); +} + +void BKE_view_layer_set_active_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup) +{ + viewlayer_lightgroup_active_set(view_layer, lightgroup); +} + +ViewLayer *BKE_view_layer_find_with_lightgroup(struct Scene *scene, + struct ViewLayerLightgroup *lightgroup) +{ + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + if (BLI_findindex(&view_layer->lightgroups, lightgroup) != -1) { + return view_layer; + } + } + return NULL; +} + +void BKE_view_layer_rename_lightgroup(ViewLayer *view_layer, + ViewLayerLightgroup *lightgroup, + const char *name) +{ + BLI_strncpy_utf8(lightgroup->name, name, sizeof(lightgroup->name)); + viewlayer_lightgroup_make_name_unique(view_layer, lightgroup); +} + +void BKE_lightgroup_membership_get(struct LightgroupMembership *lgm, char *name) +{ + if (lgm != NULL) { + BLI_strncpy(name, lgm->name, sizeof(lgm->name)); + } + else { + name[0] = '\0'; + } +} + +int BKE_lightgroup_membership_length(struct LightgroupMembership *lgm) +{ + if (lgm != NULL) { + return strlen(lgm->name); + } + return 0; +} + +void BKE_lightgroup_membership_set(struct LightgroupMembership **lgm, const char *name) +{ + if (name[0] != '\0') { + if (*lgm == NULL) { + *lgm = MEM_callocN(sizeof(LightgroupMembership), __func__); + } + BLI_strncpy((*lgm)->name, name, sizeof((*lgm)->name)); + } + else { + if (*lgm != NULL) { + MEM_freeN(*lgm); + *lgm = NULL; + } + } +} + /** \} */ diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index c00a403d5e9..833e6f882f1 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -260,6 +260,10 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in else { ob_dst->preview = nullptr; } + + if (ob_src->lightgroup) { + ob_dst->lightgroup = (LightgroupMembership *)MEM_dupallocN(ob_src->lightgroup); + } } static void object_free_data(ID *id) @@ -310,6 +314,8 @@ static void object_free_data(ID *id) } BKE_previewimg_free(&ob->preview); + + MEM_SAFE_FREE(ob->lightgroup); } static void library_foreach_modifiersForeachIDLink(void *user_data, @@ -584,6 +590,10 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre BLO_write_struct_list(writer, LinkData, &ob->pc_ids); BKE_previewimg_blend_write(writer, ob->preview); + + if (ob->lightgroup) { + BLO_write_struct(writer, LightgroupMembership, ob->lightgroup); + } } /* XXX deprecated - old animation system */ @@ -800,6 +810,8 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id) BLO_read_data_address(reader, &ob->preview); BKE_previewimg_blend_read(reader, ob->preview); + + BLO_read_data_address(reader, &ob->lightgroup); } /* XXX deprecated - old animation system */ diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index ac8b18f3395..cc3ee06f539 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -59,6 +59,8 @@ static void world_free_data(ID *id) BKE_icon_id_delete((struct ID *)wrld); BKE_previewimg_free(&wrld->preview); + + MEM_SAFE_FREE(wrld->lightgroup); } static void world_init_data(ID *id) @@ -107,6 +109,10 @@ static void world_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int else { wrld_dst->preview = NULL; } + + if (wrld_src->lightgroup) { + wrld_dst->lightgroup = (LightgroupMembership *)MEM_dupallocN(wrld_src->lightgroup); + } } static void world_foreach_id(ID *id, LibraryForeachIDData *data) @@ -142,6 +148,10 @@ static void world_blend_write(BlendWriter *writer, ID *id, const void *id_addres } BKE_previewimg_blend_write(writer, wrld->preview); + + if (wrld->lightgroup) { + BLO_write_struct(writer, LightgroupMembership, wrld->lightgroup); + } } static void world_blend_read_data(BlendDataReader *reader, ID *id) @@ -153,6 +163,8 @@ static void world_blend_read_data(BlendDataReader *reader, ID *id) BLO_read_data_address(reader, &wrld->preview); BKE_previewimg_blend_read(reader, wrld->preview); BLI_listbase_clear(&wrld->gpumaterial); + + BLO_read_data_address(reader, &wrld->lightgroup); } static void world_blend_read_lib(BlendLibReader *reader, ID *id) diff --git a/source/blender/editors/render/render_intern.hh b/source/blender/editors/render/render_intern.hh index fc40fb06851..4135a0d97a9 100644 --- a/source/blender/editors/render/render_intern.hh +++ b/source/blender/editors/render/render_intern.hh @@ -33,6 +33,8 @@ void SCENE_OT_view_layer_add(struct wmOperatorType *ot); void SCENE_OT_view_layer_remove(struct wmOperatorType *ot); void SCENE_OT_view_layer_add_aov(struct wmOperatorType *ot); void SCENE_OT_view_layer_remove_aov(struct wmOperatorType *ot); +void SCENE_OT_view_layer_add_lightgroup(struct wmOperatorType *ot); +void SCENE_OT_view_layer_remove_lightgroup(struct wmOperatorType *ot); void SCENE_OT_light_cache_bake(struct wmOperatorType *ot); void SCENE_OT_light_cache_free(struct wmOperatorType *ot); diff --git a/source/blender/editors/render/render_ops.cc b/source/blender/editors/render/render_ops.cc index 1583ce44ee5..f671b2f950d 100644 --- a/source/blender/editors/render/render_ops.cc +++ b/source/blender/editors/render/render_ops.cc @@ -39,6 +39,8 @@ void ED_operatortypes_render() WM_operatortype_append(SCENE_OT_view_layer_remove); WM_operatortype_append(SCENE_OT_view_layer_add_aov); WM_operatortype_append(SCENE_OT_view_layer_remove_aov); + WM_operatortype_append(SCENE_OT_view_layer_add_lightgroup); + WM_operatortype_append(SCENE_OT_view_layer_remove_lightgroup); WM_operatortype_append(SCENE_OT_render_view_add); WM_operatortype_append(SCENE_OT_render_view_remove); diff --git a/source/blender/editors/render/render_shading.cc b/source/blender/editors/render/render_shading.cc index f48ac99fe75..07a07b462ef 100644 --- a/source/blender/editors/render/render_shading.cc +++ b/source/blender/editors/render/render_shading.cc @@ -1115,6 +1115,86 @@ void SCENE_OT_view_layer_remove_aov(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ +/** \name View Layer Add Lightgroup Operator + * \{ */ + +static int view_layer_add_lightgroup_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + BKE_view_layer_add_lightgroup(view_layer); + + if (scene->nodetree) { + ntreeCompositUpdateRLayers(scene->nodetree); + } + + DEG_id_tag_update(&scene->id, 0); + DEG_relations_tag_update(CTX_data_main(C)); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_view_layer_add_lightgroup(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Lightgroup"; + ot->idname = "SCENE_OT_view_layer_add_lightgroup"; + ot->description = "Add a Light Group"; + + /* api callbacks */ + ot->exec = view_layer_add_lightgroup_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name View Layer Remove Lightgroup Operator + * \{ */ + +static int view_layer_remove_lightgroup_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + if (view_layer->active_lightgroup == nullptr) { + return OPERATOR_FINISHED; + } + + BKE_view_layer_remove_lightgroup(view_layer, view_layer->active_lightgroup); + + if (scene->nodetree) { + ntreeCompositUpdateRLayers(scene->nodetree); + } + + DEG_id_tag_update(&scene->id, 0); + DEG_relations_tag_update(CTX_data_main(C)); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_view_layer_remove_lightgroup(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Lightgroup"; + ot->idname = "SCENE_OT_view_layer_remove_lightgroup"; + ot->description = "Remove Active Lightgroup"; + + /* api callbacks */ + ot->exec = view_layer_remove_lightgroup_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Light Cache Bake Operator * \{ */ diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index 7b6fe3773f8..d5f7e25bb80 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -124,6 +124,21 @@ typedef struct ViewLayerAOV { * matches `eViewLayerAOVType` */ int type; } ViewLayerAOV; + +/* Lightgroup Renderpass definition. */ +typedef struct ViewLayerLightgroup { + struct ViewLayerLightgroup *next, *prev; + + /* Name of the Lightgroup */ + char name[64]; +} ViewLayerLightgroup; + +/* Lightgroup membership information. */ +typedef struct LightgroupMembership { + /* Name of the Lightgroup */ + char name[64]; +} LightgroupMembership; + typedef struct ViewLayer { struct ViewLayer *next, *prev; /** MAX_NAME. */ @@ -164,6 +179,10 @@ typedef struct ViewLayer { ListBase aovs; ViewLayerAOV *active_aov; + /* List containing the 'ViewLayerLightgroup`s */ + ListBase lightgroups; + ViewLayerLightgroup *active_lightgroup; + /* Runtime data */ /** ViewLayerEngineData. */ ListBase drawdata; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 30f80110f6e..54627e711ff 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -31,6 +31,7 @@ struct Curve; struct FluidsimSettings; struct GeometrySet; struct Ipo; +struct LightgroupMembership; struct Material; struct Mesh; struct Object; @@ -434,8 +435,10 @@ typedef struct Object { ObjectLineArt lineart; + /** Lightgroup membership information. */ + struct LightgroupMembership *lightgroup; + /** Runtime evaluation data (keep last). */ - void *_pad9; Object_Runtime runtime; } Object; diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 497b99eb04d..88f2e0c9407 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -16,6 +16,7 @@ extern "C" { struct AnimData; struct Ipo; +struct LightgroupMembership; struct bNodeTree; #ifndef MAX_MTEX @@ -70,6 +71,9 @@ typedef struct World { /* nodes */ struct bNodeTree *nodetree; + /* Lightgroup membership information. */ + struct LightgroupMembership *lightgroup; + /** Runtime. */ ListBase gpumaterial; } World; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 84f083cb37a..0df0be07fee 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -355,6 +355,10 @@ void rna_ViewLayer_active_aov_index_range( PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax); int rna_ViewLayer_active_aov_index_get(PointerRNA *ptr); void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value); +void rna_ViewLayer_active_lightgroup_index_range( + PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax); +int rna_ViewLayer_active_lightgroup_index_get(PointerRNA *ptr); +void rna_ViewLayer_active_lightgroup_index_set(PointerRNA *ptr, int value); /** * Set `r_rna_path` with the base view-layer path. * `rna_path_buffer_size` should be at least `sizeof(ViewLayer.name) * 3`. diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index e4495df36f1..f995ee3383e 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2292,6 +2292,21 @@ static int rna_Object_mesh_symmetry_yz_editable(PointerRNA *ptr, const char **UN return PROP_EDITABLE; } +void rna_Object_lightgroup_get(PointerRNA *ptr, char *value) +{ + BKE_lightgroup_membership_get(((Object *)ptr->owner_id)->lightgroup, value); +} + +int rna_Object_lightgroup_length(PointerRNA *ptr) +{ + return BKE_lightgroup_membership_length(((Object *)ptr->owner_id)->lightgroup); +} + +void rna_Object_lightgroup_set(PointerRNA *ptr, const char *value) +{ + BKE_lightgroup_membership_set(&((Object *)ptr->owner_id)->lightgroup, value); +} + #else static void rna_def_vertex_group(BlenderRNA *brna) @@ -3775,6 +3790,15 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_Object_mesh_symmetry_yz_editable"); RNA_def_property_ui_text(prop, "Z", "Enable mesh symmetry in the Z axis"); + /* Lightgroup Membership */ + prop = RNA_def_property(srna, "lightgroup", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, + "rna_Object_lightgroup_get", + "rna_Object_lightgroup_length", + "rna_Object_lightgroup_set"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Lightgroup", "Lightgroup that the object belongs to"); + RNA_define_lib_overridable(false); /* anim */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 8d5d93e10ac..0960d246257 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1767,6 +1767,10 @@ void rna_ViewLayer_pass_update(Main *bmain, Scene *activescene, PointerRNA *ptr) ViewLayerAOV *aov = (ViewLayerAOV *)ptr->data; view_layer = BKE_view_layer_find_with_aov(scene, aov); } + else if (ptr->type == &RNA_Lightgroup) { + ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data; + view_layer = BKE_view_layer_find_with_lightgroup(scene, lightgroup); + } if (view_layer) { RenderEngineType *engine_type = RE_engines_find(scene->r.engine); @@ -2447,6 +2451,49 @@ void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value) view_layer->active_aov = aov; } +void rna_ViewLayer_active_lightgroup_index_range( + PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) +{ + ViewLayer *view_layer = (ViewLayer *)ptr->data; + + *min = 0; + *max = max_ii(0, BLI_listbase_count(&view_layer->lightgroups) - 1); +} + +int rna_ViewLayer_active_lightgroup_index_get(PointerRNA *ptr) +{ + ViewLayer *view_layer = (ViewLayer *)ptr->data; + return BLI_findindex(&view_layer->lightgroups, view_layer->active_lightgroup); +} + +void rna_ViewLayer_active_lightgroup_index_set(PointerRNA *ptr, int value) +{ + ViewLayer *view_layer = (ViewLayer *)ptr->data; + ViewLayerLightgroup *lightgroup = BLI_findlink(&view_layer->lightgroups, value); + view_layer->active_lightgroup = lightgroup; +} + +static void rna_ViewLayerLightgroup_name_get(PointerRNA *ptr, char *value) +{ + ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data; + BLI_strncpy(value, lightgroup->name, sizeof(lightgroup->name)); +} + +static int rna_ViewLayerLightgroup_name_length(PointerRNA *ptr) +{ + ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data; + return strlen(lightgroup->name); +} + +static void rna_ViewLayerLightgroup_name_set(PointerRNA *ptr, const char *value) +{ + ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data; + Scene *scene = (Scene *)ptr->owner_id; + ViewLayer *view_layer = BKE_view_layer_find_with_lightgroup(scene, lightgroup); + + BKE_view_layer_rename_lightgroup(view_layer, lightgroup, value); +} + /* Fake value, used internally (not saved to DNA). */ # define V3D_ORIENT_DEFAULT -1 @@ -4156,6 +4203,43 @@ static void rna_def_view_layer_aov(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); } +static void rna_def_view_layer_lightgroups(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + /* PropertyRNA *prop; */ + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "Lightgroups"); + srna = RNA_def_struct(brna, "Lightgroups", NULL); + RNA_def_struct_sdna(srna, "ViewLayer"); + RNA_def_struct_ui_text(srna, "List of Lightgroups", "Collection of Lightgroups"); + + func = RNA_def_function(srna, "add", "BKE_view_layer_add_lightgroup"); + parm = RNA_def_pointer(func, "lightgroup", "Lightgroup", "", "Newly created Lightgroup"); + RNA_def_function_return(func, parm); +} + +static void rna_def_view_layer_lightgroup(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + srna = RNA_def_struct(brna, "Lightgroup", NULL); + RNA_def_struct_sdna(srna, "ViewLayerLightgroup"); + RNA_def_struct_ui_text(srna, "Light Group", ""); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_string_funcs(prop, + "rna_ViewLayerLightgroup_name_get", + "rna_ViewLayerLightgroup_name_length", + "rna_ViewLayerLightgroup_name_set"); + RNA_def_property_ui_text(prop, "Name", "Name of the Lightgroup"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update"); + RNA_def_struct_name_property(srna, prop); +} + void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool scene) { PropertyRNA *prop; @@ -4226,6 +4310,25 @@ void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool sce RNA_def_property_ui_text(prop, "Active AOV Index", "Index of active aov"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "lightgroups", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "lightgroups", NULL); + RNA_def_property_struct_type(prop, "Lightgroup"); + RNA_def_property_ui_text(prop, "Light Groups", ""); + rna_def_view_layer_lightgroups(brna, prop); + + prop = RNA_def_property(srna, "active_lightgroup", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Lightgroup"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Light Groups", "Active Lightgroup"); + + prop = RNA_def_property(srna, "active_lightgroup_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_funcs(prop, + "rna_ViewLayer_active_lightgroup_index_get", + "rna_ViewLayer_active_lightgroup_index_set", + "rna_ViewLayer_active_lightgroup_index_range"); + RNA_def_property_ui_text(prop, "Active Lightgroup Index", "Index of active lightgroup"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "use_pass_cryptomatte_object", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_OBJECT); RNA_def_property_ui_text( @@ -8088,6 +8191,7 @@ void RNA_def_scene(BlenderRNA *brna) rna_def_scene_display(brna); rna_def_scene_eevee(brna); rna_def_view_layer_aov(brna); + rna_def_view_layer_lightgroup(brna); rna_def_view_layer_eevee(brna); rna_def_scene_gpencil(brna); RNA_define_animate_sdna(true); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 04008665342..d1049eef2c7 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -22,6 +22,7 @@ # include "MEM_guardedalloc.h" # include "BKE_context.h" +# include "BKE_layer.h" # include "BKE_main.h" # include "BKE_texture.h" @@ -84,6 +85,21 @@ static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr) rna_World_draw_update(bmain, scene, ptr); } +void rna_World_lightgroup_get(PointerRNA *ptr, char *value) +{ + BKE_lightgroup_membership_get(((World *)ptr->owner_id)->lightgroup, value); +} + +int rna_World_lightgroup_length(PointerRNA *ptr) +{ + return BKE_lightgroup_membership_length(((World *)ptr->owner_id)->lightgroup); +} + +void rna_World_lightgroup_set(PointerRNA *ptr, const char *value) +{ + BKE_lightgroup_membership_set(&((World *)ptr->owner_id)->lightgroup, value); +} + #else static void rna_def_lighting(BlenderRNA *brna) @@ -234,6 +250,13 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the world"); RNA_def_property_update(prop, 0, "rna_World_use_nodes_update"); + /* Lightgroup Membership */ + prop = RNA_def_property(srna, "lightgroup", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs( + prop, "rna_World_lightgroup_get", "rna_World_lightgroup_length", "rna_World_lightgroup_set"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Lightgroup", "Lightgroup that the world belongs to"); + rna_def_lighting(brna); rna_def_world_mist(brna); } |