0

まず第一に、これはプログラミングについてさらに学ぶのに最適な場所のようです。両方の関数が機能する Maya Python スクリプトを作成しましたが、UI ボタン​​で superExtrude() 関数を呼び出すのに問題があります。最初の関数はジオメトリ メッシュの操作を行い、2 番目の関数はユーザー入力用の UI を生成する必要があります。

import maya.cmds as cmds

def superExtrude(extrScale, extrDist):
    """Loops through a list of selected meshes and extrudes all of the mesh faces to produce a polygon frame, based on existing mesh tesselations"""
    myObjectLt = cmds.ls(selection=True)

    for i in range(len(myObjectLt)):
        numFaces = cmds.polyEvaluate(face=True)
        item = myObjectLt[i] + ".f[:]"
        cmds.select(clear=True)
        cmds.select(item, replace=True)

        #extrude by scale
        cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=False, localScaleX=extrScale, localScaleY=extrScale, localScaleZ=extrScale)
        selFaces = cmds.ls(selection=True)
        cmds.delete(selFaces)

        #extrude by height
        cmds.select(item, replace=True)
        cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=True, localTranslateZ=extrDist)

def extrWindow():
    """Creates the user interface UI for the user input of the extrusion scale and height"""
    windowID = "superExtrWindow"

    if cmds.window(windowID, exists=True):
        cmds.deleteUI(windowID)

    cmds.window(windowID, title="SuperExtrude", sizeable=False, resizeToFitChildren=True)
    cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,120),(2,120)], columnOffset=[1,"right",3])

    cmds.text(label="Extrusion Scale:")
    extrScaleVal = cmds.floatField(text=0.9)
    cmds.text(label="Extrusion Height:")
    extrDistVal = cmds.floatField(text=-0.3)
    cmds.separator(height=10, style="none")
    cmds.separator(height=10, style="none")
    cmds.separator(height=10, style="none")

    cmds.button(label="Apply", command=superExtrude(extrScaleVal, extrDistVal))
    cmds.showWindow()

extrWindow()

私はPythonとMayaのスクリプト作成にかなり慣れていないので、どんな助けでも大歓迎です。:)

4

4 に答える 4

7

これがあなたが望む答えかどうかはわかりませんが、Mayaの「コマンド」フラグについて知っておくべきこと:

  • ボタン呼び出しに関数を入れたい場合は、引数なしで関数名を渡す必要があります (例: command = myFunction) (終わりの括弧 "()" を取り除きます)

  • 関数では、Maya ボタンは常に引数を渡すため、「*args」を追加する必要があります (「False」だと思います) (例: def myFunction(customArg1, customArg2, *args) )

  • ボタン信号で引数を渡したい場合は、functools モジュール (functools import partial から) の部分関数を使用し、次のように使用する必要があります: cmds.button( command = partial(myFunction, arg1, arg2, kwarg1=値1、kwarg2=値2) )

もう 1 つ、pymel と cmds について...おそらく終わりのない話ですが、pymel は万能ではありません...多くの情報を処理する必要がある場合 (メッシュの頂点リストを取得するなど)、pymel は何かになる可能性があります単純な Maya コマンドよりも 40 倍遅くなります。長所と短所があります... Python を使い始めたばかりの場合は、今すぐ pymel を使用することはお勧めしません。構文とコマンドに慣れ、OK になったら pymel に切り替えます (これは、オブジェクトの作成を扱う場合に非常に便利です)。

これが役に立てば幸いです、乾杯

編集 :

最初の投稿に基づいて、コードを機能させるためにコードを変更する必要があるのは次のとおりです。

import maya.cmds as cmds
from functools import partial

#You need to add the *args at the end of your function
def superExtrude(extrScaleField, extrDistField, *args):
    """Loops through a list of selected meshes and extrudes all of the mesh faces to produce a polygon frame, based on existing mesh tesselations"""
    myObjectLt = cmds.ls(selection=True)


    #In the function, we are passing the floatFields, not their values.
    #So if we want to query the value before running the script, we need to
    #use the floatField cmds with the "query" flag


    extrScale = cmds.floatField(extrScaleField, q=1, v=1)
    extrDist = cmds.floatField(extrDistField, q=1, v=1)

    for i in range(len(myObjectLt)):
        numFaces = cmds.polyEvaluate(face=True)
        item = myObjectLt[i] + ".f[:]"
        cmds.select(clear=True)
        cmds.select(item, replace=True)

        #extrude by scale
        cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=False, localScaleX=extrScale, localScaleY=extrScale, localScaleZ=extrScale)
        selFaces = cmds.ls(selection=True)
        cmds.delete(selFaces)

        #extrude by height
        cmds.select(item, replace=True)
        cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=True, localTranslateZ=extrDist)

def extrWindow():
    """Creates the user interface UI for the user input of the extrusion scale and height"""
    windowID = "superExtrWindow"

    if cmds.window(windowID, exists=True):
        cmds.deleteUI(windowID)

    cmds.window(windowID, title="SuperExtrude", sizeable=False, resizeToFitChildren=True)
    cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,120),(2,120)], columnOffset=[1,"right",3])

    cmds.text(label="Extrusion Scale:")

    # There were an error here, replace 'text' with 'value'
    # to give your floatField a default value on its creation

    extrScaleVal = cmds.floatField(value=0.9)
    cmds.text(label="Extrusion Height:")
    extrDistVal = cmds.floatField(value=-0.3)
    cmds.separator(height=10, style="none")
    cmds.separator(height=10, style="none")
    cmds.separator(height=10, style="none")

    # As said above, use the partial function to pass your arguments in the function
    # Here, the arguments are the floatFields names, so we can then query their value
    # everytime we will press the button.

    cmds.button(label="Apply", command=partial(superExtrude,extrScaleVal, extrDistVal))
    cmds.showWindow(windowID)

extrWindow()
于 2014-07-10T15:18:28.870 に答える
6
cmds.button(label="Apply", command=superExtrude(extrScaleVal, extrDistVal))

この行は を呼び出しsuperExtrude、その戻り値を に代入しますcommandsuperExtrudeは何も返さないため、ボタンには実質的にNone.

おそらくsuperExtrude、ボタンがクリックされたときに呼び出されることを意図していたのでしょう。その場合、すぐに呼び出されないようにラムダでラップする必要があります。

cmds.button(label="Apply", command=lambda *args: superExtrude(extrScaleVal, extrDistVal))
于 2014-07-07T17:59:57.457 に答える
1

St4rb0y

まず、floatField の呼び出し (33 行目、35 行目) で無効なフラグ 'text' が使用されています。おそらく「値」を使用するつもりなので、両方の行を変更してください。

extrScaleVal = cmds.floatField(v=0.9)
extrDistVal = cmds.floatField(v=-0.3)

第 2 に、UI コントロール タイプを構築する場合、'command' フラグは文字列を検索するため、コマンドとその引数を引用符で囲む必要があります。

cmds.button(label="Apply", command='superExtrude(extrScaleVal, extrDistVal)')

これらの 3 行を変更すると、すべて正常に動作するはずです。

チップ:

コードの 1 行にコメントを付けるには、行全体を 3 つの単一引用符で囲む代わりに # を使用します。三重引用符を使用すると、多くのコード行をコメントアウトするのに便利です。

コマンド フラグを制御するためのもう 1 つのヒント: コマンドを渡すために文字列変数を定義し、文字列の代わりに変数を直接使用することができます。このトリックは、動的なコントロールを構築する場合、つまり、ユーザーの選択に基づいてコマンドを組み立てる場合に役立ちます。

comStr = "superExtrude(extrScaleVal, extrDistVal)"
cmds.button(label="Apply", command=comStr)
于 2014-07-08T15:04:40.487 に答える
-2

だから私はあなたが学ぶべきものであるpymelにすべてを切り替えました.cmdsはゴミです。時間をかけて、あなたと私の違いを見てください。このようなスクリプトは、開始するのに役立ちます。さらに説明が必要な場合はお知らせください。

この td の好意を行い、pymel を学ぶ

pymel オンライン ドキュメント = http://download.autodesk.com/global/docs/maya2014/en_us/PyMel/

import pymel.core as pm
def superExtrude(*args):
    """Loops through a list of selected meshes and extrudes all of the mesh faces to produce a polygon frame, based on existing mesh tesselations"""
    #pymel uses python classes to make things easier
    #its ok to not understand what a class is but just think of it the same as if you were to add an attribute to a polycube. 
    #your code variable now has attributes 

    #so with that pymel ls returns a list of PyNodes that correspond to the objects
    #cmds ls returns a list of strings which is very unuseful
    #if you look at the help docs you can find most of whats available
    myObjectLt = pm.ls(selection=True)


    for i in myObjectLt:
        #instead of cycling through by a number were gonna cycle through the list itself
        #i is now the item in the list

        #its unnecessary to select the objects because we can specify it in the polyExtrude
        #cmds.select(item,  replace=True)

        #the extrude commands selects things but im not sure what your trying to achive here by seperating
        #the scale extrude and translate extrude
        pm.select(cl=True)



        #the way poly objects wrok is that you have a transform node and a shape node
        # if you graph it in the hypershade you'll see the two nodes
        #the faces are part of the shape node i like accessing things by this node but just know you can do it like this
        #i.f  <-- f is your attribute and i is the item
        #using i.getShape() returns the shape node

        # http://download.autodesk.com/global/docs/maya2014/en_us/PyMel/generated/classes/pymel.core.uitypes/pymel.core.uitypes.FloatField.html?highlight=floatfield#pymel.core.uitypes.FloatField
        #since were using pymel the extrScaleVal has function that lets you get the value
        thisScale = extrScaleVal.getValue()


        pm.polyExtrudeFacet(i.getShape().f, constructionHistory=True, keepFacesTogether=False, localScaleX=thisScale, localScaleY=thisScale, localScaleZ=thisScale)
        #selFaces = cmds.ls(selection=True)
        pm.delete()

        #same as before
        thisDist = extrDistVal.getValue()
        #extrude by height
        pm.polyExtrudeFacet(i.getShape().f, constructionHistory=True, keepFacesTogether=True, localTranslateZ=thisDist)

def extrWindow():
    #global is a way to transfer variables from function to function the way you had it
    # you would have had to query the value from your parameters in superExtrude
    #instead do this
    global extrScaleVal, extrDistVal
    #which will makes these parameters to the other function


    """Creates the user interface UI for the user input of the extrusion scale and height"""
    windowID = "superExtrWindow"

    #instead of having a query run just use try except
    #which will just go to except when the try fails
    try:
        pm.deleteUI(windowID)
    except:
        pass

    pm.window(windowID, title="SuperExtrude", sizeable=False, resizeToFitChildren=True)
    pm.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,120),(2,120)], columnOffset=[1,"right",3])

    pm.text(label="Extrusion Scale:")
    extrScaleVal = pm.floatField(v=0.9)
    pm.text(label="Extrusion Height:")
    extrDistVal = pm.floatField(v=-0.3)
    pm.separator(height=10, style="none")
    pm.separator(height=10, style="none")
    pm.separator(height=10, style="none")

    pm.button(label="Apply", c=superExtrude)
    pm.showWindow()

extrWindow()
于 2014-07-08T14:25:51.747 に答える