3
$\begingroup$

I can copy the data path of any property in the user interface with Copy Data Path which is rigid_body.friction in the example screenshot. Is there a way how to get the property name using the copied data path?

enter image description here

name = getPropertyNameFromDataPath("rigid_body.friction")
print(name) # needs to output "Friction"
$\endgroup$

3 Answers 3

4
$\begingroup$
import bpy


def get_property_name(data, property) -> str:
    ''' Get the name of a property.

    data (AnyType) - Data from which to take property.
    property (str) - Identifier of property in data.
    return (str) - The name of the property.
    '''
    return data.rna_type.properties[property].name if hasattr(data, property) else ''


name = get_property_name(bpy.context.object.rigid_body, 'friction')

print(name)
$\endgroup$
6
  • $\begingroup$ it works for friction. but is it possible for a generalized function for all data paths? like it should also work for modifiers["Fluid"].flow_settings.surface_distance or any other property that you right click and Copy Data Path $\endgroup$ Jul 16, 2022 at 5:06
  • $\begingroup$ Yes, it will work on all properties. You have to give the data and property in this case C.object.modifiers['Fluid'].flow_settings is the data and surface_distance is the property. $\endgroup$
    – Karan
    Jul 16, 2022 at 5:29
  • $\begingroup$ It will not work from the copied data_path from the interface, you have to specify data and property $\endgroup$
    – Karan
    Jul 16, 2022 at 5:30
  • $\begingroup$ thanks so much for your code it helped me find a generalized solution! should i post a new answer or do you want me to edit your answer? $\endgroup$ Jul 16, 2022 at 5:53
  • $\begingroup$ i posted the solution :) thank you so much! $\endgroup$ Jul 16, 2022 at 6:35
1
$\begingroup$

A big thank you to @Karan for directing me into the right path. I was able to come up with a general solution for any data path (Right click RMB any property in the user interface > Copy Data Path) and then use the function:

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

Sample Outputs:

print(get_property_name('rotation_euler'))
print(get_property_name('rigid_body.collision_shape'))
print(get_property_name('modifiers["Bevel"].width'))
print(get_property_name('modifiers["Fluid"].flow_settings.surface_distance'))

# outputs:
#
# Eurler Rotation
# Collision Shape
# Width
# Surface Emission
$\endgroup$
5
  • 1
    $\begingroup$ This will only work on the object's properties $\endgroup$
    – Karan
    Jul 16, 2022 at 6:53
  • $\begingroup$ @Karan it works perfectly even modifiers. i added some sample outputs, let me know if you find something that doesn't work :) $\endgroup$ Jul 16, 2022 at 8:10
  • $\begingroup$ @Karan you're right it can only cater to objects and its modifiers. i still need to find a way to make it possible for node trees as well. maybe a hard-coded check for node_tree.nodes in node_tree.nodes["Principled BSDF"].inputs[5].default_value $\endgroup$ Jul 16, 2022 at 13:55
  • $\begingroup$ Why do you need such function? $\endgroup$
    – Karan
    Jul 16, 2022 at 14:03
  • $\begingroup$ so that i can auto add a driver to every field in the UI blender.stackexchange.com/questions/269433/… $\endgroup$ Jul 16, 2022 at 14:19
1
$\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$
1
  • $\begingroup$ thank you very much! this will come in handy! :) $\endgroup$ Jul 18, 2022 at 10:30

You must log in to answer this question.

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