[blender] boneをコントロールするスライドバーを作るpython code(add-on)

Image

Q: blenderにおいてboneの回転(X,Y,Z)・位置(X,Y,Z)の値を簡単にコントロールできようにするスライドバーを作ることはできるか? 複数のboneを切り替えてコントロールできることを条件とする.

Copilot : はい、Blenderでボーンの回転(X, Y, Z)と位置(X, Y, Z)をスライドバーでコントロールし、さらに複数のボーンを切り替えて制御できる仕組みを作成することは可能です。この仕組みはPythonスクリプトを利用して実現できます。

以下は具体的なステップとコード例です。スクリプトは、Poseモードで選択したボーンを切り替えながら、ボーンの回転(X, Y, Z)および位置(X, Y, Z)を操作できるスライダーを提供します。

コード例: 複数ボーンの位置と回転をスライドバーでコントロール

python

# SPDX-License-Identifier: CC0-1.0
#
# Bone Control Sliders (N-Panel)
# Blender 5.0 Add-on
#
# This work is released into the public domain under CC0 1.0.
# https://creativecommons.org/publicdomain/zero/1.0/
#
# No rights reserved.


bl_info = {
    "name": "Bone Control Sliders (N-Panel)",
    "author": "KenJin",
    "version": (1, 0, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N) > BoneCtrl",
    "description": "Control selected pose bone location and rotation via sliders",
    "category": "Rigging",
}


import bpy
from bpy.types import Panel, PropertyGroup
from bpy.props import FloatProperty, PointerProperty


# ============================================================
# Internal Utilities
# ============================================================

def get_active_pose_bone(context):
    obj = context.object
    if not obj or obj.type != 'ARMATURE':
        return None
    if context.mode != 'POSE':
        return None
    bones = context.selected_pose_bones
    if not bones:
        return None
    return bones[0]


# ============================================================
# Update Callbacks
# ============================================================

def update_location(self, context):
    bone = get_active_pose_bone(context)
    if not bone:
        return

    bone.location.x = self.loc_x
    bone.location.y = self.loc_y
    bone.location.z = self.loc_z


def update_rotation(self, context):
    bone = get_active_pose_bone(context)
    if not bone:
        return

    if bone.rotation_mode not in {'XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'}:
        bone.rotation_mode = 'XYZ'

    bone.rotation_euler.x = self.rot_x
    bone.rotation_euler.y = self.rot_y
    bone.rotation_euler.z = self.rot_z


# ============================================================
# Properties
# ============================================================

class BONECTRL_Properties(PropertyGroup):

    # Location
    loc_x: FloatProperty(
        name="Location X",
        min=-1.0, max=1.0,
        update=update_location,
    )
    loc_y: FloatProperty(
        name="Location Y",
        min=-1.0, max=1.0,
        update=update_location,
    )
    loc_z: FloatProperty(
        name="Location Z",
        min=-1.0, max=1.0,
        update=update_location,
    )

    # Rotation (radians)
    rot_x: FloatProperty(
        name="Rotation X",
        min=-3.14159265, max=3.14159265,
        update=update_rotation,
    )
    rot_y: FloatProperty(
        name="Rotation Y",
        min=-3.14159265, max=3.14159265,
        update=update_rotation,
    )
    rot_z: FloatProperty(
        name="Rotation Z",
        min=-3.14159265, max=3.14159265,
        update=update_rotation,
    )


# ============================================================
# UI Panel (N-Menu)
# ============================================================

class VIEW3D_PT_bonectrl(Panel):
    bl_label = "Bone Control Sliders"
    bl_idname = "VIEW3D_PT_bonectrl"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "BoneCtrl"

    @classmethod
    def poll(cls, context):
        return context.object and context.object.type == 'ARMATURE'

    def draw(self, context):
        layout = self.layout
        props = context.object.bonectrl_props

        bone = get_active_pose_bone(context)

        if context.mode != 'POSE':
            layout.label(text="Poseモードで使用してください", icon='INFO')
            return

        if not bone:
            layout.label(text="ボーンを選択してください", icon='BONE_DATA')
            return

        layout.label(text=f"Target: {bone.name}", icon='BONE_DATA')
        layout.separator()

        box = layout.box()
        box.label(text="Location")
        box.prop(props, "loc_x")
        box.prop(props, "loc_y")
        box.prop(props, "loc_z")

        box = layout.box()
        box.label(text="Rotation (Euler)")
        box.prop(props, "rot_x")
        box.prop(props, "rot_y")
        box.prop(props, "rot_z")


# ============================================================
# Register
# ============================================================

classes = (
    BONECTRL_Properties,
    VIEW3D_PT_bonectrl,
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)

    bpy.types.Object.bonectrl_props = PointerProperty(
        type=BONECTRL_Properties
    )


def unregister():
    del bpy.types.Object.bonectrl_props

    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)


if __name__ == "__main__":
    register()

使用方法

  1. add-onとしてinstallする:
    • Blenderのスクリプトエディタ(scripting)を開く
    • Newをクリック
    • 上記のコードを貼り付ける
    • file nameのエディット窓がTEXTになっいるので,”BCS.py”などの修正する.
    • TEXT > Save Asで保存する.
    • Edit > Preferences > Add-onのInstallで前述保存したFile Nameを指定する.
    • 3D viewport.Modelingに切り替える.
  2. Poseモードで作業:
    • object modeにする.
    • 操作したいアーマチュアオブジェクトを選択し、Poseモードに切り替えます。
  3. ボーンを選択:
    • 操作したいボーンをクリックで選択します。このスクリプトでは、選択中のボーンのみにスライダーが適用されます。
  4. スライダーを使用:
    • プロパティパネル内に新しい「Bone Control Sliders」セクションが追加されます。そこで「Location X, Y, Z」および「Rotation X, Y, Z」を操作してボーンを動かします。

機能のポイント

  1. 複数ボーンの切り替え対応:
    • スクリプトは現在選択されているボーンを動的に検出し、スライダー操作が選択したボーンのみに適用されます。
  2. 位置と回転の全軸対応:
    • スライダーはすべての位置軸(X, Y, Z)と回転軸(X, Y, Z)を調整可能です。
  3. Poseモード専用:
    • このスクリプトはPoseモード専用です。Objectモードでは動作しません。
  4. 拡張性:
    • 必要に応じて、スライダーの範囲(minmax)をカスタマイズしたり、他のプロパティ(スケールなど)を追加することも可能です。

これで、ボーンの回転と位置を複数ボーン対応で簡単にコントロールできる仕組みが完成します!

2026/01/26, add-onにコード修正

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA