13#include <fmt/format.h>
36#include "RNA_prototypes.hh"
83 if (node->is_group()) {
91 if (node->is_group()) {
143 for (
bNode *node : ntree->all_nodes()) {
150 for (
bNode *node : ntree->all_nodes()) {
153 if (sock->link && sock->link->fromnode != rem_node) {
176 if (!sock_to->
link) {
190 if (!sock_to->
link) {
212 bNode *node_prev =
nullptr;
229 node_from->
typeinfo->draw_buttons_ex)
237 node_from = node_prev;
239 else if (!node_from) {
241 if (node_prev !=
nullptr) {
263 if (node_prev && node_from != node_prev) {
272 if (
STREQ(sock_prev->identifier, sock_from->identifier) &&
273 sock_prev->type == sock_from->type)
308#define UI_NODE_LINK_DISCONNECT -1
309#define UI_NODE_LINK_REMOVE -2
326 std::optional<NodeDeclaration> &r_node_decl)
337 const char *disabled_hint;
338 if ((ngroup->type != arg->
ntree->
type) ||
344 ngroup->ensure_interface_cache();
346 ngroup->interface_inputs() :
347 ngroup->interface_outputs());
373 r_node_decl->outputs;
393 for (stemp = socket_templates; stemp && stemp->
type != -1; stemp++,
i++) {
441 IFACE_(node_name.c_str()),
458 return (typeA == typeB);
470 if (ntype->
idname ==
"ShaderNodeUVAlongStroke") {
496 const char *disabled_hint;
497 if (!(ntype->poll && ntype->poll(ntype, ntree, &disabled_hint))) {
501 if (ntype->nclass != nclass) {
509 sorted_ntypes.
append(ntype);
512 qsort(sorted_ntypes.
data(),
513 sorted_ntypes.
size(),
518 for (
int j = 0; j < sorted_ntypes.
size(); j++) {
521 const char *cur_node_name =
nullptr;
523 int icon = ICON_NONE;
527 std::optional<blender::nodes::NodeDeclaration> node_decl;
542 column = &layout->
column(
false);
552 if (!cur_node_name || !
STREQ(cur_node_name, item.node_name)) {
553 cur_node_name = item.node_name;
588 TIP_(
"Add node to input"));
628 column = &
split->column(
false);
647 TIP_(
"Remove nodes connected to the input"));
661 TIP_(
"Disconnect nodes connected to the input"));
707 but->
poin = (
char *)but;
733 const char *panel_label);
743 const std::string panel_id = fmt::format(
749 if (panel_toggle_decl) {
753 &ntree.
id, &RNA_NodeSocket, &node.socket_by_decl(*panel_toggle_decl));
764 if (!panel_layout.
body) {
768 if (item_decl == panel_toggle_decl) {
772 bNodeSocket &socket = node.socket_by_decl(*socket_decl);
773 if (socket_decl->custom_draw_fn) {
782 (*socket_decl->custom_draw_fn)(
params);
784 else if (socket_decl->in_out ==
SOCK_IN) {
786 *panel_layout.
body,
C, ntree, node, socket, depth, panel_decl.
name.c_str());
795 layout_decl->draw(panel_layout.
body, &
C, &nodeptr);
809 node.
typeinfo->draw_buttons(&layout, &
C, &nodeptr);
813 if (node.declaration()) {
821 bNodeSocket &socket = node.socket_by_decl(*socket_decl);
822 if (socket_decl->custom_draw_fn) {
831 (*socket_decl->custom_draw_fn)(
params);
833 else if (socket_decl->in_out ==
SOCK_IN) {
839 if (!layout_decl->is_default) {
841 layout_decl->draw(&layout, &
C, &nodeptr);
860 const char *panel_label)
864 bool dependency_loop;
875 if (dependency_loop) {
883 row = &layout.
row(
true);
889 bool add_dummy_decorator =
false;
904 if (lnode->
typeinfo->draw_buttons) {
907 else if (lnode->declaration()) {
913 if (socket_decl->custom_draw_fn) {
929 sub = &sub->
row(
true);
934 if (dependency_loop) {
935 row->
label(
RPT_(
"Dependency Loop"), ICON_ERROR);
936 add_dummy_decorator =
true;
941 add_dummy_decorator =
true;
957 add_dummy_decorator =
true;
961 switch (
input.type) {
994 input.typeinfo->draw(&
C, sub, &inputptr, &nodeptr,
input.name);
997 add_dummy_decorator =
true;
1022 ntree->ensure_topology_cache();
1025 for (
bNode *tnode : ntree->all_nodes()) {
SpaceNode * CTX_wm_space_node(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
const char * BKE_id_name(const ID &id)
void BKE_main_ensure_invariants(Main &bmain, std::optional< blender::Span< ID * > > modified_ids=std::nullopt)
#define NODE_CLASS_LAYOUT
#define NODE_CLASS_TEXTURE
void BKE_ntree_update_tag_node_property(bNodeTree *ntree, bNode *node)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
ATTR_WARN_UNUSED_RESULT const size_t num
int char char int int int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t size_t size_t BLI_snprintf_utf8(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
#define ID_IS_EDITABLE(_id)
struct bNodeTree bNodeTree
struct bNodeSocket bNodeSocket
void ED_undo_push(bContext *C, const char *str)
static void split(const char *text, const char *seps, char ***str, int *count)
Read Guarded memory(de)allocation.
void UI_but_disable(uiBut *but, const char *disabled_hint)
uiBut * uiDefIconTextBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, std::optional< blender::StringRef > tip)
void UI_block_emboss_set(uiBlock *block, blender::ui::EmbossType emboss)
uiBut * uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, blender::StringRef str, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
void uiTemplateNodeLink(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input)
void UI_but_drawflag_enable(uiBut *but, int flag)
void UI_but_type_set_menu_from_pulldown(uiBut *but)
uiBut * uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2, uiButArgNFree func_argN_free_fn=MEM_freeN, uiButArgNCopy func_argN_copy_fn=MEM_dupallocN)
void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4])
uiBut * uiDefBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout)
eNodeSocketDatatype socket_type
const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
void append(const T &value)
Vector< ItemDeclaration * > root_items
std::optional< std::string > translation_context
Vector< ItemDeclaration * > items
const SocketDeclaration * panel_input_decl() const
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
std::string node_label(const bNodeTree &ntree, const bNode &node)
void node_remove_node(Main *bmain, bNodeTree &ntree, bNode &node, bool do_id_user, bool remove_animation=true)
bool node_group_poll(const bNodeTree *nodetree, const bNodeTree *grouptree, const char **r_disabled_hint)
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Span< bNodeType * > node_types_get()
int node_count_socket_links(const bNodeTree &ntree, const bNodeSocket &sock)
void node_position_relative(bNode &from_node, const bNode &to_node, const bNodeSocket *from_sock, const bNodeSocket &to_sock)
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
void node_set_active(bNodeTree &ntree, bNode &node)
int node_socket_link_limit(const bNodeSocket &sock)
static void node_clear_recursive(bNode *node)
static void node_socket_disconnect(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to)
static void node_link_item_apply(bNodeTree *ntree, bNode *node, NodeLinkItem *item)
static int ui_node_item_name_compare(const void *a, const void *b)
static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_p)
static void node_tag_recursive(bNode *node)
static Vector< NodeLinkItem > ui_node_link_items(NodeLinkArg *arg, int in_out, std::optional< NodeDeclaration > &r_node_decl)
static void ui_node_draw_input(uiLayout &layout, bContext &C, bNodeTree &ntree, bNode &node, bNodeSocket &input, int depth, const char *panel_label)
static void ui_node_sock_name(const bNodeTree *ntree, bNodeSocket *sock, char name[UI_MAX_NAME_STR])
void node_socket_color_get(const bContext &C, const bNodeTree &ntree, PointerRNA &node_ptr, const bNodeSocket &sock, float r_color[4])
static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, int type, NodeLinkItem *item)
static void node_remove_linked(Main *bmain, bNodeTree *ntree, bNode *rem_node)
static void ui_node_draw_node(uiLayout &layout, bContext &C, bNodeTree &ntree, bNode &node, int depth)
void node_geometry_add_attribute_search_button(const bContext &, const bNode &node, PointerRNA &socket_ptr, uiLayout &layout, const StringRef placeholder)
static int ui_compatible_sockets(int typeA, int typeB)
const char * node_socket_get_label(const bNodeSocket *socket, const char *panel_label=nullptr)
static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to)
static bool node_link_item_compare(bNode *node, NodeLinkItem *item)
static void ui_node_draw_recursive(uiLayout &layout, bContext &C, bNodeTree &ntree, bNode &node, const nodes::PanelDeclaration &panel_decl, const int depth)
static void node_menu_column_foreach_cb(void *calldata, int nclass, const StringRefNull name)
static bool ui_node_item_special_poll(const bNodeTree *, const bke::bNodeType *ntype)
static void ui_node_link(bContext *C, void *arg_p, void *event_p)
void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout)
static void node_link_item_init(NodeLinkItem &item)
void build_node_declaration(const bke::bNodeType &typeinfo, NodeDeclaration &r_declaration, const bNodeTree *ntree, const bNode *node)
void block_layout_set_current(uiBlock *block, uiLayout *layout)
void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
#define UI_NODE_LINK_DISCONNECT
void uiTemplateNodeView(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input)
void uiTemplateNodeLink(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input)
#define UI_NODE_LINK_REMOVE
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
bNodeTreeTypeHandle * typeinfo
bNodeTypeHandle * typeinfo
Compact definition of a node socket.
void(* foreach_nodeclass)(void *calldata, bNodeClassCallback func)
bNodeSocketTemplate * inputs
bNodeSocketTemplate * outputs
NodeDeclareFunction declare
bke::bNodeType * node_type
blender::Vector< std::unique_ptr< uiBut > > buttons
uiButArgNFree func_argN_free_fn
uiButArgNCopy func_argN_copy_fn
void use_property_decorate_set(bool is_sep)
void alignment_set(blender::ui::LayoutAlign alignment)
void decorator(PointerRNA *ptr, PropertyRNA *prop, int index)
PanelLayout panel(const bContext *C, blender::StringRef idname, bool default_closed)
void label(blender::StringRef name, int icon)
uiLayout & column(bool align)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
uiLayout & split(float percentage, bool align)
void use_property_split_set(bool value)
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)
uiLayout * decorate_column