From 960e2c73de79d095120d741d7f61f25129e0f03e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Nov 2023 13:59:57 +1100 Subject: [PATCH 1/2] Docs: improve bpy.app.driver_namespace, add stub example The description first described functionality that doesn't work properly. Prefer text that is to the point with what works well, elaborating on error prone & partially working solutions afterwards. Also include a stub example for script authors who prefer to develop & maintain their scripts outside of Blender. --- .../examples/bpy.app.driver_namespace.py | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/doc/python_api/examples/bpy.app.driver_namespace.py b/doc/python_api/examples/bpy.app.driver_namespace.py index ebcfbc5ea42..72c12251b39 100644 --- a/doc/python_api/examples/bpy.app.driver_namespace.py +++ b/doc/python_api/examples/bpy.app.driver_namespace.py @@ -1,18 +1,38 @@ """ File Loading & Order of Initialization - Since drivers are evaluated immediately after loading a blend-file, using the ``--python`` command line argument - to populate name-space often fails to achieve the desired goal because the initial evaluation will lookup a function - that doesn't exist yet, marking the driver as invalid - preventing further evaluation. + Since drivers may be evaluated immediately after loading a blend-file it is necessary + to ensure the driver name-space is initialized beforehand. + + This can be done by registering text data-blocks to execute on startup, + which executes the scripts before drivers are evaluated. + See *Text -> Register* from Blender's text editor. + + .. hint:: + + You may prefer to use external files instead of Blender's text-blocks. + This can be done using a text-block which executes an external file. + + This example runs ``driver_namespace.py`` located in the same directory as the text-blocks blend-file: + + .. code-block:: + + import os + import bpy + blend_dir = os.path.normalize(os.path.join(__file__, "..", "..")) + bpy.utils.execfile(os.path.join(blend_dir, "driver_namespace.py")) + + Using ``__file__`` ensures the text resolves to the expected path even when library-linked from another file. + + Other methods of populating the drivers name-space can be made to work but tend to be error prone: + + Using The ``--python`` command line argument to populate name-space often fails to achieve the desired goal + because the initial evaluation will lookup a function that doesn't exist yet, + marking the driver as invalid - preventing further evaluation. Populating the driver name-space before the blend-file loads also doesn't work since opening a file clears the name-space. - The driver name-space should be populated for newly loaded files using text-block registration. - - Text blocks may be marked to execute on startup from the text editor *Text -> Register*. - Scripts that are registered will execute after a blend-file loads & before driver evaluation. - - It's also possible to use run a script via the ``--python`` command line argument, before the blend file. + It is possible to run a script via the ``--python`` command line argument, before the blend file. This can register a load-post handler (:mod:`bpy.app.handlers.load_post`) that initialized the name-space. While this works for background tasks it has the downside that opening the file from the file selector won't setup the name-space. From cbcfca0a19e3071dca999dbbe775c933d5ed059d Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Wed, 1 Nov 2023 09:29:56 +0100 Subject: [PATCH 2/2] Fix #112716: Custom sockets ignore draw_color method Customs sockets always ignore their draw_color method and are always drawn using a magenta color. This is a regression that was introduced in e071288ab2. The commit used the simple variant even for drawing nodes where a context is available. So this patch mostly reverts those changes. Pull Request: https://projects.blender.org/blender/blender/pulls/114148 --- source/blender/editors/space_node/drawnode.cc | 34 ++++--- .../blender/editors/space_node/node_draw.cc | 88 ++++++++++++++----- .../blender/editors/space_node/node_intern.hh | 17 +++- .../editors/space_node/node_templates.cc | 5 +- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index b58190ec80c..333fa31914c 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -2088,7 +2088,8 @@ static bool node_link_is_field_link(const SpaceNode &snode, const bNodeLink &lin return false; } -static NodeLinkDrawConfig nodelink_get_draw_config(const View2D &v2d, +static NodeLinkDrawConfig nodelink_get_draw_config(const bContext &C, + const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, const int th_col1, @@ -2126,18 +2127,24 @@ static NodeLinkDrawConfig nodelink_get_draw_config(const View2D &v2d, if (snode.overlay.flag & SN_OVERLAY_SHOW_OVERLAYS && snode.overlay.flag & SN_OVERLAY_SHOW_WIRE_COLORS) { + const bNodeTree &node_tree = *snode.edittree; + PointerRNA from_node_ptr = RNA_pointer_create( + &const_cast(node_tree.id), &RNA_Node, link.fromnode); + PointerRNA to_node_ptr = RNA_pointer_create( + &const_cast(node_tree.id), &RNA_Node, link.tonode); + if (link.fromsock) { - node_socket_color_get(*link.fromsock->typeinfo, draw_config.start_color); + node_socket_color_get(C, node_tree, from_node_ptr, *link.fromsock, draw_config.start_color); } else { - node_socket_color_get(*link.tosock->typeinfo, draw_config.start_color); + node_socket_color_get(C, node_tree, to_node_ptr, *link.tosock, draw_config.start_color); } if (link.tosock) { - node_socket_color_get(*link.tosock->typeinfo, draw_config.end_color); + node_socket_color_get(C, node_tree, to_node_ptr, *link.tosock, draw_config.end_color); } else { - node_socket_color_get(*link.fromsock->typeinfo, draw_config.end_color); + node_socket_color_get(C, node_tree, from_node_ptr, *link.fromsock, draw_config.end_color); } } else { @@ -2216,7 +2223,8 @@ static void node_draw_link_bezier_ex(const SpaceNode &snode, } } -void node_draw_link_bezier(const View2D &v2d, +void node_draw_link_bezier(const bContext &C, + const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, const int th_col1, @@ -2229,12 +2237,13 @@ void node_draw_link_bezier(const View2D &v2d, return; } const NodeLinkDrawConfig draw_config = nodelink_get_draw_config( - v2d, snode, link, th_col1, th_col2, th_col3, selected); + C, v2d, snode, link, th_col1, th_col2, th_col3, selected); node_draw_link_bezier_ex(snode, draw_config, points); } -void node_draw_link(const View2D &v2d, +void node_draw_link(const bContext &C, + const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, const bool selected) @@ -2277,7 +2286,7 @@ void node_draw_link(const View2D &v2d, } } - node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, th_col3, selected); + node_draw_link_bezier(C, v2d, snode, link, th_col1, th_col2, th_col3, selected); } std::array node_link_bezier_points_dragged(const SpaceNode &snode, @@ -2294,7 +2303,10 @@ std::array node_link_bezier_points_dragged(const SpaceNode &snode, return points; } -void node_draw_link_dragged(const View2D &v2d, const SpaceNode &snode, const bNodeLink &link) +void node_draw_link_dragged(const bContext &C, + const View2D &v2d, + const SpaceNode &snode, + const bNodeLink &link) { if (link.fromsock == nullptr && link.tosock == nullptr) { return; @@ -2303,7 +2315,7 @@ void node_draw_link_dragged(const View2D &v2d, const SpaceNode &snode, const bNo const std::array points = node_link_bezier_points_dragged(snode, link); const NodeLinkDrawConfig draw_config = nodelink_get_draw_config( - v2d, snode, link, TH_ACTIVE, TH_ACTIVE, TH_WIRE, true); + C, v2d, snode, link, TH_ACTIVE, TH_ACTIVE, TH_WIRE, true); /* End marker outline. */ node_draw_link_end_markers(link, draw_config, points, true); /* Link. */ diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index cfd7f8e2a1a..4b43b1f613c 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -1079,13 +1079,16 @@ static int node_get_colorid(TreeDrawContext &tree_draw_ctx, const bNode &node) } } -static void node_draw_mute_line(const View2D &v2d, const SpaceNode &snode, const bNode &node) +static void node_draw_mute_line(const bContext &C, + const View2D &v2d, + const SpaceNode &snode, + const bNode &node) { GPU_blend(GPU_BLEND_ALPHA); for (const bNodeLink &link : node.internal_links()) { if (!nodeLinkIsHidden(&link)) { - node_draw_link_bezier(v2d, snode, link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false); + node_draw_link_bezier(C, v2d, snode, link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false); } } @@ -1184,14 +1187,21 @@ static void node_socket_outline_color_get(const bool selected, } } -void node_socket_color_get(const bNodeSocketType &type, float r_color[4]) +void node_socket_color_get(const bContext &C, + const bNodeTree &ntree, + PointerRNA &node_ptr, + const bNodeSocket &sock, + float r_color[4]) { - if (type.draw_color_simple) { - type.draw_color_simple(&type, r_color); - } - else { + if (!sock.typeinfo->draw_color) { copy_v4_v4(r_color, float4(1.0f, 0.0f, 1.0f, 1.0f)); + return; } + + BLI_assert(RNA_struct_is_a(node_ptr.type, &RNA_Node)); + PointerRNA ptr = RNA_pointer_create( + &const_cast(ntree.id), &RNA_NodeSocket, &const_cast(sock)); + sock.typeinfo->draw_color((bContext *)&C, &ptr, &node_ptr, r_color); } static void create_inspection_string_for_generic_value(const bNodeSocket &socket, @@ -1616,7 +1626,9 @@ void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, ui MEM_freeN); } -static void node_socket_draw_nested(const bNodeTree &ntree, +static void node_socket_draw_nested(const bContext &C, + const bNodeTree &ntree, + PointerRNA &node_ptr, uiBlock &block, const bNodeSocket &sock, const uint pos_id, @@ -1631,7 +1643,7 @@ static void node_socket_draw_nested(const bNodeTree &ntree, float color[4]; float outline_color[4]; - node_socket_color_get(*sock.typeinfo, color); + node_socket_color_get(C, ntree, node_ptr, sock, color); node_socket_outline_color_get(selected, sock.type, outline_color); node_socket_draw(sock, @@ -1826,6 +1838,7 @@ static void node_draw_shadow(const SpaceNode &snode, } static void node_draw_sockets(const View2D &v2d, + const bContext &C, const bNodeTree &ntree, const bNode &node, uiBlock &block, @@ -1862,6 +1875,9 @@ static void node_draw_sockets(const View2D &v2d, immBeginAtMost(GPU_PRIM_POINTS, node.input_sockets().size() + node.output_sockets().size()); } + PointerRNA node_ptr = RNA_pointer_create( + &const_cast(ntree.id), &RNA_Node, &const_cast(node)); + /* Socket inputs. */ int selected_input_len = 0; for (const bNodeSocket *sock : node.input_sockets()) { @@ -1881,8 +1897,18 @@ static void node_draw_sockets(const View2D &v2d, continue; } - node_socket_draw_nested( - ntree, block, *sock, pos_id, col_id, shape_id, size_id, outline_col_id, scale, selected); + node_socket_draw_nested(C, + ntree, + node_ptr, + block, + *sock, + pos_id, + col_id, + shape_id, + size_id, + outline_col_id, + scale, + selected); } /* Socket outputs. */ @@ -1898,8 +1924,18 @@ static void node_draw_sockets(const View2D &v2d, continue; } - node_socket_draw_nested( - ntree, block, *sock, pos_id, col_id, shape_id, size_id, outline_col_id, scale, selected); + node_socket_draw_nested(C, + ntree, + node_ptr, + block, + *sock, + pos_id, + col_id, + shape_id, + size_id, + outline_col_id, + scale, + selected); } } @@ -1926,7 +1962,9 @@ static void node_draw_sockets(const View2D &v2d, continue; } if (select_all || (sock->flag & SELECT)) { - node_socket_draw_nested(ntree, + node_socket_draw_nested(C, + ntree, + node_ptr, block, *sock, pos_id, @@ -1951,7 +1989,9 @@ static void node_draw_sockets(const View2D &v2d, continue; } if (select_all || (sock->flag & SELECT)) { - node_socket_draw_nested(ntree, + node_socket_draw_nested(C, + ntree, + node_ptr, block, *sock, pos_id, @@ -1993,7 +2033,7 @@ static void node_draw_sockets(const View2D &v2d, float color[4]; float outline_color[4]; - node_socket_color_get(*socket->typeinfo, color); + node_socket_color_get(C, ntree, node_ptr, *socket, color); node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color); const float2 location = socket->runtime->location; @@ -3005,7 +3045,7 @@ static void node_draw_basis(const bContext &C, /* Wire across the node when muted/disabled. */ if (node.flag & NODE_MUTED) { - node_draw_mute_line(v2d, snode, node); + node_draw_mute_line(C, v2d, snode, node); } /* Body. */ @@ -3109,7 +3149,7 @@ static void node_draw_basis(const bContext &C, /* Skip slow socket drawing if zoom is small. */ if (scale > 0.2f) { - node_draw_sockets(v2d, ntree, node, block, true, false); + node_draw_sockets(v2d, C, ntree, node, block, true, false); } if (is_node_panels_supported(node)) { @@ -3144,7 +3184,7 @@ static void node_draw_hidden(const bContext &C, /* Wire across the node when muted/disabled. */ if (node.flag & NODE_MUTED) { - node_draw_mute_line(v2d, snode, node); + node_draw_mute_line(C, v2d, snode, node); } /* Body. */ @@ -3294,7 +3334,7 @@ static void node_draw_hidden(const bContext &C, immUnbindProgram(); GPU_blend(GPU_BLEND_NONE); - node_draw_sockets(v2d, ntree, node, block, true, false); + node_draw_sockets(v2d, C, ntree, node, block, true, false); UI_block_end(&C, &block); UI_block_draw(&C, &block); @@ -3669,7 +3709,7 @@ static void reroute_node_draw( /* Only draw input socket as they all are placed on the same position highlight * if node itself is selected, since we don't display the node body separately. */ - node_draw_sockets(region.v2d, ntree, node, block, false, node.flag & SELECT); + node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT); UI_block_end(&C, &block); UI_block_draw(&C, &block); @@ -3927,14 +3967,14 @@ static void node_draw_nodetree(const bContext &C, for (const bNodeLink *link : ntree.all_links()) { if (!nodeLinkIsHidden(link) && !bke::nodeLinkIsSelected(link)) { - node_draw_link(region.v2d, snode, *link, false); + node_draw_link(C, region.v2d, snode, *link, false); } } /* Draw selected node links after the unselected ones, so they are shown on top. */ for (const bNodeLink *link : ntree.all_links()) { if (!nodeLinkIsHidden(link) && bke::nodeLinkIsSelected(link)) { - node_draw_link(region.v2d, snode, *link, true); + node_draw_link(C, region.v2d, snode, *link, true); } } @@ -4185,7 +4225,7 @@ void node_draw_space(const bContext &C, ARegion ®ion) GPU_line_smooth(true); if (snode.runtime->linkdrag) { for (const bNodeLink &link : snode.runtime->linkdrag->links) { - node_draw_link_dragged(v2d, snode, link); + node_draw_link_dragged(C, v2d, snode, link); } } GPU_line_smooth(false); diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index cd420627a01..f94ef5de624 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -165,7 +165,11 @@ int node_get_resize_cursor(NodeResizeDirection directions); * Usual convention here would be #node_socket_get_color(), * but that's already used (for setting a color property socket). */ -void node_socket_color_get(const bNodeSocketType &type, float r_color[4]); +void node_socket_color_get(const bContext &C, + const bNodeTree &ntree, + PointerRNA &node_ptr, + const bNodeSocket &sock, + float r_color[4]); const char *node_socket_get_label(const bNodeSocket *socket, const char *panel_label); @@ -243,15 +247,20 @@ void nodelink_batch_end(SpaceNode &snode); /** * \note this is used for fake links in groups too. */ -void node_draw_link(const View2D &v2d, +void node_draw_link(const bContext &C, + const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, bool selected); -void node_draw_link_dragged(const View2D &v2d, const SpaceNode &snode, const bNodeLink &link); +void node_draw_link_dragged(const bContext &C, + const View2D &v2d, + const SpaceNode &snode, + const bNodeLink &link); /** * Don't do shadows if th_col3 is -1. */ -void node_draw_link_bezier(const View2D &v2d, +void node_draw_link_bezier(const bContext &C, + const View2D &v2d, const SpaceNode &snode, const bNodeLink &link, int th_col1, diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc index 127da55fcf6..45822818994 100644 --- a/source/blender/editors/space_node/node_templates.cc +++ b/source/blender/editors/space_node/node_templates.cc @@ -713,7 +713,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ } // namespace blender::ed::space_node void uiTemplateNodeLink( - uiLayout *layout, bContext * /*C*/, bNodeTree *ntree, bNode *node, bNodeSocket *input) + uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input) { using namespace blender::ed::space_node; @@ -727,7 +727,8 @@ void uiTemplateNodeLink( arg->node = node; arg->sock = input; - node_socket_color_get(*input->typeinfo, socket_col); + PointerRNA node_ptr = RNA_pointer_create(&ntree->id, &RNA_Node, node); + node_socket_color_get(*C, *ntree, node_ptr, *input, socket_col); UI_block_layout_set_current(block, layout);