0
$\begingroup$

I’m trying to write a script that will change the name of a parent bone. However digging for data I’m not getting what I suspected to get. I realize that to change data I will have to do it through Edit_Bones not data.bones, I’m just searching for names at this point.

My code currently looks like this:

  bpy.ops.object.mode_set(mode="OBJECT")
     for ob in bpy.data.objects:
        if ob.type == "ARMATURE" and ob.users !=0:
            for bone in ob.data.bones:
                print('%s, %s' %(bone.name, bone.parent))

What it returns look like this:

pelvis, None

spine_01, <"bpy_struct, Bone("pelvis")>

spine_02, <"bpy_struct, Bone("spine_01")>

spine_03, <"bpy_struct, Bone("spine_02")>

spine_04, <"bpy_struct, Bone("spine_03")>

The return is correct, but I want to be able to just return the parent bone name and be able to change it to something else.

If I try to use bone.parent.name the script errors out on the Root (Pelvis) Bone with a NoneType Error.

Traceback (most recent call last): File "C:\Users\ME\Desktop\PKTEST\Clown_REdo.blend\toTxt_BoneRolls.py", line 41, in AttributeError: 'NoneType' object has no attribute 'name' Error: Python script fail, look in the console for now...

How would I get just the Parent name (Right side of the comma) for the bone on the left?

$\endgroup$
5
  • $\begingroup$ A parent value of None indicates no parent bone. Something like getattr(bone.parent, "name", "None") will return "None" if the bone.parent is None. $\endgroup$
    – batFINGER
    Commented Oct 23, 2018 at 6:38
  • $\begingroup$ batFinger you are great at answering these things. In fact, I think you're batting 98% of or all my questions asked. (lol) $\endgroup$
    – PteJack
    Commented Oct 23, 2018 at 7:03
  • $\begingroup$ The getattr() returns what I'm looking for , but how would I update this. I use a dictionary and code like 'code' bones = bpy.context.selected_objects[0].data.bones if (bones): for bone in bones: newName = names.get(bone.name) if (newName): bone.name = newname 'code' $\endgroup$
    – PteJack
    Commented Oct 23, 2018 at 7:10
  • $\begingroup$ That is the code I use for renaming bones. Not what I would use in this case or parents, or would it work if I switch to edit_bones and a code like if (newName): bone.parent.name = newname $\endgroup$
    – PteJack
    Commented Oct 23, 2018 at 7:16
  • 1
    $\begingroup$ and for gawd sake, answer the question so I can credit you!!! lol $\endgroup$
    – PteJack
    Commented Oct 23, 2018 at 7:18

1 Answer 1

2
$\begingroup$

Since parent as a property is always present (being either an object or None and objects always have a name) you can make a ternary conditional inside the print since it's the second access that causes issues not the first (accessing the parent's name not accesing the parent itself).

print('%s, %s' %(bone.name, bone.parent.name if bone.parent else "No Parent"))

When updating the property, similarly you can simply check or place it inside a try/except block:

if bone.parent:
     bone.parent.name = ""

or

try:
     bone.parent.name = ""
except:
     pass
$\endgroup$

You must log in to answer this question.

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