[Bf-blender-cvs] [088e6a52829] geometry-nodes: Geometry Nodes: initial support for implicitly type casting attributes
Jacques Lucke
noreply at git.blender.org
Fri Nov 20 18:12:41 CET 2020
Commit: 088e6a52829dfb9c264c811323db7c3a25a93326
Author: Jacques Lucke
Date: Fri Nov 20 18:10:24 2020 +0100
Branches: geometry-nodes
https://developer.blender.org/rB088e6a52829dfb9c264c811323db7c3a25a93326
Geometry Nodes: initial support for implicitly type casting attributes
Those allows e.g. float attributes to be accessed as if they were vector attributes.
===================================================================
M source/blender/blenkernel/intern/attribute_access.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index af4cea3322b..5218230bfe0 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -29,6 +29,13 @@
#include "BLI_float2.hh"
#include "BLI_span.hh"
+#include "NOD_node_tree_multi_function.hh"
+
+using blender::float3;
+using blender::StringRef;
+using blender::bke::ReadAttributePtr;
+using blender::bke::WriteAttributePtr;
+
namespace blender::bke {
/* -------------------------------------------------------------------- */
@@ -217,6 +224,38 @@ class ConstantReadAttribute final : public ReadAttribute {
}
};
+class ConvertedReadAttribute final : public ReadAttribute {
+ private:
+ const CPPType &from_type_;
+ const CPPType &to_type_;
+ ReadAttributePtr base_attribute_;
+ const nodes::DataTypeConversions &conversions_;
+
+ static constexpr int MaxValueSize = 64;
+ static constexpr int MaxValueAlignment = 64;
+
+ public:
+ ConvertedReadAttribute(ReadAttributePtr base_attribute, const CPPType &to_type)
+ : ReadAttribute(base_attribute->domain(), to_type, base_attribute->size()),
+ from_type_(base_attribute->cpp_type()),
+ to_type_(to_type),
+ base_attribute_(std::move(base_attribute)),
+ conversions_(nodes::get_implicit_type_conversions())
+ {
+ if (from_type_.size() > MaxValueSize || from_type_.alignment() > MaxValueAlignment) {
+ throw std::runtime_error(
+ "type is larger than expected, the buffer size has to be increased");
+ }
+ }
+
+ void get_internal(const int64_t index, void *r_value) const override
+ {
+ AlignedBuffer<MaxValueSize, MaxValueAlignment> buffer;
+ base_attribute_->get(index, buffer.ptr());
+ conversions_.convert(from_type_, to_type_, buffer.ptr(), r_value);
+ }
+};
+
/** \} */
const blender::fn::CPPType *custom_data_type_to_cpp_type(const CustomDataType type)
@@ -264,11 +303,6 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
/** \name Utilities for accessing attributes.
* \{ */
-using blender::float3;
-using blender::StringRef;
-using blender::bke::ReadAttributePtr;
-using blender::bke::WriteAttributePtr;
-
static ReadAttributePtr read_attribute_from_custom_data(const CustomData &custom_data,
const int size,
const StringRef attribute_name,
@@ -407,6 +441,23 @@ bool GeometryComponent::attribute_try_create(const StringRef UNUSED(attribute_na
return false;
}
+static ReadAttributePtr try_adapt_data_type(ReadAttributePtr attribute,
+ const blender::fn::CPPType &to_type)
+{
+ const blender::fn::CPPType &from_type = attribute->cpp_type();
+ if (from_type == to_type) {
+ return attribute;
+ }
+
+ const blender::nodes::DataTypeConversions &conversions =
+ blender::nodes::get_implicit_type_conversions();
+ if (!conversions.is_convertible(from_type, to_type)) {
+ return {};
+ }
+
+ return std::make_unique<blender::bke::ConvertedReadAttribute>(std::move(attribute), to_type);
+}
+
ReadAttributePtr GeometryComponent::attribute_try_get_for_read(
const StringRef attribute_name,
const AttributeDomain domain,
@@ -431,8 +482,10 @@ ReadAttributePtr GeometryComponent::attribute_try_get_for_read(
const blender::fn::CPPType *cpp_type = blender::bke::custom_data_type_to_cpp_type(data_type);
BLI_assert(cpp_type != nullptr);
if (attribute->cpp_type() != *cpp_type) {
- /* TODO: Support some type conversions. */
- return {};
+ attribute = try_adapt_data_type(std::move(attribute), *cpp_type);
+ if (!attribute) {
+ return {};
+ }
}
return attribute;
More information about the Bf-blender-cvs
mailing list