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:
authorHans Goudey <h.goudey@me.com>2021-04-22 16:05:02 +0300
committerHans Goudey <h.goudey@me.com>2021-04-22 16:05:02 +0300
commitb9a7b40924f6284af5867cb63078dc79c714a675 (patch)
tree76a455cc2ab73f930c3176aa0e518452d5f00a22
parentf6efacfec74e0c20fffc75e05007df01536d8924 (diff)
Geometry Nodes: Get attribute domain and type without allocation
Because we use virtual classes (and for other reasons), we had to do a small allocation when simply retrieving the data type and domain of an existing attribute. This happened quite a lot actually-- to determine these values for result attributes. This patch adds a simple function to retrieve this meta data without building the virtual array. This should lower the overhead of every attribute node, though the difference probably won't be noticible unless a tree has very many nodes. Differential Revision: https://developer.blender.org/D11047
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh4
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc17
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc24
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc9
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc14
16 files changed, 96 insertions, 83 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 38f692fee0e..e9545cba1f1 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -102,6 +102,10 @@ class GeometryComponent {
/* Return true when any attribute with this name exists, including built in attributes. */
bool attribute_exists(const blender::StringRef attribute_name) const;
+ /* Return the data type and domain of an attribute with the given name if it exists. */
+ std::optional<AttributeMetaData> attribute_get_meta_data(
+ const blender::StringRef attribute_name) const;
+
/* Returns true when the geometry component supports this attribute domain. */
bool attribute_domain_supported(const AttributeDomain domain) const;
/* Can only be used with supported domain types. */
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 3b2ee126d91..571763e3719 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -729,6 +729,20 @@ bool GeometryComponent::attribute_exists(const blender::StringRef attribute_name
return false;
}
+std::optional<AttributeMetaData> GeometryComponent::attribute_get_meta_data(
+ const StringRef attribute_name) const
+{
+ std::optional<AttributeMetaData> result{std::nullopt};
+ this->attribute_foreach([&](StringRefNull name, const AttributeMetaData &meta_data) {
+ if (attribute_name == name) {
+ result = meta_data;
+ return false;
+ }
+ return true;
+ });
+ return result;
+}
+
static std::unique_ptr<blender::fn::GVArray> try_adapt_data_type(
std::unique_ptr<blender::fn::GVArray> varray, const blender::fn::CPPType &to_type)
{
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 e7677ed41e1..1943971d49f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc
@@ -126,13 +126,13 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef source_name,
StringRef result_name)
{
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
- ReadAttributeLookup source_attribute = component.attribute_try_get_for_read(source_name);
- if (source_attribute) {
- return source_attribute.domain;
+ std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name);
+ if (source_info) {
+ return source_info->domain;
}
return ATTR_DOMAIN_POINT;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
index af65fe110e9..9e697226a01 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc
@@ -47,15 +47,15 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef result_name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the input attribute's domain if it exists. */
- ReadAttributeLookup input_attribute = component.attribute_try_get_for_read(input_name);
- if (input_attribute) {
- return input_attribute.domain;
+ std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(input_name);
+ if (source_info) {
+ return source_info->domain;
}
return ATTR_DOMAIN_POINT;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
index c3db26c7299..69e628267a4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc
@@ -77,9 +77,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef result_name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the highest priority domain from existing input attributes, or the default. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
index 22855787ab0..ccfaeb9bb47 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc
@@ -234,9 +234,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef result_name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the highest priority domain from existing input attributes, or the default. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc
index bb46c5c84cd..60bb27191b4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc
@@ -55,13 +55,13 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef source_name,
StringRef result_name)
{
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
- ReadAttributeLookup source_attribute = component.attribute_try_get_for_read(source_name);
- if (source_attribute) {
- return source_attribute.domain;
+ std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name);
+ if (source_info) {
+ return source_info->domain;
}
return ATTR_DOMAIN_POINT;
}
@@ -75,14 +75,14 @@ static bool conversion_can_be_skipped(const GeometryComponent &component,
if (source_name != result_name) {
return false;
}
- ReadAttributeLookup read_attribute = component.attribute_try_get_for_read(source_name);
- if (!read_attribute) {
+ std::optional<AttributeMetaData> info = component.attribute_get_meta_data(result_name);
+ if (!info) {
return false;
}
- if (read_attribute.domain != result_domain) {
+ if (info->domain != result_domain) {
return false;
}
- if (read_attribute.varray->type() != *bke::custom_data_type_to_cpp_type(result_type)) {
+ if (info->data_type != result_type) {
return false;
}
return true;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
index 8287313e400..3df64625b99 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
@@ -68,13 +68,12 @@ static void geo_node_attribute_fill_update(bNodeTree *UNUSED(ntree), bNode *node
namespace blender::nodes {
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- StringRef attribute_name)
+static AttributeDomain get_result_domain(const GeometryComponent &component, const StringRef name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(attribute_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(name);
+ if (result_info) {
+ return result_info->domain;
}
return ATTR_DOMAIN_POINT;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc
index 4a98d6caed2..5d82897e9db 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc
@@ -318,13 +318,13 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef source_name,
StringRef result_name)
{
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
- ReadAttributeLookup source_attribute = component.attribute_try_get_for_read(source_name);
- if (source_attribute) {
- return source_attribute.domain;
+ std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name);
+ if (source_info) {
+ return source_info->domain;
}
return ATTR_DOMAIN_POINT;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
index 99ba6acd94d..00ae6b373b2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc
@@ -200,9 +200,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef result_name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the highest priority domain from existing input attributes, or the default. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
index e7f0de8f28e..7129679117d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
@@ -141,9 +141,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component,
StringRef result_name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the highest priority domain from existing input attributes, or the default. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
index e86fa3ae0ed..cc6aacaca79 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
@@ -196,12 +196,12 @@ Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &compo
static AttributeDomain get_result_domain(const GeometryComponent &component,
const GeoNodeExecParams &params,
- StringRef attribute_name)
+ const StringRef name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(attribute_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the input domain chosen in the interface. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
index 5b3fd75342a..fa11ef936cd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
@@ -49,20 +49,19 @@ static void geo_node_attribute_sample_texture_layout(uiLayout *layout,
namespace blender::nodes {
static AttributeDomain get_result_domain(const GeometryComponent &component,
- StringRef result_attribute_name,
- StringRef map_attribute_name)
+ const StringRef result_name,
+ const StringRef map_name)
{
/* Use the domain of the result attribute if it already exists. */
- ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(
- result_attribute_name);
- if (result_attribute) {
- return result_attribute.domain;
+ std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
+ if (result_info) {
+ return result_info->domain;
}
/* Otherwise use the name of the map attribute. */
- ReadAttributeLookup map_attribute = component.attribute_try_get_for_read(map_attribute_name);
- if (map_attribute) {
- return map_attribute.domain;
+ std::optional<AttributeMetaData> map_info = component.attribute_get_meta_data(map_name);
+ if (map_info) {
+ return map_info->domain;
}
/* The node won't execute in this case, but we still have to return a value. */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
index daf61b6bf57..bbc6cb71032 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc
@@ -71,23 +71,23 @@ static void extract_input(const int index, const Span<float3> &input, MutableSpa
static AttributeDomain get_result_domain(const GeometryComponent &component,
const GeoNodeExecParams &params,
- StringRef result_name_x,
- StringRef result_name_y,
- StringRef result_name_z)
+ const StringRef name_x,
+ const StringRef name_y,
+ const StringRef name_z)
{
/* Use the highest priority domain from any existing attribute outputs. */
Vector<AttributeDomain, 3> output_domains;
- ReadAttributeLookup attribute_x = component.attribute_try_get_for_read(result_name_x);
- ReadAttributeLookup attribute_y = component.attribute_try_get_for_read(result_name_y);
- ReadAttributeLookup attribute_z = component.attribute_try_get_for_read(result_name_z);
- if (attribute_x) {
- output_domains.append(attribute_x.domain);
+ std::optional<AttributeMetaData> info_x = component.attribute_get_meta_data(name_x);
+ std::optional<AttributeMetaData> info_y = component.attribute_get_meta_data(name_y);
+ std::optional<AttributeMetaData> info_z = component.attribute_get_meta_data(name_z);
+ if (info_x) {
+ output_domains.append(info_x->domain);
}
- if (attribute_y) {
- output_domains.append(attribute_y.domain);
+ if (info_y) {
+ output_domains.append(info_y->domain);
}
- if (attribute_z) {
- output_domains.append(attribute_z.domain);
+ if (info_z) {
+ output_domains.append(info_z->domain);
}
if (output_domains.size() > 0) {
return bke::attribute_domain_highest_priority(output_domains);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
index 28d5d9a96f7..772bd8a1080 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
@@ -306,17 +306,14 @@ BLI_NOINLINE static void interpolate_existing_attributes(
const MeshComponent &source_component = *set.get_component_for_read<MeshComponent>();
const Mesh &mesh = *source_component.get_for_read();
- /* Use a dummy read without specifying a domain or data type in order to
- * get the existing attribute's domain. Interpolation is done manually based
- * on the bary coords in #interpolate_attribute. */
- ReadAttributeLookup dummy_attribute = source_component.attribute_try_get_for_read(
+ std::optional<AttributeMetaData> attribute_info = component.attribute_get_meta_data(
attribute_name);
- if (!dummy_attribute) {
+ if (!attribute_info) {
i_instance += set_group.transforms.size();
continue;
}
- const AttributeDomain source_domain = dummy_attribute.domain;
+ const AttributeDomain source_domain = attribute_info->domain;
GVArrayPtr source_attribute = source_component.attribute_get_for_read(
attribute_name, source_domain, output_data_type, nullptr);
if (!source_attribute) {
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 2648336f0c0..08fbe1ac1e6 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -126,11 +126,11 @@ CustomDataType GeoNodeExecParams::get_input_attribute_data_type(
if (found_socket->type == SOCK_STRING) {
const std::string name = this->get_input<std::string>(found_socket->identifier);
- ReadAttributeLookup attribute = component.attribute_try_get_for_read(name);
- if (!attribute) {
- return default_type;
+ std::optional<AttributeMetaData> info = component.attribute_get_meta_data(name);
+ if (info) {
+ return info->data_type;
}
- return bke::cpp_type_to_custom_data_type(attribute.varray->type());
+ return default_type;
}
if (found_socket->type == SOCK_FLOAT) {
return CD_PROP_FLOAT;
@@ -169,9 +169,9 @@ AttributeDomain GeoNodeExecParams::get_highest_priority_input_domain(
if (found_socket->type == SOCK_STRING) {
const std::string name = this->get_input<std::string>(found_socket->identifier);
- ReadAttributeLookup attribute = component.attribute_try_get_for_read(name);
- if (attribute) {
- input_domains.append(attribute.domain);
+ std::optional<AttributeMetaData> info = component.attribute_get_meta_data(name);
+ if (info) {
+ input_domains.append(info->domain);
}
}
}