3
2

More than 3 years have passed since last update.

既存ボーンにスクリプトで補助ボーンを生やしてみる

Last updated at Posted at 2020-12-17

Blender Advent Calendar 2020
https://qiita.com/advent-calendar/2020/blender
に空きが目立ったのもあって Twitterのタイムラインで話題を見かけた
既存のボーンに補助ボーンを作成するスクリプトを即興で書いてみました。

選択しているボーンと垂直に補助ボーンを作るスクリプト

subbone.py
import bpy
import math
from mathutils import Vector, Matrix

context = bpy.context
obj = context.active_object
if context.mode == 'EDIT_ARMATURE':
    obj.update_from_editmode()
    edit_bones = obj.data.edit_bones
    for bone in edit_bones:
        if bone.select:
            #選択ボーンの変換マトリクス
            mat = bone.matrix
            tail_pos = bone.tail
            arm_1 = edit_bones.new('X_arm')
            arm_1.head = tail_pos
            arm_1.tail = mat @ Vector((1,bone.length,0)) 
            arm_2 = edit_bones.new('-X_arm')
            arm_2.head = tail_pos
            arm_2.tail = mat @ Vector((-1,bone.length,0)) 

image.png
即興なので特に工夫もないけれど軽く解説すると
編集中のアーマーチュアのボーンをたどって 選択されているボーンで
ボーンの変換マトリクスを取得(bone.matrix)
ただしこのマトリクスはボーンのヘッド部分を基準にするマトリクスになる

Blenderのボーンの座標軸はヘッドからテールを向いた方向が+Y軸なので
X軸方向に好きな長さを入れて Y軸にボーン長さを入れた座標にボーンのマトリクスをかけてやればテイルから垂直に伸びた座標になるというわけ。
(mat @ Vector((1,bone.length,0))  部分)
選択ボーンをと親子関係をつけた状態にしたければ 

arm_1.parent = bone
arm_2.parent = bone

とでも書き足せばいいらしい。

Blender2.8以降で Vector, Matrixの演算の書き方が少しだけ変わっているので
2.7時代のコードを参照するときにはちょっと注意が必要かも?

個人的追記

ボーンの情報取得には bones と edit_bonesの2つがあって微妙に内容が違う
エディットモードのボーン編集はedit_bonesで ポーズモードの方も含めた情報はbonesで取得するのか?

dir(obj.data.bones[0])
['AxisRollFromMatrix', 'MatrixFromAxisRoll', '__doc__', '__module__', '__slots__', 'bbone_curveinx', 'bbone_curveiny', 'bbone_curveoutx', 'bbone_curveouty', 'bbone_custom_handle_end', 'bbone_custom_handle_start', 'bbone_easein', 'bbone_easeout', 'bbone_handle_type_end', 'bbone_handle_type_start', 'bbone_rollin', 'bbone_rollout', 'bbone_scaleinx', 'bbone_scaleiny', 'bbone_scaleoutx', 'bbone_scaleouty', 'bbone_segments', 'bbone_x', 'bbone_z', 'bl_rna', 'children', 'convert_local_to_pose', 'envelope_distance', 'envelope_weight', 'evaluate_envelope', 'head', 'head_local', 'head_radius', 'hide', 'hide_select', 'inherit_scale', 'layers', 'length', 'matrix', 'matrix_local', 'name', 'parent', 'rna_type', 'select', 'select_head', 'select_tail', 'show_wire', 'tail', 'tail_local', 'tail_radius', 'use_connect', 'use_cyclic_offset', 'use_deform', 'use_endroll_as_inroll', 'use_envelope_multiply', 'use_inherit_rotation', 'use_inherit_scale', 'use_local_location', 'use_relative_parent']
dir(obj.data.edit_bones[0])
['__doc__', '__module__', '__slots__', 'align_orientation', 'align_roll', 'bbone_curveinx', 'bbone_curveiny', 'bbone_curveoutx', 'bbone_curveouty', 'bbone_custom_handle_end', 'bbone_custom_handle_start', 'bbone_easein', 'bbone_easeout', 'bbone_handle_type_end', 'bbone_handle_type_start', 'bbone_rollin', 'bbone_rollout', 'bbone_scaleinx', 'bbone_scaleiny', 'bbone_scaleoutx', 'bbone_scaleouty', 'bbone_segments', 'bbone_x', 'bbone_z', 'bl_rna', 'envelope_distance', 'envelope_weight', 'head', 'head_radius', 'hide', 'hide_select', 'inherit_scale', 'layers', 'length', 'lock', 'matrix', 'name', 'parent', 'rna_type', 'roll', 'select', 'select_head', 'select_tail', 'show_wire', 'tail', 'tail_radius', 'transform', 'use_connect', 'use_cyclic_offset', 'use_deform', 'use_endroll_as_inroll', 'use_envelope_multiply', 'use_inherit_rotation', 'use_inherit_scale', 'use_local_location', 'use_relative_parent']
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2