1
$\begingroup$

I'm trying to write a function for my script that will distribute the standard 5 nodes along the x axis, without overlapping.

My current setup looks like this:

for index, node in enumerate((texCoord, mapping, texture, diffuse, output)):
node.location.x = 200.0 * index

This works well, and will separate the nodes equally at 200 px apart, which is fine normally but the mapping node is a little over-sized, and it covers my image texture.

Like so: nodes distributed but overlaping

edit: I have tried an if statement, that looked like:

for index, node in enumerate((texCoord, mapping, texture, diffuse, output)):
if node == mapping:
    node.location.x = 400.0 * index
else:
    node.location.x = 200.0 * index

but that does this:

I also tried adjusting the values, like so:

for index, node in enumerate((texCoord, mapping, texture, diffuse, output)):
if node == mapping:
    node.location.x = 100.0 * index
else:
    node.location.x = 250.0 * index

But that ends up not moving the texture coordinate enough:

I also tried using a while loop, but that crashes blender.

I feel like there is probably a better way to adjust for this size, but I can't think of anything.

$\endgroup$

2 Answers 2

3
$\begingroup$

Because nodes are not necessarily in the order we want in the node tree, I made a list of the nodes in their proper order (listing them from left to right). I then loop through that list and get the nodes by name in the node tree, moving them accordingly.

import bpy

nodes = bpy.data.materials['Material'].node_tree.nodes
list = ['Texture Coordinate', 'Mapping', 'Checker Texture','Diffuse BSDF', 'Material Output']
loc = 0
for i in list:
    nodes[i].location.x = loc
    loc += nodes[i].width + 50
    nodes[i].location.y = 0

The script is rather simple. I loop through my list of node names; then simply set the node's x location to the loc variable.
The next line loc += nodes[i].width + 50 is adding the width of the node, plus 50 (the margin around the nodes) to the already tallied widths.
Then next time around the next node will get moved over that amount.

The only important part is that you add the width of the node to the loc variable after the node has been moved.

$\endgroup$
7
  • $\begingroup$ Wow! I had no idea that the area around the node was a measured attribute. That is awesome. $\endgroup$
    – Rug
    Commented Aug 17, 2017 at 23:24
  • $\begingroup$ When you access the nodes using node_tree.nodes, it returns the name of each node inside the material as a string? If not, how is the connection between the string name and the node itself established? $\endgroup$
    – Rug
    Commented Aug 18, 2017 at 0:18
  • $\begingroup$ Yep you are right I am storing the nodes' name in my list. node_tree.nodes['Mapping'] is one way to get to the mapping node. However if it was the second mapping node I added to the tree, its name by default would be "Mapping.001" $\endgroup$
    – David
    Commented Aug 18, 2017 at 0:41
  • $\begingroup$ Thats really neat. Lets say we do need 2 mapping nodes, just for the sake of the argument. How might you change that to be more flexible? Or would you just go and hardcode the name "Mapping.001" instead of "Mapping" into a secondary list? $\endgroup$
    – Rug
    Commented Aug 18, 2017 at 1:08
  • 1
    $\begingroup$ @Rug well kind of. It would be easy to loop through the nodes and get all "TEX_IMAGE" (node[].type) but then what? Ask yourself: how do you want to sort them? alphabetically wont help any, so you will need some metric, maybe the node connections to get something useful to sort on. $\endgroup$
    – David
    Commented Aug 18, 2017 at 13:14
0
$\begingroup$

In order to space it out far enough, I have increased the pixel difference for both the regular index as well as the mapping node. This is my code now:

for index, node in enumerate((texCoord, mapping, texture, diffuse, output)):
if node == mapping:
    node.location.x = 200.0 * index
else:
    node.location.x = 300.0 * index

I still feel like there must be a more elegant solution, but I will leave this answer for those in the meantime.

$\endgroup$

You must log in to answer this question.

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