diff options
25 files changed, 363 insertions, 108 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh index 9efa64d1474..4482e13e1cf 100644 --- a/source/blender/blenkernel/BKE_attribute_math.hh +++ b/source/blender/blenkernel/BKE_attribute_math.hh @@ -5,6 +5,7 @@ #include "BLI_array.hh" #include "BLI_color.hh" #include "BLI_cpp_type.hh" +#include "BLI_math_color.hh" #include "BLI_math_vector.h" #include "BLI_math_vector.hh" @@ -18,17 +19,23 @@ namespace blender::attribute_math { template<typename Func> inline void convert_to_static_type(const CPPType &cpp_type, const Func &func) { - cpp_type.to_static_type_tag<float, float2, float3, int, bool, int8_t, ColorGeometry4f>( - [&](auto type_tag) { - using T = typename decltype(type_tag)::type; - if constexpr (std::is_same_v<T, void>) { - /* It's expected that the given cpp type is one of the supported ones. */ - BLI_assert_unreachable(); - } - else { - func(T()); - } - }); + cpp_type.to_static_type_tag<float, + float2, + float3, + int, + bool, + int8_t, + ColorGeometry4f, + ColorGeometry4b>([&](auto type_tag) { + using T = typename decltype(type_tag)::type; + if constexpr (std::is_same_v<T, void>) { + /* It's expected that the given cpp type is one of the supported ones. */ + BLI_assert_unreachable(); + } + else { + func(T()); + } + }); } template<typename Func> @@ -91,6 +98,22 @@ inline ColorGeometry4f mix3(const float3 &weights, return result; } +template<> +inline ColorGeometry4b mix3(const float3 &weights, + const ColorGeometry4b &v0, + const ColorGeometry4b &v1, + const ColorGeometry4b &v2) +{ + const float4 v0_f{&v0.r}; + const float4 v1_f{&v1.r}; + const float4 v2_f{&v2.r}; + const float4 mixed = v0_f * weights[0] + v1_f * weights[1] + v2_f * weights[2]; + return ColorGeometry4b{static_cast<uint8_t>(mixed[0]), + static_cast<uint8_t>(mixed[1]), + static_cast<uint8_t>(mixed[2]), + static_cast<uint8_t>(mixed[3])}; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -134,9 +157,13 @@ template<> inline float3 mix2(const float factor, const float3 &a, const float3 template<> inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b) { - ColorGeometry4f result; - interp_v4_v4v4(result, a, b, factor); - return result; + return math::interpolate(a, b, factor); +} + +template<> +inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b) +{ + return math::interpolate(a, b, factor); } /** \} */ @@ -278,19 +305,33 @@ class SimpleMixerWithAccumulationType { } }; -class ColorGeometryMixer { +class ColorGeometry4fMixer { private: MutableSpan<ColorGeometry4f> buffer_; ColorGeometry4f default_color_; Array<float> total_weights_; public: - ColorGeometryMixer(MutableSpan<ColorGeometry4f> buffer, - ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f)); + ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer, + ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f)); void mix_in(int64_t index, const ColorGeometry4f &color, float weight = 1.0f); void finalize(); }; +class ColorGeometry4bMixer { + private: + MutableSpan<ColorGeometry4b> buffer_; + ColorGeometry4b default_color_; + Array<float> total_weights_; + Array<float4> accumulation_buffer_; + + public: + ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer, + ColorGeometry4b default_color = ColorGeometry4b(0, 0, 0, 255)); + void mix_in(int64_t index, const ColorGeometry4b &color, float weight = 1.0f); + void finalize(); +}; + template<typename T> struct DefaultMixerStruct { /* Use void by default. This can be checked for in `if constexpr` statements. */ using type = void; @@ -307,7 +348,10 @@ template<> struct DefaultMixerStruct<float3> { template<> struct DefaultMixerStruct<ColorGeometry4f> { /* Use a special mixer for colors. ColorGeometry4f can't be added/multiplied, because this is not * something one should usually do with colors. */ - using type = ColorGeometryMixer; + using type = ColorGeometry4fMixer; +}; +template<> struct DefaultMixerStruct<ColorGeometry4b> { + using type = ColorGeometry4bMixer; }; template<> struct DefaultMixerStruct<int> { static int double_to_int(const double &value) diff --git a/source/blender/blenkernel/BKE_type_conversions.hh b/source/blender/blenkernel/BKE_type_conversions.hh index 5152989d137..1cca172e188 100644 --- a/source/blender/blenkernel/BKE_type_conversions.hh +++ b/source/blender/blenkernel/BKE_type_conversions.hh @@ -2,6 +2,7 @@ #pragma once +#include "FN_field.hh" #include "FN_multi_function.hh" namespace blender::bke { @@ -59,8 +60,8 @@ class DataTypeConversions { void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const; GVArray try_convert(GVArray varray, const CPPType &to_type) const; - GVMutableArray try_convert(GVMutableArray varray, const CPPType &to_type) const; + fn::GField try_convert(fn::GField field, const CPPType &to_type) const; }; const DataTypeConversions &get_implicit_type_conversions(); diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 7e1fc8ca02c..77c7857a528 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -70,11 +70,11 @@ static int attribute_data_type_complexity(const CustomDataType data_type) return 4; case CD_PROP_FLOAT3: return 5; - case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: return 6; + case CD_PROP_COLOR: + return 7; #if 0 /* These attribute types are not supported yet. */ - case CD_PROP_BYTE_COLOR: - return 3; case CD_PROP_STRING: return 6; #endif diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index bfc4c8fcde0..8c021ed0e21 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -127,7 +127,7 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { static constexpr uint64_t supported_types_mask = CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL | - CD_MASK_PROP_INT8; + CD_MASK_PROP_INT8 | CD_MASK_PROP_BYTE_COLOR; const AttributeDomain domain_; const CustomDataAccessInfo custom_data_access_; diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc index df3cab474cd..c38df2a2969 100644 --- a/source/blender/blenkernel/intern/attribute_math.cc +++ b/source/blender/blenkernel/intern/attribute_math.cc @@ -4,8 +4,8 @@ namespace blender::attribute_math { -ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffer, - ColorGeometry4f default_color) +ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> output_buffer, + ColorGeometry4f default_color) : buffer_(output_buffer), default_color_(default_color), total_weights_(output_buffer.size(), 0.0f) @@ -13,9 +13,9 @@ ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffe buffer_.fill(ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f)); } -void ColorGeometryMixer::mix_in(const int64_t index, - const ColorGeometry4f &color, - const float weight) +void ColorGeometry4fMixer::mix_in(const int64_t index, + const ColorGeometry4f &color, + const float weight) { BLI_assert(weight >= 0.0f); ColorGeometry4f &output_color = buffer_[index]; @@ -26,7 +26,7 @@ void ColorGeometryMixer::mix_in(const int64_t index, total_weights_[index] += weight; } -void ColorGeometryMixer::finalize() +void ColorGeometry4fMixer::finalize() { for (const int64_t i : buffer_.index_range()) { const float weight = total_weights_[i]; @@ -44,4 +44,43 @@ void ColorGeometryMixer::finalize() } } +ColorGeometry4bMixer::ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer, + ColorGeometry4b default_color) + : buffer_(buffer), + default_color_(default_color), + total_weights_(buffer.size(), 0.0f), + accumulation_buffer_(buffer.size(), float4(0, 0, 0, 0)) +{ +} + +void ColorGeometry4bMixer::mix_in(int64_t index, const ColorGeometry4b &color, float weight) +{ + BLI_assert(weight >= 0.0f); + float4 &accum_value = accumulation_buffer_[index]; + accum_value[0] += color.r * weight; + accum_value[1] += color.g * weight; + accum_value[2] += color.b * weight; + accum_value[3] += color.a * weight; + total_weights_[index] += weight; +} + +void ColorGeometry4bMixer::finalize() +{ + for (const int64_t i : buffer_.index_range()) { + const float weight = total_weights_[i]; + const float4 &accum_value = accumulation_buffer_[i]; + ColorGeometry4b &output_color = buffer_[i]; + if (weight > 0.0f) { + const float weight_inv = 1.0f / weight; + output_color.r = accum_value[0] * weight_inv; + output_color.g = accum_value[1] * weight_inv; + output_color.b = accum_value[2] * weight_inv; + output_color.a = accum_value[3] * weight_inv; + } + else { + output_color = default_color_; + } + } +} + } // namespace blender::attribute_math diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index a50351d19c0..1b3c914c69b 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -5399,6 +5399,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type) return &CPPType::get<bool>(); case CD_PROP_INT8: return &CPPType::get<int8_t>(); + case CD_PROP_BYTE_COLOR: + return &CPPType::get<ColorGeometry4b>(); default: return nullptr; } @@ -5428,6 +5430,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) if (type.is<int8_t>()) { return CD_PROP_INT8; } + if (type.is<ColorGeometry4b>()) { + return CD_PROP_BYTE_COLOR; + } return static_cast<CustomDataType>(-1); } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 597e4efe284..fb39861d3e7 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -903,22 +903,6 @@ static void set_loop_uv(MLoopUV &uv, float2 co) copy_v2_v2(uv.uv, co); } -static ColorGeometry4f get_loop_color(const MLoopCol &col) -{ - ColorGeometry4b encoded_color = ColorGeometry4b(col.r, col.g, col.b, col.a); - ColorGeometry4f linear_color = encoded_color.decode(); - return linear_color; -} - -static void set_loop_color(MLoopCol &col, ColorGeometry4f linear_color) -{ - ColorGeometry4b encoded_color = linear_color.encode(); - col.r = encoded_color.r; - col.g = encoded_color.g; - col.b = encoded_color.b; - col.a = encoded_color.a; -} - static float get_crease(const MEdge &edge) { return edge.crease / 255.0f; @@ -1293,14 +1277,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_derived_read_attribute<MLoopUV, float2, get_loop_uv>, make_derived_write_attribute<MLoopUV, float2, get_loop_uv, set_loop_uv>); - static NamedLegacyCustomDataProvider vertex_colors( - ATTR_DOMAIN_CORNER, - CD_PROP_COLOR, - CD_PROP_BYTE_COLOR, - corner_access, - make_derived_read_attribute<MLoopCol, ColorGeometry4f, get_loop_color>, - make_derived_write_attribute<MLoopCol, ColorGeometry4f, get_loop_color, set_loop_color>); - static VertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); @@ -1310,7 +1286,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() return ComponentAttributeProviders( {&position, &id, &material_index, &shade_smooth, &normal, &crease}, {&uvs, - &vertex_colors, &corner_custom_data, &vertex_groups, &point_custom_data, diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc index e84ec5b3890..1c2665769db 100644 --- a/source/blender/blenkernel/intern/type_conversions.cc +++ b/source/blender/blenkernel/intern/type_conversions.cc @@ -2,6 +2,8 @@ #include "BKE_type_conversions.hh" +#include "DNA_meshdata_types.h" + #include "FN_multi_function_builder.hh" #include "BLI_color.hh" @@ -61,6 +63,10 @@ static ColorGeometry4f float_to_color(const float &a) { return ColorGeometry4f(a, a, a, 1.0f); } +static ColorGeometry4b float_to_byte_color(const float &a) +{ + return float_to_color(a).encode(); +} static float3 float2_to_float3(const float2 &a) { @@ -86,6 +92,10 @@ static ColorGeometry4f float2_to_color(const float2 &a) { return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f); } +static ColorGeometry4b float2_to_byte_color(const float2 &a) +{ + return float2_to_color(a).encode(); +} static bool float3_to_bool(const float3 &a) { @@ -111,6 +121,10 @@ static ColorGeometry4f float3_to_color(const float3 &a) { return ColorGeometry4f(a.x, a.y, a.z, 1.0f); } +static ColorGeometry4b float3_to_byte_color(const float3 &a) +{ + return float3_to_color(a).encode(); +} static bool int_to_bool(const int32_t &a) { @@ -137,6 +151,10 @@ static ColorGeometry4f int_to_color(const int32_t &a) { return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f); } +static ColorGeometry4b int_to_byte_color(const int32_t &a) +{ + return int_to_color(a).encode(); +} static bool int8_to_bool(const int8_t &a) { @@ -162,6 +180,10 @@ static ColorGeometry4f int8_to_color(const int8_t &a) { return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f); } +static ColorGeometry4b int8_to_byte_color(const int8_t &a) +{ + return int8_to_color(a).encode(); +} static float bool_to_float(const bool &a) { @@ -187,6 +209,10 @@ static ColorGeometry4f bool_to_color(const bool &a) { return (a) ? ColorGeometry4f(1.0f, 1.0f, 1.0f, 1.0f) : ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f); } +static ColorGeometry4b bool_to_byte_color(const bool &a) +{ + return bool_to_color(a).encode(); +} static bool color_to_bool(const ColorGeometry4f &a) { @@ -212,6 +238,39 @@ static float3 color_to_float3(const ColorGeometry4f &a) { return float3(a.r, a.g, a.b); } +static ColorGeometry4b color_to_byte_color(const ColorGeometry4f &a) +{ + return a.encode(); +} + +static bool byte_color_to_bool(const ColorGeometry4b &a) +{ + return a.r > 0 || a.g > 0 || a.b > 0; +} +static float byte_color_to_float(const ColorGeometry4b &a) +{ + return color_to_float(a.decode()); +} +static int32_t byte_color_to_int(const ColorGeometry4b &a) +{ + return color_to_int(a.decode()); +} +static int8_t byte_color_to_int8(const ColorGeometry4b &a) +{ + return color_to_int8(a.decode()); +} +static float2 byte_color_to_float2(const ColorGeometry4b &a) +{ + return color_to_float2(a.decode()); +} +static float3 byte_color_to_float3(const ColorGeometry4b &a) +{ + return color_to_float3(a.decode()); +} +static ColorGeometry4f byte_color_to_color(const ColorGeometry4b &a) +{ + return a.decode(); +} static DataTypeConversions create_implicit_conversions() { @@ -223,6 +282,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float, bool, float_to_bool>(conversions); add_implicit_conversion<float, int8_t, float_to_int8>(conversions); add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions); + add_implicit_conversion<float, ColorGeometry4b, float_to_byte_color>(conversions); add_implicit_conversion<float2, float3, float2_to_float3>(conversions); add_implicit_conversion<float2, float, float2_to_float>(conversions); @@ -230,6 +290,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float2, bool, float2_to_bool>(conversions); add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions); add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions); + add_implicit_conversion<float2, ColorGeometry4b, float2_to_byte_color>(conversions); add_implicit_conversion<float3, bool, float3_to_bool>(conversions); add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions); @@ -237,6 +298,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float3, int32_t, float3_to_int>(conversions); add_implicit_conversion<float3, float2, float3_to_float2>(conversions); add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions); + add_implicit_conversion<float3, ColorGeometry4b, float3_to_byte_color>(conversions); add_implicit_conversion<int32_t, bool, int_to_bool>(conversions); add_implicit_conversion<int32_t, int8_t, int_to_int8>(conversions); @@ -244,6 +306,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<int32_t, float2, int_to_float2>(conversions); add_implicit_conversion<int32_t, float3, int_to_float3>(conversions); add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions); + add_implicit_conversion<int32_t, ColorGeometry4b, int_to_byte_color>(conversions); add_implicit_conversion<int8_t, bool, int8_to_bool>(conversions); add_implicit_conversion<int8_t, int32_t, int8_to_int>(conversions); @@ -251,6 +314,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<int8_t, float2, int8_to_float2>(conversions); add_implicit_conversion<int8_t, float3, int8_to_float3>(conversions); add_implicit_conversion<int8_t, ColorGeometry4f, int8_to_color>(conversions); + add_implicit_conversion<int8_t, ColorGeometry4b, int8_to_byte_color>(conversions); add_implicit_conversion<bool, float, bool_to_float>(conversions); add_implicit_conversion<bool, int8_t, bool_to_int8>(conversions); @@ -258,6 +322,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<bool, float2, bool_to_float2>(conversions); add_implicit_conversion<bool, float3, bool_to_float3>(conversions); add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions); + add_implicit_conversion<bool, ColorGeometry4b, bool_to_byte_color>(conversions); add_implicit_conversion<ColorGeometry4f, bool, color_to_bool>(conversions); add_implicit_conversion<ColorGeometry4f, int8_t, color_to_int8>(conversions); @@ -265,6 +330,15 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions); add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions); add_implicit_conversion<ColorGeometry4f, float3, color_to_float3>(conversions); + add_implicit_conversion<ColorGeometry4f, ColorGeometry4b, color_to_byte_color>(conversions); + + add_implicit_conversion<ColorGeometry4b, bool, byte_color_to_bool>(conversions); + add_implicit_conversion<ColorGeometry4b, int8_t, byte_color_to_int8>(conversions); + add_implicit_conversion<ColorGeometry4b, float, byte_color_to_float>(conversions); + add_implicit_conversion<ColorGeometry4b, int32_t, byte_color_to_int>(conversions); + add_implicit_conversion<ColorGeometry4b, float2, byte_color_to_float2>(conversions); + add_implicit_conversion<ColorGeometry4b, float3, byte_color_to_float3>(conversions); + add_implicit_conversion<ColorGeometry4b, ColorGeometry4f, byte_color_to_color>(conversions); return conversions; } @@ -411,4 +485,19 @@ GVMutableArray DataTypeConversions::try_convert(GVMutableArray varray, std::move(varray), to_type, *this); } +fn::GField DataTypeConversions::try_convert(fn::GField field, const CPPType &to_type) const +{ + const CPPType &from_type = field.cpp_type(); + if (from_type == to_type) { + return field; + } + if (!this->is_convertible(from_type, to_type)) { + return {}; + } + const fn::MultiFunction &fn = + *bke::get_implicit_type_conversions().get_conversion_multi_function( + fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type)); + return {std::make_shared<fn::FieldOperation>(fn, Vector<fn::GField>{std::move(field)})}; +} + } // namespace blender::bke diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 83f414f853a..81f5343056e 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -102,7 +102,10 @@ template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T fract(cons return a - std::floor(a); } -template<typename T, typename FactorT, BLI_ENABLE_IF((is_math_float_type<FactorT>))> +template<typename T, + typename FactorT, + BLI_ENABLE_IF((std::is_arithmetic_v<T>)), + BLI_ENABLE_IF((is_math_float_type<FactorT>))> inline T interpolate(const T &a, const T &b, const FactorT &t) { return a * (1 - t) + b * t; diff --git a/source/blender/blenlib/BLI_math_color.hh b/source/blender/blenlib/BLI_math_color.hh index 5195cfb6238..b16053509cf 100644 --- a/source/blender/blenlib/BLI_math_color.hh +++ b/source/blender/blenlib/BLI_math_color.hh @@ -15,9 +15,22 @@ namespace blender::math { -inline ColorGeometry4f interpolate(const ColorGeometry4f &a, - const ColorGeometry4f &b, - const float t) +template<eAlpha Alpha> +inline ColorSceneLinear4f<Alpha> interpolate(const ColorSceneLinear4f<Alpha> &a, + const ColorSceneLinear4f<Alpha> &b, + const float t) +{ + return {math::interpolate(a.r, b.r, t), + math::interpolate(a.g, b.g, t), + math::interpolate(a.b, b.b, t), + math::interpolate(a.a, b.a, t)}; +} + +template<eAlpha Alpha> +inline ColorSceneLinearByteEncoded4b<Alpha> interpolate( + const ColorSceneLinearByteEncoded4b<Alpha> &a, + const ColorSceneLinearByteEncoded4b<Alpha> &b, + const float t) { return {math::interpolate(a.r, b.r, t), math::interpolate(a.g, b.g, t), diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index 0850864d86f..e36bbedee32 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -201,6 +201,14 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> } } + template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))> + explicit vec_base(const U *ptr) + { + for (int i = 0; i < Size; i++) { + (*this)[i] = ptr[i]; + } + } + vec_base(const T (*ptr)[Size]) : vec_base(static_cast<const T *>(ptr[0])) { } diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 446aabd13c8..452f1df86fb 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -241,7 +241,6 @@ enum class ConvertAttributeMode { Generic, UVMap, VertexGroup, - VertexColor, }; static bool geometry_attribute_convert_poll(bContext *C) @@ -288,7 +287,7 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) const CustomDataType dst_type = static_cast<CustomDataType>( RNA_enum_get(op->ptr, "data_type")); - if (ELEM(dst_type, CD_PROP_STRING, CD_PROP_BYTE_COLOR)) { + if (ELEM(dst_type, CD_PROP_STRING)) { BKE_report(op->reports, RPT_ERROR, "Cannot convert to the selected type"); return OPERATOR_CANCELLED; } @@ -314,20 +313,6 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) &mesh->ldata, CD_MLOOPUV, CD_ASSIGN, dst_uvs, mesh->totloop, name.c_str()); break; } - case ConvertAttributeMode::VertexColor: { - MLoopCol *dst_colors = static_cast<MLoopCol *>( - MEM_calloc_arrayN(mesh->totloop, sizeof(MLoopCol), __func__)); - VArray<ColorGeometry4f> src_varray = mesh_component.attribute_get_for_read<ColorGeometry4f>( - name, ATTR_DOMAIN_CORNER, ColorGeometry4f{0.0f, 0.0f, 0.0f, 1.0f}); - for (const int i : IndexRange(mesh->totloop)) { - ColorGeometry4b encoded_color = src_varray[i].encode(); - copy_v4_v4_uchar(&dst_colors[i].r, &encoded_color.r); - } - mesh_component.attribute_try_delete(name); - CustomData_add_layer_named( - &mesh->ldata, CD_PROP_BYTE_COLOR, CD_ASSIGN, dst_colors, mesh->totloop, name.c_str()); - break; - } case ConvertAttributeMode::VertexGroup: { Array<float> src_weights(mesh->totvert); VArray<float> src_varray = mesh_component.attribute_get_for_read<float>( @@ -550,7 +535,6 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot) {int(ConvertAttributeMode::Generic), "GENERIC", 0, "Generic", ""}, {int(ConvertAttributeMode::UVMap), "UV_MAP", 0, "UV Map", ""}, {int(ConvertAttributeMode::VertexGroup), "VERTEX_GROUP", 0, "Vertex Group", ""}, - {int(ConvertAttributeMode::VertexColor), "VERTEX_COLOR", 0, "Color Attribute", ""}, {0, nullptr, 0, nullptr, nullptr}, }; diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index 14b9dbe4b44..b3d6c395e89 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -300,6 +300,7 @@ static float get_default_column_width(const ColumnValues &values) return values.default_width; } static const float float_width = 3; + static const float int_width = 2; switch (values.type()) { case SPREADSHEET_VALUE_TYPE_BOOL: return 2.0f; @@ -317,6 +318,8 @@ static float get_default_column_width(const ColumnValues &values) return 8.0f; case SPREADSHEET_VALUE_TYPE_STRING: return 5.0f; + case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: + return 4.0f * int_width; case SPREADSHEET_VALUE_TYPE_UNKNOWN: return 2.0f; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc index 19fe61f0ed3..a29aa1fd026 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc @@ -44,6 +44,9 @@ eSpreadsheetColumnValueType cpp_type_to_column_type(const CPPType &type) if (type.is<InstanceReference>()) { return SPREADSHEET_VALUE_TYPE_INSTANCES; } + if (type.is<ColorGeometry4b>()) { + return SPREADSHEET_VALUE_TYPE_BYTE_COLOR; + } return SPREADSHEET_VALUE_TYPE_UNKNOWN; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc index db466f8ccf3..e19a343335a 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc @@ -191,6 +191,10 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { const ColorGeometry4f value = data.get<ColorGeometry4f>(real_index); this->draw_float_vector(params, Span(&value.r, 4)); } + else if (data.type().is<ColorGeometry4b>()) { + const ColorGeometry4b value = data.get<ColorGeometry4b>(real_index); + this->draw_int_vector(params, {value.r, value.g, value.b, value.a}); + } else if (data.type().is<InstanceReference>()) { const InstanceReference value = data.get<InstanceReference>(real_index); switch (value.type()) { @@ -304,6 +308,34 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { } } + void draw_int_vector(const CellDrawParams ¶ms, const Span<int> values) const + { + BLI_assert(!values.is_empty()); + const float segment_width = (float)params.width / values.size(); + for (const int i : values.index_range()) { + const int value = values[i]; + const std::string value_str = std::to_string(value); + uiBut *but = uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_NONE, + value_str.c_str(), + params.xmin + i * segment_width, + params.ymin, + segment_width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + /* Right-align Ints. */ + UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); + UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT); + } + } + int column_width(int column_index) const final { return spreadsheet_layout_.columns[column_index].width; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc index e45317c2a5c..eb8f111baa0 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc @@ -106,10 +106,10 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, const float2 value = row_filter.value_float2; switch (row_filter.operation) { case SPREADSHEET_ROW_FILTER_EQUAL: { - const float threshold_sq = row_filter.threshold; + const float threshold_sq = pow2f(row_filter.threshold); apply_filter_operation( column_data.typed<float2>(), - [&](const float2 cell) { return math::distance_squared(cell, value) > threshold_sq; }, + [&](const float2 cell) { return math::distance_squared(cell, value) <= threshold_sq; }, prev_mask, new_indices); break; @@ -136,10 +136,10 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, const float3 value = row_filter.value_float3; switch (row_filter.operation) { case SPREADSHEET_ROW_FILTER_EQUAL: { - const float threshold_sq = row_filter.threshold; + const float threshold_sq = pow2f(row_filter.threshold); apply_filter_operation( column_data.typed<float3>(), - [&](const float3 cell) { return math::distance_squared(cell, value) > threshold_sq; }, + [&](const float3 cell) { return math::distance_squared(cell, value) <= threshold_sq; }, prev_mask, new_indices); break; @@ -168,19 +168,25 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, } else if (column_data.type().is<ColorGeometry4f>()) { const ColorGeometry4f value = row_filter.value_color; - switch (row_filter.operation) { - case SPREADSHEET_ROW_FILTER_EQUAL: { - const float threshold_sq = row_filter.threshold; - apply_filter_operation( - column_data.typed<ColorGeometry4f>(), - [&](const ColorGeometry4f cell) { - return len_squared_v4v4(cell, value) > threshold_sq; - }, - prev_mask, - new_indices); - break; - } - } + const float threshold_sq = pow2f(row_filter.threshold); + apply_filter_operation( + column_data.typed<ColorGeometry4f>(), + [&](const ColorGeometry4f cell) { return len_squared_v4v4(cell, value) <= threshold_sq; }, + prev_mask, + new_indices); + } + else if (column_data.type().is<ColorGeometry4b>()) { + const ColorGeometry4b value = row_filter.value_byte_color; + const float4 value_floats = {(float)value.r, (float)value.g, (float)value.b, (float)value.a}; + const float threshold_sq = pow2f(row_filter.threshold); + apply_filter_operation( + column_data.typed<ColorGeometry4b>(), + [&](const ColorGeometry4b cell) { + const float4 cell_floats = {(float)cell.r, (float)cell.g, (float)cell.b, (float)cell.a}; + return len_squared_v4v4(value_floats, cell_floats) <= threshold_sq; + }, + prev_mask, + new_indices); } else if (column_data.type().is<InstanceReference>()) { const StringRef value = row_filter.value_string; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc index 6206b2d0c03..7c1ac024c12 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc @@ -42,7 +42,8 @@ static std::string operation_string(const eSpreadsheetColumnValueType data_type, if (ELEM(data_type, SPREADSHEET_VALUE_TYPE_BOOL, SPREADSHEET_VALUE_TYPE_INSTANCES, - SPREADSHEET_VALUE_TYPE_COLOR)) { + SPREADSHEET_VALUE_TYPE_COLOR, + SPREADSHEET_VALUE_TYPE_BYTE_COLOR)) { return "="; } @@ -101,6 +102,14 @@ static std::string value_string(const SpreadsheetRowFilter &row_filter, } case SPREADSHEET_VALUE_TYPE_STRING: return row_filter.value_string; + case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: { + std::ostringstream result; + result.precision(3); + result << std::fixed << "(" << (int)row_filter.value_byte_color[0] << ", " + << (int)row_filter.value_byte_color[1] << ", " << (int)row_filter.value_byte_color[2] + << ", " << (int)row_filter.value_byte_color[3] << ")"; + return result.str(); + } case SPREADSHEET_VALUE_TYPE_UNKNOWN: return ""; } @@ -229,6 +238,10 @@ static void spreadsheet_filter_panel_draw(const bContext *C, Panel *panel) case SPREADSHEET_VALUE_TYPE_STRING: uiItemR(layout, filter_ptr, "value_string", 0, IFACE_("Value"), ICON_NONE); break; + case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: + uiItemR(layout, filter_ptr, "value_byte_color", 0, IFACE_("Value"), ICON_NONE); + uiItemR(layout, filter_ptr, "threshold", 0, nullptr, ICON_NONE); + break; case SPREADSHEET_VALUE_TYPE_UNKNOWN: uiItemL(layout, IFACE_("Unknown column type"), ICON_ERROR); break; diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index 5a27cda0787..0005d788a3b 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -38,7 +38,7 @@ #include "BLI_vector.hh" #include "BLI_vector_set.hh" -#include "FN_multi_function_builder.hh" +#include "FN_multi_function.hh" namespace blender::fn { diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc index a2adc2ea8b6..5c43fffdd61 100644 --- a/source/blender/functions/intern/cpp_types.cc +++ b/source/blender/functions/intern/cpp_types.cc @@ -11,6 +11,7 @@ MAKE_FIELD_CPP_TYPE(FloatField, float); MAKE_FIELD_CPP_TYPE(Float2Field, blender::float2); MAKE_FIELD_CPP_TYPE(Float3Field, blender::float3); MAKE_FIELD_CPP_TYPE(ColorGeometry4fField, blender::ColorGeometry4f); +MAKE_FIELD_CPP_TYPE(ColorGeometry4bField, blender::ColorGeometry4b); MAKE_FIELD_CPP_TYPE(BoolField, bool); MAKE_FIELD_CPP_TYPE(Int8Field, int8_t); MAKE_FIELD_CPP_TYPE(Int32Field, int32_t); diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 944674c23a9..a53da717606 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -8,6 +8,7 @@ #include "BLI_vector_set.hh" #include "FN_field.hh" +#include "FN_multi_function_builder.hh" #include "FN_multi_function_procedure.hh" #include "FN_multi_function_procedure_builder.hh" #include "FN_multi_function_procedure_executor.hh" diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 8d527caa361..bce124a26cf 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1968,8 +1968,7 @@ typedef struct SpreadsheetRowFilter { float value_float2[2]; float value_float3[3]; float value_color[4]; - - char _pad1[4]; + uint8_t value_byte_color[4]; } SpreadsheetRowFilter; typedef enum eSpaceSpreadsheet_RowFilterFlag { @@ -2006,6 +2005,7 @@ typedef enum eSpreadsheetColumnValueType { SPREADSHEET_VALUE_TYPE_COLOR = 5, SPREADSHEET_VALUE_TYPE_INSTANCES = 6, SPREADSHEET_VALUE_TYPE_STRING = 7, + SPREADSHEET_VALUE_TYPE_BYTE_COLOR = 8, } eSpreadsheetColumnValueType; /** diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 090d4a81210..4195782db08 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2144,8 +2144,13 @@ static void rna_GeometryNodeCompare_data_type_update(Main *bmain, Scene *scene, static bool generic_attribute_type_supported(const EnumPropertyItem *item) { - return ELEM( - item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL, CD_PROP_INT32); + return ELEM(item->value, + CD_PROP_FLOAT, + CD_PROP_FLOAT3, + CD_PROP_COLOR, + CD_PROP_BOOL, + CD_PROP_INT32, + CD_PROP_BYTE_COLOR); } static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), @@ -2156,6 +2161,18 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext return itemf_function_check(rna_enum_attribute_type_items, generic_attribute_type_supported); } +static bool generic_attribute_type_supported_with_socket(const EnumPropertyItem *item) +{ + return generic_attribute_type_supported(item) && !ELEM(item->value, CD_PROP_BYTE_COLOR); +} +static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_with_socket_itemf( + bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + *r_free = true; + return itemf_function_check(rna_enum_attribute_type_items, + generic_attribute_type_supported_with_socket); +} + static bool transfer_attribute_type_supported(const EnumPropertyItem *item) { return ELEM( @@ -10219,7 +10236,8 @@ static void def_geo_raycast(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10271,7 +10289,8 @@ static void def_geo_input_named_attribute(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", "The data type used to read the attribute values"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10285,7 +10304,8 @@ static void def_geo_attribute_capture(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10512,7 +10532,8 @@ static void def_geo_viewer(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10542,7 +10563,8 @@ static void def_geo_field_at_index(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom2"); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_ui_text(prop, "Data Type", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c40a2ed9260..4da8cfb8bb8 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -7752,6 +7752,12 @@ static void rna_def_spreadsheet_row_filter(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Color Value", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); + prop = RNA_def_property(srna, "value_byte_color", PROP_INT, PROP_NONE); + RNA_def_property_array(prop, 4); + RNA_def_property_range(prop, 0, 255); + RNA_def_property_ui_text(prop, "Byte Color Value", ""); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); + prop = RNA_def_property(srna, "value_string", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Text Value", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc index 68207d84015..e43d2b4ad85 100644 --- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc +++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc @@ -1635,10 +1635,8 @@ class GeometryNodesEvaluator { if (conversions_.is_convertible(from_base_type, to_base_type)) { if (from_field_type->is_field(from_value)) { const GField &from_field = *from_field_type->get_field_ptr(from_value); - const MultiFunction &fn = *conversions_.get_conversion_multi_function( - MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type)); - auto operation = std::make_shared<fn::FieldOperation>(fn, Vector<GField>{from_field}); - to_field_type->construct_from_field(to_value, GField(std::move(operation), 0)); + to_field_type->construct_from_field(to_value, + conversions_.try_convert(from_field, to_base_type)); } else { to_field_type->default_construct(to_value); diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index 92614d1a31d..b51fc063ab8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -5,6 +5,8 @@ #include "NOD_socket_search_link.hh" +#include "BKE_type_conversions.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_store_named_attribute_cc { @@ -55,7 +57,8 @@ static void node_update(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3); nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT); - nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR); + nodeSetSocketAvailability( + ntree, socket_color4f, ELEM(data_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)); nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL); nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32); } @@ -149,6 +152,12 @@ static void node_geo_exec(GeoNodeExecParams params) case CD_PROP_COLOR: field = params.get_input<Field<ColorGeometry4f>>("Value_Color"); break; + case CD_PROP_BYTE_COLOR: { + field = params.get_input<Field<ColorGeometry4f>>("Value_Color"); + field = bke::get_implicit_type_conversions().try_convert(field, + CPPType::get<ColorGeometry4b>()); + break; + } case CD_PROP_BOOL: field = params.get_input<Field<bool>>("Value_Bool"); break; |