Cycles: OSL Camera: Improve Property UI

This expands Cycles' support for handling OSL property metadata for
Custom camera parameters and translating it to Blender's UI.

Specifically, it adds support for:
- Translation inputs (`string vecsemantics = "POINT"`)
- Normal inputs (`string vecsemantics = "NORMAL"`)
- File inputs (`string widget = "filename"`)
- Angle inputs (`string unit = "radians"`)
- Distance inputs (`string unit = "m"`)
- Time inputs (`string unit = "s"` or `string unit = "sec"`)
- Enum inputs (`string widget = "mapper", string options = "left:0|right:1"`)

It also sets the default value correctly, and corrects a warning string to
also mention cameras in addition to nodes as possible users of OSL shaders.

Co-authored-by: Lukas Stockner <lukas@lukasstockner.de>
Pull Request: https://projects.blender.org/blender/blender/pulls/146736
This commit is contained in:
Damien Picard
2025-09-29 02:20:23 +02:00
committed by Lukas Stockner
parent b5863c401e
commit 6c6d1a9b63
3 changed files with 40 additions and 2 deletions

View File

@@ -135,12 +135,40 @@ def osl_param_ensure_property(ccam, param):
ui = ccam.id_properties_ui(name)
ui.clear()
ui.update(default=tuple(default) if len(default) > 1 else default[0])
# Determine subtype (no unit support for now)
# Determine subtype (limited unit support for now)
if param.type.vecsemantics == param.type.vecsemantics.COLOR:
ui.update(subtype='COLOR')
elif param.type.vecsemantics == param.type.vecsemantics.POINT:
ui.update(subtype='TRANSLATION')
elif param.type.vecsemantics == param.type.vecsemantics.NORMAL:
ui.update(subtype='DIRECTION')
elif datatype is str and metadata.get('widget') == 'filename':
ui.update(subtype='FILE_PATH')
elif datatype is float and metadata.get('unit') == 'radians':
ui.update(subtype='ANGLE')
elif datatype is float and metadata.get('unit') == 'm':
ui.update(subtype='DISTANCE')
elif datatype is float and metadata.get('unit') in ('s', 'sec'):
ui.update(subtype='TIME_ABSOLUTE')
elif metadata.get('slider'):
ui.update(subtype='FACTOR')
elif datatype is int and metadata.get('widget') == 'mapper':
options = metadata.get('options', "")
options = options.split("|")
option_items = []
for option in options:
if ":" not in option:
continue
item, index = option.split(":")
# Ensure that the index can be converted to an integer
try:
int(index)
except ValueError:
continue
option_items.append((str(index), bpy.path.display_name(item), ""))
ui.update(items=option_items)
# Map OSL metadata to Blender names
option_map = {

View File

@@ -435,6 +435,16 @@ class BlenderCameraParamQuery : public OSLCameraParamQuery {
data.push_back(RNA_property_boolean_get(&custom_props, prop));
}
}
else if (RNA_property_type(prop) == PROP_ENUM) {
const char *identifier = "";
const int value = RNA_property_enum_get(&custom_props, prop);
if (RNA_property_enum_identifier(nullptr, &custom_props, prop, value, &identifier)) {
data.push_back(atoi(identifier));
}
else {
data.push_back(value);
}
}
else {
if (array_len > 0) {
data.resize(array_len);