LoginSignup
6
3

More than 3 years have passed since last update.

Ramp制御を含むGUIを作る

Last updated at Posted at 2020-12-07

この記事はMaya Advent Calender 2020の3日目の記事です。
AdventCalenderに初めて参加させていただきます。

はじめに

Rampのカーブを入力として利用したツールを制作する為に調べました。
今回は、PySideではなくmayaコマンドでGUIを作っています。

GUI.png

サンプル

下記のコードを実行すると、GUIが表示されます。

import maya.cmds as cmds
import maya.mel as mel

class rampWindow(object):
    @classmethod
    def showUI(cls):
        """
        showUI
            UIを表示させます。
        """ 
        win = cls()
        win.create()
        return win

    def deleteUI(self, *args):
        """
        deleteUI
            UIを削除します。
            rampアトリビュート用のNullを削除します。
        """ 
        cmds.deleteUI(self.window, window=True)
        self.deleteRampNode()

    def deleteRampNode(self, *args):
        """
        deleteRampNode
            rampアトリビュート用のNullを削除します。
            ウィンドウの×を押した時のコマンド用。
        """ 
        if cmds.ls(self.nodeName):
            cmds.delete( self.nodeName )

    def __init__(self):
        """
        __init__
            初期化。
        """ 
        self.window = 'rampWindow'
        self.title = 'rampWindow'
        self.width=200

        self.rampName = "ramp"
        self.nodeName = "rampNull"

    def create(self):
        """
        create
            レイアウト作成。
        """ 

        #   多重ウィンドウ対応
        if cmds.window(self.window, exists=True):
            self.deleteUI()

        #   rampアトリビュート用Nullを作成
        cmds.group(em=True, n=self.nodeName)
        createRampAttrbute( self.nodeName, self.rampName )

        #   ウィンドウ作成
        self.window = cmds.window( self.window, t=self.title, w=self.width, cc=self.deleteRampNode )
        cmds.columnLayout()

        #   Layout Frame Range
        rampLayout( self.nodeName, self.rampName )

        cmds.showWindow(  )

def createRampAttrbute( nodeName, rampName ):
    """
    createRampAttrbute
        RampAttrbuteを設定します。   
    Args:
        String nodeName  :   RampAttrbuteの追加するノード名
        String rampName  :   RampAttrbute名
    """
    cmds.addAttr( nodeName, ln=rampName, at='compound', nc=3, m=True)
    cmds.addAttr( nodeName, ln='ramp_Position', at='float', p=rampName, dv=-1)
    cmds.addAttr( nodeName, ln='ramp_FloatValue', at='float', p=rampName, dv=-1)
    cmds.addAttr( nodeName, ln='ramp_Interp', at='enum', en='None:Linear:Smooth:Spline', dv=1, min=0, max=3, p=rampName)
    cmds.setAttr( '{0}.{1}[0]'.format(nodeName, rampName), 0, 1, 2)
    cmds.setAttr( '{0}.{1}[1]'.format(nodeName, rampName), 1, 1, 2)

def rampLayout( nodeName, rampName ):
    """
    rampLayout
        rampをレイアウトします。
    Args:
        String nodeName  :   RampAttrbuteの追加されているノード名
        String rampName  :   RampAttrbute名
    """
    mel.eval('if (! exists("AEmakeLargeRamp")) source AEaddRampControl')
    mel.eval('AEmakeLargeRamp("{0}.{1}", 0, 0, 0, 0, 0)'.format(nodeName, rampName))


if __name__ == '__main__':
    rampWindow.showUI()

解説

  • レイアウトを行う前に、GUIで使用するRampのパラメータを保持する為にNullを用意しています。 そのNullにRampアトリビュートを追加します。
#   rampアトリビュート用Nullを作成
cmds.group(em=True, n=self.nodeName)
createRampAttrbute( self.nodeName, self.rampName )

ramp2.png

  • ウィンドウを用意し、Rampをレイアウトします。
mel.eval('if (! exists("AEmakeLargeRamp")) source AEaddRampControl')
mel.eval('AEmakeLargeRamp("{0}.{1}", 0, 0, 0, 0, 0)'.format(nodeName, rampName))
  • AEmakeLargeRamp コマンド。引数が6個必要ですが、rampのアトリビュート名を指定すれば、後は0で問題ないと思います。
AEaddRampControl.mel
global proc AEmakeLargeRamp( string $nodeAttr,
                            int $bound,
                            int $indent,
                            int $staticEntries,
                            int $staticPositions,
                            int $adaptiveScaling )

おまけ

実行ボタンを起動しランプの値をとる際には、Fit関数を用意すると便利です。
この関数で、パラメータの「開始値1・終了値1」間の変化を、「開始2・終了2」間の変化にマッピングします。
HoudiniのVEXライクな関数を作ってみました。

def fit(parameter, startValue1, endValue1, startValue2=0, endValue2=1):

    """
    fit
        値の範囲を別の値にマッピングする。
    Args:
        Float parameter  :   パラメータ
        Float startValue1  :   開始値1
        Float endValue1  :   終了値1
        Float startValue2 :   開始値2
        Float endValue2  :   終了値2
    Returns:
        Float   value  :   マッピングされたの値
    """ 

    if parameter < startValue1:
        parameter = startValue1
    if parameter > endValue1:
        parameter = endValue1

    Span1 = endValue1 - startValue1
    Span2 = endValue2 - startValue2

    rate = float( parameter - startValue1 ) / Span1
    value = startValue2 + ( rate * Span2 )
    return value

参照

ryusas/test_falloffCurveAttr.py
https://gist.github.com/ryusas/699ad3f5fa8469a00e8df4b3672aa89f


Maya Python Advent Calender 2020の4日目は、it_ksさんの記事です!!

6
3
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
6
3