[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 ¶ms)
{
+ 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