17#include "RNA_prototypes.hh"
29 const bNode *node =
b.node_or_null();
38 auto &index =
b.add_input<
decl::Int>(
"Index").
min(0).max(std::max<int>(0, items.
size() - 1));
39 if (supports_fields) {
40 index.supports_field();
45 auto &input =
b.add_input(data_type, std::to_string(i), std::move(identifier));
46 if (supports_fields) {
47 input.supports_field();
53 auto &output =
b.add_output(data_type,
"Output");
54 if (supports_fields) {
55 output.dependent_field().reference_pass_all();
58 output.propagate_all();
74 uiItemO(panel,
IFACE_(
"Add Item"), ICON_ADD,
"node.index_switch_item_add");
78 uiItemL(row, node.input_socket(i + 1).name, ICON_NONE);
79 uiItemIntO(row,
"", ICON_REMOVE,
"node.index_switch_item_remove",
"index", i);
92 ot,
"Remove Item", __func__,
"Remove an item from the index switch");
105 data->next_identifier = 0;
108 const int default_items_num = 2;
109 data->items = MEM_cnew_array<IndexSwitchItem>(default_items_num, __func__);
110 for (
const int i :
IndexRange(default_items_num)) {
111 data->items[i].identifier = data->next_identifier++;
113 data->items_num = default_items_num;
115 node->storage =
data;
122 bNode &node =
params.add_node(
"GeometryNodeIndexSwitch");
123 node_storage(node).data_type =
params.socket.type;
124 params.update_and_connect_available_socket(node,
"Output");
129 if (
params.node_tree().typeinfo->validate_link(other_type,
SOCK_INT)) {
131 bNode &node =
params.add_node(
"GeometryNodeIndexSwitch");
132 params.update_and_connect_available_socket(node,
"Index");
148 builder.single_input<
int>(
"Index");
151 debug_names_[i] = std::to_string(i);
152 builder.single_input(debug_names_[i].c_str(), type);
154 builder.single_output(
"Output", type);
160 const int inputs_num = signature_.
params.size() - 2;
164 signature_.
params.index_range().last(),
"Output");
165 const CPPType &type = output.type();
167 if (
const std::optional<int> i = indices.get_if_single()) {
170 inputs.materialize_to_uninitialized(mask, output.data());
173 type.fill_construct_indices(type.default_value(), output.data(),
mask);
179 const int invalid_index = inputs_num;
186 const int index = indices[i];
192 if (!masks[i].is_empty()) {
194 inputs.materialize_to_uninitialized(masks[i], output.data());
198 type.fill_construct_indices(type.default_value(), output.data(), masks[invalid_index]);
212 bool can_be_field_ =
false;
213 const CPPType *field_base_type_;
222 const bNodeSocket &index_socket = node.input_socket(0);
223 const bNodeSocket &output_socket = node.output_socket(0);
224 const CPPType &cpp_type = *output_socket.
typeinfo->geometry_nodes_cpp_type;
228 field_base_type_ = output_socket.
typeinfo->base_cpp_type;
232 lf_index_by_bsocket[index_socket.index_in_tree()] =
inputs_.append_and_get_index_as(
234 lf_index_by_bsocket[output_socket.index_in_tree()] =
outputs_.append_and_get_index_as(
237 for (
const int i : storage.items_span().index_range()) {
239 lf_index_by_bsocket[input.index_in_tree()] =
inputs_.append_and_get_index_as(
240 input.identifier, cpp_type, lf::ValueUsage::Maybe);
277 if (value_to_forward ==
nullptr) {
282 void *output_ptr =
params.get_output_data_ptr(0);
283 type.move_construct(value_to_forward, output_ptr);
295 if (input_values.
as_span().contains(
nullptr)) {
305 std::unique_ptr<mf::MultiFunction> switch_fn = std::make_unique<IndexSwitchFunction>(
309 void *output_ptr =
params.get_output_data_ptr(0);
357 auto *dst_storage = MEM_cnew<NodeIndexSwitch>(__func__, src_storage);
358 dst_node->
storage = dst_storage;
366 *ntree, *node, *node, *link);
395 using namespace node_geo_index_switch_cc;
396 BLI_assert(node.type == GEO_NODE_INDEX_SWITCH);
397 return std::make_unique<LazyFunctionForIndexSwitchNode>(node, lf_graph_info);
405 const auto &storage = *
static_cast<const NodeIndexSwitch *
>(node.storage);
#define NODE_CLASS_CONVERTER
#define NODE_STORAGE_FUNCS(StorageT)
#define GEO_NODE_INDEX_SWITCH
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
void uiItemL(uiLayout *layout, const char *name, int icon)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
PanelLayout uiLayoutPanel(const bContext *C, uiLayout *layout, const char *idname, bool default_closed)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
__forceinline float extract(const int4 &b)
Span< T > as_span() const
void reinitialize(const int64_t new_size)
static const CPPType & get()
constexpr bool contains(int64_t value) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void append(const T &value)
bool is_context_dependent_field() const
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
Vector< Output > outputs_
void set_signature(const Signature *signature)
static void from_groups(const IndexMask &universe, IndexMaskMemory &memory, Fn &&get_group_index, MutableSpan< IndexMask > r_masks)
IndexSwitchFunction(const CPPType &type, const int items_num)
ExecutionHints get_execution_hints() const override
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
void execute_single(const int index, lf::Params ¶ms) const
void execute_field(Field< int > index, lf::Params ¶ms) const
LazyFunctionForIndexSwitchNode(const bNode &node, GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
void execute_impl(lf::Params ¶ms, const lf::Context &) const override
local_group_size(16, 16) .push_constant(Type b
void MEM_freeN(void *vmemh)
ccl_device_inline float4 mask(const int4 mask, const float4 a)
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void node_register_type(bNodeType *ntype)
static void node_copy_storage(bNodeTree *, bNode *dst_node, const bNode *src_node)
static void node_init(bNodeTree *, bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
static void NODE_OT_index_switch_item_add(wmOperatorType *ot)
static void NODE_OT_index_switch_item_remove(wmOperatorType *ot)
static void node_declare(NodeDeclarationBuilder &b)
static void register_node()
static void node_rna(StructRNA *srna)
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_operators()
constexpr int value_inputs_start
static void node_free_storage(bNode *node)
static bool node_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link)
void remove_item_by_index(wmOperatorType *ot, const char *name, const char *idname, const char *description)
void add_item(wmOperatorType *ot, const char *name, const char *idname, const char *description)
void destruct_array(bNode &node)
void copy_array(const bNode &src_node, bNode &dst_node)
bool try_add_item_via_any_extend_socket(bNodeTree &ntree, bNode &extend_node, bNode &storage_node, bNodeLink &link, const std::optional< StringRef > socket_identifier=std::nullopt)
std::unique_ptr< LazyFunction > get_index_switch_node_lazy_function(const bNode &node, GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
void set_default_remaining_node_outputs(lf::Params ¶ms, const bNode &node)
const EnumPropertyItem * enum_items_filter(const EnumPropertyItem *original_item_array, FunctionRef< bool(const EnumPropertyItem &item)> fn)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
const EnumPropertyItem rna_enum_node_socket_data_type_items[]
bNodeSocketTypeHandle * typeinfo
void(* initfunc)(bNodeTree *ntree, bNode *node)
void(* draw_buttons_ex)(uiLayout *, bContext *C, PointerRNA *ptr)
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
bool(* insert_link)(bNodeTree *ntree, bNode *node, bNodeLink *link)
NodeDeclareFunction declare
void(* register_operators)()
Vector< ParamInfo > params
Array< int > lf_index_by_bsocket
GeometryNodeLazyFunctionGraphMapping mapping
static void blend_write(BlendWriter *writer, const bNode &node)
static StructRNA * item_srna
static std::string socket_identifier_for_item(const IndexSwitchItem &item)
static void blend_read_data(BlendDataReader *reader, bNode &node)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))