Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-12-09 18:20:48 +0300
committerJacques Lucke <jacques@blender.org>2020-12-09 18:20:57 +0300
commit4a5f36638b0244b586607e76451669ffbc3c1174 (patch)
treec38ffdd8035e029b0c0451d91336b58fdf6bdffe
parent25e151cc34715f4f27f2cecad252b02d1498ba15 (diff)
Geometry Nodes: simplify supporting different input socket types for attributes
This is a non-functional change. The functionality introduced in this commit is not used in master yet. It is used by nodes that are being developed in other branches though.
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh8
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc33
-rw-r--r--source/blender/makesdna/DNA_node_types.h7
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh20
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc21
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh6
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc41
7 files changed, 136 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index ef3ae3c381c..3398da9896b 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -157,6 +157,14 @@ class GeometryComponent {
const CustomDataType data_type,
const void *value) const;
+ /* Create a read-only dummy attribute that always returns the same value.
+ * The given value is converted to the correct type if necessary. */
+ blender::bke::ReadAttributePtr attribute_get_constant_for_read_converted(
+ const AttributeDomain domain,
+ const CustomDataType in_data_type,
+ const CustomDataType out_data_type,
+ const void *value) const;
+
/* Get a read-only dummy attribute that always returns the same value. */
template<typename T>
blender::bke::TypedReadAttribute<T> attribute_get_constant_for_read(const AttributeDomain domain,
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 9f5795291f0..d79168d5443 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -668,6 +668,39 @@ blender::bke::ReadAttributePtr GeometryComponent::attribute_get_constant_for_rea
domain, domain_size, *cpp_type, value);
}
+blender::bke::ReadAttributePtr GeometryComponent::attribute_get_constant_for_read_converted(
+ const AttributeDomain domain,
+ const CustomDataType in_data_type,
+ const CustomDataType out_data_type,
+ const void *value) const
+{
+ BLI_assert(this->attribute_domain_supported(domain));
+ if (value == nullptr || in_data_type == out_data_type) {
+ return this->attribute_get_constant_for_read(domain, out_data_type, value);
+ }
+
+ const blender::fn::CPPType *in_cpp_type = blender::bke::custom_data_type_to_cpp_type(
+ in_data_type);
+ const blender::fn::CPPType *out_cpp_type = blender::bke::custom_data_type_to_cpp_type(
+ out_data_type);
+ BLI_assert(in_cpp_type != nullptr);
+ BLI_assert(out_cpp_type != nullptr);
+
+ const blender::nodes::DataTypeConversions &conversions =
+ blender::nodes::get_implicit_type_conversions();
+ BLI_assert(conversions.is_convertible(*in_cpp_type, *out_cpp_type));
+
+ void *out_value = alloca(out_cpp_type->size());
+ conversions.convert(*in_cpp_type, *out_cpp_type, value, out_value);
+
+ const int domain_size = this->attribute_domain_size(domain);
+ blender::bke::ReadAttributePtr attribute = std::make_unique<blender::bke::ConstantReadAttribute>(
+ domain, domain_size, *out_cpp_type, out_value);
+
+ out_cpp_type->destruct(out_value);
+ return attribute;
+}
+
WriteAttributePtr GeometryComponent::attribute_try_ensure_for_write(const StringRef attribute_name,
const AttributeDomain domain,
const CustomDataType data_type)
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 29c83d2d4ed..13f8b11352a 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1464,6 +1464,13 @@ typedef enum GeometryNodeUseAttributeFlag {
GEO_NODE_USE_ATTRIBUTE_B = (1 << 1),
} GeometryNodeUseAttributeFlag;
+typedef enum GeometryNodeAttributeInputMode {
+ GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE = 0,
+ GEO_NODE_ATTRIBUTE_INPUT_FLOAT = 1,
+ GEO_NODE_ATTRIBUTE_INPUT_VECTOR = 2,
+ GEO_NODE_ATTRIBUTE_INPUT_COLOR = 3,
+} GeometryNodeAttributeInputMode;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index fde576d7429..a7df4bc3e1b 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -148,6 +148,26 @@ class GeoNodeExecParams {
return self_object_;
}
+ /**
+ * Creates a read-only attribute based on node inputs. The method automatically detects which
+ * input with the given name is available.
+ */
+ ReadAttributePtr get_input_attribute(const StringRef name,
+ const GeometryComponent &component,
+ const AttributeDomain domain,
+ const CustomDataType type,
+ const void *default_value) const;
+
+ template<typename T>
+ bke::TypedReadAttribute<T> get_input_attribute(const StringRef name,
+ const GeometryComponent &component,
+ const AttributeDomain domain,
+ const T &default_value) const
+ {
+ const CustomDataType type = bke::cpp_type_to_custom_data_type(CPPType::get<T>());
+ return this->get_input_attribute(name, component, domain, type, &default_value);
+ }
+
private:
/* Utilities for detecting common errors at when using this class. */
void check_extract_input(StringRef identifier, const CPPType *requested_type = nullptr) const;
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 41bdb1cfff0..34c7d224f03 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -17,6 +17,27 @@
#include "node_geometry_util.hh"
#include "node_util.h"
+namespace blender::nodes {
+
+void update_attribute_input_socket_availabilities(bNode &node,
+ const StringRef name,
+ const GeometryNodeAttributeInputMode mode)
+{
+ const GeometryNodeAttributeInputMode mode_ = (GeometryNodeAttributeInputMode)mode;
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+ if (name == socket->name) {
+ const bool is_available =
+ ((socket->type == SOCK_STRING && mode_ == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) ||
+ (socket->type == SOCK_FLOAT && mode_ == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) ||
+ (socket->type == SOCK_VECTOR && mode_ == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) ||
+ (socket->type == SOCK_RGBA && mode_ == GEO_NODE_ATTRIBUTE_INPUT_COLOR));
+ nodeSetSocketAvailability(socket, is_available);
+ }
+ }
+}
+
+} // namespace blender::nodes
+
bool geo_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
{
return STREQ(ntree->idname, "GeometryNodeTree");
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index bb26763642b..ec389961615 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -37,3 +37,9 @@
void geo_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
bool geo_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+
+namespace blender::nodes {
+void update_attribute_input_socket_availabilities(bNode &node,
+ const StringRef name,
+ const GeometryNodeAttributeInputMode mode);
+}
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 50292cb8cfb..a6d9115f01f 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -19,6 +19,47 @@
namespace blender::nodes {
+ReadAttributePtr GeoNodeExecParams::get_input_attribute(const StringRef name,
+ const GeometryComponent &component,
+ const AttributeDomain domain,
+ const CustomDataType type,
+ const void *default_value) const
+{
+ const bNodeSocket *found_socket = nullptr;
+ LISTBASE_FOREACH (const bNodeSocket *, socket, &node_.inputs) {
+ if ((socket->flag & SOCK_UNAVAIL) != 0) {
+ continue;
+ }
+ if (name == socket->name) {
+ found_socket = socket;
+ break;
+ }
+ }
+ BLI_assert(found_socket != nullptr);
+
+ if (found_socket->type == SOCK_STRING) {
+ const std::string name = this->get_input<std::string>(found_socket->identifier);
+ return component.attribute_get_for_read(name, domain, type, default_value);
+ }
+ if (found_socket->type == SOCK_FLOAT) {
+ const float value = this->get_input<float>(found_socket->identifier);
+ return component.attribute_get_constant_for_read_converted(
+ domain, CD_PROP_FLOAT, type, &value);
+ }
+ if (found_socket->type == SOCK_VECTOR) {
+ const float3 value = this->get_input<float3>(found_socket->identifier);
+ return component.attribute_get_constant_for_read_converted(
+ domain, CD_PROP_FLOAT3, type, &value);
+ }
+ if (found_socket->type == SOCK_RGBA) {
+ const Color4f value = this->get_input<Color4f>(found_socket->identifier);
+ return component.attribute_get_constant_for_read_converted(
+ domain, CD_PROP_COLOR, type, &value);
+ }
+ BLI_assert(false);
+ return component.attribute_get_constant_for_read(domain, type, default_value);
+}
+
void GeoNodeExecParams::check_extract_input(StringRef identifier,
const CPPType *requested_type) const
{