27#include "RNA_prototypes.hh"
39 return ELEM(data_type,
58 const bNode *node =
b.node_or_null();
59 if (node ==
nullptr) {
67 if (supports_fields) {
68 menu.supports_field();
73 auto &input =
b.add_input(data_type, enum_item.name, std::move(identifier))
77 if (supports_fields) {
78 input.supports_field();
84 auto &output =
b.add_output(data_type,
"Output");
85 if (supports_fields) {
86 output.dependent_field().reference_pass_all();
89 output.propagate_all();
104 data->enum_definition.next_identifier = 0;
105 data->enum_definition.items_array =
nullptr;
106 data->enum_definition.items_num = 0;
107 node->storage =
data;
122 NodeMenuSwitch *dst_storage = MEM_cnew<NodeMenuSwitch>(__func__, src_storage);
123 dst_node->
storage = dst_storage;
134 bNode &node =
params.add_node(
"GeometryNodeMenuSwitch");
135 params.update_and_connect_available_socket(node,
"Menu");
142 bNode &node =
params.add_node(
"GeometryNodeMenuSwitch");
143 node_storage(node).data_type =
params.socket.type;
144 params.update_and_connect_available_socket(node,
"Output");
161 : enum_def_(enum_def), type_(type)
164 builder.single_input<
int>(
"Menu");
165 for (
const NodeEnumItem &enum_item : enum_def.items()) {
166 builder.single_input(enum_item.name, type);
168 builder.single_output(
"Output", type);
175 const int value_inputs_start = 1;
176 const int inputs_num = enum_def_.
items_num;
179 const int invalid_index = inputs_num;
182 signature_.
params.index_range().last(),
"Output");
184 auto find_item_index = [&](
const int value) ->
int {
185 for (
const int i : enum_def_.items().index_range()) {
191 return invalid_index;
194 if (
const std::optional<int> value = values.get_if_single()) {
195 const int index = find_item_index(*value);
196 if (index < inputs_num) {
197 const GVArray inputs =
params.readonly_single_input(value_inputs_start + index);
198 inputs.materialize_to_uninitialized(mask, output.data());
209 mask, memory, [&](
const int64_t i) {
return find_item_index(values[i]); }, masks);
212 if (!masks[i].is_empty()) {
213 const GVArray inputs =
params.readonly_single_input(value_inputs_start + i);
214 inputs.materialize_to_uninitialized(masks[i], output.data());
225 bool can_be_field_ =
false;
228 const CPPType *field_base_type_;
233 : node_(node), enum_def_(node_storage(node).enum_definition)
246 lf_index_by_bsocket[node.input_socket(0).index_in_tree()] =
inputs_.append_and_get_index_as(
248 for (
const int i : enum_def_.items().index_range()) {
250 lf_index_by_bsocket[node.input_socket(i + 1).index_in_tree()] =
251 inputs_.append_and_get_index_as(enum_item.
name, *cpp_type_, lf::ValueUsage::Maybe);
253 lf_index_by_bsocket[node.output_socket(0).index_in_tree()] =
outputs_.append_and_get_index_as(
254 "Value", *cpp_type_);
272 const int input_index = i + 1;
274 void *value_to_forward =
params.try_get_input_data_ptr_or_request(input_index);
275 if (value_to_forward ==
nullptr) {
280 void *output_ptr =
params.get_output_data_ptr(0);
285 params.set_input_unused(input_index);
296 const int values_num = this->enum_def_.
items_num;
299 const int input_index = i + 1;
302 if (input_values.
as_span().contains(
nullptr)) {
308 item_fields[0] = std::move(condition);
310 item_fields[i + 1] = input_values[i]->extract<
GField>();
312 std::unique_ptr<MultiFunction> multi_function = std::make_unique<MenuSwitchFn>(
313 enum_def_, *field_base_type_);
316 void *output_ptr =
params.get_output_data_ptr(0);
332 : enum_def_(node_storage(node).enum_definition)
347 params.set_output(i,
true);
351 const int32_t value = condition_variant.
get<
int>();
379 static const uiListType *menu_items_list = []() {
380 uiListType *list = MEM_cnew<uiListType>(__func__);
381 STRNCPY(list->idname,
"NODE_UL_enum_definition_items");
409 uiItemO(add_remove_col,
"", ICON_ADD,
"node.enum_definition_item_add");
410 uiItemO(add_remove_col,
"", ICON_REMOVE,
"node.enum_definition_item_remove");
415 up_down_col,
"node.enum_definition_item_move",
"", ICON_TRIA_UP,
"direction", 0);
417 up_down_col,
"node.enum_definition_item_move",
"", ICON_TRIA_DOWN,
"direction", 1);
421 auto &storage = node_storage(node);
422 if (storage.enum_definition.active_index >= 0 &&
423 storage.enum_definition.active_index < storage.enum_definition.items_num)
426 storage.enum_definition.items_array[storage.enum_definition.active_index];
439 ot,
"Add Menu Item", __func__,
"Add menu item");
445 ot,
"Remove Menu Item", __func__,
"Remove active menu item");
451 ot,
"Move Menu Item", __func__,
"Move active menu item");
464 *ntree, *node, *node, *link);
512 using namespace node_geo_menu_switch_cc;
513 BLI_assert(node.type == GEO_NODE_MENU_SWITCH);
514 return std::make_unique<LazyFunctionForMenuSwitchNode>(node, lf_graph_info);
519 using namespace node_geo_menu_switch_cc;
520 BLI_assert(node.type == GEO_NODE_MENU_SWITCH);
521 return std::make_unique<LazyFunctionForMenuSwitchSocketUsage>(node);
#define GEO_NODE_MENU_SWITCH
#define NODE_CLASS_CONVERTER
#define NODE_STORAGE_FUNCS(StorageT)
#define STRNCPY(dst, src)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#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)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value)
void uiTemplateList(uiLayout *layout, const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags)
PanelLayout uiLayoutPanel(const bContext *C, uiLayout *layout, const char *idname, bool default_closed)
void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
@ UI_TEMPLATE_LIST_FLAG_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
Span< T > as_span() const
void fill_construct_indices(const void *value, void *dst, const IndexMask &mask) const
static const CPPType & get()
const void * default_value() const
void move_construct(void *src, void *dst) const
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)
local_group_size(16, 16) .push_constant(Type b
void MEM_freeN(void *vmemh)
bNodeSocketType * node_socket_type_find(const char *idname)
const char * node_static_socket_type(int type, int subtype)
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)
void move_active_item(wmOperatorType *ot, const char *name, const char *idname, const char *description)
void remove_active_item(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)
Accessor::ItemT * add_item_with_name(bNode &node, const char *name)
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)
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)
std::unique_ptr< LazyFunction > get_menu_switch_node_socket_usage_lazy_function(const bNode &node)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
void set_default_remaining_node_outputs(lf::Params ¶ms, const bNode &node)
std::unique_ptr< LazyFunction > get_menu_switch_node_lazy_function(const bNode &node, GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
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)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
const EnumPropertyItem rna_enum_node_socket_data_type_items[]
NodeEnumItem * items_array
const blender::CPPType * geometry_nodes_cpp_type
const blender::CPPType * base_cpp_type
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
char idname[BKE_ST_MAXNAME]
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
bool WM_uilisttype_add(uiListType *ult)