1
$\begingroup$

In this post Is it possible to get the property name from a data_path? I am able to get the field names from RMB > Copy Data Path in all object properties as well as their modifier name fields using this code:

def get_property_name(data_path) -> str:
    s = data_path
    i = s.find('.')
    data_path_1 = ""
    data_path_2 = data_path
    if i > 0:
        ri = s.rindex('.')
        data_path_1 = '.' + s[0:ri]
        data_path_2 = s[ri+1:len(s)]
    data_block = "bpy.context.object"
    data = eval(data_block + data_path_1)
    return data.rna_type.properties[data_path_2].name if hasattr(data, data_path_2) else ''

Unfortunately if you change the line data_block = "bpy.context.object" with, for example the default material of the default cube named Material value to line data_block = 'bpy.data.materials["Material"]' and then call the function with any node field's data path, it will always return the same name Default Value. For example, the data path for the node field Subsurface Radius is node_tree.nodes["Principled BSDF"].inputs[2].default_value and will return the name Default Value instead of Subsurface Radius as will all the other node fields. Is there any other way how we can retrieve the node field name?

enter image description here

$\endgroup$

2 Answers 2

2
$\begingroup$

This method here will work for all node trees including Shader Nodes, Compositor Nodes, and Geometry Nodes.

material = bpy.data.materials['Material']
path = 'node_tree.nodes["Principled BSDF"].inputs[2].default_value'
material.path_resolve(path, False).data.name  # => Subsurface Radius
$\endgroup$
4
  • $\begingroup$ excellent!! thank you soo much! $\endgroup$
    – Harry McKenzie
    Commented Jul 18, 2022 at 8:37
  • $\begingroup$ there are times i pass an incorrect path and path_resolve throws an error, is there some check i can make before calling this function? something like if is_path_resolveable(): path_resolve()? $\endgroup$
    – Harry McKenzie
    Commented Jul 21, 2022 at 12:40
  • $\begingroup$ Use a try and catch the error. $\endgroup$
    – scurest
    Commented Jul 21, 2022 at 12:45
  • $\begingroup$ hmmm yeah but i tried to avoid that as it is expensive XD well if there's no other way, then i'll use a try/catch :) thanks! $\endgroup$
    – Harry McKenzie
    Commented Jul 21, 2022 at 12:50
2
$\begingroup$

Use Full Data Path instead of Data Path

import bpy


def get_property_name_from_data_path(data_path) -> str:
    ''' Get the name of a property.

    data_path (str) - Data path from which to take data and property.
    return (str) - The name of the property.
    '''
    data = eval('.'.join(data_path.split('.')[:-1]))
    property = data_path.split('.')[-1]
    if property == 'default_value':
        return data.name

    return data.rna_type.properties[property].name if hasattr(data, property) else ''

name = get_property_name_from_data_path('bpy.data.materials["Material"].node_tree.nodes["Principled BSDF"].inputs[2].default_value')

print(name)
$\endgroup$
3
  • $\begingroup$ thank you. unfortunately, i can't use full data path because i'm depending on the keying_set feature. when i do Add to Keying Set it will only put the relative path. So i only have that value to deal with. $\endgroup$
    – Harry McKenzie
    Commented Jul 18, 2022 at 9:17
  • 1
    $\begingroup$ Ok, but this will work on every property. $\endgroup$
    – Karan
    Commented Jul 18, 2022 at 9:19
  • $\begingroup$ but yeah this is also really cool it can get the name for every property for all node trees! great job and thank you very much! $\endgroup$
    – Harry McKenzie
    Commented Jul 18, 2022 at 9:21

You must log in to answer this question.

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