Blender V4.5
node_geo_separate_bundle.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "NOD_geo_bundle.hh"
11
12#include "BLO_read_write.hh"
13
15
16#include "UI_interface.hh"
17
18#include <fmt/format.h>
19
21
23
25{
26 b.add_input<decl::Bundle>("Bundle");
27 const bNodeTree *tree = b.tree_or_null();
28 const bNode *node = b.node_or_null();
29 if (tree && node) {
30 const NodeGeometrySeparateBundle &storage = node_storage(*node);
31 for (const int i : IndexRange(storage.items_num)) {
32 const NodeGeometrySeparateBundleItem &item = storage.items[i];
33 const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
34 const StringRef name = item.name ? item.name : "";
35 const std::string identifier = SeparateBundleItemsAccessor::socket_identifier_for_item(item);
36 b.add_output(socket_type, name, identifier)
37 .socket_name_ptr(&tree->id, SeparateBundleItemsAccessor::item_srna, &item, "name")
38 .propagate_all()
39 .reference_pass_all();
40 }
41 }
42 b.add_output<decl::Extend>("", "__extend__");
43}
44
45static void node_init(bNodeTree * /*tree*/, bNode *node)
46{
47 auto *storage = MEM_callocN<NodeGeometrySeparateBundle>(__func__);
48 node->storage = storage;
49}
50
51static void node_copy_storage(bNodeTree * /*dst_tree*/, bNode *dst_node, const bNode *src_node)
52{
53 const NodeGeometrySeparateBundle &src_storage = node_storage(*src_node);
54 auto *dst_storage = MEM_dupallocN<NodeGeometrySeparateBundle>(__func__, src_storage);
55 dst_node->storage = dst_storage;
56
58}
59
65
71
72static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *node_ptr)
73{
74 bNodeTree &ntree = *reinterpret_cast<bNodeTree *>(node_ptr->owner_id);
75 bNode &node = *static_cast<bNode *>(node_ptr->data);
76
77 if (uiLayout *panel = layout->panel(C, "bundle_items", false, TIP_("Bundle Items"))) {
79 C, panel, ntree, node);
81 ntree, node, [&](PointerRNA *item_ptr) {
82 panel->prop(item_ptr, "socket_type", UI_ITEM_NONE, "Type", ICON_NONE);
83 });
84 }
85}
86
91
93{
94 if (!U.experimental.use_bundle_and_closure_nodes) {
95 params.set_default_remaining_outputs();
96 return;
97 }
98
99 nodes::BundlePtr bundle = params.extract_input<nodes::BundlePtr>("Bundle");
100 if (!bundle) {
101 params.set_default_remaining_outputs();
102 return;
103 }
104
105 const bNode &node = params.node();
106 const NodeGeometrySeparateBundle &storage = node_storage(node);
107
108 lf::Params &lf_params = params.low_level_lazy_function_params();
109
110 for (const int i : IndexRange(storage.items_num)) {
111 const NodeGeometrySeparateBundleItem &item = storage.items[i];
112 const StringRef name = item.name;
113 if (name.is_empty()) {
114 continue;
115 }
117 if (!stype || !stype->geometry_nodes_cpp_type) {
118 continue;
119 }
120 const std::optional<Bundle::Item> value = bundle->lookup(SocketInterfaceKey(name));
121 if (!value) {
122 params.error_message_add(NodeWarningType::Error,
123 fmt::format(fmt::runtime(TIP_("Value not found: \"{}\"")), name));
124 continue;
125 }
126 void *output_ptr = lf_params.get_output_data_ptr(i);
127 if (!implicitly_convert_socket_value(*value->type, value->value, *stype, output_ptr)) {
128 construct_socket_default_value(*stype, output_ptr);
129 }
130 lf_params.output_set(i);
131 }
132
133 params.set_default_remaining_outputs();
134}
135
136static void node_blend_write(const bNodeTree & /*tree*/, const bNode &node, BlendWriter &writer)
137{
139}
140
141static void node_blend_read(bNodeTree & /*tree*/, bNode &node, BlendDataReader &reader)
142{
144}
145
146static void node_register()
147{
148 static blender::bke::bNodeType ntype;
149
150 geo_node_type_base(&ntype, "GeometryNodeSeparateBundle", GEO_NODE_SEPARATE_BUNDLE);
151 ntype.ui_name = "Separate Bundle";
152 ntype.ui_description = "Split a bundle into multiple sockets.";
154 ntype.declare = node_declare;
155 ntype.initfunc = node_init;
163 ntype, "NodeGeometrySeparateBundle", node_free_storage, node_copy_storage);
165}
167
168} // namespace blender::nodes::node_geo_separate_bundle_cc
169
170namespace blender::nodes {
171
172StructRNA *SeparateBundleItemsAccessor::item_srna = &RNA_NodeGeometrySeparateBundleItem;
173
175{
176 BLO_write_string(writer, item.name);
177}
178
183
184} // namespace blender::nodes
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:439
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1215
#define GEO_NODE_SEPARATE_BUNDLE
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
Definition readfile.cc:5351
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define TIP_(msgid)
eNodeSocketDatatype
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define C
Definition RandGen.cpp:29
#define UI_ITEM_NONE
#define U
constexpr bool is_empty() const
KDTree_3d * tree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void node_register_type(bNodeType &ntype)
Definition node.cc:2748
bNodeSocketType * node_socket_type_find_static(int type, int subtype=0)
Definition node.cc:2803
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))
Definition node.cc:5603
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
static void node_blend_write(const bNodeTree &, const bNode &node, BlendWriter &writer)
static void node_init(bNodeTree *, bNode *node)
static void node_layout_ex(uiLayout *layout, bContext *C, PointerRNA *node_ptr)
static bool node_insert_link(bNodeTree *tree, bNode *node, bNodeLink *link)
static void node_copy_storage(bNodeTree *, bNode *dst_node, const bNode *src_node)
static void node_blend_read(bNodeTree &, bNode &node, BlendDataReader &reader)
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)
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)
ImplicitSharingPtr< Bundle > BundlePtr
bool implicitly_convert_socket_value(const bke::bNodeSocketType &from_type, const void *from_value, const bke::bNodeSocketType &to_type, void *r_to_value)
void construct_socket_default_value(const bke::bNodeSocketType &stype, void *r_value)
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
NodeGeometrySeparateBundleItem * items
ID * owner_id
Definition RNA_types.hh:51
void * data
Definition RNA_types.hh:53
void * storage
Defines a socket type.
Definition BKE_node.hh:152
const blender::CPPType * geometry_nodes_cpp_type
Definition BKE_node.hh:203
Defines a node type.
Definition BKE_node.hh:226
NodeBlendWriteFunction blend_write_storage_content
Definition BKE_node.hh:383
std::string ui_description
Definition BKE_node.hh:232
NodeBlendDataReadFunction blend_data_read_storage_content
Definition BKE_node.hh:384
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
void(* draw_buttons_ex)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:249
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:347
bool(* insert_link)(bNodeTree *ntree, bNode *node, bNodeLink *link)
Definition BKE_node.hh:321
NodeDeclareFunction declare
Definition BKE_node.hh:355
void(* register_operators)()
Definition BKE_node.hh:410
static void blend_write_item(BlendWriter *writer, const ItemT &item)
static void blend_read_data_item(BlendDataReader *reader, ItemT &item)
static std::string socket_identifier_for_item(const ItemT &item)
PanelLayout panel(const bContext *C, blender::StringRef idname, bool default_closed)
i
Definition text_draw.cc:230