見出し画像

【Maya 2019】スキニング作業を効率化するジョイント回転ツール

スキニング作業中、頂点選択モードからオブジェクト選択モードに切り替える手間が煩わしく感じていました。 このツールは、頂点選択モードのままジョイントの回転ができるようにし、スキニング作業を効率化を目指しました。
尚GUIが不完全であったり、素人作成のため粗があるというかChatGPTのサポート作ってるのでなんで動くのかよく理解していません。ご了承下さい。
とりあえず、動く。

複数選択もできます。

スクリプトの概要

頂点選択モードから選択モードの切り替えをせずに、ジョイントの回転を可能にするツールです。
従来はオブジェクト選択に切り替えて、回転ツールで回転させたり、ジョイントにアニメーションをつけて、動作確認をしながらスキニング作業するため、ウェイト値の設定とモデルの動作確認の切り替えが大変でした。
このツールはそのような手間を省き、頂点選択モードから切り替えずスキニング作業ができるものです。

スクリプトの導入方法

以下のスクリプトをコピーして、MayaのScript Editorに貼り付け、実行してください。

import maya.cmds as cmds
import uuid

class JointSelectionTool:
    def __init__(self):
        self.window_name = "jointSelectionWindow_" + str(uuid.uuid4())
        self.selected_joints = []  # 変更: selected_joint をリストに変更
        self.create_window()

    def on_set_joint_button_clicked(self, *args):
        self.selected_joints = cmds.ls(selection=True, type="joint")
        if not self.selected_joints:
            cmds.warning("No joint selected. Please select a joint in the scene.")
            return

        cmds.text(self.joint_name_text, edit=True, label=', '.join(self.selected_joints))

    def on_slider_changed_x(self, value):
        if self.selected_joints:
            for joint in self.selected_joints:
                cmds.setAttr(joint + ".rotateX", value)

    def on_slider_changed_y(self, value):
        if self.selected_joints:
            for joint in self.selected_joints:
                cmds.setAttr(joint + ".rotateY", value)

    def on_slider_changed_z(self, value):
        if self.selected_joints:
            for joint in self.selected_joints:
                cmds.setAttr(joint + ".rotateZ", value)


    def reset_rotation_x(self, *args):
        if self.selected_joints:  # 変更: selected_joints をチェック
            for joint in self.selected_joints:  # 変更: すべての選択したジョイントに対してリセットを適用
                cmds.setAttr(joint + ".rotateX", 0)
        cmds.floatSliderGrp(self.rotation_slider_x, edit=True, value=0)

    def reset_rotation_y(self, *args):
        if self.selected_joints:  # 修正: selected_joints をチェック
            for joint in self.selected_joints:  # 変更: すべての選択したジョイントに対してリセットを適用
                cmds.setAttr(joint + ".rotateY", 0)
        cmds.floatSliderGrp(self.rotation_slider_y, edit=True, value=0)

    def reset_rotation_z(self, *args):
        if self.selected_joints:  # 修正: selected_joints をチェック
            for joint in self.selected_joints:  # 変更: すべての選択したジョイントに対してリセットを適用
                cmds.setAttr(joint + ".rotateZ", 0)
        cmds.floatSliderGrp(self.rotation_slider_z, edit=True, value=0)


    def create_window(self):
        if cmds.window(self.window_name, exists=True):
            cmds.deleteUI(self.window_name)

    def create_window(self):
        if cmds.window(self.window_name, exists=True):
            cmds.deleteUI(self.window_name)

        window = cmds.window(self.window_name, title="Joint Selection", widthHeight=(430, 110))
        cmds.columnLayout(adjustableColumn=True)

        # SetJointボタンとジョイント名表示
        cmds.rowLayout(numberOfColumns=2, columnWidth2=(60, 240))
        cmds.button(label="SetJoint", command=lambda *args: self.on_set_joint_button_clicked())
        self.joint_name_text = cmds.text(label="")

        # スライドバーの作成
        cmds.setParent("..")
        cmds.rowLayout(numberOfColumns=3, columnWidth3=(20, 60, 220))
        cmds.button(label="0", command=lambda *args: self.reset_rotation_x())
        self.rotation_slider_x = cmds.floatSliderGrp(label="Rotate X", field=True, minValue=-360, maxValue=360, fieldMinValue=-360, fieldMaxValue=360, changeCommand=lambda value: self.on_slider_changed_x(value), dragCommand=lambda value: self.on_slider_changed_x(value))

        cmds.setParent("..")
        cmds.rowLayout(numberOfColumns=3, columnWidth3=(20, 60, 220))
        cmds.button(label="0", command=lambda *args: self.reset_rotation_y())
        self.rotation_slider_y = cmds.floatSliderGrp(label="Rotate Y", field=True, minValue=-360, maxValue=360, fieldMinValue=-360, fieldMaxValue=360, changeCommand=lambda value: self.on_slider_changed_y(value), dragCommand=lambda value: self.on_slider_changed_y(value))

        cmds.setParent("..")
        cmds.rowLayout(numberOfColumns=3, columnWidth3=(20, 60, 220))
        cmds.button(label="0", command=lambda *args: self.reset_rotation_z())
        self.rotation_slider_z = cmds.floatSliderGrp(label="Rotate Z", field=True, minValue=-360, maxValue=360, fieldMinValue=-360, fieldMaxValue=360, changeCommand=lambda value: self.on_slider_changed_z(value), dragCommand=lambda value: self.on_slider_changed_z(value))

        cmds.showWindow(window)

joint_tool1 = JointSelectionTool()
joint_tool2 = JointSelectionTool()
joint_tool3 = JointSelectionTool()

使用方法

  1. スクリプトを実行すると、新しいウィンドウが開きます。

  2. ジョイントをシーン内で選択し、「SetJoint」ボタンをクリックして、回転させたいジョイントを指定します。

  3. 指定したジョイントの回転X、Y、Zの値をスライダーで調整し、ジョイントの回転を行います。

  4. 必要に応じて、「0」ボタンをクリックして、回転をリセットできます。

探せばきっと同じようなツールはあるのかと思うのですが、諸般の事情で自作しました。

不完全な部分としては
アンドゥヒストリに回転履歴が細かく刻まれてしまうのだけは気をつけてください。こいつを使ったら過去のアンドゥヒストリは消えると思ってください。
あとGUIで0ボタンとスライダがやたら離れているのも、、、、

直したい…やりかたわからない…

この記事が気に入ったらサポートをしてみませんか?