2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

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

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']
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?