This is a followup to my previous question. While that answer tells me how to stack all nodes along the x axis, I now need to stack certain nodes along the y axis, at the same x axis point.

My code right now uses this loop:

for i in node_names:
    nodes[i].location.x = locx
    locx += nodes[i].width + 50
    nodes[i].location.y = 0
    if nodes[i].type == "TEX_IMAGE":
        nodes[i].location.y = locy
        locy += nodes[i].height + 200
        newlocx = nodes[i].location.x
        nodes[i].location.x = newlocx

This gives me a result where the nodes "staircase" up the graph.

enter image description here

I think what I want is to remember the x value of the first image node, but only the first one, and save it to a variable. That way I can just pass that coord as the x value for the rest of them.

I have tried setting the image nodes as their own array and looping through it, but that throws an error because the blender's method doesn't process lists, it processes strings or ints.

I can provide more context if need be.

  • $\begingroup$ The main question is how dynamic you want your script to be. Do you have a list of the nodes in the correct order, or do you want the script to generate the order along x axis automatically (which will be much more complicated)? $\endgroup$ – Dimali Aug 24 '17 at 17:53
  • $\begingroup$ In my script, the order is generated correctly; although I use reversed() when it is called so that it writes it out in the correct order. $\endgroup$ – Rug Aug 24 '17 at 19:23
import bpy

node_names = ['Texture Coordinate', 'Mapping', 'Image Texture','Image Texture 2','Diffuse BSDF','Material Output']
nodes = bpy.data.materials['Material'].node_tree.nodes
startlocy = 0
startlocx = 0

locx = startlocx
locy = startlocy
# Set the first node's X and y coords to 0,0
nodes[node_names[0]].location.x = locx
nodes[node_names[0]].location.y = locy
# For index, node in the list 'node_names'
for i, node in enumerate(node_names[1:]):
    # Set the last used node
    lastnode = node_names[i]
    #if the last node AND the current node are texture images
    if nodes[lastnode].type == "TEX_IMAGE" and nodes[node].type == "TEX_IMAGE":
        # Set current node to the height of the last one plus 200px
        locy += nodes[lastnode].height + 200
        # Otherwise, set the y to the default (0)
        locy = startlocy
        # Set the x to the width of the node plus 50px
        locx += nodes[lastnode].width + 50
    nodes[node].location.x = locx 
    nodes[node].location.y = locy 

This seems to work if your texture nodes have the same width, else only the highest node influences the next x position. You need to write the node names in the right order in the list node_names.

|improve this answer|||||

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.