I am trying to write a script where nodes are spawned and sorted according to where they need to be in the node editor. Thanks to help from other users, I have learned to move the nodes properly. However, the answers they provided used a hard-coded list:
atomicNodes = ['Texture Coordinate', 'Mapping', ...] imageTextures = ['Image Texture', 'Image Texture.001', 'Image Texture.002']
I have a method of returning a list of nodes that exist in the scene, but they aren't instantiated as a list when I call them:
for i in atomicNodes: nodes[i].location.x = locx locx += nodes[i].width + 50 nodes[i].location.y = 0 for i in imageTextures: nodes[i].location.y = locy locy += nodes[i].height + 200 nodes[i].location.x = nodes.location.x
When I go ahead and just print out the nodes, in the scene using:
it gives me this in the console:
Using the Python documentation for listing dictionary keys in this format:
nodes = bpy.data.materials['Material'].node_tree.nodes nodeValues = nodes.values() nodeKeys = nodes.keys()
then changing the variable atomicNodes to
atomicNodes = nodeKeys
Makes it run correctly.
Here are the scripts on GitHub, I am using the latest release candidate for 2.79 because I am interacting with the principled shader, but I have been having this issue while testing in stable versions of 2.78 too.
Edit: The issue seems to be that while the nodes variable
nodes = bpy.data.materials['Material'].node_tree.nodes
is a dictionary already by default, when I get the Image Texture nodes it is converted to a list, which I obviously can't grab keys from.
When I use my method to collect the Image Textures, it places them into a List already. Unfortunately there is a lot of extra content that I don't need:
[bpy.data...nodes["Image Texture"], bpy.data...nodes["Image Texture.001"], bpy.data...nodes["Image Texture.002"]]
I only want what is inside of the quotation marks of this list, is there any way of doing that aside from regular expressions?