# version blender 4.2
import bpy
from bpy.utils import escape_identifier
blendData_to_class = {
"actions": "Action",
"armatures": "Armature",
"brushes": "Brush",
"cache_files": "CacheFile",
"cameras": "Camera",
"collections": "Collection",
"curves": "Curve",
"fonts": "VectorFont",
"grease_pencils": "GreasePencil",
"hair_curves": "Curves",
"images": "Image",
"lattices": "Lattice",
"libraries": "Library",
"lightprobes": "LightProbe",
"lights": "Light",
"linestyles": "FreestyleLineStyle",
"masks": "Mask",
"materials": "Material",
"meshes": "Mesh",
"metaballs": "MetaBall",
"movieclips": "MovieClip",
"node_groups": "NodeTree",
"objects": "Object",
"paint_curves": "PaintCurve",
"palettes": "Palette",
"particles": "ParticleSettings",
"pointclouds": "PointCloud",
"scenes": "Scene",
"screens": "Screen",
"shape_keys": "Key",
"sounds": "Sound",
"speakers": "Speaker",
"texts": "Text",
"textures": "Texture",
"volumes": "Volume",
"window_managers": "WindowManager",
"workspaces": "WorkSpace",
"worlds": "World"}
class_to_blendData = {v: k for k, v in blendData_to_class.items()}
def get_ob_dp(obj):
try:
if hasattr(obj, "library") and obj.library:
return f'bpy.data.{class_to_blendData[obj.rna_type.identifier]}["{escape_identifier(obj.name)}", "{escape_identifier(obj.library.filepath)}"]'
else:
return f'bpy.data.{class_to_blendData[obj.rna_type.identifier]}["{escape_identifier(obj.name)}"]'
except:
return ""
def get_full_dp(base_object, attrs):
dp = get_ob_dp(base_object)
if dp:
if not attrs:
return dp
if attrs.startswith('["'):
return f'{dp}{attrs}'
return f'{dp}.{attrs}'
return ""
Get bone datapath
ob = bpy.data.armatures[0]
bone = ob.bones[0]
dp = get_full_dp(ob, f'bones["{escape_identifier(bone.name)}"].bbone_segments')
print(dp)
# >>>> bpy.data.armatures["Armature"].bones["Bone"].bbone_segments
Custom properties
ob = bpy.context.object
dp = get_full_dp(ob, '["prop"]')
print(dp)
# >>>> bpy.data.objects["Armature"]["prop"]
Linked Data-block
ob = bpy.context.object
dp = get_full_dp(ob, "")
print(dp)
# >>>> bpy.data.objects["Cube", "D:\\OneDrive\\Blender\\test.blend"]
escape_identifier
s = escape_identifier('\n"abc中"')
print(s)
# >>>> \n\"abc中\"
Tips and hints
Avoid using single quotes in blender datapath
# Wrong way:
import bpy
ob = bpy.context.object
dp = "modifiers['Boolean'].show_render"
fc = ob.animation_data.action.fcurves.find(dp)
print(fc) # It get None when the datapath has keyframes
# Correct Way:
dp = 'modifiers["Boolean"].show_render'
# and don't forget to check if animation_data exists and is None
Get All Object Keys
# Wrong way:
import bpy
kys = bpy.data.objects.keys()
print(kys)
# >>>> ['Cube', 'Cube']
# Correct way:
def get_key(ob):
if hasattr(ob, "library") and ob.library:
return ob.name, ob.library.filepath
return ob.name
kys = [get_key(ob) for ob in bpy.data.objects]
print(kys)
# >>>> ['Cube', ('Cube', 'D:\\OneDrive\\test.blend')]