Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <optional>
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "NOD_geo_simulation.hh"
#include "NOD_socket_items.hh"
#include "RNA_access.hh"
#include "BLI_index_range.hh"
namespace blender {
struct NodesModifierData;
struct NodesModifierBake;
struct SpaceNode;
struct Object;
namespace nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for index
* bake node items.
*/
struct BakeItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeGeometryBakeItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeBake";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_bake_node_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_bake_node_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_bake_node_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_bake_node_items";
};
struct rna_names {
static constexpr StringRefNull items = "bake_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeGeometryBakeItem> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometryBake *>(node.storage);
return {&storage->items, &storage->items_num, &storage->active_index};
}
static void copy_item(const NodeGeometryBakeItem &src, NodeGeometryBakeItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(NodeGeometryBakeItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const NodeGeometryBakeItem &item)
{
return item.socket_type;
}
static char **get_name(NodeGeometryBakeItem &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return SimulationItemsAccessor::supports_socket_type(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
NodeGeometryBakeItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryBake *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<BakeItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const NodeGeometryBakeItem &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
struct BakeDrawContext {
const bNode *node;
SpaceNode *snode;
const Object *object;
const NodesModifierData *nmd;
const NodesModifierBake *bake;
PointerRNA bake_rna;
std::optional<IndexRange> baked_range;
std::optional<IndexRange> frame_range;
bool bake_still;
bool is_baked;
std::optional<NodesModifierBakeTarget> bake_target;
bool is_bakeable_in_current_context;
};
[[nodiscard]] bool get_bake_draw_context(const bContext *C,
const bNode &node,
BakeDrawContext &r_ctx);
std::string get_baked_string(const BakeDrawContext &ctx);
std::optional<std::string> get_bake_state_string(const BakeDrawContext &ctx);
void draw_common_bake_settings(bContext *C, BakeDrawContext &ctx, ui::Layout &layout);
void draw_bake_button_row(const BakeDrawContext &ctx,
ui::Layout &layout,
bool is_in_sidebar = false);
} // namespace nodes
} // namespace blender

View File

@@ -0,0 +1,176 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
inline bool socket_type_supported_in_bundle(const eNodeSocketDatatype socket_type,
const int ntree_type)
{
return bke::node_tree_type_supports_socket_type_static(ntree_type, socket_type);
}
struct CombineBundleItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeCombineBundleItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "NodeCombineBundle";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
static constexpr bool has_name_validation = true;
static constexpr char unique_name_separator = '_';
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_combine_bundle_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_combine_bundle_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_combine_bundle_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_combine_bundle_items";
};
struct rna_names {
static constexpr StringRefNull items = "bundle_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeCombineBundle *>(node.storage);
return {&storage->items, &storage->items_num, &storage->active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return socket_type_supported_in_bundle(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeCombineBundle *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<CombineBundleItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Item_" + std::to_string(item.identifier);
}
static std::string validate_name(const StringRef name);
};
struct SeparateBundleItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeSeparateBundleItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "NodeSeparateBundle";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
static constexpr bool has_name_validation = true;
static constexpr char unique_name_separator = '_';
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_separate_bundle_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_separate_bundle_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_separate_bundle_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_separate_bundle_items";
};
struct rna_names {
static constexpr StringRefNull items = "bundle_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeSeparateBundle *>(node.storage);
return {&storage->items, &storage->items_num, &storage->active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return socket_type_supported_in_bundle(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeSeparateBundle *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<SeparateBundleItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Item_" + std::to_string(item.identifier);
}
static std::string validate_name(const StringRef name)
{
return CombineBundleItemsAccessor::validate_name(name);
}
};
std::optional<StringRefNull> combine_bundle_node_type(const bNodeTree &tree, const bNode &node);
} // namespace blender::nodes

View File

@@ -0,0 +1,105 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
#include "BKE_customdata.hh"
namespace blender::nodes {
struct CaptureAttributeItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeGeometryAttributeCaptureItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeCaptureAttribute";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
static constexpr bool has_single_identifier_str = false;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_capture_attribute_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_capture_attribute_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_capture_attribute_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "NODE_UL_capture_items_list";
};
struct rna_names {
static constexpr StringRefNull items = "capture_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeGeometryAttributeCaptureItem> get_items_from_node(
bNode &node)
{
auto *storage = static_cast<NodeGeometryAttributeCapture *>(node.storage);
return {&storage->capture_items, &storage->capture_items_num, &storage->active_index};
}
static void copy_item(const NodeGeometryAttributeCaptureItem &src,
NodeGeometryAttributeCaptureItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(NodeGeometryAttributeCaptureItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const NodeGeometryAttributeCaptureItem &item)
{
return *bke::custom_data_type_to_socket_type(eCustomDataType(item.data_type));
}
static char **get_name(NodeGeometryAttributeCaptureItem &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
return bke::socket_type_to_custom_data_type(socket_type).has_value() &&
socket_type != SOCK_STRING;
}
static void init_with_socket_type_and_name(bNode &node,
NodeGeometryAttributeCaptureItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryAttributeCapture *>(node.storage);
item.data_type = *bke::socket_type_to_custom_data_type(socket_type);
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<CaptureAttributeItemsAccessor>(node, item, name);
}
static std::string input_socket_identifier_for_item(const NodeGeometryAttributeCaptureItem &item)
{
if (item.identifier == 0) {
/* This special case exists for compatibility. */
return "Value";
}
return "Value_" + std::to_string(item.identifier);
}
static std::string output_socket_identifier_for_item(
const NodeGeometryAttributeCaptureItem &item)
{
if (item.identifier == 0) {
/* This special case exists for compatibility. */
return "Attribute";
}
return "Attribute_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,325 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
#include "BKE_node.hh"
namespace blender::nodes {
inline bool socket_type_supported_in_closure(const eNodeSocketDatatype socket_type,
const int ntree_type)
{
return bke::node_tree_type_supports_socket_type_static(ntree_type, socket_type);
}
struct ClosureInputItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeClosureInputItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "NodeClosureOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_closure_input_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_closure_input_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_closure_input_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_closure_input_items";
};
struct rna_names {
static constexpr StringRefNull items = "input_items";
static constexpr StringRefNull active_index = "active_input_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeClosureOutput *>(node.storage);
return {&storage->input_items.items,
&storage->input_items.items_num,
&storage->input_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return socket_type_supported_in_closure(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeClosureOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->input_items.next_identifier++;
socket_items::set_item_name_and_make_unique<ClosureInputItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
struct ClosureOutputItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeClosureOutputItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "NodeClosureOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_closure_output_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_closure_output_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_closure_output_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_closure_output_items";
};
struct rna_names {
static constexpr StringRefNull items = "output_items";
static constexpr StringRefNull active_index = "active_output_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeClosureOutput *>(node.storage);
return {&storage->output_items.items,
&storage->output_items.items_num,
&storage->output_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return socket_type_supported_in_closure(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeClosureOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->output_items.next_identifier++;
socket_items::set_item_name_and_make_unique<ClosureOutputItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
struct EvaluateClosureInputItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeEvaluateClosureInputItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "NodeEvaluateClosure";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_evaluate_closure_input_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_evaluate_closure_input_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_evaluate_closure_input_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_evaluate_closure_input_items";
};
struct rna_names {
static constexpr StringRefNull items = "input_items";
static constexpr StringRefNull active_index = "active_input_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeEvaluateClosure *>(node.storage);
return {&storage->input_items.items,
&storage->input_items.items_num,
&storage->input_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return socket_type_supported_in_closure(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeEvaluateClosure *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->input_items.next_identifier++;
socket_items::set_item_name_and_make_unique<EvaluateClosureInputItemsAccessor>(
node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
struct EvaluateClosureOutputItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeEvaluateClosureOutputItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "NodeEvaluateClosure";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_evaluate_closure_output_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_evaluate_closure_output_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_evaluate_closure_output_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_evaluate_closure_output_items";
};
struct rna_names {
static constexpr StringRefNull items = "output_items";
static constexpr StringRefNull active_index = "active_output_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeEvaluateClosure *>(node.storage);
return {&storage->output_items.items,
&storage->output_items.items_num,
&storage->output_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return socket_type_supported_in_closure(socket_type, ntree_type);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeEvaluateClosure *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->output_items.next_identifier++;
socket_items::set_item_name_and_make_unique<EvaluateClosureOutputItemsAccessor>(
node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
/**
* Gets an input socket that can be considered to be internally linked to the given output, or
* null if there is none.
*/
const bNodeSocket *evaluate_closure_node_internally_linked_input(const bNodeSocket &output_socket);
} // namespace blender::nodes

View File

@@ -0,0 +1,98 @@
/* SPDX-FileCopyrightText: 2026 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for field
* to grid items.
*/
struct ClosureToListItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = GeometryNodeClosureToListItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeClosureToList";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
static constexpr bool has_single_identifier_str = false;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_closure_to_list_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_closure_to_list_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_closure_to_list_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "NODE_UL_closure_to_list_items";
};
struct rna_names {
static constexpr StringRefNull items = "list_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<GeometryNodeClosureToListItem> get_items_from_node(
bNode &node)
{
auto &storage = *static_cast<GeometryNodeClosureToList *>(node.storage);
return {&storage.items, &storage.items_num, &storage.active_index};
}
static void copy_item(const GeometryNodeClosureToListItem &src,
GeometryNodeClosureToListItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(GeometryNodeClosureToListItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return eNodeSocketDatatype(item.socket_type);
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return bke::node_tree_type_supports_socket_type_static(ntree_type, socket_type);
}
static char **get_name(GeometryNodeClosureToListItem &item)
{
return &item.name;
}
static void init_with_socket_type_and_name(bNode &node,
GeometryNodeClosureToListItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<GeometryNodeClosureToList *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
item.structure_type = NodeSocketInterfaceStructureType::Single;
socket_items::set_item_name_and_make_unique<ClosureToListItemsAccessor>(node, item, name);
}
static std::string input_socket_identifier_for_item(
const GeometryNodeClosureToListItem & /*item*/)
{
return {};
}
static std::string output_socket_identifier_for_item(const GeometryNodeClosureToListItem &item)
{
return "List_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,95 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for field
* to grid items.
*/
struct FieldToGridItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = GeometryNodeFieldToGridItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeFieldToGrid";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
static constexpr bool has_single_identifier_str = false;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_field_to_grid_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_field_to_grid_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_field_to_grid_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "NODE_UL_field_to_grid_items";
};
struct rna_names {
static constexpr StringRefNull items = "grid_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<GeometryNodeFieldToGridItem> get_items_from_node(bNode &node)
{
auto &storage = *static_cast<GeometryNodeFieldToGrid *>(node.storage);
return {&storage.items, &storage.items_num, &storage.active_index};
}
static void copy_item(const GeometryNodeFieldToGridItem &src, GeometryNodeFieldToGridItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(GeometryNodeFieldToGridItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.data_type;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
return socket_type_supports_grids(socket_type);
}
static char **get_name(GeometryNodeFieldToGridItem &item)
{
return &item.name;
}
static void init_with_socket_type_and_name(bNode &node,
GeometryNodeFieldToGridItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<GeometryNodeFieldToGrid *>(node.storage);
item.data_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<FieldToGridItemsAccessor>(node, item, name);
}
static std::string input_socket_identifier_for_item(const GeometryNodeFieldToGridItem &item)
{
return "Field_" + std::to_string(item.identifier);
}
static std::string output_socket_identifier_for_item(const GeometryNodeFieldToGridItem &item)
{
return "Grid_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,95 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for field
* to grid items.
*/
struct FieldToListItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = GeometryNodeFieldToListItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeFieldToList";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
static constexpr bool has_single_identifier_str = false;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_field_to_list_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_field_to_list_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_field_to_list_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "NODE_UL_field_to_list_items";
};
struct rna_names {
static constexpr StringRefNull items = "list_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<GeometryNodeFieldToListItem> get_items_from_node(bNode &node)
{
auto &storage = *static_cast<GeometryNodeFieldToList *>(node.storage);
return {&storage.items, &storage.items_num, &storage.active_index};
}
static void copy_item(const GeometryNodeFieldToListItem &src, GeometryNodeFieldToListItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(GeometryNodeFieldToListItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
return socket_type_supports_fields(socket_type);
}
static char **get_name(GeometryNodeFieldToListItem &item)
{
return &item.name;
}
static void init_with_socket_type_and_name(bNode &node,
GeometryNodeFieldToListItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<GeometryNodeFieldToList *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<FieldToListItemsAccessor>(node, item, name);
}
static std::string input_socket_identifier_for_item(const GeometryNodeFieldToListItem &item)
{
return "Field_" + std::to_string(item.identifier);
}
static std::string output_socket_identifier_for_item(const GeometryNodeFieldToListItem &item)
{
return "List_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,272 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
struct ForeachGeometryElementInputItemsAccessor
: public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeForeachGeometryElementInputItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeForeachGeometryElementOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item =
"NODE_OT_foreach_geometry_element_zone_input_item_add";
static constexpr StringRefNull remove_item =
"NODE_OT_foreach_geometry_element_zone_input_item_remove";
static constexpr StringRefNull move_item =
"NODE_OT_foreach_geometry_element_zone_input_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_foreach_geometry_element_input_items";
};
struct rna_names {
static constexpr StringRefNull items = "input_items";
static constexpr StringRefNull active_index = "active_input_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometryForeachGeometryElementOutput *>(node.storage);
return {&storage->input_items.items,
&storage->input_items.items_num,
&storage->input_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
return ELEM(socket_type,
SOCK_FLOAT,
SOCK_VECTOR,
SOCK_RGBA,
SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_MATRIX,
SOCK_INT,
SOCK_MENU);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryForeachGeometryElementOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->generation_items.next_identifier++;
socket_items::set_item_name_and_make_unique<ForeachGeometryElementInputItemsAccessor>(
node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Input_" + std::to_string(item.identifier);
}
};
struct ForeachGeometryElementMainItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeForeachGeometryElementMainItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeForeachGeometryElementOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item =
"NODE_OT_foreach_geometry_element_zone_main_item_add";
static constexpr StringRefNull remove_item =
"NODE_OT_foreach_geometry_element_zone_main_item_remove";
static constexpr StringRefNull move_item =
"NODE_OT_foreach_geometry_element_zone_main_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_foreach_geometry_element_main_items";
};
struct rna_names {
static constexpr StringRefNull items = "main_items";
static constexpr StringRefNull active_index = "active_main_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometryForeachGeometryElementOutput *>(node.storage);
return {&storage->main_items.items,
&storage->main_items.items_num,
&storage->main_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
return ELEM(socket_type,
SOCK_FLOAT,
SOCK_VECTOR,
SOCK_RGBA,
SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_MATRIX,
SOCK_INT);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryForeachGeometryElementOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->generation_items.next_identifier++;
socket_items::set_item_name_and_make_unique<ForeachGeometryElementMainItemsAccessor>(
node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Main_" + std::to_string(item.identifier);
}
};
struct ForeachGeometryElementGenerationItemsAccessor
: public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeForeachGeometryElementGenerationItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeForeachGeometryElementOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item =
"NODE_OT_foreach_geometry_element_zone_generation_item_add";
static constexpr StringRefNull remove_item =
"NODE_OT_foreach_geometry_element_zone_generation_item_remove";
static constexpr StringRefNull move_item =
"NODE_OT_foreach_geometry_element_zone_generation_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_foreach_geometry_element_generation_items";
};
struct rna_names {
static constexpr StringRefNull items = "generation_items";
static constexpr StringRefNull active_index = "active_generation_index";
};
static socket_items::SocketItemsRef<ItemT> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometryForeachGeometryElementOutput *>(node.storage);
return {&storage->generation_items.items,
&storage->generation_items.items_num,
&storage->generation_items.active_index};
}
static void copy_item(const ItemT &src, ItemT &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(ItemT *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const ItemT &item)
{
return item.socket_type;
}
static char **get_name(ItemT &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
return ELEM(socket_type,
SOCK_FLOAT,
SOCK_VECTOR,
SOCK_RGBA,
SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_MATRIX,
SOCK_INT,
SOCK_GEOMETRY);
}
static void init_with_socket_type_and_name(bNode &node,
ItemT &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryForeachGeometryElementOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->generation_items.next_identifier++;
socket_items::set_item_name_and_make_unique<ForeachGeometryElementGenerationItemsAccessor>(
node, item, name);
}
static std::string socket_identifier_for_item(const ItemT &item)
{
return "Generation_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,58 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for index
* switch items.
*/
struct IndexSwitchItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = IndexSwitchItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeIndexSwitch";
static constexpr bool has_type = false;
static constexpr bool has_name = false;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_index_switch_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_index_switch_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_index_switch_item_move";
};
static socket_items::SocketItemsRef<IndexSwitchItem> get_items_from_node(bNode &node)
{
auto &storage = *static_cast<NodeIndexSwitch *>(node.storage);
return {&storage.items, &storage.items_num, nullptr};
}
static void copy_item(const IndexSwitchItem &src, IndexSwitchItem &dst)
{
dst = src;
}
static void destruct_item(IndexSwitchItem * /*item*/) {}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static void init(bNode &node, IndexSwitchItem &item)
{
auto &storage = *static_cast<NodeIndexSwitch *>(node.storage);
item.identifier = storage.next_identifier++;
}
static std::string socket_identifier_for_item(const IndexSwitchItem &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,80 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for menu
* switch node items.
*/
struct MenuSwitchItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeEnumItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeMenuSwitch";
static constexpr bool has_type = false;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_enum_definition_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_enum_definition_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_enum_definition_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "NODE_UL_enum_definition_items";
};
struct rna_names {
static constexpr StringRefNull items = "enum_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeEnumItem> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeMenuSwitch *>(node.storage);
return {&storage->enum_definition.items_array,
&storage->enum_definition.items_num,
&storage->enum_definition.active_index};
}
static void copy_item(const NodeEnumItem &src, NodeEnumItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
dst.description = BLI_strdup_null(dst.description);
}
static void destruct_item(NodeEnumItem *item)
{
MEM_SAFE_DELETE(item->name);
MEM_SAFE_DELETE(item->description);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static char **get_name(NodeEnumItem &item)
{
return &item.name;
}
static void init_with_name(bNode &node, NodeEnumItem &item, const char *name)
{
auto *storage = static_cast<NodeMenuSwitch *>(node.storage);
item.identifier = storage->enum_definition.next_identifier++;
socket_items::set_item_name_and_make_unique<MenuSwitchItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const NodeEnumItem &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,89 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) with
* repeat items.
*/
struct RepeatItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeRepeatItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeRepeatOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_repeat_zone_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_repeat_zone_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_repeat_zone_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_repeat_zone_state";
};
struct rna_names {
static constexpr StringRefNull items = "repeat_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeRepeatItem> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometryRepeatOutput *>(node.storage);
return {&storage->items, &storage->items_num, &storage->active_index};
}
static void copy_item(const NodeRepeatItem &src, NodeRepeatItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(NodeRepeatItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const NodeRepeatItem &item)
{
return item.socket_type;
}
static char **get_name(NodeRepeatItem &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return bke::node_tree_type_supports_socket_type_static(ntree_type, socket_type);
}
static void init_with_socket_type_and_name(bNode &node,
NodeRepeatItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryRepeatOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<RepeatItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const NodeRepeatItem &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,100 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) with
* simulation items.
*/
struct SimulationItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeSimulationItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeSimulationOutput";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_simulation_zone_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_simulation_zone_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_simulation_zone_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "DATA_UL_simulation_zone_state";
};
struct rna_names {
static constexpr StringRefNull items = "state_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeSimulationItem> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometrySimulationOutput *>(node.storage);
return {&storage->items, &storage->items_num, &storage->active_index};
}
static void copy_item(const NodeSimulationItem &src, NodeSimulationItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(NodeSimulationItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const NodeSimulationItem &item)
{
return item.socket_type;
}
static char **get_name(NodeSimulationItem &item)
{
return &item.name;
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int /*ntree_type*/)
{
/* Data-block types and closures are not supported. */
return ELEM(socket_type,
SOCK_FLOAT,
SOCK_VECTOR,
SOCK_RGBA,
SOCK_BOOLEAN,
SOCK_ROTATION,
SOCK_MATRIX,
SOCK_INT,
SOCK_STRING,
SOCK_GEOMETRY,
SOCK_BUNDLE);
}
static void init_with_socket_type_and_name(bNode &node,
NodeSimulationItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometrySimulationOutput *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<SimulationItemsAccessor>(node, item, name);
}
static std::string socket_identifier_for_item(const NodeSimulationItem &item)
{
return "Item_" + std::to_string(item.identifier);
}
};
} // namespace blender::nodes

View File

@@ -0,0 +1,14 @@
/* SPDX-FileCopyrightText: 2026 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BLI_set.hh"
#include "BLI_string_ref.hh"
namespace blender::nodes {
bool tag_filter_matches(const StringRef tag_filter, const Set<std::string> &tags);
} // namespace blender::nodes

View File

@@ -0,0 +1,102 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_types.h"
#include "NOD_eval_log.hh"
#include "NOD_socket_items.hh"
namespace blender::nodes {
/**
* Makes it possible to use various functions (e.g. the ones in `NOD_socket_items.hh`) for viewer
* node items.
*/
struct GeoViewerItemsAccessor : public socket_items::SocketItemsAccessorDefaults {
using ItemT = NodeGeometryViewerItem;
static StructRNA **item_srna;
static int node_type;
static constexpr StringRefNull node_idname = "GeometryNodeViewer";
static constexpr bool has_type = true;
static constexpr bool has_name = true;
struct operator_idnames {
static constexpr StringRefNull add_item = "NODE_OT_geometry_nodes_viewer_item_add";
static constexpr StringRefNull remove_item = "NODE_OT_geometry_nodes_viewer_item_remove";
static constexpr StringRefNull move_item = "NODE_OT_geometry_nodes_viewer_item_move";
};
struct ui_idnames {
static constexpr StringRefNull list = "NODE_UL_geometry_nodes_viewer_items";
};
struct rna_names {
static constexpr StringRefNull items = "viewer_items";
static constexpr StringRefNull active_index = "active_index";
};
static socket_items::SocketItemsRef<NodeGeometryViewerItem> get_items_from_node(bNode &node)
{
auto *storage = static_cast<NodeGeometryViewer *>(node.storage);
return {&storage->items, &storage->items_num, &storage->active_index};
}
static void copy_item(const NodeGeometryViewerItem &src, NodeGeometryViewerItem &dst)
{
dst = src;
dst.name = BLI_strdup_null(dst.name);
}
static void destruct_item(NodeGeometryViewerItem *item)
{
MEM_SAFE_DELETE(item->name);
}
static void blend_write_item(BlendWriter *writer, const ItemT &item);
static void blend_read_data_item(BlendDataReader *reader, ItemT &item);
static eNodeSocketDatatype get_socket_type(const NodeGeometryViewerItem &item)
{
return item.socket_type;
}
static char **get_name(NodeGeometryViewerItem &item)
{
return &item.name;
}
static void init_with_socket_type_and_name(bNode &node,
NodeGeometryViewerItem &item,
const eNodeSocketDatatype socket_type,
const char *name)
{
auto *storage = static_cast<NodeGeometryViewer *>(node.storage);
item.socket_type = socket_type;
item.identifier = storage->next_identifier++;
socket_items::set_item_name_and_make_unique<GeoViewerItemsAccessor>(node, item, name);
}
static bool supports_socket_type(const eNodeSocketDatatype socket_type, const int ntree_type)
{
return bke::node_tree_type_supports_socket_type_static(ntree_type, socket_type);
}
static std::string socket_identifier_for_item(const NodeGeometryViewerItem &item)
{
/* These special cases exist for compatibility with older Blender versions when the viewer did
* not have a dynamic number of inputs yet. */
if (item.identifier == 0 && item.socket_type == SOCK_GEOMETRY) {
return "Geometry";
}
if (item.identifier == 1 && item.socket_type != SOCK_GEOMETRY) {
return "Value";
}
return "Item_" + std::to_string(item.identifier);
}
};
void geo_viewer_node_log(const bNode &node,
const Span<bke::SocketValueVariant *> input_values,
eval_log::ViewerNodeLog &r_log);
} // namespace blender::nodes