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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1114,6 +1114,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
|
||||
* \{ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user