25#include "RNA_prototypes.hh"
37 if (!
U.experimental.use_bundle_and_closure_nodes) {
42 return ELEM(data_type,
65 if (
node ==
nullptr) {
73 if (supports_fields) {
74 menu.supports_field();
79 auto &
input =
b.add_input(data_type, enum_item.name, std::move(identifier))
83 if (supports_fields) {
84 input.supports_field();
90 auto &
output =
b.add_output(data_type,
"Output");
91 if (supports_fields) {
92 output.dependent_field().reference_pass_all();
98 b.add_input<
decl::Extend>(
"",
"__extend__").structure_type(StructureType::Dynamic);
110 data->enum_definition.next_identifier = 0;
111 data->enum_definition.items_array =
nullptr;
112 data->enum_definition.items_num = 0;
129 dst_node->
storage = dst_storage;
141 params.update_and_connect_available_socket(
node,
"Menu");
149 node_storage(
node).data_type =
params.socket.type;
150 params.update_and_connect_available_socket(
node,
"Output");
167 : enum_def_(enum_def), type_(type)
170 builder.single_input<
int>(
"Menu");
171 for (
const NodeEnumItem &enum_item : enum_def.items()) {
172 builder.single_input(enum_item.name, type);
174 builder.single_output(
"Output", type);
181 const int value_inputs_start = 1;
182 const int inputs_num = enum_def_.
items_num;
185 const int invalid_index = inputs_num;
188 signature_.
params.index_range().last(),
"Output");
190 auto find_item_index = [&](
const int value) ->
int {
191 for (
const int i : enum_def_.items().index_range()) {
197 return invalid_index;
201 const int index = find_item_index(*
value);
202 if (index < inputs_num) {
215 mask, memory, [&](
const int64_t i) {
return find_item_index(values[i]); }, masks);
218 if (!masks[i].is_empty()) {
231 bool can_be_field_ =
false;
234 const CPPType *field_base_type_;
239 : node_(
node), enum_def_(node_storage(
node).enum_definition)
251 lf_index_by_bsocket[
node.input_socket(0).index_in_tree()] =
inputs_.append_and_get_index_as(
253 for (
const int i : enum_def_.items().index_range()) {
255 lf_index_by_bsocket[
node.input_socket(i + 1).index_in_tree()] =
256 inputs_.append_and_get_index_as(enum_item.
name, *cpp_type_, lf::ValueUsage::Maybe);
258 lf_index_by_bsocket[
node.output_socket(0).index_in_tree()] =
outputs_.append_and_get_index_as(
259 "Value", *cpp_type_);
277 const int input_index = i + 1;
279 void *value_to_forward =
params.try_get_input_data_ptr_or_request(input_index);
280 if (value_to_forward ==
nullptr) {
285 void *output_ptr =
params.get_output_data_ptr(0);
290 params.set_input_unused(input_index);
301 const int values_num = this->enum_def_.
items_num;
304 const int input_index = i + 1;
307 if (input_values.
as_span().contains(
nullptr)) {
313 item_fields[0] = std::move(condition);
315 item_fields[i + 1] = input_values[i]->extract<
GField>();
317 std::unique_ptr<MultiFunction> multi_function = std::make_unique<MenuSwitchFn>(
318 enum_def_, *field_base_type_);
321 void *output_ptr =
params.get_output_data_ptr(0);
337 : enum_def_(node_storage(
node).enum_definition)
352 params.set_output(i,
true);
372 if (
uiLayout *panel = layout->
panel(C,
"menu_switch_items",
false,
IFACE_(
"Menu Items"))) {
379 panel->prop(item_ptr,
"description",
UI_ITEM_NONE, std::nullopt, ICON_NONE);
414 return &
node.input_socket(1);
470 using namespace node_geo_menu_switch_cc;
472 return std::make_unique<LazyFunctionForMenuSwitchNode>(
node, lf_graph_info);
477 using namespace node_geo_menu_switch_cc;
479 return std::make_unique<LazyFunctionForMenuSwitchSocketUsage>(
node);
#define NODE_CLASS_CONVERTER
#define NODE_STORAGE_FUNCS(StorageT)
#define GEO_NODE_MENU_SWITCH
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
Span< T > as_span() const
static const CPPType & get()
void fill_construct_indices(const void *value, void *dst, const IndexMask &mask) const
const void * default_value() const
void move_construct(void *src, void *dst) const
std::optional< T > get_if_single() 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)
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
bNodeSocketType * node_socket_type_find_static(int type, int subtype=0)
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void make_common_operators()
static void draw_items_list_with_operators(const bContext *C, uiLayout *layout, const bNodeTree &tree, const bNode &node)
static void draw_active_item_props(const bNodeTree &tree, const bNode &node, const FunctionRef< void(PointerRNA *item_ptr)> draw_item)
void blend_write(BlendWriter *writer, const bNode &node)
Accessor::ItemT * add_item_with_name(bNode &node, const char *name)
void destruct_array(bNode &node)
void blend_read_data(BlendDataReader *reader, 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, std::string idname, const std::optional< int16_t > legacy_type)
static blender::bke::bNodeSocketTemplate inputs[]
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
NodeInternallyLinkedInputFunction internally_linked_input
NodeBlendWriteFunction blend_write_storage_content
std::string ui_description
NodeBlendDataReadFunction blend_data_read_storage_content
void(* initfunc)(bNodeTree *ntree, bNode *node)
void(* draw_buttons_ex)(uiLayout *, bContext *C, PointerRNA *ptr)
const char * enum_name_legacy
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)()
bool ignore_inferred_input_socket_visibility
Vector< ParamInfo > params
Array< int > lf_index_by_bsocket
GeometryNodeLazyFunctionGraphMapping mapping
PanelLayout panel(const bContext *C, blender::StringRef idname, bool default_closed)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)