Blender  V3.3
node_geo_field_at_index.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "node_geometry_util.hh"
4 
5 #include "UI_interface.h"
6 #include "UI_resources.h"
7 
8 #include "BKE_attribute_math.hh"
9 
10 #include "BLI_task.hh"
11 
13 
15 
17 {
18  b.add_input<decl::Int>(N_("Index")).min(0).supports_field();
19 
20  b.add_input<decl::Float>(N_("Value"), "Value_Float").hide_value().supports_field();
21  b.add_input<decl::Int>(N_("Value"), "Value_Int").hide_value().supports_field();
22  b.add_input<decl::Vector>(N_("Value"), "Value_Vector").hide_value().supports_field();
23  b.add_input<decl::Color>(N_("Value"), "Value_Color").hide_value().supports_field();
24  b.add_input<decl::Bool>(N_("Value"), "Value_Bool").hide_value().supports_field();
25 
26  b.add_output<decl::Float>(N_("Value"), "Value_Float").field_source();
27  b.add_output<decl::Int>(N_("Value"), "Value_Int").field_source();
28  b.add_output<decl::Vector>(N_("Value"), "Value_Vector").field_source();
29  b.add_output<decl::Color>(N_("Value"), "Value_Color").field_source();
30  b.add_output<decl::Bool>(N_("Value"), "Value_Bool").field_source();
31 }
32 
33 static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
34 {
35  uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
36  uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
37 }
38 
40 {
41  node->custom1 = ATTR_DOMAIN_POINT;
42  node->custom2 = CD_PROP_FLOAT;
43 }
44 
46 {
47  const eCustomDataType data_type = static_cast<eCustomDataType>(node->custom2);
48 
49  bNodeSocket *sock_index = static_cast<bNodeSocket *>(node->inputs.first);
50  bNodeSocket *sock_in_float = sock_index->next;
51  bNodeSocket *sock_in_int = sock_in_float->next;
52  bNodeSocket *sock_in_vector = sock_in_int->next;
53  bNodeSocket *sock_in_color = sock_in_vector->next;
54  bNodeSocket *sock_in_bool = sock_in_color->next;
55 
56  bNodeSocket *sock_out_float = static_cast<bNodeSocket *>(node->outputs.first);
57  bNodeSocket *sock_out_int = sock_out_float->next;
58  bNodeSocket *sock_out_vector = sock_out_int->next;
59  bNodeSocket *sock_out_color = sock_out_vector->next;
60  bNodeSocket *sock_out_bool = sock_out_color->next;
61 
62  nodeSetSocketAvailability(ntree, sock_in_float, data_type == CD_PROP_FLOAT);
63  nodeSetSocketAvailability(ntree, sock_in_int, data_type == CD_PROP_INT32);
64  nodeSetSocketAvailability(ntree, sock_in_vector, data_type == CD_PROP_FLOAT3);
65  nodeSetSocketAvailability(ntree, sock_in_color, data_type == CD_PROP_COLOR);
66  nodeSetSocketAvailability(ntree, sock_in_bool, data_type == CD_PROP_BOOL);
67 
68  nodeSetSocketAvailability(ntree, sock_out_float, data_type == CD_PROP_FLOAT);
69  nodeSetSocketAvailability(ntree, sock_out_int, data_type == CD_PROP_INT32);
70  nodeSetSocketAvailability(ntree, sock_out_vector, data_type == CD_PROP_FLOAT3);
71  nodeSetSocketAvailability(ntree, sock_out_color, data_type == CD_PROP_COLOR);
72  nodeSetSocketAvailability(ntree, sock_out_bool, data_type == CD_PROP_BOOL);
73 }
74 
76 {
77  const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
78  search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
79 
80  const bNodeType &node_type = params.node_type();
81  const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
82  (eNodeSocketDatatype)params.other_socket().type);
83  if (type && *type != CD_PROP_STRING) {
84  params.add_item(IFACE_("Value"), [node_type, type](LinkSearchOpParams &params) {
85  bNode &node = params.add_node(node_type);
86  node.custom2 = *type;
87  params.update_and_connect_available_socket(node, "Value");
88  });
89  }
90 }
91 
93  private:
94  Field<int> index_field_;
95  GField value_field_;
96  eAttrDomain value_field_domain_;
97 
98  public:
99  FieldAtIndex(Field<int> index_field, GField value_field, eAttrDomain value_field_domain)
100  : GeometryFieldInput(value_field.cpp_type(), "Field at Index"),
101  index_field_(std::move(index_field)),
102  value_field_(std::move(value_field)),
103  value_field_domain_(value_field_domain)
104  {
105  }
106 
108  const eAttrDomain domain,
109  IndexMask mask) const final
110  {
111  const GeometryComponentFieldContext value_field_context{component, value_field_domain_};
112  FieldEvaluator value_evaluator{value_field_context,
113  component.attribute_domain_size(value_field_domain_)};
114  value_evaluator.add(value_field_);
115  value_evaluator.evaluate();
116  const GVArray &values = value_evaluator.get_evaluated(0);
117 
118  const GeometryComponentFieldContext index_field_context{component, domain};
119  FieldEvaluator index_evaluator{index_field_context, &mask};
120  index_evaluator.add(index_field_);
121  index_evaluator.evaluate();
122  const VArray<int> indices = index_evaluator.get_evaluated<int>(0);
123 
124  GVArray output_array;
126  using T = decltype(dummy);
127  Array<T> dst_array(mask.min_array_size());
128  VArray<T> src_values = values.typed<T>();
129  threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
130  for (const int i : mask.slice(range)) {
131  const int index = indices[i];
132  if (index >= 0 && index < src_values.size()) {
133  dst_array[i] = src_values[index];
134  }
135  else {
136  dst_array[i] = {};
137  }
138  }
139  });
140  output_array = VArray<T>::ForContainer(std::move(dst_array));
141  });
142 
143  return output_array;
144  }
145 };
146 
148 {
149  switch (data_type) {
150  case CD_PROP_BOOL:
151  return "Bool";
152  case CD_PROP_FLOAT:
153  return "Float";
154  case CD_PROP_INT32:
155  return "Int";
156  case CD_PROP_COLOR:
157  return "Color";
158  case CD_PROP_FLOAT3:
159  return "Vector";
160  default:
162  return "";
163  }
164 }
165 
167 {
168  const bNode &node = params.node();
169  const eAttrDomain domain = static_cast<eAttrDomain>(node.custom1);
170  const eCustomDataType data_type = static_cast<eCustomDataType>(node.custom2);
171 
172  Field<int> index_field = params.extract_input<Field<int>>("Index");
173  attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
174  using T = decltype(dummy);
175  static const std::string identifier = "Value_" + identifier_suffix(data_type);
176  Field<T> value_field = params.extract_input<Field<T>>(identifier);
177  Field<T> output_field{
178  std::make_shared<FieldAtIndex>(std::move(index_field), std::move(value_field), domain)};
179  params.set_output(identifier, std::move(output_field));
180  });
181 }
182 
183 } // namespace blender::nodes::node_geo_field_at_index_cc
184 
186 {
187  namespace file_ns = blender::nodes::node_geo_field_at_index_cc;
188 
189  static bNodeType ntype;
190 
198  nodeRegisterType(&ntype);
199 }
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
#define NODE_CLASS_CONVERTER
Definition: BKE_node.h:351
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
#define GEO_NODE_FIELD_AT_INDEX
Definition: BKE_node.h:1489
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define final(a, b, c)
Definition: BLI_hash.h:21
#define UNUSED(x)
#define IFACE_(msgid)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
eCustomDataType
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_PROP_COLOR
@ CD_PROP_INT32
@ CD_PROP_BOOL
@ CD_PROP_STRING
eNodeSocketDatatype
_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)
VArray< T > typed() const
static VArray ForContainer(ContainerT container)
const CPPType * type_
Definition: FN_field.hh:253
const CPPType & cpp_type() const
Definition: FN_field.hh:663
Span< SocketDeclarationPtr > inputs() const
FieldAtIndex(Field< int > index_field, GField value_field, eAttrDomain value_field_domain)
GVArray get_varray_for_context(const GeometryComponent &component, const eAttrDomain domain, IndexMask mask) const final
OperationNode * node
void * tree
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_gpu_kernel_postfix int ccl_global int * indices
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define T
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
static StringRefNull identifier_suffix(eCustomDataType data_type)
static void node_update(bNodeTree *ntree, bNode *node)
static void node_geo_exec(GeoNodeExecParams params)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_gather_link_searches(GatherLinkSearchOpParams &params)
std::optional< eCustomDataType > node_data_type_to_custom_data_type(const eNodeSocketDatatype type)
void search_link_ops_for_declarations(GatherLinkSearchOpParams &params, Span< SocketDeclarationPtr > declarations)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:1082
void register_node_type_geo_field_at_index()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
#define min(a, b)
Definition: sort.c:35
struct bNodeSocket * next
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition: BKE_node.h:335
void(* updatefunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:265
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
void(* initfunc)(struct bNodeTree *ntree, struct bNode *node)
Definition: BKE_node.h:270
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480