forked from blender/blender
A runtime registrations for a nodes: refactoring by py script #3
@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
#include "BKE_attribute_math.hh"
|
#include "BKE_attribute_math.hh"
|
||||||
|
|
||||||
#include "BLI_array.hh"
|
|
||||||
#include "BLI_generic_virtual_array.hh"
|
|
||||||
#include "BLI_virtual_array.hh"
|
|
||||||
|
|
||||||
#include "NOD_socket_search_link.hh"
|
#include "NOD_socket_search_link.hh"
|
||||||
|
|
||||||
#include "node_geometry_util.hh"
|
#include "node_geometry_util.hh"
|
||||||
@ -196,19 +192,19 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AccumulateFieldInput final : public bke::GeometryFieldInput {
|
template<typename T> class AccumulateFieldInput final : public bke::GeometryFieldInput {
|
||||||
private:
|
private:
|
||||||
GField input_;
|
Field<T> input_;
|
||||||
Field<int> group_index_;
|
Field<int> group_index_;
|
||||||
eAttrDomain source_domain_;
|
eAttrDomain source_domain_;
|
||||||
AccumulationMode accumulation_mode_;
|
AccumulationMode accumulation_mode_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AccumulateFieldInput(const eAttrDomain source_domain,
|
AccumulateFieldInput(const eAttrDomain source_domain,
|
||||||
GField input,
|
Field<T> input,
|
||||||
Field<int> group_index,
|
Field<int> group_index,
|
||||||
AccumulationMode accumulation_mode)
|
AccumulationMode accumulation_mode)
|
||||||
: bke::GeometryFieldInput(input.cpp_type(), "Accumulation"),
|
: bke::GeometryFieldInput(CPPType::get<T>(), "Accumulation"),
|
||||||
input_(input),
|
input_(input),
|
||||||
group_index_(group_index),
|
group_index_(group_index),
|
||||||
source_domain_(source_domain),
|
source_domain_(source_domain),
|
||||||
@ -220,7 +216,7 @@ class AccumulateFieldInput final : public bke::GeometryFieldInput {
|
|||||||
const IndexMask /*mask*/) const final
|
const IndexMask /*mask*/) const final
|
||||||
{
|
{
|
||||||
const AttributeAccessor attributes = *context.attributes();
|
const AttributeAccessor attributes = *context.attributes();
|
||||||
const int64_t domain_size = attributes.domain_size(source_domain_);
|
const int domain_size = attributes.domain_size(source_domain_);
|
||||||
if (domain_size == 0) {
|
if (domain_size == 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -231,28 +227,22 @@ class AccumulateFieldInput final : public bke::GeometryFieldInput {
|
|||||||
evaluator.add(input_);
|
evaluator.add(input_);
|
||||||
evaluator.add(group_index_);
|
evaluator.add(group_index_);
|
||||||
evaluator.evaluate();
|
evaluator.evaluate();
|
||||||
const GVArray g_values = evaluator.get_evaluated(0);
|
const VArray<T> values = evaluator.get_evaluated<T>(0);
|
||||||
const VArray<int> group_indices = evaluator.get_evaluated<int>(1);
|
const VArray<int> group_indices = evaluator.get_evaluated<int>(1);
|
||||||
|
|
||||||
GVArray g_output;
|
Array<T> accumulations_out(domain_size);
|
||||||
|
|
||||||
attribute_math::convert_to_static_type(g_values.type(), [&](auto dummy) {
|
|
||||||
using T = decltype(dummy);
|
|
||||||
if constexpr (is_same_any_v<T, int, float, float3>) {
|
|
||||||
Array<T> outputs(domain_size);
|
|
||||||
const VArray<T> values = g_values.typed<T>();
|
|
||||||
|
|
||||||
if (group_indices.is_single()) {
|
if (group_indices.is_single()) {
|
||||||
T accumulation = T();
|
T accumulation = T();
|
||||||
if (accumulation_mode_ == AccumulationMode::Leading) {
|
if (accumulation_mode_ == AccumulationMode::Leading) {
|
||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
accumulation = values[i] + accumulation;
|
accumulation = values[i] + accumulation;
|
||||||
outputs[i] = accumulation;
|
accumulations_out[i] = accumulation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
outputs[i] = accumulation;
|
accumulations_out[i] = accumulation;
|
||||||
accumulation = values[i] + accumulation;
|
accumulation = values[i] + accumulation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,23 +253,20 @@ class AccumulateFieldInput final : public bke::GeometryFieldInput {
|
|||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
T &accumulation_value = accumulations.lookup_or_add_default(group_indices[i]);
|
T &accumulation_value = accumulations.lookup_or_add_default(group_indices[i]);
|
||||||
accumulation_value += values[i];
|
accumulation_value += values[i];
|
||||||
outputs[i] = accumulation_value;
|
accumulations_out[i] = accumulation_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
T &accumulation_value = accumulations.lookup_or_add_default(group_indices[i]);
|
T &accumulation_value = accumulations.lookup_or_add_default(group_indices[i]);
|
||||||
outputs[i] = accumulation_value;
|
accumulations_out[i] = accumulation_value;
|
||||||
accumulation_value += values[i];
|
accumulation_value += values[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_output = VArray<T>::ForContainer(std::move(outputs));
|
return attributes.adapt_domain<T>(
|
||||||
}
|
VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, context.domain());
|
||||||
});
|
|
||||||
|
|
||||||
return attributes.adapt_domain(std::move(g_output), source_domain_, context.domain());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
@ -306,15 +293,15 @@ class AccumulateFieldInput final : public bke::GeometryFieldInput {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TotalFieldInput final : public bke::GeometryFieldInput {
|
template<typename T> class TotalFieldInput final : public bke::GeometryFieldInput {
|
||||||
private:
|
private:
|
||||||
GField input_;
|
Field<T> input_;
|
||||||
Field<int> group_index_;
|
Field<int> group_index_;
|
||||||
eAttrDomain source_domain_;
|
eAttrDomain source_domain_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TotalFieldInput(const eAttrDomain source_domain, GField input, Field<int> group_index)
|
TotalFieldInput(const eAttrDomain source_domain, Field<T> input, Field<int> group_index)
|
||||||
: bke::GeometryFieldInput(input.cpp_type(), "Total Value"),
|
: bke::GeometryFieldInput(CPPType::get<T>(), "Total Value"),
|
||||||
input_(input),
|
input_(input),
|
||||||
group_index_(group_index),
|
group_index_(group_index),
|
||||||
source_domain_(source_domain)
|
source_domain_(source_domain)
|
||||||
@ -325,7 +312,7 @@ class TotalFieldInput final : public bke::GeometryFieldInput {
|
|||||||
IndexMask /*mask*/) const final
|
IndexMask /*mask*/) const final
|
||||||
{
|
{
|
||||||
const AttributeAccessor attributes = *context.attributes();
|
const AttributeAccessor attributes = *context.attributes();
|
||||||
const int64_t domain_size = attributes.domain_size(source_domain_);
|
const int domain_size = attributes.domain_size(source_domain_);
|
||||||
if (domain_size == 0) {
|
if (domain_size == 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -336,38 +323,29 @@ class TotalFieldInput final : public bke::GeometryFieldInput {
|
|||||||
evaluator.add(input_);
|
evaluator.add(input_);
|
||||||
evaluator.add(group_index_);
|
evaluator.add(group_index_);
|
||||||
evaluator.evaluate();
|
evaluator.evaluate();
|
||||||
const GVArray g_values = evaluator.get_evaluated(0);
|
const VArray<T> values = evaluator.get_evaluated<T>(0);
|
||||||
const VArray<int> group_indices = evaluator.get_evaluated<int>(1);
|
const VArray<int> group_indices = evaluator.get_evaluated<int>(1);
|
||||||
|
|
||||||
GVArray g_outputs;
|
|
||||||
|
|
||||||
attribute_math::convert_to_static_type(g_values.type(), [&](auto dummy) {
|
|
||||||
using T = decltype(dummy);
|
|
||||||
if constexpr (is_same_any_v<T, int, float, float3>) {
|
|
||||||
const VArray<T> values = g_values.typed<T>();
|
|
||||||
if (group_indices.is_single()) {
|
if (group_indices.is_single()) {
|
||||||
T accumulation = {};
|
T accumulation = T();
|
||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
accumulation = values[i] + accumulation;
|
accumulation = values[i] + accumulation;
|
||||||
}
|
}
|
||||||
g_outputs = VArray<T>::ForSingle(accumulation, domain_size);
|
return VArray<T>::ForSingle(accumulation, domain_size);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
Array<T> accumulations_out(domain_size);
|
||||||
Map<int, T> accumulations;
|
Map<int, T> accumulations;
|
||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
T &value = accumulations.lookup_or_add_default(group_indices[i]);
|
T &value = accumulations.lookup_or_add_default(group_indices[i]);
|
||||||
value = value + values[i];
|
value = value + values[i];
|
||||||
}
|
}
|
||||||
Array<T> outputs(domain_size);
|
|
||||||
for (const int i : values.index_range()) {
|
for (const int i : values.index_range()) {
|
||||||
outputs[i] = accumulations.lookup(group_indices[i]);
|
accumulations_out[i] = accumulations.lookup(group_indices[i]);
|
||||||
}
|
}
|
||||||
g_outputs = VArray<T>::ForContainer(std::move(outputs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return attributes.adapt_domain(std::move(g_outputs), source_domain_, context.domain());
|
return attributes.adapt_domain<T>(
|
||||||
|
VArray<T>::ForContainer(std::move(accumulations_out)), source_domain_, context.domain());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
@ -413,24 +391,25 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||||||
Field<int> group_index_field = params.extract_input<Field<int>>("Group Index");
|
Field<int> group_index_field = params.extract_input<Field<int>>("Group Index");
|
||||||
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
||||||
using T = decltype(dummy);
|
using T = decltype(dummy);
|
||||||
if constexpr (is_same_any_v<T, int, float, float3>) {
|
if constexpr (std::is_same_v<T, int> || std::is_same_v<T, float> ||
|
||||||
|
std::is_same_v<T, float3>) {
|
||||||
const std::string suffix = " " + identifier_suffix<T>();
|
const std::string suffix = " " + identifier_suffix<T>();
|
||||||
Field<T> input_field = params.extract_input<Field<T>>("Value" + suffix);
|
Field<T> input_field = params.extract_input<Field<T>>("Value" + suffix);
|
||||||
if (params.output_is_required("Leading" + suffix)) {
|
if (params.output_is_required("Leading" + suffix)) {
|
||||||
params.set_output(
|
params.set_output(
|
||||||
"Leading" + suffix,
|
"Leading" + suffix,
|
||||||
Field<T>{std::make_shared<AccumulateFieldInput>(
|
Field<T>{std::make_shared<AccumulateFieldInput<T>>(
|
||||||
source_domain, input_field, group_index_field, AccumulationMode::Leading)});
|
source_domain, input_field, group_index_field, AccumulationMode::Leading)});
|
||||||
}
|
}
|
||||||
if (params.output_is_required("Trailing" + suffix)) {
|
if (params.output_is_required("Trailing" + suffix)) {
|
||||||
params.set_output(
|
params.set_output(
|
||||||
"Trailing" + suffix,
|
"Trailing" + suffix,
|
||||||
Field<T>{std::make_shared<AccumulateFieldInput>(
|
Field<T>{std::make_shared<AccumulateFieldInput<T>>(
|
||||||
source_domain, input_field, group_index_field, AccumulationMode::Trailing)});
|
source_domain, input_field, group_index_field, AccumulationMode::Trailing)});
|
||||||
}
|
}
|
||||||
if (params.output_is_required("Total" + suffix)) {
|
if (params.output_is_required("Total" + suffix)) {
|
||||||
params.set_output("Total" + suffix,
|
params.set_output("Total" + suffix,
|
||||||
Field<T>{std::make_shared<TotalFieldInput>(
|
Field<T>{std::make_shared<TotalFieldInput<T>>(
|
||||||
source_domain, input_field, group_index_field)});
|
source_domain, input_field, group_index_field)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user