2
$\begingroup$

In this example I will use a Voronoi Texture node, and then eventually understand how to manage the other Textures nodes with options.

Let's start with these settings:

enter image description here

In this example, the node exposes these properties:

n.voronoi_dimensions
n.feature
n.distance

Here we already have the first problem, assuming we want to draw these properties, it seems we should know them and then draw them in a panel:

def draw(self, context, node):
    layout = self.layout
    col = layout.column()
    
    col.prop(node, 'voronoi_dimensions')
    col.prop(node, 'feature')
    col.prop(node, 'distance')

    for i in node.inputs:
        if i.is_linked:
            continue

        if i.is_unavailable:
            continue

        col.prop(i, 'default_value', text=i.name)

This code above will draw a panel with such properties.

This code above will draw a panel with such properties, but only if the node in question is a texture Voronoi node. Otherwise it will fail.

So is there a way to understand which properties are exposed? (Such as node inputs for example)

Furthermore, I ask this because precisely, these nodes have different situations, like this:

enter image description here

Same node but in this case some properties will not be exposed, they will still be present in the node, but they will not have any use.

It would be useful to know if there is a way to understand which properties are drawn on the node, to intercept them and draw them in a panel, but I don't know if there are any that can help with this.

The goal is to have a dynamic function that analyzes the node and finds the properties exposed on that node.

Little panel Example:

enter image description here


Note:

In order to draw the properties, i found solution:

for key in node.bl_rna.properties.keys():
    if node.is_property_readonly(key):
        continue

    prop = node.bl_rna.properties[key]

    # Check if the property is a EnumProperty
    if prop.type != 'ENUM':
        continue

    row = col.row()
    row.prop(node, key, text=str(key))

The problem remains, however, I don't know which property will actually be drawn on the node, therefore usable.

$\endgroup$

1 Answer 1

3
$\begingroup$

Starting with Blender 4.1+ you can use template_node_inputs()

import bpy


class HelloWorldPanel(bpy.types.Panel):
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Test"

    def draw(self, context):
        layout = self.layout

        material = bpy.data.materials.get("Material")
        
        voronoi_node = material.node_tree.nodes.get("Voronoi Texture")
        
        layout.template_node_inputs(voronoi_node)


def register():
    bpy.utils.register_class(HelloWorldPanel)


def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ very nice. thanks for sharing. would be cool though if you could also show how you can show only certain properties instead of all? $\endgroup$
    – Harry McKenzie
    Commented May 18 at 4:48

You must log in to answer this question.

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