Commit: b5105085139227a713f154446ff6a3255cb8be99 Author: Jacques Lucke Date: Tue Jan 17 13:29:55 2023 +0100 Branches: master https://developer.blender.org/rBb5105085139227a713f154446ff6a3255cb8be99
Geometry Nodes: optimize Sample Index node with constant index Previously, the node would always evaluate the input field on the entire geometry domain. This is good when most indices will be accessed afterwards. However, it is quite a bad when only a single index is used. Now the field is only evaluated for that one index. =================================================================== M source/blender/nodes/geometry/nodes/node_geo_sample_index.cc =================================================================== diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 4f6062cb553..850b2cfdd66 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -299,12 +299,39 @@ static void node_geo_exec(GeoNodeExecParams params) const eCustomDataType data_type = eCustomDataType(storage.data_type); const eAttrDomain domain = eAttrDomain(storage.domain); - auto fn = std::make_shared<SampleIndexFunction>(std::move(geometry), - get_input_attribute_field(params, data_type), - domain, - bool(storage.clamp)); - auto op = FieldOperation::Create(std::move(fn), {params.extract_input<Field<int>>("Index")}); - output_attribute_field(params, GField(std::move(op))); + GField value_field = get_input_attribute_field(params, data_type); + ValueOrField<int> index_value_or_field = params.extract_input<ValueOrField<int>>("Index"); + const CPPType &cpp_type = value_field.cpp_type(); + + GField output_field; + if (index_value_or_field.is_field()) { + /* If the index is a field, the output has to be a field that still depends on the input. */ + auto fn = std::make_shared<SampleIndexFunction>( + std::move(geometry), std::move(value_field), domain, bool(storage.clamp)); + auto op = FieldOperation::Create(std::move(fn), {index_value_or_field.as_field()}); + output_field = GField(std::move(op)); + } + else if (const GeometryComponent *component = find_source_component(geometry, domain)) { + /* Optimization for the case when the index is a single value. Here only that one index has to + * be evaluated. */ + const int index = index_value_or_field.as_value(); + const IndexMask mask = IndexRange(index, 1); + bke::GeometryFieldContext geometry_context(*component, domain); + FieldEvaluator evaluator(geometry_context, &mask); + evaluator.add(value_field); + evaluator.evaluate(); + const GVArray &data = evaluator.get_evaluated(0); + BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, buffer); + data.get_to_uninitialized(index, buffer); + output_field = fn::make_constant_field(cpp_type, cpp_type.default_value()); + cpp_type.destruct(buffer); + } + else { + /* Output default value if there is no geometry. */ + output_field = fn::make_constant_field(cpp_type, cpp_type.default_value()); + } + + output_attribute_field(params, std::move(output_field)); } } // namespace blender::nodes::node_geo_sample_index_cc _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs