diff options
Diffstat (limited to 'source/blender/blenkernel')
8 files changed, 207 insertions, 54 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 |