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$
  • $\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 Oct 23 '18 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 Oct 23 '18 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 Oct 23 '18 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 Oct 23 '18 at 7:16
  • 1
    $\begingroup$ and for gawd sake, answer the question so I can credit you!!! lol $\endgroup$ – PteJack Oct 23 '18 at 7:18
1
$\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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.