1
$\begingroup$

When putting a node near a frame node Blender will sometimes automatically include the node into the frame. I find that behavior to be quite annoying, is there a way to disable it?

$\endgroup$
6
  • 2
    $\begingroup$ There is no "near a frame node" here. When you drag and drop a node over frame, the position of the mouse pointer determines whether the node is embedded in the frame or not. $\endgroup$
    – quellenform
    Jun 15, 2022 at 12:29
  • $\begingroup$ github.com/blender/blender/blob/master/source/blender/editors/… $\endgroup$
    – quellenform
    Jun 15, 2022 at 16:27
  • $\begingroup$ Well you kind of can, with Python, a script where you would add "locked" frames, and it would very frequently check if the children of those frames changed, if so, it would unparent the children. The tricky part would be optimizing the script so it's not too slow for a lot of nodes/node trees... $\endgroup$ Jun 15, 2022 at 21:14
  • $\begingroup$ @MarkusvonBroady I think I'm starting to understand what he's getting at.... Therefore, the question to the Python guru: Would it be theoretically possible to draw free forms that can be drawn independently of all nodes and behave similarly to frames (or exactly like frames, only that no nodes can be dropped in them)? $\endgroup$
    – quellenform
    Jun 15, 2022 at 23:32
  • 1
    $\begingroup$ @quellenform might be possible, though probably too much work: you need to program in resizing the frame, auto-resize if you want it, saving to/loading from a file... And still you can't easily share it in this form. \@tempdev - I don't think so, checked the attributes of a frame just now, and I didn't see any option not accessible from the interface. There's also no event that you could capture and block for a particular frame. $\endgroup$ Jun 16, 2022 at 16:02

2 Answers 2

2
$\begingroup$

When you drag and drop a node over a frame, the position of the mouse pointer determines whether the node is embedded in the frame or not.

Can I change this behavior in a solid way?

No. -> Source

Can I manipulate it with a hack that comes out with what do I know?

Somehow, see Markus's answer (He seems to have somehow managed once again to bend Blender completely with his Python skills) 😊

$\endgroup$
5
  • $\begingroup$ Yes I know that. I want to disable this feature, so that it never embeds it in the frame. $\endgroup$ Jun 15, 2022 at 13:28
  • 1
    $\begingroup$ @tempdevnova It looked like you knew this, but the answer can only be completed with a clear "no". How else would it be possible to put a node into a frame? $\endgroup$
    – quellenform
    Jun 15, 2022 at 14:20
  • $\begingroup$ The only way you can disable this feature is to edit the source code responsible for this behavior. you can checkout the blender repository by doing a git clone git://git.blender.org/blender.git and edit the source file Source then compile the blender program again. Here's more information wiki.blender.org/wiki/Tools/Git $\endgroup$ Jun 16, 2022 at 0:04
  • $\begingroup$ @quellenform you can manually put a node inside a frame using CTRL P $\endgroup$ Jun 16, 2022 at 13:07
  • $\begingroup$ @tempdevnova I like the idea too ;-) ...I would suggest to implement this as an option in the settings and bring it into the source code of Blender. Then you (and others) have that switchable in the future. $\endgroup$
    – quellenform
    Jun 16, 2022 at 13:17
1
$\begingroup$

Python

You can use the strategy from this answer:

Driver based on shading types/ change boolean when switching shading types

to constantly poll and check if bpy.ops.node.translate_attach was executed. If so, check if node selection stayed the same (very unlikely, since typically you change selection with an operator). If so, it's possible that you've just inserted a node into a frame, so check against the mapping you update whenever the above-mentioned checks fail.

import bpy
from bpy import context as C
from bpy.types import SpaceNodeEditor as SNE

last_selection = []
last_parenting = {}

def test():
    if not C.active_operator or C.active_operator.name != 'Move and Attach':
        update_last()
        return
    sel = C.selected_nodes
    if sel != last_selection:
        update_last()
        return
    if not sel:  # empty
        return
    # node_tree = C.annotation_data_owner
    node_tree = sel[0].id_data
    nodes = node_tree.nodes
    for node_name, old_parent in last_parenting.items():
        n = nodes[node_name]
        if old_parent is None:
            if n.parent:
                print("remove unwanted parent")
                n.parent = None
        elif n.parent.name != old_parent:
            # the node would move from a frame to a nested frame
            print("restore old parent")
            n.parent = nodes[old_parent]


def update_last():
    sel = C.selected_nodes[:]
    global last_parenting
    # `a and b` gives b if a is truthy
    last_parenting = {n.name: (n.parent and n.parent.name) for n in sel}
    global last_selection
    last_selection = sel


try:
    SNE.draw_handler_remove(SNE.my_handler, 'WINDOW')
except (AttributeError, ValueError):
    pass

SNE.my_handler = SNE.draw_handler_add(test, (), 'WINDOW', 'PRE_VIEW')

Note: You can still parent with ✲ CtrlP, since this shortcut runs a different operator bpy.ops.node.parent_set.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .