[Bf-blender-cvs] [9de2d0350f5] geometry-nodes-mix-attributes: initial working mix attributes node

Jacques Lucke noreply at git.blender.org
Tue Dec 1 16:08:26 CET 2020


Commit: 9de2d0350f55a6f0996af62990a6960c5ce84e3a
Author: Jacques Lucke
Date:   Tue Dec 1 16:08:06 2020 +0100
Branches: geometry-nodes-mix-attributes
https://developer.blender.org/rB9de2d0350f55a6f0996af62990a6960c5ce84e3a

initial working mix attributes node

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

M	source/blender/blenkernel/BKE_attribute_access.hh
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/geometry/nodes/node_geo_mix_attributes.cc
M	source/blender/nodes/intern/node_tree_multi_function.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index e58fba36342..c4a704ef385 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -23,6 +23,7 @@
 
 #include "BKE_attribute.h"
 
+#include "BLI_color.hh"
 #include "BLI_float3.hh"
 
 struct Mesh;
@@ -31,6 +32,9 @@ namespace blender::bke {
 
 using fn::CPPType;
 
+const CPPType *custom_data_type_to_cpp_type(const CustomDataType type);
+CustomDataType cpp_type_to_custom_data_type(const CPPType &type);
+
 /**
  * This class offers an indirection for reading an attribute.
  * This is useful for the following reasons:
@@ -47,6 +51,7 @@ class ReadAttribute {
  protected:
   const AttributeDomain domain_;
   const CPPType &cpp_type_;
+  const CustomDataType custom_data_type_;
   const int64_t size_;
 
   /* Protects the span below, so that no two threads initialize it at the same time. */
@@ -59,7 +64,10 @@ class ReadAttribute {
 
  public:
   ReadAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
-      : domain_(domain), cpp_type_(cpp_type), size_(size)
+      : domain_(domain),
+        cpp_type_(cpp_type),
+        custom_data_type_(cpp_type_to_custom_data_type(cpp_type)),
+        size_(size)
   {
   }
 
@@ -75,6 +83,11 @@ class ReadAttribute {
     return cpp_type_;
   }
 
+  CustomDataType custom_data_type() const
+  {
+    return custom_data_type_;
+  }
+
   int64_t size() const
   {
     return size_;
@@ -104,6 +117,7 @@ class WriteAttribute {
  protected:
   const AttributeDomain domain_;
   const CPPType &cpp_type_;
+  const CustomDataType custom_data_type_;
   const int64_t size_;
 
   /* When not null, this points either to the attribute array or to a temporary array. */
@@ -115,7 +129,10 @@ class WriteAttribute {
 
  public:
   WriteAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
-      : domain_(domain), cpp_type_(cpp_type), size_(size)
+      : domain_(domain),
+        cpp_type_(cpp_type),
+        custom_data_type_(cpp_type_to_custom_data_type(cpp_type)),
+        size_(size)
   {
   }
 
@@ -131,6 +148,11 @@ class WriteAttribute {
     return cpp_type_;
   }
 
+  CustomDataType custom_data_type() const
+  {
+    return custom_data_type_;
+  }
+
   int64_t size() const
   {
     return size_;
@@ -246,10 +268,9 @@ template<typename T> class TypedWriteAttribute {
 
 using FloatReadAttribute = TypedReadAttribute<float>;
 using Float3ReadAttribute = TypedReadAttribute<float3>;
+using Color4fReadAttribute = TypedReadAttribute<Color4f>;
 using FloatWriteAttribute = TypedWriteAttribute<float>;
 using Float3WriteAttribute = TypedWriteAttribute<float3>;
-
-const CPPType *custom_data_type_to_cpp_type(const CustomDataType type);
-CustomDataType cpp_type_to_custom_data_type(const CPPType &type);
+using Color4fWriteAttribute = TypedWriteAttribute<Color4f>;
 
 }  // namespace blender::bke
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 2b95f76d06b..fde576d7429 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -26,6 +26,8 @@
 
 namespace blender::nodes {
 
+using bke::Color4fReadAttribute;
+using bke::Color4fWriteAttribute;
 using bke::Float3ReadAttribute;
 using bke::Float3WriteAttribute;
 using bke::FloatReadAttribute;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mix_attributes.cc b/source/blender/nodes/geometry/nodes/node_geo_mix_attributes.cc
index 48ca89a9312..17bf69f8abb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mix_attributes.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mix_attributes.cc
@@ -14,10 +14,13 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "BKE_material.h"
+
 #include "node_geometry_util.hh"
 
 static bNodeSocketTemplate geo_node_mix_attributes_in[] = {
     {SOCK_GEOMETRY, N_("Geometry")},
+    {SOCK_STRING, N_("Factor")},
     {SOCK_STRING, N_("Attribute A")},
     {SOCK_STRING, N_("Attribute B")},
     {SOCK_STRING, N_("Result")},
@@ -31,9 +34,117 @@ static bNodeSocketTemplate geo_node_mix_attribute_out[] = {
 
 namespace blender::nodes {
 
-static void mix_attributes_calc(GeometryComponent &UNUSED(component),
-                                const GeoNodeExecParams &UNUSED(params))
+static void do_mix_operation_float(const int blend_mode,
+                                   const FloatReadAttribute &factors,
+                                   const FloatReadAttribute &inputs_a,
+                                   const FloatReadAttribute &inputs_b,
+                                   FloatWriteAttribute &results)
+{
+  const int size = results.size();
+  for (const int i : IndexRange(size)) {
+    const float factor = factors[i];
+    float3 a{inputs_a[i]};
+    const float3 b{inputs_b[i]};
+    ramp_blend(blend_mode, a, factor, b);
+    const float result = a.length();
+    results.set(i, result);
+  }
+}
+
+static void do_mix_operation_float3(const int blend_mode,
+                                    const FloatReadAttribute &factors,
+                                    const Float3ReadAttribute &inputs_a,
+                                    const Float3ReadAttribute &inputs_b,
+                                    Float3WriteAttribute &results)
+{
+  const int size = results.size();
+  for (const int i : IndexRange(size)) {
+    const float factor = factors[i];
+    float3 a = inputs_a[i];
+    const float3 b = inputs_b[i];
+    ramp_blend(blend_mode, a, factor, b);
+    results.set(i, a);
+  }
+}
+
+static void do_mix_operation_color4f(const int blend_mode,
+                                     const FloatReadAttribute &factors,
+                                     const Color4fReadAttribute &inputs_a,
+                                     const Color4fReadAttribute &inputs_b,
+                                     Color4fWriteAttribute &results)
+{
+  const int size = results.size();
+  for (const int i : IndexRange(size)) {
+    const float factor = factors[i];
+    Color4f a = inputs_a[i];
+    const Color4f b = inputs_b[i];
+    ramp_blend(blend_mode, a, factor, b);
+    results.set(i, a);
+  }
+}
+
+static void mix_attributes_calc(GeometryComponent &component, const GeoNodeExecParams &params)
 {
+  const bNode &node = params.node();
+  const int blend_mode = node.custom1;
+
+  const std::string factor_name = params.get_input<std::string>("Factor");
+  const std::string attribute_a_name = params.get_input<std::string>("Attribute A");
+  const std::string attribute_b_name = params.get_input<std::string>("Attribute B");
+  const std::string result_name = params.get_input<std::string>("Result");
+
+  CustomDataType result_type = CD_PROP_COLOR;
+  AttributeDomain result_domain = ATTR_DOMAIN_POINT;
+
+  const ReadAttributePtr result_attribute_read = component.attribute_try_get_for_read(result_name);
+  if (result_attribute_read) {
+    result_type = result_attribute_read->custom_data_type();
+    result_domain = result_attribute_read->domain();
+  }
+
+  WriteAttributePtr attribute_result = component.attribute_try_ensure_for_write(
+      result_name, result_domain, result_type);
+  if (!attribute_result) {
+    return;
+  }
+
+  FloatReadAttribute attribute_factor = component.attribute_get_for_read<float>(
+      factor_name, result_domain, 0.5f);
+  ReadAttributePtr attribute_a = component.attribute_get_for_read(
+      attribute_a_name, result_domain, result_type, nullptr);
+  ReadAttributePtr attribute_b = component.attribute_get_for_read(
+      attribute_b_name, result_domain, result_type, nullptr);
+
+  if (result_type == CD_PROP_FLOAT) {
+    FloatReadAttribute attribute_a_float = std::move(attribute_a);
+    FloatReadAttribute attribute_b_float = std::move(attribute_b);
+    FloatWriteAttribute attribute_result_float = std::move(attribute_result);
+    do_mix_operation_float(blend_mode,
+                           attribute_factor,
+                           attribute_a_float,
+                           attribute_b_float,
+                           attribute_result_float);
+  }
+  else if (result_type == CD_PROP_FLOAT3) {
+    Float3ReadAttribute attribute_a_float3 = std::move(attribute_a);
+    Float3ReadAttribute attribute_b_float3 = std::move(attribute_b);
+    Float3WriteAttribute attribute_result_float3 = std::move(attribute_result);
+    do_mix_operation_float3(blend_mode,
+                            attribute_factor,
+                            attribute_a_float3,
+                            attribute_b_float3,
+                            attribute_result_float3);
+  }
+  else if (result_type == CD_PROP_COLOR) {
+    Color4fReadAttribute attribute_a_color4f = std::move(attribute_a);
+    Color4fReadAttribute attribute_b_color4f = std::move(attribute_b);
+    Color4fWriteAttribute attribute_result_color4f = std::move(attribute_result);
+    do_mix_operation_color4f(blend_mode,
+                             attribute_factor,
+                             attribute_a_color4f,
+                             attribute_b_color4f,
+                             attribute_result_color4f);
+  }
 }
 
 static void geo_node_mix_attributes_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index 8440e996651..66a16285eec 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -204,6 +204,10 @@ static DataTypeConversions create_implicit_conversions()
       conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
   add_implicit_conversion<Color4f, float3>(
       conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
+  add_implicit_conversion<float, Color4f>(
+      conversions, "float to Color4f", [](float a) { return Color4f(a, a, a, 1.0f); });
+  add_implicit_conversion<Color4f, float>(
+      conversions, "Color4f to float", [](Color4f a) { return float3(a.r, a.g, a.b).length(); });
   return conversions;
 }



More information about the Bf-blender-cvs mailing list