[Bf-blender-cvs] [b9799dfb8a7] master: Geometry Nodes: better support for byte color attributes

Jacques Lucke noreply at git.blender.org
Thu Apr 21 16:11:46 CEST 2022


Commit: b9799dfb8a78dddbb3591dcb3e0b4de954c80fee
Author: Jacques Lucke
Date:   Thu Apr 21 16:11:26 2022 +0200
Branches: master
https://developer.blender.org/rBb9799dfb8a78dddbb3591dcb3e0b4de954c80fee

Geometry Nodes: better support for byte color attributes

Since {rBeae36be372a6b16ee3e76eff0485a47da4f3c230} the distinction
between float and byte colors is more explicit in the ui. So far, geometry
nodes couldn't really deal with byte colors in general. This patch fixes that.
There is still only one color socket, which contains float colors. Conversion
to and from byte colors is done when read from or writing to attributes.

* Support writing to byte color attributes in Store Named Attribute node.
* Support converting to/from byte color in attribute conversion operator.
* Support propagating byte color attributes.
* Add all the implicit conversions from byte colors to the other types.
* Display byte colors as integers in spreadsheet.

Differential Revision: https://developer.blender.org/D14705

===================================================================

M	source/blender/blenkernel/BKE_attribute_math.hh
M	source/blender/blenkernel/BKE_type_conversions.hh
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/attribute_access_intern.hh
M	source/blender/blenkernel/intern/attribute_math.cc
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenkernel/intern/geometry_component_mesh.cc
M	source/blender/blenkernel/intern/type_conversions.cc
M	source/blender/blenlib/BLI_math_base.hh
M	source/blender/blenlib/BLI_math_color.hh
M	source/blender/blenlib/BLI_math_vec_types.hh
M	source/blender/editors/geometry/geometry_attributes.cc
M	source/blender/editors/space_spreadsheet/space_spreadsheet.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_column.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
M	source/blender/functions/FN_field.hh
M	source/blender/functions/intern/cpp_types.cc
M	source/blender/functions/intern/field.cc
M	source/blender/makesdna/DNA_space_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/modifiers/intern/MOD_nodes_evaluator.cc
M	source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc

===================================================================

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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list