13#include <fmt/format.h>
35#include "RNA_prototypes.hh"
82 if (node->is_group()) {
90 if (node->is_group()) {
142 for (
bNode *node : ntree->all_nodes()) {
149 for (
bNode *node : ntree->all_nodes()) {
152 if (sock->link && sock->link->fromnode != rem_node) {
175 if (!sock_to->
link) {
189 if (!sock_to->
link) {
211 bNode *node_prev =
nullptr;
228 node_from->
typeinfo->draw_buttons_ex)
236 node_from = node_prev;
238 else if (!node_from) {
240 if (node_prev !=
nullptr) {
262 if (node_prev && node_from != node_prev) {
271 if (
STREQ(sock_prev->identifier, sock_from->identifier) &&
272 sock_prev->type == sock_from->type)
307#define UI_NODE_LINK_DISCONNECT -1
308#define UI_NODE_LINK_REMOVE -2
325 std::optional<NodeDeclaration> &r_node_decl)
336 const char *disabled_hint;
337 if ((ngroup->type != arg->
ntree->
type) ||
343 ngroup->ensure_interface_cache();
345 ngroup->interface_inputs() :
346 ngroup->interface_outputs());
372 r_node_decl->outputs;
392 for (stemp = socket_templates; stemp && stemp->
type != -1; stemp++,
i++) {
440 IFACE_(node_name.c_str()),
457 return (typeA == typeB);
469 if (ntype->
idname ==
"ShaderNodeUVAlongStroke") {
495 const char *disabled_hint;
496 if (!(ntype->poll && ntype->poll(ntype, ntree, &disabled_hint))) {
500 if (ntype->nclass != nclass) {
508 sorted_ntypes.
append(ntype);
511 qsort(sorted_ntypes.
data(),
512 sorted_ntypes.
size(),
517 for (
int j = 0; j < sorted_ntypes.
size(); j++) {
520 const char *cur_node_name =
nullptr;
522 int icon = ICON_NONE;
526 std::optional<blender::nodes::NodeDeclaration> node_decl;
541 column = &layout->
column(
false);
551 if (!cur_node_name || !
STREQ(cur_node_name, item.node_name)) {
552 cur_node_name = item.node_name;
589 TIP_(
"Add node to input"));
629 column = &
split->column(
false);
648 TIP_(
"Remove nodes connected to the input"));
662 TIP_(
"Disconnect nodes connected to the input"));
708 but->
poin = (
char *)but;
730 const char *panel_label);
740 const std::string panel_id = fmt::format(
746 if (panel_toggle_decl) {
750 &ntree.
id, &RNA_NodeSocket, &node.socket_by_decl(*panel_toggle_decl));
761 if (!panel_layout.
body) {
765 if (item_decl == panel_toggle_decl) {
769 bNodeSocket &socket = node.socket_by_decl(*socket_decl);
770 if (socket_decl->custom_draw_fn) {
779 (*socket_decl->custom_draw_fn)(
params);
781 else if (socket_decl->in_out ==
SOCK_IN) {
783 *panel_layout.
body,
C, ntree, node, socket, depth, panel_decl.
name.c_str());
792 layout_decl->draw(panel_layout.
body, &
C, &nodeptr);
806 node.
typeinfo->draw_buttons(&layout, &
C, &nodeptr);
810 if (node.declaration()) {
818 bNodeSocket &socket = node.socket_by_decl(*socket_decl);
819 if (socket_decl->custom_draw_fn) {
828 (*socket_decl->custom_draw_fn)(
params);
830 else if (socket_decl->in_out ==
SOCK_IN) {
850 const char *panel_label)
854 bool dependency_loop;
865 if (dependency_loop) {
873 row = &layout.
row(
true);
879 bool add_dummy_decorator =
false;
894 if (lnode->
typeinfo->draw_buttons) {
897 else if (lnode->declaration()) {
903 if (socket_decl->custom_draw_fn) {
919 sub = &sub->
row(
true);
924 if (dependency_loop) {
925 row->
label(
RPT_(
"Dependency Loop"), ICON_ERROR);
926 add_dummy_decorator =
true;
931 add_dummy_decorator =
true;
947 add_dummy_decorator =
true;
951 switch (
input.type) {
985 sub->
label(
RPT_(
"Unsupported Menu Socket"), ICON_NONE);
988 input.typeinfo->draw(&
C, sub, &inputptr, &nodeptr,
input.name);
991 add_dummy_decorator =
true;
1016 ntree->ensure_topology_cache();
1019 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
#define SNPRINTF(dst, format,...)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
int char char int int int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT 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
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.
uiBut * uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, 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)
uiBut * uiDefBut(uiBlock *block, int 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)
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])
void uiItemDecoratorR(uiLayout *layout, PointerRNA *ptr, std::optional< blender::StringRefNull > propname, int index)
uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
eNodeSocketDatatype socket_type
const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr const char * c_str() 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)
const char * node_socket_get_label(const bNodeSocket *socket, const char *panel_label)
static int ui_compatible_sockets(int typeA, int typeB)
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 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
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 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