[Bf-blender-cvs] [d2c047999be] virtual-array-attributes: start implementing output attribute
Jacques Lucke
noreply at git.blender.org
Thu Apr 15 16:13:11 CEST 2021
Commit: d2c047999be2bbc763ed47e2d13c34db8c589d3a
Author: Jacques Lucke
Date: Thu Apr 15 13:07:52 2021 +0200
Branches: virtual-array-attributes
https://developer.blender.org/rBd2c047999be2bbc763ed47e2d13c34db8c589d3a
start implementing output attribute
===================================================================
M source/blender/blenkernel/BKE_attribute_access.hh
M source/blender/blenkernel/BKE_geometry_set.hh
M source/blender/blenkernel/intern/attribute_access.cc
M source/blender/nodes/NOD_type_conversions.hh
M source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_proximity.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
M source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc
M source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
M source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
M source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
M source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
M source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
M source/blender/nodes/geometry/nodes/node_geo_point_rotate.cc
M source/blender/nodes/geometry/nodes/node_geo_point_separate.cc
M source/blender/nodes/geometry/nodes/node_geo_point_translate.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index e70eb8d3997..0dff3cfeda4 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -68,12 +68,19 @@ class OutputAttribute {
AttributeDomain domain_;
SaveF save_;
std::optional<fn::GVMutableArray_GSpan> optional_span_varray_;
+ bool ignore_old_values_ = false;
public:
OutputAttribute() = default;
- OutputAttribute(std::unique_ptr<GVMutableArray> varray, AttributeDomain domain, SaveF save)
- : varray_(std::move(varray)), domain_(domain), save_(std::move(save))
+ OutputAttribute(std::unique_ptr<GVMutableArray> varray,
+ AttributeDomain domain,
+ SaveF save,
+ const bool ignore_old_values)
+ : varray_(std::move(varray)),
+ domain_(domain),
+ save_(std::move(save)),
+ ignore_old_values_(ignore_old_values)
{
}
@@ -115,7 +122,8 @@ class OutputAttribute {
fn::GMutableSpan as_span()
{
if (!optional_span_varray_.has_value()) {
- optional_span_varray_.emplace(*varray_);
+ const bool materialize_old_values = !ignore_old_values_;
+ optional_span_varray_.emplace(*varray_, materialize_old_values);
}
fn::GVMutableArray_GSpan &span_varray = *optional_span_varray_;
return span_varray;
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index b5e1fa3d518..012b0be36a2 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -107,6 +107,8 @@ class GeometryComponent {
/* Can only be used with supported domain types. */
virtual int attribute_domain_size(const AttributeDomain domain) const;
+ bool attribute_is_deletable(const blender::StringRef attribute_name) const;
+
/* Get read-only access to the highest priority attribute with the given name.
* Returns null if the attribute does not exist. */
blender::bke::ReadAttributeLookup attribute_try_get_for_read(
@@ -157,7 +159,7 @@ class GeometryComponent {
const blender::StringRef attribute_name,
const AttributeDomain domain,
const CustomDataType data_type,
- const void *default_value) const;
+ const void *default_value = nullptr) const;
/* Get a typed read-only attribute for the given domain and type. */
template<typename T>
@@ -188,13 +190,27 @@ class GeometryComponent {
const CustomDataType data_type,
const void *default_value = nullptr);
+ blender::bke::OutputAttribute attribute_try_get_for_output_only(
+ const blender::StringRef attribute_name,
+ const AttributeDomain domain,
+ const CustomDataType data_type);
+
template<typename T>
blender::bke::OutputAttribute_Typed<T> attribute_try_get_for_output(
+ const blender::StringRef attribute_name, const AttributeDomain domain, const T default_value)
+ {
+ const blender::fn::CPPType &cpp_type = blender::fn::CPPType::get<T>();
+ const CustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(cpp_type);
+ return this->attribute_try_get_for_output(attribute_name, domain, data_type, &default_value);
+ }
+
+ template<typename T>
+ blender::bke::OutputAttribute_Typed<T> attribute_try_get_for_output_only(
const blender::StringRef attribute_name, const AttributeDomain domain)
{
const blender::fn::CPPType &cpp_type = blender::fn::CPPType::get<T>();
const CustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(cpp_type);
- return this->attribute_try_get_for_output(attribute_name, domain, data_type, nullptr);
+ return this->attribute_try_get_for_output_only(attribute_name, domain, data_type);
}
private:
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index fad6f111458..d1322081f58 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -770,6 +770,9 @@ std::unique_ptr<blender::bke::GVArray> GeometryComponent::attribute_get_for_read
return varray;
}
const blender::fn::CPPType *type = blender::bke::custom_data_type_to_cpp_type(data_type);
+ if (default_value == nullptr) {
+ default_value = type->default_value();
+ }
const int domain_size = this->attribute_domain_size(domain);
return std::make_unique<blender::fn::GVArray_For_SingleValue>(*type, domain_size, default_value);
}
@@ -788,3 +791,82 @@ blender::bke::OutputAttribute GeometryComponent::attribute_try_get_for_output(
/* TODO */
return {};
}
+
+class GVMutableAttribute_For_OutputAttribute
+ : public blender::fn::GVMutableArray_For_GMutableSpan {
+ public:
+ GeometryComponent *component;
+ std::string final_name;
+
+ GVMutableAttribute_For_OutputAttribute(GMutableSpan data,
+ GeometryComponent &component,
+ std::string final_name)
+ : blender::fn::GVMutableArray_For_GMutableSpan(data),
+ component(&component),
+ final_name(std::move(final_name))
+ {
+ }
+
+ ~GVMutableAttribute_For_OutputAttribute() override
+ {
+ type_->destruct_n(data_, size_);
+ MEM_freeN(data_);
+ }
+};
+
+blender::bke::OutputAttribute GeometryComponent::attribute_try_get_for_output_only(
+ const blender::StringRef attribute_name,
+ const AttributeDomain domain,
+ const CustomDataType data_type)
+{
+ using namespace blender;
+ using namespace blender::fn;
+ using namespace blender::bke;
+ const CPPType *cpp_type = custom_data_type_to_cpp_type(data_type);
+ BLI_assert(cpp_type != nullptr);
+
+ WriteAttributeLookup attribute = this->attribute_try_get_for_write(attribute_name);
+ if (attribute) {
+ if (attribute.domain == domain) {
+ if (attribute.varray->type() == *cpp_type) {
+ /* Best case, attribute with correct type and domain exists already. */
+ return OutputAttribute(std::move(attribute.varray), domain, {}, true);
+ }
+ if (!this->attribute_is_deletable(attribute_name)) {
+ /* Can't delete this attribute later on, so adapt the data type. */
+ const nodes::DataTypeConversions &conversions = nodes::get_implicit_type_conversions();
+ std::unique_ptr<GVMutableArray> varray = conversions.try_convert(
+ std::move(attribute.varray), *cpp_type);
+ return OutputAttribute(std::move(varray), domain, {}, true);
+ }
+ }
+ }
+ else if (this->attribute_try_create(attribute_name, domain, data_type)) {
+ /* There is no conflicting attribute, so create it and return the new attribute. */
+ attribute = this->attribute_try_get_for_write(attribute_name);
+ return OutputAttribute(std::move(attribute.varray), domain, {}, true);
+ }
+
+ const int domain_size = this->attribute_domain_size(domain);
+ void *data = MEM_mallocN_aligned(
+ cpp_type->size() * domain_size, cpp_type->alignment(), __func__);
+ cpp_type->construct_default_n(data, domain);
+ std::unique_ptr<GVMutableArray> varray =
+ std::make_unique<GVMutableAttribute_For_OutputAttribute>(
+ GMutableSpan{*cpp_type, data, domain_size}, *this, attribute_name);
+ auto save = [](OutputAttribute &attribute) {
+ GVMutableAttribute_For_OutputAttribute &varray =
+ dynamic_cast<GVMutableAttribute_For_OutputAttribute &>(attribute.varray());
+ varray.component->attribute_try_delete(varray.final_name);
+ varray.component->attribute_try_create(
+ varray.final_name, attribute.domain(), attribute.custom_data_type());
+ WriteAttributeLookup write_attribute = varray.component->attribute_try_get_for_write(
+ varray.final_name);
+ BUFFER_FOR_CPP_TYPE_VALUE(varray.type(), buffer);
+ for (const int i : IndexRange(varray.size())) {
+ varray.get(i, buffer);
+ write_attribute.varray->set_by_relocate(i, buffer);
+ }
+ };
+ return OutputAttribute(std::move(varray), domain, save, true);
+}
diff --git a/source/blender/nodes/NOD_type_conversions.hh b/source/blender/nodes/NOD_type_conversions.hh
index dc24e35d0f7..7b7e63bd1bc 100644
--- a/source/blender/nodes/NOD_type_conversions.hh
+++ b/source/blender/nodes/NOD_type_conversions.hh
@@ -75,6 +75,9 @@ class DataTypeConversions {
std::unique_ptr<fn::GVArray> try_convert(std::unique_ptr<fn::GVArray> varray,
const CPPType &to_type) const;
+
+ std::unique_ptr<fn::GVMutableArray> try_convert(std::unique_ptr<fn::GVMutableArray> varray,
+ const CPPType &to_type) const;
};
const DataTypeConversions &get_implicit_type_conversions();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc b/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
index ffcbae6b5cd..0135b3da90b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_align_rotation_to_vector.cc
@@ -145,7 +145,7 @@ static void align_rotations_on_component(GeometryComponent &component,
node.storage;
OutputAttribute_Typed<float3> rotations = component.attribute_try_get_for_output<float3>(
- "rotation", ATTR_DOMAIN_POINT);
+ "rotation", ATTR_DOMAIN_POINT, {0, 0, 0});
if (!rotations) {
return;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
index 2bd36cfd119..0da3d92dc79 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
@@ -160,7 +160,7 @@ static void clamp_attribute(GeometryComponent &component, const GeoNodeExecParam
std::unique_ptr<GVArray> attribute_input = component.attribute_try_get_for_read(
attribute_name, domain, data_type);
- OutputAttribute attribute_result = component.attribute_try_get_for_output(
+ OutputAttribute attribute_result = component.attribute_t
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list