Blender python 骨をアーマチュアに追加する

やあ

同じボーン階層のキャラクターをいっぱい作った後に、骨を追加したいなって思って書いたよ。
※注意 : 今回はやってることはリーフボーンの追加なので、骨と骨の間に追加したい場合はちょっと書き換える必要があります。自分で使う機会があれば追記します。

スクリプト

import bpy
from typing import List, Any

def get_obj(name : str):
    return bpy.data.objects.get(name)
     
bpy.ops.object.mode_set(mode='OBJECT')

"""
骨を追加したいアーマチュアの名前
"""
target_obj_names = [
"Armature_A",
"Armature_B"
]

class NewBoneSpec:
    def __init__(self, 
        NewBoneName: str, ParentName: str, 
        Head: List[float] = [0.0, 0.0, 0.0], 
        Tail: List[float] = [0.0, 0.0, 1.0], 
        Roll: float = 0.0,
        bAutoTransform: bool = False
    ):
        self.parent = ParentName
        self.new_bone = NewBoneName
        self.head = Head
        self.tail = Tail
        self.roll = Roll
        self.bAutoTransform = bAutoTransform

class NewBoneMaker:
    def __init__(self, 
        Spec: NewBoneSpec,
        Armature: Any
    ):
        self.spec = Spec
        self.Armature = Armature
    def DoMake(self):
        if self.Armature:
            edit_bones = self.Armature.data.edit_bones
            if edit_bones:
                if not edit_bones.get(self.spec.new_bone):
                    new_bone = edit_bones.new(self.spec.new_bone)
                    if new_bone:
                        parent = target_edit_bone.get(self.spec.parent)
                        if parent:
                            new_bone.parent = target_edit_bone.get(self.spec.parent)
                            if self.spec.bAutoTransform:
                                head = [new_bone.parent.tail[0], new_bone.parent.tail[1], new_bone.parent.tail[2]]
                                new_bone.head = head
                                tail = [head[0], head[1], head[2] + 1.0]
                                new_bone.tail = tail
                                new_bone.roll = 0.0
                            else:
                                new_bone.head = new_bone_spec.head
                                new_bone.tail = new_bone_spec.tail
                                new_bone.roll = new_bone_spec.roll

new_bone_specs = [
    NewBoneSpec(NewBoneName="Weapon_R", ParentName="Hand_R", bAutoTransform=True),
    NewBoneSpec(NewBoneName="Weapon_L", ParentName="Hand_L", bAutoTransform=True),
]
for target_obj_name in target_obj_names:
    target_armature = get_obj(target_obj_name)
    if target_armature:
        target_armature.select = True
        bpy.ops.object.mode_set(mode='EDIT')
        target_edit_bone = target_armature.data.edit_bones
        if target_edit_bone:
            for new_bone_spec in new_bone_specs:
                new_bone_maker = NewBoneMaker(new_bone_spec, target_armature)
                new_bone_maker.DoMake()
        target_armature.select = False
    bpy.ops.object.mode_set(mode='OBJECT')

使い方

  1. target_obj_namesに骨を追加したいアーマチュアの名前を入れます。
  2. new_bone_specsに、新しく追加したい骨の名前と、その親の骨の名前を入れます。
    このとき、トランスフォームを手動で決めることもできます。
    また、bAutoTransform = Trueに指定すると、新しい骨が親の骨に対して垂直に追加されます。

  3. 実行