Geometry Nodes: cleanup attribute usage

Now that typed attribute wrappers don't need to own the
attribute anymore, many `std::move` calls can be removed.
This commit is contained in:
Jacques Lucke 2021-01-13 12:27:16 +01:00
parent 76fd41e9db
commit ed1042ee06
9 changed files with 110 additions and 154 deletions

View File

@ -100,6 +100,11 @@ class ReadAttribute {
/* Get a span that contains all attribute values. */
fn::GSpan get_span() const;
template<typename T> Span<T> get_span() const
{
return this->get_span().typed<T>();
}
protected:
/* r_value is expected to be uninitialized. */
virtual void get_internal(const int64_t index, void *r_value) const = 0;
@ -176,6 +181,16 @@ class WriteAttribute {
/* Write the changes to the span into the actual attribute, if they aren't already. */
void apply_span();
template<typename T> MutableSpan<T> get_span()
{
return this->get_span().typed<T>();
}
template<typename T> MutableSpan<T> get_span_for_write_only()
{
return this->get_span_for_write_only().typed<T>();
}
protected:
virtual void get_internal(const int64_t index, void *r_value) const = 0;
virtual void set_internal(const int64_t index, const void *value) = 0;
@ -191,8 +206,8 @@ using WriteAttributePtr = std::unique_ptr<WriteAttribute>;
* The underlying ReadAttribute is owned optionally. */
template<typename T> class TypedReadAttribute {
private:
std::unique_ptr<ReadAttribute> owned_attribute_;
ReadAttribute *attribute_;
std::unique_ptr<const ReadAttribute> owned_attribute_;
const ReadAttribute *attribute_;
public:
TypedReadAttribute(ReadAttributePtr attribute) : TypedReadAttribute(*attribute)
@ -201,7 +216,7 @@ template<typename T> class TypedReadAttribute {
BLI_assert(owned_attribute_);
}
TypedReadAttribute(ReadAttribute &attribute) : attribute_(&attribute)
TypedReadAttribute(const ReadAttribute &attribute) : attribute_(&attribute)
{
BLI_assert(attribute_->cpp_type().is<T>());
}

View File

@ -51,21 +51,19 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
return;
}
Color4fWriteAttribute attribute_out = std::move(attribute_result);
const std::string input_name = params.get_input<std::string>("Attribute");
FloatReadAttribute attribute_in = component.attribute_get_for_read<float>(
input_name, result_domain, 0.0f);
Span<float> data_in = attribute_in.get_span();
MutableSpan<Color4f> data_out = attribute_out.get_span_for_write_only();
MutableSpan<Color4f> data_out = attribute_result->get_span_for_write_only<Color4f>();
ColorBand *color_ramp = &node_storage->color_ramp;
for (const int i : data_in.index_range()) {
BKE_colorband_evaluate(color_ramp, data_in[i], data_out[i]);
}
attribute_out.apply_span();
attribute_result->apply_span();
}
static void geo_node_attribute_color_ramp_exec(GeoNodeExecParams params)

View File

@ -103,10 +103,10 @@ static void do_math_operation(const FloatReadAttribute &input_a,
BLI_assert(false);
}
static void do_equal_operation(const FloatReadAttribute &input_a,
const FloatReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
static void do_equal_operation_float(const FloatReadAttribute &input_a,
const FloatReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const int size = input_a.size();
for (const int i : IndexRange(size)) {
@ -116,10 +116,10 @@ static void do_equal_operation(const FloatReadAttribute &input_a,
}
}
static void do_equal_operation(const Float3ReadAttribute &input_a,
const Float3ReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
static void do_equal_operation_float3(const Float3ReadAttribute &input_a,
const Float3ReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const float threshold_squared = pow2f(threshold);
const int size = input_a.size();
@ -130,10 +130,10 @@ static void do_equal_operation(const Float3ReadAttribute &input_a,
}
}
static void do_equal_operation(const Color4fReadAttribute &input_a,
const Color4fReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
static void do_equal_operation_color4f(const Color4fReadAttribute &input_a,
const Color4fReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const float threshold_squared = pow2f(threshold);
const int size = input_a.size();
@ -144,10 +144,10 @@ static void do_equal_operation(const Color4fReadAttribute &input_a,
}
}
static void do_equal_operation(const BooleanReadAttribute &input_a,
const BooleanReadAttribute &input_b,
const float UNUSED(threshold),
MutableSpan<bool> span_result)
static void do_equal_operation_bool(const BooleanReadAttribute &input_a,
const BooleanReadAttribute &input_b,
const float UNUSED(threshold),
MutableSpan<bool> span_result)
{
const int size = input_a.size();
for (const int i : IndexRange(size)) {
@ -157,10 +157,10 @@ static void do_equal_operation(const BooleanReadAttribute &input_a,
}
}
static void do_not_equal_operation(const FloatReadAttribute &input_a,
const FloatReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
static void do_not_equal_operation_float(const FloatReadAttribute &input_a,
const FloatReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const int size = input_a.size();
for (const int i : IndexRange(size)) {
@ -170,10 +170,10 @@ static void do_not_equal_operation(const FloatReadAttribute &input_a,
}
}
static void do_not_equal_operation(const Float3ReadAttribute &input_a,
const Float3ReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
static void do_not_equal_operation_float3(const Float3ReadAttribute &input_a,
const Float3ReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const float threshold_squared = pow2f(threshold);
const int size = input_a.size();
@ -184,10 +184,10 @@ static void do_not_equal_operation(const Float3ReadAttribute &input_a,
}
}
static void do_not_equal_operation(const Color4fReadAttribute &input_a,
const Color4fReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
static void do_not_equal_operation_color4f(const Color4fReadAttribute &input_a,
const Color4fReadAttribute &input_b,
const float threshold,
MutableSpan<bool> span_result)
{
const float threshold_squared = pow2f(threshold);
const int size = input_a.size();
@ -198,10 +198,10 @@ static void do_not_equal_operation(const Color4fReadAttribute &input_a,
}
}
static void do_not_equal_operation(const BooleanReadAttribute &input_a,
const BooleanReadAttribute &input_b,
const float UNUSED(threshold),
MutableSpan<bool> span_result)
static void do_not_equal_operation_bool(const BooleanReadAttribute &input_a,
const BooleanReadAttribute &input_b,
const float UNUSED(threshold),
MutableSpan<bool> span_result)
{
const int size = input_a.size();
for (const int i : IndexRange(size)) {
@ -260,7 +260,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
return;
}
BooleanWriteAttribute attribute_result_bool = std::move(attribute_result);
BooleanWriteAttribute attribute_result_bool = *attribute_result;
MutableSpan<bool> result_span = attribute_result_bool.get_span_for_write_only();
/* Use specific types for correct equality operations, but for other operations we use implicit
@ -269,59 +269,35 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
const float threshold = params.get_input<float>("Threshold");
if (operation == NODE_FLOAT_COMPARE_EQUAL) {
if (input_data_type == CD_PROP_FLOAT) {
FloatReadAttribute attribute_a_float = std::move(attribute_a);
FloatReadAttribute attribute_b_float = std::move(attribute_b);
do_equal_operation(
std::move(attribute_a_float), std::move(attribute_b_float), threshold, result_span);
do_equal_operation_float(*attribute_a, *attribute_b, threshold, result_span);
}
else if (input_data_type == CD_PROP_FLOAT3) {
Float3ReadAttribute attribute_a_float3 = std::move(attribute_a);
Float3ReadAttribute attribute_b_float3 = std::move(attribute_b);
do_equal_operation(
std::move(attribute_a_float3), std::move(attribute_b_float3), threshold, result_span);
do_equal_operation_float3(*attribute_a, *attribute_b, threshold, result_span);
}
else if (input_data_type == CD_PROP_COLOR) {
Color4fReadAttribute attribute_a_color = std::move(attribute_a);
Color4fReadAttribute attribute_b_color = std::move(attribute_b);
do_equal_operation(
std::move(attribute_a_color), std::move(attribute_b_color), threshold, result_span);
do_equal_operation_color4f(*attribute_a, *attribute_b, threshold, result_span);
}
else if (input_data_type == CD_PROP_BOOL) {
BooleanReadAttribute attribute_a_bool = std::move(attribute_a);
BooleanReadAttribute attribute_b_bool = std::move(attribute_b);
do_equal_operation(
std::move(attribute_a_bool), std::move(attribute_b_bool), threshold, result_span);
do_equal_operation_bool(*attribute_a, *attribute_b, threshold, result_span);
}
}
else if (operation == NODE_FLOAT_COMPARE_NOT_EQUAL) {
if (input_data_type == CD_PROP_FLOAT) {
FloatReadAttribute attribute_a_float = std::move(attribute_a);
FloatReadAttribute attribute_b_float = std::move(attribute_b);
do_not_equal_operation(
std::move(attribute_a_float), std::move(attribute_b_float), threshold, result_span);
do_not_equal_operation_float(*attribute_a, *attribute_b, threshold, result_span);
}
else if (input_data_type == CD_PROP_FLOAT3) {
Float3ReadAttribute attribute_a_float3 = std::move(attribute_a);
Float3ReadAttribute attribute_b_float3 = std::move(attribute_b);
do_not_equal_operation(
std::move(attribute_a_float3), std::move(attribute_b_float3), threshold, result_span);
do_not_equal_operation_float3(*attribute_a, *attribute_b, threshold, result_span);
}
else if (input_data_type == CD_PROP_COLOR) {
Color4fReadAttribute attribute_a_color = std::move(attribute_a);
Color4fReadAttribute attribute_b_color = std::move(attribute_b);
do_not_equal_operation(
std::move(attribute_a_color), std::move(attribute_b_color), threshold, result_span);
do_not_equal_operation_color4f(*attribute_a, *attribute_b, threshold, result_span);
}
else if (input_data_type == CD_PROP_BOOL) {
BooleanReadAttribute attribute_a_bool = std::move(attribute_a);
BooleanReadAttribute attribute_b_bool = std::move(attribute_b);
do_not_equal_operation(
std::move(attribute_a_bool), std::move(attribute_b_bool), threshold, result_span);
do_not_equal_operation_bool(*attribute_a, *attribute_b, threshold, result_span);
}
}
}
else {
do_math_operation(std::move(attribute_a), std::move(attribute_b), operation, result_span);
do_math_operation(*attribute_a, *attribute_b, operation, result_span);
}
attribute_result_bool.apply_span();

View File

@ -76,35 +76,31 @@ static void fill_attribute(GeometryComponent &component, const GeoNodeExecParams
switch (data_type) {
case CD_PROP_FLOAT: {
FloatWriteAttribute float_attribute = std::move(attribute);
const float value = params.get_input<float>("Value_001");
MutableSpan<float> attribute_span = float_attribute.get_span_for_write_only();
MutableSpan<float> attribute_span = attribute->get_span_for_write_only<float>();
attribute_span.fill(value);
float_attribute.apply_span();
attribute->apply_span();
break;
}
case CD_PROP_FLOAT3: {
Float3WriteAttribute float3_attribute = std::move(attribute);
const float3 value = params.get_input<float3>("Value");
MutableSpan<float3> attribute_span = float3_attribute.get_span_for_write_only();
MutableSpan<float3> attribute_span = attribute->get_span_for_write_only<float3>();
attribute_span.fill(value);
float3_attribute.apply_span();
attribute->apply_span();
break;
}
case CD_PROP_COLOR: {
Color4fWriteAttribute color4f_attribute = std::move(attribute);
const Color4f value = params.get_input<Color4f>("Value_002");
MutableSpan<Color4f> attribute_span = color4f_attribute.get_span_for_write_only();
MutableSpan<Color4f> attribute_span = attribute->get_span_for_write_only<Color4f>();
attribute_span.fill(value);
color4f_attribute.apply_span();
attribute->apply_span();
break;
}
case CD_PROP_BOOL: {
BooleanWriteAttribute boolean_attribute = std::move(attribute);
const bool value = params.get_input<bool>("Value_003");
MutableSpan<bool> attribute_span = boolean_attribute.get_span_for_write_only();
MutableSpan<bool> attribute_span = attribute->get_span_for_write_only<bool>();
attribute_span.fill(value);
boolean_attribute.apply_span();
attribute->apply_span();
break;
}
default:

View File

@ -122,8 +122,7 @@ static void attribute_math_calc(GeometryComponent &component, const GeoNodeExecP
return;
}
do_math_operation(
std::move(attribute_a), std::move(attribute_b), std::move(attribute_result), operation);
do_math_operation(*attribute_a, *attribute_b, *attribute_result, operation);
}
static void geo_node_attribute_math_exec(GeoNodeExecParams params)

View File

@ -47,7 +47,7 @@ static void do_mix_operation_float(const int blend_mode,
const FloatReadAttribute &factors,
const FloatReadAttribute &inputs_a,
const FloatReadAttribute &inputs_b,
FloatWriteAttribute &results)
FloatWriteAttribute results)
{
const int size = results.size();
for (const int i : IndexRange(size)) {
@ -64,7 +64,7 @@ static void do_mix_operation_float3(const int blend_mode,
const FloatReadAttribute &factors,
const Float3ReadAttribute &inputs_a,
const Float3ReadAttribute &inputs_b,
Float3WriteAttribute &results)
Float3WriteAttribute results)
{
const int size = results.size();
for (const int i : IndexRange(size)) {
@ -80,7 +80,7 @@ static void do_mix_operation_color4f(const int blend_mode,
const FloatReadAttribute &factors,
const Color4fReadAttribute &inputs_a,
const Color4fReadAttribute &inputs_b,
Color4fWriteAttribute &results)
Color4fWriteAttribute results)
{
const int size = results.size();
for (const int i : IndexRange(size)) {
@ -95,39 +95,21 @@ static void do_mix_operation_color4f(const int blend_mode,
static void do_mix_operation(const CustomDataType result_type,
int blend_mode,
const FloatReadAttribute &attribute_factor,
ReadAttributePtr attribute_a,
ReadAttributePtr attribute_b,
WriteAttributePtr attribute_result)
const ReadAttribute &attribute_a,
const ReadAttribute &attribute_b,
WriteAttribute &attribute_result)
{
if (result_type == CD_PROP_FLOAT) {
FloatReadAttribute attribute_a_float = std::move(attribute_a);
FloatReadAttribute attribute_b_float = std::move(attribute_b);
FloatWriteAttribute attribute_result_float = std::move(attribute_result);
do_mix_operation_float(blend_mode,
attribute_factor,
attribute_a_float,
attribute_b_float,
attribute_result_float);
do_mix_operation_float(
blend_mode, attribute_factor, attribute_a, attribute_b, attribute_result);
}
else if (result_type == CD_PROP_FLOAT3) {
Float3ReadAttribute attribute_a_float3 = std::move(attribute_a);
Float3ReadAttribute attribute_b_float3 = std::move(attribute_b);
Float3WriteAttribute attribute_result_float3 = std::move(attribute_result);
do_mix_operation_float3(blend_mode,
attribute_factor,
attribute_a_float3,
attribute_b_float3,
attribute_result_float3);
do_mix_operation_float3(
blend_mode, attribute_factor, attribute_a, attribute_b, attribute_result);
}
else if (result_type == CD_PROP_COLOR) {
Color4fReadAttribute attribute_a_color4f = std::move(attribute_a);
Color4fReadAttribute attribute_b_color4f = std::move(attribute_b);
Color4fWriteAttribute attribute_result_color4f = std::move(attribute_result);
do_mix_operation_color4f(blend_mode,
attribute_factor,
attribute_a_color4f,
attribute_b_color4f,
attribute_result_color4f);
do_mix_operation_color4f(
blend_mode, attribute_factor, attribute_a, attribute_b, attribute_result);
}
}
@ -170,9 +152,9 @@ static void attribute_mix_calc(GeometryComponent &component, const GeoNodeExecPa
do_mix_operation(result_type,
node_storage->blend_type,
attribute_factor,
std::move(attribute_a),
std::move(attribute_b),
std::move(attribute_result));
*attribute_a,
*attribute_b,
*attribute_result);
}
static void geo_node_attribute_mix_exec(GeoNodeExecParams params)

View File

@ -74,9 +74,9 @@ static float noise_from_index(const int seed, const int hash)
return BLI_hash_int_01(combined_hash);
}
static void randomize_attribute(BooleanWriteAttribute &attribute,
Span<uint32_t> hashes,
const int seed)
static void randomize_attribute_bool(BooleanWriteAttribute attribute,
Span<uint32_t> hashes,
const int seed)
{
MutableSpan<bool> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@ -86,8 +86,8 @@ static void randomize_attribute(BooleanWriteAttribute &attribute,
attribute.apply_span();
}
static void randomize_attribute(
FloatWriteAttribute &attribute, float min, float max, Span<uint32_t> hashes, const int seed)
static void randomize_attribute_float(
FloatWriteAttribute attribute, float min, float max, Span<uint32_t> hashes, const int seed)
{
MutableSpan<float> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@ -97,8 +97,8 @@ static void randomize_attribute(
attribute.apply_span();
}
static void randomize_attribute(
Float3WriteAttribute &attribute, float3 min, float3 max, Span<uint32_t> hashes, const int seed)
static void randomize_attribute_float3(
Float3WriteAttribute attribute, float3 min, float3 max, Span<uint32_t> hashes, const int seed)
{
MutableSpan<float3> attribute_span = attribute.get_span();
for (const int i : IndexRange(attribute.size())) {
@ -161,22 +161,19 @@ static void randomize_attribute(GeometryComponent &component,
switch (data_type) {
case CD_PROP_FLOAT: {
FloatWriteAttribute float_attribute = std::move(attribute);
const float min_value = params.get_input<float>("Min_001");
const float max_value = params.get_input<float>("Max_001");
randomize_attribute(float_attribute, min_value, max_value, hashes, seed);
randomize_attribute_float(*attribute, min_value, max_value, hashes, seed);
break;
}
case CD_PROP_FLOAT3: {
Float3WriteAttribute float3_attribute = std::move(attribute);
const float3 min_value = params.get_input<float3>("Min");
const float3 max_value = params.get_input<float3>("Max");
randomize_attribute(float3_attribute, min_value, max_value, hashes, seed);
randomize_attribute_float3(*attribute, min_value, max_value, hashes, seed);
break;
}
case CD_PROP_BOOL: {
BooleanWriteAttribute boolean_attribute = std::move(attribute);
randomize_attribute(boolean_attribute, hashes, seed);
randomize_attribute_bool(*attribute, hashes, seed);
break;
}
default:

View File

@ -363,20 +363,17 @@ static void attribute_vector_math_calc(GeometryComponent &component,
case NODE_VECTOR_MATH_MODULO:
case NODE_VECTOR_MATH_MINIMUM:
case NODE_VECTOR_MATH_MAXIMUM:
do_math_operation_fl3_fl3_to_fl3(
std::move(attribute_a), std::move(attribute_b), std::move(attribute_result), operation);
do_math_operation_fl3_fl3_to_fl3(*attribute_a, *attribute_b, *attribute_result, operation);
break;
case NODE_VECTOR_MATH_DOT_PRODUCT:
case NODE_VECTOR_MATH_DISTANCE:
do_math_operation_fl3_fl3_to_fl(
std::move(attribute_a), std::move(attribute_b), std::move(attribute_result), operation);
do_math_operation_fl3_fl3_to_fl(*attribute_a, *attribute_b, *attribute_result, operation);
break;
case NODE_VECTOR_MATH_LENGTH:
do_math_operation_fl3_to_fl(std::move(attribute_a), std::move(attribute_result), operation);
do_math_operation_fl3_to_fl(*attribute_a, *attribute_result, operation);
break;
case NODE_VECTOR_MATH_SCALE:
do_math_operation_fl3_fl_to_fl3(
std::move(attribute_a), std::move(attribute_b), std::move(attribute_result), operation);
do_math_operation_fl3_fl_to_fl3(*attribute_a, *attribute_b, *attribute_result, operation);
break;
case NODE_VECTOR_MATH_NORMALIZE:
case NODE_VECTOR_MATH_FLOOR:
@ -386,14 +383,11 @@ static void attribute_vector_math_calc(GeometryComponent &component,
case NODE_VECTOR_MATH_SINE:
case NODE_VECTOR_MATH_COSINE:
case NODE_VECTOR_MATH_TANGENT:
do_math_operation_fl3_to_fl3(std::move(attribute_a), std::move(attribute_result), operation);
do_math_operation_fl3_to_fl3(*attribute_a, *attribute_result, operation);
break;
case NODE_VECTOR_MATH_WRAP:
do_math_operation_fl3_fl3_fl3_to_fl3(std::move(attribute_a),
std::move(attribute_b),
std::move(attribute_c),
std::move(attribute_result),
operation);
do_math_operation_fl3_fl3_fl3_to_fl3(
*attribute_a, *attribute_b, *attribute_c, *attribute_result, operation);
break;
}
}

View File

@ -38,22 +38,22 @@ static bNodeSocketTemplate geo_node_point_instance_out[] = {
namespace blender::nodes {
static void fill_new_attribute_from_input(ReadAttributePtr input_attribute,
WriteAttributePtr out_attribute_a,
WriteAttributePtr out_attribute_b,
static void fill_new_attribute_from_input(const ReadAttribute &input_attribute,
WriteAttribute &out_attribute_a,
WriteAttribute &out_attribute_b,
Span<bool> a_or_b)
{
fn::GSpan in_span = input_attribute->get_span();
fn::GSpan in_span = input_attribute.get_span();
int i_a = 0;
int i_b = 0;
for (int i_in = 0; i_in < in_span.size(); i_in++) {
const bool move_to_b = a_or_b[i_in];
if (move_to_b) {
out_attribute_b->set(i_b, in_span[i_in]);
out_attribute_b.set(i_b, in_span[i_in]);
i_b++;
}
else {
out_attribute_a->set(i_a, in_span[i_in]);
out_attribute_a.set(i_a, in_span[i_in]);
i_a++;
}
}
@ -108,8 +108,7 @@ static void move_split_attributes(const GeometryComponent &in_component,
continue;
}
fill_new_attribute_from_input(
std::move(attribute), std::move(out_attribute_a), std::move(out_attribute_b), a_or_b);
fill_new_attribute_from_input(*attribute, *out_attribute_a, *out_attribute_b, a_or_b);
}
}