機械学習基礎理論独習

誤りがあればご指摘いただけると幸いです。数式が整うまで少し時間かかります。リンクフリーです。

勉強ログです。リンクフリーです
目次へ戻る

【Blender - Script】Bone を追加する Script (Add Bone)

概要

Head または Tail に 長さを指定して親のボーンと平行に Bone を作成する Script です。
親の Head に子の Bone を作成するときに便利です。

使用可能 Mode

Mode Armature Mesh
Edit Mode Active -

変数

変数名 デフォルト値 説明
name string 'Bone' Bone の名称
use_length bool True Boneの長さを決めるのに length を使うのか ratio を使うのか
length float 1.0 Bone の長さ(use_length == True 時に参照)
ratio float 0.5 Bone の親の Bone に対する長さの比率(use_length == False 時に参照)
add_to_head bool True True 時は Head に追加、False 時は Tail に追加
join_name bool True 親の Bone の名称と指定した名称を下線を入れて結合するか
親の名前が 'Parent' で名前が 'Child' の時、'Parent_Child' となる

Script

import bpy, mathutils

def select_sidebar_tag(tag = 'Item'):
    # Cache 
    context = bpy.context
    
    # Select 'Item'
    # https://blenderartists.org/t/is-it-impossible-to-select-a-tab-in-a-side-panel-through-script/1522596/2
    areas = context.screen.areas
    area = [a for a in areas if a.type == 'VIEW_3D'][0]
    with context.temp_override(area=area):
        area.regions[5].active_panel_category = tag # 'Item', 'Tool', 'View' or any addon name
        context.object.hide_render = context.object.hide_render

def select_bone_in_edit_armature(armature, bone):
    # Cache
    ops = bpy.ops
    
    # Deselect all
    ops.armature.select_all(action='DESELECT')
    # Set as active 
    armature.data.edit_bones.active = bone
    # Select in viewport
    bone.select = True

def main():
    # Variables
    name = 'Bone'       # Bone name
    use_length = True   # Use bone_length
    length = 1.0        # Bone length
    ratio = 0.5         # Bone length ratio
    add_to_head = True  # Add to Head    
    join_name = True    # Join parent.name to name

    # Cache
    context = bpy.context
        
    if context.mode == 'EDIT_ARMATURE':        
        armature = context.object
        parent = armature.data.edit_bones.active
        if parent:
            # Join name
            if join_name == True:
                name = parent.name + '_' + name

            # Get parents' vector
            parent_vec = parent.tail - parent.head
            # Unit length vector
            parent_unit_vec = parent_vec.normalized()
            # Calc new vector length
            if use_length == True:
                child_length = length
            else:
                child_length = parent_vec.length * ratio
            child_vec = parent_unit_vec * child_length    
            
            # Add child bone
            child = armature.data.edit_bones.new(name)
            if add_to_head == True:
                child.head = mathutils.Vector(parent.head)
            else:
                child.head = mathutils.Vector(parent.tail)
            child.tail = child.head + child_vec
            child.use_connect = False
            child.roll = parent.roll
            child.parent = parent

            # Select child bone
            select_bone_in_edit_armature(armature, child)

            # Select sidebar 'Item'
            select_sidebar_tag('Item')
        else:
            print('warning: no active bone.')
    else:
        print('warning: not edit armature.')

main()
目次へ戻る