3
$\begingroup$

The aim of the question is to calculate a node tree layout for a generated node tree.

Nodes have height, width and dimensions.

It seems that dimensions corresponds to some default size and that height and width to the currently displayed dimensions. But these last two are not set until the node is effectively displayed somewhere in the editor (or am I wrong?).

But if you want to generate a node layout for a material or a node tree which is itself generated and which is not displayed for now, is it possible to get the dimensions? If yes, how?

We can:

bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)

to force a layout calculation. But this works only when the node tree is displayed in the Node Editor (at least it seems to be the case).

How can we get the 'future' default dimensions so that a node tree layout could be calculated?

Edit: Some extra details

When creating a node tree, it is not displayed until it is used (instantiated) in a material and opened for editing.

In this case,

  • width and height are some default values: 140 and 100
  • dimensions is a Vector(0.0000, 0.0000)

I've experimented and found that these values are updated when the node is displayed (and bpy.ops.wm.redraw() is called). So that typically, the Principled and Diffuse shader nodes do not end up having the same dimensions. But before that, the dimension values are as given above.

The complete code is hard to share here, but here are some basic snippets:

Creating a node tree (node group) is:

node_group = node_groups.new( node_group_name, 'ShaderNodeTree' )

Creating a material is:

material = materials.new( material_name )

Creating a node in both cases:

self.internal_node = node_tree_nodes.new( type = self.name )

But once the data is created, there are two cases:

The node tree is displayed in a view and

bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)

can be use to 'force' a layout update and get the dimensions (if this bpy.ops is not called height, width, and dimensions are not updated).

Or the node tree (bpy.data.node_groups typically) is not displayed and I can't find a way to retrieve the 'future displayed' dimensions.

$\endgroup$
  • $\begingroup$ Can you give a little more info about what you're doing? As soon as I create a node with node_tree.nodes.new('nodeType') it adds the node to the node tree anyway. How are you creating nodes but not displaying them? $\endgroup$ – Ray Mairlot Aug 22 at 14:15
  • 1
    $\begingroup$ @RayMairlot, typically it's the case when creating a node tree which is not displayed until an instance of it is linked to a material. Will add code samples to explain better. $\endgroup$ – lemon Aug 22 at 18:27
  • $\begingroup$ @RayMairlot, the node trees or materials are correctly created (and can be used), this is only a layout problem. $\endgroup$ – lemon Aug 22 at 18:36
  • $\begingroup$ @RayMairlot, thanks for the edit. $\endgroup$ – lemon Aug 22 at 19:24
  • 1
    $\begingroup$ My guess is that the values aren't hard coded because the size the node displays at is dependant on the theme settings and the interface display size/dpi (ui_scale in 2.79 preferences). Changing the display size causes the dimensions to change. Maybe there's a way of combining these values with the dimensions to arrive at the final size. $\endgroup$ – Ray Mairlot Aug 22 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.