11

The node editor is constantly changing due to cycles. There are new nodes in every release of blender so I'd like to know whether there is a way to get all available node types in a list. I remembered that Node Wrangler has this beautiful "switch my node to something else" thing, which I thought already implements that functionality. However, all nodes are hard coded like that:

shaders_output_nodes_props = (
    ('ShaderNodeOutputMaterial', 'OUTPUT_MATERIAL', 'Material Output'),
    ('ShaderNodeOutputLamp', 'OUTPUT_LAMP', 'Lamp Output'),
    ('ShaderNodeOutputWorld', 'OUTPUT_WORLD', 'World Output'),
)

Q: Is there a way to get a complete list of all available node types by category and ideally all custom groups as well with bpy.types or something similar?

brockmann
  • 12,613
  • 4
  • 50
  • 93

3 Answers3

16

This addresses the second part of your question. How to auto generate all this.

Node Category (cycles) and each registered node.bl_idname in the category

import bpy

ddir = lambda data, filter_str: [i for i in dir(data) if i.startswith(filter_str)]
get_nodes = lambda cat: [i for i in getattr(bpy.types, cat).category.items(None)]

cycles_categories = ddir(bpy.types, "NODE_MT_category_SH_NEW")
for cat in cycles_categories: 
    print(cat)
    for node in get_nodes(cat):
        print('bl_idname: {node.nodetype}, type: {node.label}'.format(node=node))      

Output is (snipped):

NODE_MT_category_SH_NEW_CONVERTOR
bl_idname: ShaderNodeBlackbody, type: Blackbody
bl_idname: ShaderNodeValToRGB, type: ColorRamp
bl_idname: ShaderNodeCombineHSV, type: Combine HSV
bl_idname: ShaderNodeCombineRGB, type: Combine RGB
bl_idname: ShaderNodeCombineXYZ, type: Combine XYZ
bl_idname: ShaderNodeMath, type: Math
bl_idname: ShaderNodeRGBToBW, type: RGB to BW

Custom Node Groups of type ShaderNodeTree

[ng for ng in bpy.data.node_groups if ng.bl_idname == 'ShaderNodeTree']
brockmann
  • 12,613
  • 4
  • 50
  • 93
zeffii
  • 39,634
  • 9
  • 103
  • 186
  • I can't tell if I should just delete my answer now that you have answered it far better. – Ray Mairlot May 21 '17 at 16:06
  • What a mess... Thanks @zeffii. Is there a way get all custom groups in this way too? – brockmann May 21 '17 at 16:08
  • @RayMairlot keep your answer, someone might invest time in making a "prettier" answer than this silly example of mine :). – zeffii May 21 '17 at 17:02
  • @brockmann custom groups ? ill add that.. – zeffii May 21 '17 at 17:06
  • I don't like to call something a mess when it can be achieved in just a few lines of python. Hardcoding all of those mapping lists just doesn't seem right. – zeffii May 22 '17 at 07:54
  • 1
    Right, didn't meant your code. I meant that the majority of blender's API is well designed (far better than in many other DCC's). However when it comes to the node editor it feels mad sometimes. In this case that's a heavy iteration to get 30 node types (IMHO). Nevermind, many many thanks for posting that @zeffii – brockmann May 22 '17 at 08:34
  • 2
    I agree, some of parts of the API are a little lacking. Iterate once, and then cache it in a dict. – zeffii May 22 '17 at 08:39
8

Yes, this is possible in a similar way to Best way to get a list of modifiers in Python?

You can use bpy.types.ShaderNode.__subclasses__() to see everything which uses ShaderNode as its base, e.g. the Cycles nodes.

This returns a list of all the nodes, from which you can extract information. Below, I collect the identifier of each node and then print them out:

import bpy

nodes = [node.bl_rna.identifier for node in bpy.types.ShaderNode.__subclasses__()]

for node in nodes:
    print(node)

Result:

ShaderNodeLightFalloff
ShaderNodeBsdfVelvet
ShaderNodeCombineXYZ
ShaderNodeBackground
ShaderNodeHoldout
ShaderNodeTexPointDensity
ShaderNodeMaterial
etc...
etc..
etc.

Using node.bl_rna.name instead of node.bl_rna.identifier would result in:

Light Falloff
Velvet BSDF
Combine XYZ
Background
Holdout
Point Density
Material
etc...
etc..
etc.

To explore the available properties, e.g. identifier, name etc. you can enter this in the Python Console:

nodes = bpy.types.ShaderNode.__subclasses__()

Then to access a single node type this and press Ctrl+Space to autocomplete and show the available options:

nodes[0].bl_rna.   
Ray Mairlot
  • 29,192
  • 11
  • 103
  • 125
  • 2
    Thanks. Is there any way to get the categories too? – brockmann May 17 '17 at 12:59
  • What do you mean by categories? If you mean the 'Add' menu, I presume that's defined manually. If there is a property on the node that does that, I haven't found it yet. – Ray Mairlot May 17 '17 at 13:09
  • If this answer has helped you, please consider accepting it. See: http://stackoverflow.com/help/accepted-answer – Ray Mairlot May 17 '17 at 13:14
  • 1
    Yes, Shader, Texture, Color and so on. Populating a complete list would be awesome, furthermore your solution not work for custom groups... (upvoted already) – brockmann May 17 '17 at 14:41
  • I think as far as the current question goes, I have answered it, but in regards to your additional comments you should probably add those details into your original question. – Ray Mairlot May 17 '17 at 14:49
  • @brockmann Node groups are accessible with bpy.data.node_groups. Is that what you mean? – Ray Mairlot May 17 '17 at 15:17
  • Yeah, I think we can combine both worlds... Thanks, I'll give it a try @RayMairlot. – brockmann May 17 '17 at 15:23
  • In blender 4.0, the first answer here doesn't seem to work anymore (prints an empty list) and the second answer only prints a few nodes, not all of them. I'm actually trying to print a list of all Geometry Nodes. Any help appreciated. – Peeter Maimik Dec 09 '23 at 23:04
1
import bpy

def GetAllNodes(target):
    set_result = set()
    for li in bpy.types.__dir__():
        type = getattr(bpy.types, li)
        if hasattr(type,'bl_rna'):
            base = type.bl_rna.base
            while base:
                if base.identifier==target:
                    set_result.add(type.bl_rna.identifier)
                    break
                base = base.bl_rna.base
    return set_result

print(len(GetAllNodes('Node')), "All")
print(len(GetAllNodes('ShaderNode')), "Shader")
print(len(GetAllNodes('GeometryNode')), "Geometry")
print(len(GetAllNodes('CompositorNode')), "Compositor")
print(len(GetAllNodes('TextureNode')), "Texture")
ugorek
  • 997
  • 1
  • 2
  • 15