Workbench: UI for custom studio lights/matcaps

- all known image types are supported
- BpyAPI for studiolights added
- added open user pref operator in shading menu
- possible to add multiple files in a single run

For now refreshing studio lights will free all studiolights and reinit
the whole mechanism. This can be improved by only freeing deleted, reset
updated and add new custom studiolights.

details to show currently only shows the path we perhaps want to add
other information also
This commit is contained in:
Jeroen Bakker 2018-06-07 16:01:57 +02:00
parent 4d16d00154
commit b3c8ffcb3e
7 changed files with 368 additions and 11 deletions

@ -19,13 +19,17 @@
# <pep8 compliant> # <pep8 compliant>
import bpy import bpy
from bpy.types import Operator from bpy.types import (
Operator,
OperatorFileListElement
)
from bpy.props import ( from bpy.props import (
BoolProperty, BoolProperty,
EnumProperty, EnumProperty,
FloatProperty, FloatProperty,
IntProperty, IntProperty,
StringProperty, StringProperty,
CollectionProperty,
) )
from bpy.app.translations import pgettext_tip as tip_ from bpy.app.translations import pgettext_tip as tip_
@ -2400,6 +2404,120 @@ class WM_OT_toolbar(Operator):
return {'FINISHED'} return {'FINISHED'}
# Studio Light operations
class WM_OT_studiolight_install(Operator):
"""Install a user defined studio light"""
bl_idname = "wm.studiolight_install"
bl_label = "Install Custom Studio Light"
files = CollectionProperty(
name="File Path",
type=OperatorFileListElement,
)
directory = StringProperty(
subtype='DIR_PATH',
)
filter_folder = BoolProperty(
name="Filter folders",
default=True,
options={'HIDDEN'},
)
filter_glob = StringProperty(
default="*.png;*.jpg;*.hdr;*.exr",
options={'HIDDEN'},
)
orientation = EnumProperty(
items=(
("MATCAP", "MatCap", ""),
("WORLD", "World", ""),
("CAMERA", "Camera", ""),
)
)
def execute(self, context):
import traceback
import shutil
import pathlib
userpref = context.user_preferences
filepaths = [pathlib.Path(self.directory, e.name) for e in self.files]
path_studiolights = bpy.utils.user_resource('DATAFILES')
if not path_studiolights:
self.report({'ERROR'}, "Failed to get Studio Light path")
return {'CANCELLED'}
path_studiolights = pathlib.Path(path_studiolights, "studiolights", self.orientation.lower())
if not path_studiolights.exists():
try:
path_studiolights.mkdir(parents=True, exist_ok=True)
except:
traceback.print_exc()
for filepath in filepaths:
shutil.copy(str(filepath), str(path_studiolights))
userpref.studio_lights_refresh()
# print message
msg = (
tip_("StudioLight Installed %r into %r") %
(", ".join(str(x.name) for x in self.files), str(path_studiolights))
)
print(msg)
self.report({'INFO'}, msg)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
class WM_OT_studiolight_uninstall(Operator):
bl_idname = 'wm.studiolight_uninstall'
bl_label = "Uninstall Studio Light"
index = bpy.props.IntProperty()
def execute(self, context):
import pathlib
userpref = context.user_preferences
for studio_light in userpref.studio_lights:
if studio_light.index == self.index:
path = pathlib.Path(studio_light.path)
if path.exists():
path.unlink()
userpref.studio_lights_refresh()
return {'FINISHED'}
return {'CANCELLED'}
class WM_OT_studiolight_expand(Operator):
bl_idname = "wm.studiolight_expand"
bl_label = "Expand Studio Light"
index = bpy.props.IntProperty()
def execute(self, context):
userpref = context.user_preferences
for studio_light in userpref.studio_lights:
if studio_light.index == self.index:
studio_light.show_expanded = not studio_light.show_expanded
break
return {'FINISHED'}
class WM_OT_studiolight_userpref_show(Operator):
"""Show light user preferences"""
bl_idname = "wm.studiolight_userpref_show"
bl_label = ""
bl_options = {'INTERNAL'}
def execute(self, context):
context.user_preferences.active_section = 'LIGHTS'
bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
return {'FINISHED'}
classes = ( classes = (
BRUSH_OT_active_index_set, BRUSH_OT_active_index_set,
WM_OT_addon_disable, WM_OT_addon_disable,
@ -2454,6 +2572,10 @@ classes = (
WM_OT_owner_disable, WM_OT_owner_disable,
WM_OT_owner_enable, WM_OT_owner_enable,
WM_OT_url_open, WM_OT_url_open,
WM_OT_studiolight_expand,
WM_OT_studiolight_install,
WM_OT_studiolight_uninstall,
WM_OT_studiolight_userpref_show,
WM_OT_tool_set_by_name, WM_OT_tool_set_by_name,
WM_OT_toolbar, WM_OT_toolbar,
) )

@ -22,6 +22,7 @@ from bpy.types import (
Header, Header,
Menu, Menu,
Panel, Panel,
Operator,
) )
from bpy.app.translations import pgettext_iface as iface_ from bpy.app.translations import pgettext_iface as iface_
from bpy.app.translations import contexts as i18n_contexts from bpy.app.translations import contexts as i18n_contexts
@ -1570,6 +1571,50 @@ class USERPREF_PT_addons(Panel):
row.label(text=module_name, translate=False) row.label(text=module_name, translate=False)
class USERPREF_PT_studiolight(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Lights"
bl_region_type = 'WINDOW'
bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
userpref = context.user_preferences
return (userpref.active_section == 'LIGHTS')
def draw_studio_light(self, layout, studio_light):
box = layout.box()
row = box.row()
op = row.operator('wm.studiolight_expand', emboss=False, text="", icon='TRIA_DOWN' if studio_light.show_expanded else 'TRIA_RIGHT')
op.index = studio_light.index
row.label(text=studio_light.name, icon_value=studio_light.radiance_icon_id)
op = row.operator('wm.studiolight_uninstall', text="", icon='ZOOMOUT')
op.index = studio_light.index
if studio_light.show_expanded:
box.label(studio_light.path)
def draw(self, context):
layout = self.layout
userpref = context.user_preferences
lights = [light for light in userpref.studio_lights if light.is_user_defined]
layout.label("MatCaps")
for studio_light in filter(lambda x: x.orientation=='MATCAP', lights):
self.draw_studio_light(layout, studio_light)
layout.operator('wm.studiolight_install', text="Install Custom MatCap").orientation='MATCAP'
layout.label("World HDRI")
for studio_light in filter(lambda x: x.orientation=='WORLD', lights):
self.draw_studio_light(layout, studio_light)
layout.operator('wm.studiolight_install', text="Install Custom HDRI").orientation='WORLD'
layout.label("Camera HDRI")
for studio_light in filter(lambda x: x.orientation=='CAMERA', lights):
self.draw_studio_light(layout, studio_light)
layout.operator('wm.studiolight_install', text="Install Custom Camera HDRI").orientation='CAMERA'
classes = ( classes = (
USERPREF_HT_header, USERPREF_HT_header,
USERPREF_PT_tabs, USERPREF_PT_tabs,
@ -1590,6 +1635,7 @@ classes = (
USERPREF_PT_input, USERPREF_PT_input,
USERPREF_MT_addons_online_resources, USERPREF_MT_addons_online_resources,
USERPREF_PT_addons, USERPREF_PT_addons,
USERPREF_PT_studiolight,
) )
if __name__ == "__main__": # only for live edit. if __name__ == "__main__": # only for live edit.

@ -3518,12 +3518,16 @@ class VIEW3D_PT_shading(Panel):
if shading.type in ('SOLID', 'TEXTURED'): if shading.type in ('SOLID', 'TEXTURED'):
col.row().prop(shading, "light", expand=True) col.row().prop(shading, "light", expand=True)
if shading.light == 'STUDIO': if shading.light == 'STUDIO':
col.row().template_icon_view(shading, "studio_light") row = col.row()
row.template_icon_view(shading, "studio_light")
op = row.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='ZOOMIN')
if shading.studio_light_orientation == 'WORLD': if shading.studio_light_orientation == 'WORLD':
col.row().prop(shading, "studiolight_rot_z") col.row().prop(shading, "studiolight_rot_z")
elif shading.light == 'MATCAP': elif shading.light == 'MATCAP':
col.row().template_icon_view(shading, "matcap") row = col.row()
row.template_icon_view(shading, "matcap")
op = row.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='ZOOMIN')
if shading.type == 'SOLID': if shading.type == 'SOLID':
col.separator() col.separator()
@ -3571,7 +3575,9 @@ class VIEW3D_PT_shading(Panel):
col.prop(view, "show_world") col.prop(view, "show_world")
elif shading.type in ('MATERIAL'): elif shading.type in ('MATERIAL'):
col.row().template_icon_view(shading, "studio_light") row = col.row()
row.template_icon_view(shading, "studio_light")
op = row.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='ZOOMIN')
if shading.studio_light_orientation == 'WORLD': if shading.studio_light_orientation == 'WORLD':
col.row().prop(shading, "studiolight_rot_z") col.row().prop(shading, "studiolight_rot_z")
col.row().prop(shading, "studiolight_background") col.row().prop(shading, "studiolight_background")

@ -61,6 +61,7 @@ enum StudioLightFlag {
STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1), STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1),
STUDIOLIGHT_INTERNAL = (1 << 2), STUDIOLIGHT_INTERNAL = (1 << 2),
STUDIOLIGHT_EXTERNAL_FILE = (1 << 3), STUDIOLIGHT_EXTERNAL_FILE = (1 << 3),
STUDIOLIGHT_USER_DEFINED = (1 << 12),
STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 4), STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 4),
STUDIOLIGHT_ORIENTATION_WORLD = (1 << 5), STUDIOLIGHT_ORIENTATION_WORLD = (1 << 5),
STUDIOLIGHT_ORIENTATION_VIEWNORMAL = (1 << 6), STUDIOLIGHT_ORIENTATION_VIEWNORMAL = (1 << 6),
@ -69,6 +70,7 @@ enum StudioLightFlag {
STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE = (1 << 9), STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE = (1 << 9),
STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 10), STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 10),
STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11), STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11),
STUDIOLIGHT_UI_EXPANDED = (1 << 13),
} StudioLightFlag; } StudioLightFlag;
#define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE) #define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE)
#define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL) #define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL)
@ -98,7 +100,8 @@ struct StudioLight *BKE_studiolight_find(const char *name, int flag);
struct StudioLight *BKE_studiolight_findindex(int index, int flag); struct StudioLight *BKE_studiolight_findindex(int index, int flag);
struct StudioLight *BKE_studiolight_find_first(int flag); struct StudioLight *BKE_studiolight_find_first(int flag);
unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type); unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type);
const struct ListBase *BKE_studiolight_listbase(void); struct ListBase *BKE_studiolight_listbase(void);
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag); void BKE_studiolight_ensure_flag(StudioLight *sl, int flag);
void BKE_studiolight_refresh(void);
#endif /* __BKE_STUDIOLIGHT_H__ */ #endif /* __BKE_STUDIOLIGHT_H__ */

@ -55,7 +55,6 @@
/* Statics */ /* Statics */
static ListBase studiolights; static ListBase studiolights;
#define STUDIOLIGHT_EXTENSIONS ".jpg", ".hdr"
#define STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE 8 #define STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE 8
#define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT 32 #define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT 32
#define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH (STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT * 2) #define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH (STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT * 2)
@ -482,7 +481,7 @@ static void studiolight_add_files_from_datafolder(const int folder_id, const cha
if ((dir[i].type & S_IFREG)) { if ((dir[i].type & S_IFREG)) {
const char *filename = dir[i].relname; const char *filename = dir[i].relname;
const char *path = dir[i].path; const char *path = dir[i].path;
if (BLI_testextensie_n(filename, STUDIOLIGHT_EXTENSIONS, NULL)) { if (BLI_testextensie_array(filename, imb_ext_image)) {
sl = studiolight_create(); sl = studiolight_create();
sl->flag = STUDIOLIGHT_EXTERNAL_FILE | flag; sl->flag = STUDIOLIGHT_EXTERNAL_FILE | flag;
BLI_strncpy(sl->name, filename, FILE_MAXFILE); BLI_strncpy(sl->name, filename, FILE_MAXFILE);
@ -726,11 +725,11 @@ void BKE_studiolight_init(void)
BLI_addtail(&studiolights, sl); BLI_addtail(&studiolights, sl);
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_USER_DEFINED);
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD); studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD); studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_USER_DEFINED);
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL | STUDIOLIGHT_USER_DEFINED);
/* sort studio lights on filename. */ /* sort studio lights on filename. */
BLI_listbase_sort(&studiolights, studiolight_cmp); BLI_listbase_sort(&studiolights, studiolight_cmp);
@ -782,7 +781,7 @@ struct StudioLight *BKE_studiolight_findindex(int index, int flag)
return BKE_studiolight_find_first(flag); return BKE_studiolight_find_first(flag);
} }
const struct ListBase *BKE_studiolight_listbase(void) struct ListBase *BKE_studiolight_listbase(void)
{ {
return &studiolights; return &studiolights;
} }
@ -830,3 +829,9 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
studiolight_calculate_irradiance_equirectangular_image(sl); studiolight_calculate_irradiance_equirectangular_image(sl);
} }
} }
void BKE_studiolight_refresh(void)
{
BKE_studiolight_free();
BKE_studiolight_init();
}

@ -617,6 +617,7 @@ typedef enum eUserPref_Section {
USER_SECTION_THEME = 4, USER_SECTION_THEME = 4,
USER_SECTION_INPUT = 5, USER_SECTION_INPUT = 5,
USER_SECTION_ADDONS = 6, USER_SECTION_ADDONS = 6,
USER_SECTION_LIGHT = 7,
} eUserPref_Section; } eUserPref_Section;
/* UserDef.flag */ /* UserDef.flag */

@ -41,6 +41,7 @@
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_sound.h" #include "BKE_sound.h"
#include "BKE_addon.h" #include "BKE_addon.h"
#include "BKE_studiolight.h"
#include "RNA_access.h" #include "RNA_access.h"
#include "RNA_define.h" #include "RNA_define.h"
@ -653,6 +654,104 @@ static void rna_ThemeUI_roundness_set(PointerRNA *ptr, float value)
tui->roundness = value * 0.5f; tui->roundness = value * 0.5f;
} }
/* Studio Light */
static void rna_UserDef_studiolight_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
{
rna_iterator_listbase_begin(iter, BKE_studiolight_listbase(), NULL);
}
static void rna_UserDef_studiolight_refresh(UserDef *UNUSED(userdef))
{
BKE_studiolight_refresh();
}
/* StudioLight.name */
static void rna_UserDef_studiolight_name_get(PointerRNA *ptr, char *value)
{
StudioLight *sl = (StudioLight *)ptr->data;
BLI_strncpy(value, sl->name, FILE_MAXFILE);
}
static int rna_UserDef_studiolight_name_length(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return strlen(sl->name);
}
/* StudioLight.path */
static void rna_UserDef_studiolight_path_get(PointerRNA *ptr, char *value)
{
StudioLight *sl = (StudioLight *)ptr->data;
if (sl->path) {
BLI_strncpy(value, sl->path, FILE_MAX);
}
else {
value[0] = '\0';
}
}
static int rna_UserDef_studiolight_path_length(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return strlen(sl->path);
}
/* StudioLight.index */
static int rna_UserDef_studiolight_index_get(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return sl->index;
}
/* StudioLight.radiance_icon_id */
static int rna_UserDef_studiolight_radiance_icon_id_get(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return sl->radiance_icon_id;
}
/* StudioLight.irradiance_icon_id */
static int rna_UserDef_studiolight_irradiance_icon_id_get(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return sl->irradiance_icon_id;
}
/* StudioLight.is_user_defined */
static int rna_UserDef_studiolight_is_user_defined_get(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return (sl->flag & STUDIOLIGHT_USER_DEFINED) > 0;
}
/* StudioLight.show_expanded */
static int rna_UserDef_studiolight_show_expanded_get(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return (sl->flag & STUDIOLIGHT_UI_EXPANDED) > 0;
}
static void rna_UserDef_studiolight_show_expanded_set(PointerRNA *ptr, const bool value)
{
StudioLight *sl = (StudioLight *)ptr->data;
sl->flag ^= STUDIOLIGHT_UI_EXPANDED;
sl->flag |= value?STUDIOLIGHT_UI_EXPANDED: 0;
}
/* StudioLight.orientation */
static int rna_UserDef_studiolight_orientation_get(PointerRNA *ptr)
{
StudioLight *sl = (StudioLight *)ptr->data;
return sl->flag & STUDIOLIGHT_FLAG_ORIENTATIONS;
}
static void rna_UserDef_studiolight_orientation_set(PointerRNA *UNUSED(ptr), const int UNUSED(value))
{
}
#else #else
/* TODO(sergey): This technically belongs to blenlib, but we don't link /* TODO(sergey): This technically belongs to blenlib, but we don't link
@ -3161,6 +3260,67 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL); RNA_def_property_pointer_funcs(prop, "rna_Addon_preferences_get", NULL, NULL, NULL);
} }
static void rna_def_userdef_studiolight(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static const EnumPropertyItem rna_enum_studio_light_orientation_items[] = {
{STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA", 0, "Camera", ""},
{STUDIOLIGHT_ORIENTATION_WORLD, "WORLD", 0, "World", ""},
{STUDIOLIGHT_ORIENTATION_VIEWNORMAL, "MATCAP", 0, "MatCap", ""},
{0, NULL, 0, NULL, NULL}
};
RNA_define_verify_sdna(false);
srna = RNA_def_struct(brna, "StudioLight", NULL);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Studio Light", "Studio light");
prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop, "rna_UserDef_studiolight_index_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Index", "");
prop = RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UserDef_studiolight_is_user_defined_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "User Defined", "");
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_UserDef_studiolight_show_expanded_get", "rna_UserDef_studiolight_show_expanded_set");
RNA_def_property_ui_text(prop, "Show Expanded", "");
prop = RNA_def_property(srna, "orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_studio_light_orientation_items);
RNA_def_property_enum_funcs(prop, "rna_UserDef_studiolight_orientation_get", "rna_UserDef_studiolight_orientation_set", NULL);
RNA_def_property_ui_text(prop, "Orientation", "");
prop = RNA_def_property(srna, "radiance_icon_id", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop, "rna_UserDef_studiolight_radiance_icon_id_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Radiance Icon", "");
prop = RNA_def_property(srna, "irradiance_icon_id", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(prop, "rna_UserDef_studiolight_irradiance_icon_id_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Irradiance Icon", "");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_UserDef_studiolight_name_get", "rna_UserDef_studiolight_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_struct_name_property(srna, prop);
prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_funcs(prop, "rna_UserDef_studiolight_path_get", "rna_UserDef_studiolight_path_length", NULL);
RNA_def_property_ui_text(prop, "Path", "");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_define_verify_sdna(true);
}
static void rna_def_userdef_pathcompare(BlenderRNA *brna) static void rna_def_userdef_pathcompare(BlenderRNA *brna)
{ {
StructRNA *srna; StructRNA *srna;
@ -4665,6 +4825,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{ {
StructRNA *srna; StructRNA *srna;
PropertyRNA *prop; PropertyRNA *prop;
FunctionRNA *func;
static const EnumPropertyItem user_pref_sections[] = { static const EnumPropertyItem user_pref_sections[] = {
{USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""}, {USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""},
@ -4672,6 +4833,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""}, {USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
{USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""}, {USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""},
{USER_SECTION_THEME, "THEMES", 0, "Themes", ""}, {USER_SECTION_THEME, "THEMES", 0, "Themes", ""},
{USER_SECTION_LIGHT, "LIGHTS", 0, "Lights", ""},
{USER_SECTION_FILE, "FILES", 0, "File", ""}, {USER_SECTION_FILE, "FILES", 0, "File", ""},
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""}, {USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
{0, NULL, 0, NULL, NULL} {0, NULL, 0, NULL, NULL}
@ -4757,6 +4919,17 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_flag(prop, PROP_THICK_WRAP); RNA_def_property_flag(prop, PROP_THICK_WRAP);
prop = RNA_def_property(srna, "studio_lights", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "StudioLight");
RNA_def_property_collection_funcs(prop, "rna_UserDef_studiolight_begin", "rna_iterator_listbase_next",
"rna_iterator_listbase_end", "rna_iterator_listbase_get",
NULL, NULL, NULL, NULL);
func = RNA_def_function(srna, "studio_lights_refresh", "rna_UserDef_studiolight_refresh");
RNA_def_function_ui_description(func, "Refresh Studio Lights");
RNA_def_property_ui_text(prop, "Studio Lights", "");
rna_def_userdef_view(brna); rna_def_userdef_view(brna);
rna_def_userdef_edit(brna); rna_def_userdef_edit(brna);
rna_def_userdef_input(brna); rna_def_userdef_input(brna);
@ -4764,6 +4937,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_system(brna); rna_def_userdef_system(brna);
rna_def_userdef_addon(brna); rna_def_userdef_addon(brna);
rna_def_userdef_addon_pref(brna); rna_def_userdef_addon_pref(brna);
rna_def_userdef_studiolight(brna);
rna_def_userdef_pathcompare(brna); rna_def_userdef_pathcompare(brna);
} }