HEXA BLOG

その他

HEXA BLOGその他2016.8.26

本日のmayaPython

皆様、スープカレーは食べていますか。

デザイナーのヨセミテです。

 

IMG_9756

今月の中ごろに目黒駅~恵比寿駅の間くらいにある薬膳スープカレー、シャナイアに行ってまいりました。

狭い路地の先にあり、駅からだと少々遠かったのですが、それでもお店は並んでいる人たちがおりました。かなり濃厚でとろみのあるスープでした。非常に美味しかったです。

 

住宅街の中にあるスープカレー屋さん、近隣の住民の方々が非常にうらやましい限りです。僕も家の前にスープカレー屋が欲しいです。

 


 

▼mayaPythonの話

最近は業務ではスクリプトから離れてSubstance等の業務が主でした。

ですので今回のブログ用のスクリプトは書いたのがえらく久しぶりな気がします。

 

前々からちょっと考えていたスクリプトで、ヒストリを操作するためのものです。

 

ヒストリを操作する機会はあまり頻繁には無いのですが、いざ複数を触る必要が出てくると、

 historyEditor 1

ここ(赤枠)にたどり着くのがわりと面倒だと思っていたので作ってみました。

作成はPymelです。パフォーマンスは望めないのですが、やはりPymelは思いついたものを形にするという意味では非常に優れていますね。

選択したオブジェクトのヒストリをリストアップし、選んだヒストリをON、OFF、削除が出来るようにしました。

historyEditor 4

historyEditor 3 historyEditor 5

 

 

※先にも述べましたがヒストリはMayaのクラッシュの原因になる可能性が、非常に高い部分です。スクリプトを利用する場合は自己責任の上でお願いします。

 

以下、ソースです。

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
##########################################
# 8月26日ブログスクリプト

import pymel.core as pm

class commonValue():
    ### =====================================================
    ### 定数定義
    ### =====================================================
    # list Param
    historyListFieldManageName  = "historyListFieldManageName"
    historyListFieldSize        = {"w" : 256, "h" : 512}

    # button Param
    buttonTitle_loadHistory = "Load History"
    buttonTitle_historyOn   = "on  History"
    buttonTitle_historyOff  = "off History"
    buttonTitle_historyDel  = "delete History"

    buttonFieldSize         = {"w" : 128, "h" : 512}
    buttonSize              = {"w" : 128, "h" : 64}

    # window Param
    windowTitle         = "BlogScript --- HistoryEditor"
    windowManageName    = "historyEdiroManageName"
    windowSize          = {"w" : historyListFieldSize["w"] + buttonFieldSize["w"],
                           "h" : 512}

class main(commonValue):
    ### =====================================================
    ### 実行クラス
    ### =====================================================
    # uiname
    UI_historyList = ""

    # インスタンス変数
    listedDict = {}     # リスト化されたヒストリの情報を格納するための領域
    listedObjects = []  # リフレッシュする際に再読み込みをするオブジェクト

    # 取得変数と表示内容への変換
    displayFormat_historyVisible = {0:True, 1:False}

    ### =====================================================
    ### 処理用の関数
    ### =====================================================
    def getHistoryTree(self,targetNode):
        # -----------------------------------------------------
        # 全ヒストリを取得する
        # -----------------------------------------------------
        return pm.listHistory(targetNode)

    def listReflesh(self):
        # -----------------------------------------------------
        # テキストリストを削除
        # -----------------------------------------------------
        selectionIndex = self.UI_historyList.getSelectIndexedItem()
        self.UI_historyList.removeAll()
        self.listedDict = {}
        return selectionIndex

    def recoverySelection(self, indexList):
        # -----------------------------------------------------
        # 指定のインデックスを選択
        # 再選択に失敗するようならパスで
        # -----------------------------------------------------
        try:
            self.UI_historyList.setSelectIndexedItem(indexList)
        except:pass

    def listAdd(self, addText = ""):
        # -----------------------------------------------------
        # テキストリストに項目を追加
        # -----------------------------------------------------
        self.UI_historyList.append(addText)

    def listGetSelection(self):
        # -----------------------------------------------------
        # テキストリストの選択項目を取得
        # -----------------------------------------------------
        selectionIndex = self.UI_historyList.getSelectIndexedItem()
        resultList = []
        for n in selectionIndex:
            resultList.append( self.listedDict[n])
        return resultList


    def addListedData(self,listIndex,  node):
        # -----------------------------------------------------
        # 取得したヒストリノードの情報を格納
        # -----------------------------------------------------
        nodeState = pm.getAttr("{}.nodeState".format(node))

        thisNodeData = {"node": node,
                         "state": nodeState}
        self.listedDict[listIndex] = thisNodeData
        return thisNodeData

    ### =====================================================
    ### 処理用の関数
    ### =====================================================
    def makeUI(self):
        # -----------------------------------------------------
        # UI作成メイン
        # -----------------------------------------------------
        self.makeUIParts_createMainWindow()
        mainLayout = pm.rowLayout(nc = 2)
        with mainLayout:
            self.makeUIParts_historyListField()
            self.makeUIParts_buttonField()
        pm.showWindow()

    def makeUIParts_createMainWindow(self):
        # -----------------------------------------------------
        # メインウィンドウ作成と有無の確認
        # -----------------------------------------------------
        if pm.window(commonValue.windowManageName,ex = True):
            pm.deleteUI(commonValue.windowManageName)
        window = pm.window(commonValue.windowManageName,t = commonValue.windowTitle)
        return window

    def makeUIParts_historyListField(self):
        # -----------------------------------------------------
        # 取得したヒストリのリストを表示する領域
        # -----------------------------------------------------
        with pm.columnLayout():
            self.UI_historyList = pm.textScrollList(commonValue.historyListFieldManageName,ams = True,
                                                    w = commonValue.historyListFieldSize["w"],h = commonValue.historyListFieldSize["h"])

    def makeUIParts_buttonField(self):
        # -----------------------------------------------------
        # UIの作成
        # -----------------------------------------------------
        with pm.columnLayout(w = commonValue.buttonFieldSize["w"], h = commonValue.buttonFieldSize["h"]):
            pm.button(label = commonValue.buttonTitle_loadHistory,  w = commonValue.buttonSize["w"], h = commonValue.buttonSize["h"],
                      command = pm.Callback(self.UICommand_loadHistory), bgc = [0.6,0.6,0.6])
            pm.button(label = commonValue.buttonTitle_historyOn,    w = commonValue.buttonSize["w"], h = commonValue.buttonSize["h"],
                      command = pm.Callback(self.UICommand_onHistory))
            pm.button(label = commonValue.buttonTitle_historyOff,   w = commonValue.buttonSize["w"], h = commonValue.buttonSize["h"],
                      command = pm.Callback(self.UICommand_offHistory))
            pm.button(label = commonValue.buttonTitle_historyDel,   w = commonValue.buttonSize["w"], h = commonValue.buttonSize["h"],
                      command = pm.Callback(self.UICommand_deleteHistory), bgc = [0.5,0.2,0.2])

    ### =====================================================
    ### UIからの呼出し命令
    ### =====================================================
    def UICommand_loadHistory(self, targetNodes = None):
        # -----------------------------------------------------
        # --- UIからの呼びだし命令
        # ヒストリの呼びだし
        # -----------------------------------------------------
        selectionIndex = self.listReflesh()
        self.listedDict = {}
        self.listedObjects = []

        # 指定のノードが存在する場合はそれらを対象とする
        if targetNodes:
            selectionNodes  = pm.ls(targetNodes)
            targetNodes = None
        else:
            selectionNodes  = pm.ls(sl = True)

        listIndex = 1       # textScrollListのindexは1から始まるので初期値1

        for currentNode in selectionNodes:
            addSourceText =   "sel : {}".format(currentNode)
            self.listAdd(addSourceText)
            gettedHistory   = self.getHistoryTree(currentNode)
            thisNodeData = self.addListedData(listIndex,  currentNode)
            self.listedObjects.append(currentNode)              # リスト作成時に選択していたオブジェクト
            listIndex +=1   # index表記タイトル分

            for currentHistory in gettedHistory:
                thisHistoryNodeData = self.addListedData(listIndex,  currentHistory)
                addNodeText =   "    {} : {}".format(thisHistoryNodeData["node"], self.displayFormat_historyVisible[thisHistoryNodeData["state"]])
                self.listAdd(addNodeText)
                listIndex +=1
        self.recoverySelection(selectionIndex)

    def UICommand_onHistory(self):
        # -----------------------------------------------------
        # --- UIからの呼びだし命令
        # ヒストリのオン
        # -----------------------------------------------------
        listSelection = self.listGetSelection()
        for currentSel in listSelection:
            pm.setAttr("{}.nodeState".format(currentSel["node"]),0)
        selectionIndex = self.listReflesh()
        self.UICommand_loadHistory(self.listedObjects)
        self.recoverySelection(selectionIndex)

    def UICommand_offHistory(self):
        # -----------------------------------------------------
        # --- UIからの呼びだし命令
        # ヒストリのオフ
        # -----------------------------------------------------
        listSelection = self.listGetSelection()
        for currentSel in listSelection:
            pm.setAttr("{}.nodeState".format(currentSel["node"]),1)
        selectionIndex = self.listReflesh()
        self.UICommand_loadHistory(self.listedObjects)
        self.recoverySelection(selectionIndex)

    def UICommand_deleteHistory(self):
        # -----------------------------------------------------
        # --- UIからの呼びだし命令
        # ヒストリの削除
        # -----------------------------------------------------
        listSelection = self.listGetSelection()
        selectionIndex = self.listReflesh()
        for currentSel in listSelection:
            print currentSel
            pm.delete(currentSel["node"])
        self.UICommand_loadHistory(self.listedObjects)
        self.recoverySelection(selectionIndex)

    def create(self):
        #-----------------------------------------------------
        # main
        #-----------------------------------------------------
        self.makeUI()


### === そのまま打ち込み用実行文
historyEditorInstace = main()
historyEditorInstace.create()

 

作ってみてから思いましたが、実際に利用する際にはソート機能やフィルタ機能も入れると便利そうですね。

今回は主に自分のための復習でした。次の投稿では自分の勉強のためにAPI2.0を使って何か作ってみたいと思います。

それでは。

 

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE 

NEWS