18 std::string value_in_description =
"The values to be accumulated";
19 std::string leading_out_description =
20 "The running total of values in the corresponding group, starting at the first value";
21 std::string trailing_out_description =
22 "The running total of values in the corresponding group, starting at zero";
23 std::string total_out_description =
"The total of all of the values in the corresponding group";
26 .default_value({1.0f, 1.0f, 1.0f})
40 N_(
"An index used to group values together for multiple separate accumulations"));
75 uiItemR(layout,
ptr,
"data_type", 0,
"", ICON_NONE);
76 uiItemR(layout,
ptr,
"domain", 0,
"", ICON_NONE);
128 switch (socket.
type) {
153 node_storage(
node).data_type = *
type;
154 params.update_and_connect_available_socket(
node,
"Leading");
161 node_storage(
node).data_type = *
type;
162 params.update_and_connect_available_socket(
node,
"Trailing");
169 node_storage(
node).data_type = *
type;
170 params.update_and_connect_available_socket(
node,
"Total");
179 node_storage(
node).data_type = *
type;
180 params.update_and_connect_available_socket(
node,
"Value");
188 node_storage(
node).data_type = *
type;
189 params.update_and_connect_available_socket(
node,
"Group Index");
209 group_index_(group_index),
210 source_domain_(source_domain),
211 accumulation_mode_(accumulation_mode)
220 const int domain_size =
component.attribute_domain_size(field_context.domain());
221 if (domain_size == 0) {
227 evaluator.
add(input_);
228 evaluator.add(group_index_);
229 evaluator.evaluate();
230 const VArray<T> values = evaluator.get_evaluated<
T>(0);
231 const VArray<int> group_indices = evaluator.get_evaluated<
int>(1);
233 Array<T> accumulations_out(domain_size);
235 if (group_indices.is_single()) {
236 T accumulation =
T();
239 accumulation = values[i] + accumulation;
240 accumulations_out[i] = accumulation;
245 accumulations_out[i] = accumulation;
246 accumulation = values[i] + accumulation;
255 accumulation_value += values[i];
256 accumulations_out[i] = accumulation_value;
262 accumulations_out[i] = accumulation_value;
263 accumulation_value += values[i];
281 return input_ == other_accumulate->input_ &&
282 group_index_ == other_accumulate->group_index_ &&
283 source_domain_ == other_accumulate->source_domain_ &&
284 accumulation_mode_ == other_accumulate->accumulation_mode_;
300 group_index_(group_index),
301 source_domain_(source_domain)
310 const int domain_size =
component.attribute_domain_size(field_context.domain());
311 if (domain_size == 0) {
317 evaluator.
add(input_);
318 evaluator.add(group_index_);
319 evaluator.evaluate();
320 const VArray<T> values = evaluator.get_evaluated<
T>(0);
321 const VArray<int> group_indices = evaluator.get_evaluated<
int>(1);
323 if (group_indices.is_single()) {
324 T accumulation =
T();
326 accumulation = values[i] + accumulation;
331 Array<T> accumulations_out(domain_size);
335 value = value + values[i];
338 accumulations_out[i] = accumulations.
lookup(group_indices[i]);
353 return input_ == other_field->input_ && group_index_ == other_field->group_index_ &&
354 source_domain_ == other_field->source_domain_;
362 if constexpr (std::is_same_v<T, int>) {
365 if constexpr (std::is_same_v<T, float>) {
368 if constexpr (std::is_same_v<T, float3>) {
381 using T = decltype(dummy);
382 if constexpr (std::is_same_v<T, int> || std::is_same_v<T, float> ||
383 std::is_same_v<T, float3>) {
384 const std::string suffix =
" " + identifier_suffix<T>();
386 if (
params.output_is_required(
"Leading" + suffix)) {
389 Field<T>{std::make_shared<AccumulateFieldInput<T>>(
392 if (
params.output_is_required(
"Trailing" + suffix)) {
395 Field<T>{std::make_shared<AccumulateFieldInput<T>>(
398 if (
params.output_is_required(
"Total" + suffix)) {
399 params.set_output(
"Total" + suffix,
400 Field<T>{std::make_shared<TotalFieldInput<T>>(
401 source_domain, input_field, group_index_field)});
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
#define NODE_CLASS_CONVERTER
#define NODE_STORAGE_FUNCS(StorageT)
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
#define GEO_NODE_ACCUMULATE_FIELD
void nodeRegisterType(struct bNodeType *ntype)
static uint8 component(Color32 c, uint i)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
const Value & lookup(const Key &key) const
Value & lookup_or_add_default(const Key &key)
IndexRange index_range() const
static VArray ForContainer(ContainerT container)
static VArray ForSingle(T value, const int64_t size)
GVArray adapt_domain(const GVArray &varray, const eAttrDomain from_domain, const eAttrDomain to_domain) const
int add(GField field, GVArray *varray_ptr)
StringRefNull description() const
ccl_global KernelShaderEvalInput * input
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
static void node_update(bNodeTree *ntree, bNode *node)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static std::optional< eCustomDataType > node_type_from_other_socket(const bNodeSocket &socket)
static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
std::string identifier_suffix()
static void node_geo_exec(GeoNodeExecParams params)
uint64_t get_default_hash_4(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
uint64_t get_default_hash_3(const T1 &v1, const T2 &v2, const T3 &v3)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
void register_node_type_geo_accumulate_field()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
void node_free_standard_storage(bNode *node)
unsigned __int64 uint64_t
struct bNodeSocket * next
NodeGeometryExecFunction geometry_node_execute
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
NodeDeclareFunction declare