1

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?

quellenform
  • 35,177
  • 10
  • 50
  • 133
tempdev nova
  • 1,495
  • 4
  • 21
  • 2
    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. – quellenform Jun 15 '22 at 12:29
  • https://github.com/blender/blender/blob/master/source/blender/editors/space_node/node_relationships.cc#L2208 – quellenform Jun 15 '22 at 16:27
  • 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... – Markus von Broady Jun 15 '22 at 21:14
  • @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)? – quellenform Jun 15 '22 at 23:32
  • @MarkusvonBroady isn't it possible to simple disable the ability of a node frame to accept new nodes into it? – tempdev nova Jun 16 '22 at 13:09
  • 1
    @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. – Markus von Broady Jun 16 '22 at 16:02

2 Answers2

2

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)

quellenform
  • 35,177
  • 10
  • 50
  • 133
  • Yes I know that. I want to disable this feature, so that it never embeds it in the frame. – tempdev nova Jun 15 '22 at 13:28
  • 1
    @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? – quellenform Jun 15 '22 at 14:20
  • 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 https://wiki.blender.org/wiki/Tools/Git – Harry McKenzie Jun 16 '22 at 00:04
  • @quellenform you can manually put a node inside a frame using CTRL P – tempdev nova Jun 16 '22 at 13:07
  • @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. – quellenform Jun 16 '22 at 13:17
1

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.

Markus von Broady
  • 36,563
  • 3
  • 30
  • 99