UI: Add Wavelength unit for scene-independent nanometer-scale inputs #120900

Merged
Lukas Stockner merged 1 commits from LukasStockner/blender:wavelength-unit into main 2024-04-22 13:10:29 +02:00
13 changed files with 96 additions and 4 deletions

View File

@ -124,6 +124,10 @@ static const bNodeSocketStaticTypeInfo node_socket_subtypes[] = {
SOCK_FLOAT,
PROP_TIME_ABSOLUTE},
{"NodeSocketFloatDistance", "NodeTreeInterfaceSocketFloatDistance", SOCK_FLOAT, PROP_DISTANCE},
{"NodeSocketFloatWavelength",
"NodeTreeInterfaceSocketFloatWavelength",
SOCK_FLOAT,
PROP_WAVELENGTH},
{"NodeSocketInt", "NodeTreeInterfaceSocketInt", SOCK_INT, PROP_NONE},
{"NodeSocketIntUnsigned", "NodeTreeInterfaceSocketIntUnsigned", SOCK_INT, PROP_UNSIGNED},
{"NodeSocketIntPercentage", "NodeTreeInterfaceSocketIntPercentage", SOCK_INT, PROP_PERCENTAGE},

View File

@ -116,5 +116,6 @@ enum {
B_UNIT_CAMERA = 10,
B_UNIT_POWER = 11,
B_UNIT_TEMPERATURE = 12,
B_UNIT_TYPE_TOT = 13,
B_UNIT_WAVELENGTH = 13,
B_UNIT_TYPE_TOT = 14,
};

View File

@ -527,6 +527,8 @@ static StringRef get_legacy_socket_subtype_idname(StringRef idname, const void *
return "NodeSocketFloatTimeAbsolute";
case PROP_DISTANCE:
return "NodeSocketFloatDistance";
case PROP_WAVELENGTH:
return "NodeSocketFloatWavelength";
}
}
if (idname == "NodeSocketInt") {
@ -2089,6 +2091,8 @@ const char *nodeStaticSocketType(const int type, const int subtype)
return "NodeSocketFloatTimeAbsolute";
case PROP_DISTANCE:
return "NodeSocketFloatDistance";
case PROP_WAVELENGTH:
return "NodeSocketFloatWavelength";
case PROP_NONE:
default:
return "NodeSocketFloat";
@ -2174,6 +2178,8 @@ const char *nodeStaticSocketInterfaceTypeNew(const int type, const int subtype)
return "NodeTreeInterfaceSocketFloatTimeAbsolute";
case PROP_DISTANCE:
return "NodeTreeInterfaceSocketFloatDistance";
case PROP_WAVELENGTH:
return "NodeTreeInterfaceSocketFloatWavelength";
case PROP_NONE:
default:
return "NodeTreeInterfaceSocketFloat";

View File

@ -2921,6 +2921,7 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl
case B_UNIT_MASS:
return value * pow(unit->scale_length, 3);
case B_UNIT_CAMERA: /* *Do not* use scene's unit scale for camera focal lens! See #42026. */
case B_UNIT_WAVELENGTH: /* Wavelength values are independent of the scene scale. */
default:
return value;
}

View File

@ -387,6 +387,62 @@ static bUnitCollection buImperialLenCollection = {
/*length*/ UNIT_COLLECTION_LENGTH(buImperialLenDef),
};
/* Wavelengths (scene-independent, with nm as the base unit). */
static bUnitDef buWavelengthLenDef[] = {
{
/*name*/ "millimeter",
/*name_plural*/ "millimeters",
/*name_short*/ "mm",
/*name_alt*/ nullptr,
/*name_display*/ "Millimeters",
/*identifier*/ nullptr,
/*scalar*/ 1e6f,
/*bias*/ 0.0,
/*flag*/ B_UNIT_DEF_NONE,
},
{
/*name*/ "micrometer",
/*name_plural*/ "micrometers",
/*name_short*/ "µm",
/*name_alt*/ "um",
/*name_display*/ "Micrometers",
/*identifier*/ nullptr,
/*scalar*/ 1e3f,
/*bias*/ 0.0,
/*flag*/ B_UNIT_DEF_NONE,
},
/* Base unit. */
{
/*name*/ "nanometer",
/*name_plural*/ "nanometers",
/*name_short*/ "nm",
/*name_alt*/ nullptr,
/*name_display*/ "Nanometers",
/*identifier*/ nullptr,
/*scalar*/ 1.0f,
/*bias*/ 0.0,
/*flag*/ B_UNIT_DEF_NONE,
},
{
/*name*/ "picometer",
/*name_plural*/ "picometers",
/*name_short*/ "pm",
/*name_alt*/ nullptr,
/*name_display*/ "Picometers",
/*identifier*/ nullptr,
/*scalar*/ 1e-3f,
/*bias*/ 0.0,
/*flag*/ B_UNIT_DEF_NONE,
},
NULL_UNIT,
};
static bUnitCollection buWavelengthLenCollection = {
/*units*/ buWavelengthLenDef,
/*base_unit*/ 2,
/*flag*/ 0,
/*length*/ UNIT_COLLECTION_LENGTH(buWavelengthLenDef),
};
/* Areas. */
static bUnitDef buMetricAreaDef[] = {
{
@ -1420,6 +1476,7 @@ static const bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = {
/*B_UNIT_CAMERA*/ nullptr,
/*B_UNIT_POWER*/ nullptr,
/*B_UNIT_TEMPERATURE*/ nullptr,
/*B_UNIT_WAVELENGTH*/ nullptr,
},
/* Metric. */
{
@ -1436,6 +1493,7 @@ static const bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = {
/*B_UNIT_CAMERA*/ &buCameraLenCollection,
/*B_UNIT_POWER*/ &buPowerCollection,
/*B_UNIT_TEMPERATURE*/ &buMetricTempCollection,
/*B_UNIT_WAVELENGTH*/ &buWavelengthLenCollection,
},
/* Imperial. */
{
@ -1452,6 +1510,7 @@ static const bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = {
/*B_UNIT_CAMERA*/ &buCameraLenCollection,
/*B_UNIT_POWER*/ &buPowerCollection,
/*B_UNIT_TEMPERATURE*/ &buImperialTempCollection,
/*B_UNIT_WAVELENGTH*/ &buWavelengthLenCollection,
},
{nullptr},
};
@ -1599,7 +1658,7 @@ static size_t unit_as_string(char *str,
static bool unit_should_be_split(int type)
{
return ELEM(type, B_UNIT_LENGTH, B_UNIT_MASS, B_UNIT_TIME, B_UNIT_CAMERA);
return ELEM(type, B_UNIT_LENGTH, B_UNIT_MASS, B_UNIT_TIME, B_UNIT_CAMERA, B_UNIT_WAVELENGTH);
}
struct PreferredUnits {

View File

@ -84,6 +84,7 @@ enum PropertyUnit {
PROP_UNIT_CAMERA = (10 << 16), /* mm */
PROP_UNIT_POWER = (11 << 16), /* W */
PROP_UNIT_TEMPERATURE = (12 << 16), /* C */
PROP_UNIT_WAVELENGTH = (13 << 16), /* nm (independent of scene) */
};
ENUM_OPERATORS(PropertyUnit, PROP_UNIT_TEMPERATURE)
@ -180,6 +181,9 @@ enum PropertySubType {
/* temperature */
PROP_TEMPERATURE = 43 | PROP_UNIT_TEMPERATURE,
/* wavelength */
PROP_WAVELENGTH = 44 | PROP_UNIT_WAVELENGTH,
};
/* Make sure enums are updated with these */

View File

@ -3619,6 +3619,8 @@ static const char *rna_property_subtypename(PropertySubType type)
return "PROP_POWER";
case PROP_TEMPERATURE:
return "PROP_TEMPERATURE";
case PROP_WAVELENGTH:
return "PROP_WAVELENGTH";
default: {
/* in case we don't have a type preset that includes the subtype */
if (RNA_SUBTYPE_UNIT(type)) {
@ -3658,6 +3660,8 @@ static const char *rna_property_subtype_unit(PropertySubType type)
return "PROP_UNIT_POWER";
case PROP_UNIT_TEMPERATURE:
return "PROP_UNIT_TEMPERATURE";
case PROP_UNIT_WAVELENGTH:
return "PROP_UNIT_WAVELENGTH";
default:
return "PROP_UNIT_UNKNOWN";
}

View File

@ -1551,6 +1551,10 @@ static const bNodeSocketStaticTypeInfo node_socket_subtypes[] = {
SOCK_FLOAT,
PROP_TIME_ABSOLUTE},
{"NodeSocketFloatDistance", "NodeTreeInterfaceSocketFloatDistance", SOCK_FLOAT, PROP_DISTANCE},
{"NodeSocketFloatWavelength",
"NodeTreeInterfaceSocketFloatWavelength",
SOCK_FLOAT,
PROP_WAVELENGTH},
{"NodeSocketInt", "NodeTreeInterfaceSocketInt", SOCK_INT, PROP_NONE},
{"NodeSocketIntUnsigned", "NodeTreeInterfaceSocketIntUnsigned", SOCK_INT, PROP_UNSIGNED},
{"NodeSocketIntPercentage", "NodeTreeInterfaceSocketIntPercentage", SOCK_INT, PROP_PERCENTAGE},

View File

@ -704,6 +704,7 @@ static const EnumPropertyItem *rna_NodeTreeInterfaceSocketFloat_subtype_itemf(
PROP_TIME,
PROP_TIME_ABSOLUTE,
PROP_DISTANCE,
PROP_WAVELENGTH,
PROP_NONE},
r_free);
}

View File

@ -78,7 +78,8 @@ const EnumPropertyItem rna_enum_property_type_items[] = {
{PROP_DISTANCE, "DISTANCE", 0, "Distance", ""}, \
{PROP_DISTANCE_CAMERA, "DISTANCE_CAMERA", 0, "Camera Distance", ""}, \
{PROP_POWER, "POWER", 0, "Power", ""}, \
{PROP_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""}
{PROP_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""}, \
{PROP_WAVELENGTH, "WAVELENGTH", 0, "Wavelength", ""}
#define RNA_ENUM_PROPERTY_SUBTYPE_NUMBER_ARRAY_ITEMS \
{PROP_COLOR, "COLOR", 0, "Color", ""}, \
@ -150,6 +151,7 @@ const EnumPropertyItem rna_enum_property_unit_items[] = {
{PROP_UNIT_CAMERA, "CAMERA", 0, "Camera", ""},
{PROP_UNIT_POWER, "POWER", 0, "Power", ""},
{PROP_UNIT_TEMPERATURE, "TEMPERATURE", 0, "Temperature", ""},
{PROP_UNIT_WAVELENGTH, "WAVELENGTH", 0, "Wavelength", ""},
{0, nullptr, 0, nullptr, nullptr},
};

View File

@ -1143,6 +1143,7 @@ void register_standard_node_socket_types()
nodeRegisterSocketType(make_socket_type_float(PROP_TIME));
nodeRegisterSocketType(make_socket_type_float(PROP_TIME_ABSOLUTE));
nodeRegisterSocketType(make_socket_type_float(PROP_DISTANCE));
nodeRegisterSocketType(make_socket_type_float(PROP_WAVELENGTH));
nodeRegisterSocketType(make_socket_type_int(PROP_NONE));
nodeRegisterSocketType(make_socket_type_int(PROP_UNSIGNED));

View File

@ -10,7 +10,11 @@ namespace blender::nodes::node_shader_wavelength_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>("Wavelength").default_value(500.0f).min(380.0f).max(780.0f);
b.add_input<decl::Float>("Wavelength")
.default_value(500.0f)
.min(380.0f)
.max(780.0f)
.subtype(PROP_WAVELENGTH);
b.add_output<decl::Color>("Color");
}

View File

@ -52,6 +52,7 @@ static const char *bpyunits_ucategories_items[] = {
"CAMERA",
"POWER",
"TEMPERATURE",
"WAVELENGTH",
nullptr,
};