局部变量与全局变量,未定义名称“ EXAMPLE”

时间:2019-05-14 19:32:05

标签: python maya mel

我正在创建一个自定义的浮动窗口,在其中可以有一个架子等按钮,这些按钮可以为我调用并运行脚本。对于对像我这样不做大量脚本编写工作的艺术家进行建模非常有用! :P我希望无需过多修改Script_B即可解决此问题,但是我们将看到必须做的事情! :D

就目前而言,我有两个脚本Script_A和Script_B。脚本B保存为“ my_custom_script_name.py”。我正在尝试使用Script_A运行它,但是从未正确定义变量。

当我在适当位置保存了Script_B的情况下运行Script_A时,UI甚至没有加载,因为它在定义的第一个变量上出错了。

# Error: NameError: file C:/Users/polyshifter/Documents/maya/2019/prefs/scripts\my_custom_script_name.py line 2: global name 'mc' is not defined # 

所以我们甚至还没有接触到其他变量,并且它已经坏了。

脚本A

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

# Create a custom floating window with 
if mc.window('ToolsWindow', q=True, exists=True):
    mc.deleteUI('ToolsWindow')
if mc.workspaceControl('ToolsWorkspaceControl', q=True, exists=True):
    mc.deleteUI('ToolsWorkspaceControl')
mc.window('ToolsWindow')
mc.tabLayout('ToolsTabs')

###IMPORT PANEL###

tabMenu = mc.columnLayout("Menu", adj=True)
separator_long = mc.separator(
                         height=10,
                         style='in')


mc.button(label="MyCustomScript", command = "my_custom_script_com()")

mc.setParent('..')
mc.showWindow()

#### My custom script ####
def my_custom_script_com(*args):
    import my_custom_script_name
    my_custom_script_name.run_my_custom_script_ui()

脚本B

def run_my_custom_script_ui():
    import maya.cmds as mc
    if mc.window('my_script_ui', q=True, exists=True):
        mc.deleteUI('my_script_ui')
    else:
        mc.window('my_script_ui')

    mc.columnLayout("Menu", adj=True)

    mc.button(label="Please_print", command = "please_print()")

    mc.setParent('..')
    mc.showWindow()
    def please_print():
        print "OMG IT'S FINALLY WORKING!! YAY!!"

我尝试将Script_B放在Script_A的脚本结尾处,例如:

def my_custom_script_com(*args):
    import maya.cmds as mc
    if mc.window('my_script_ui', q=True, exists=True):
        mc.deleteUI('my_script_ui')
    else:
        mc.window('my_script_ui')

    mc.columnLayout("Menu", adj=True)

    mc.button(label="Please_print", command = "please_print()")

    mc.setParent('..')
    mc.showWindow()
    def please_print():
        print "OMG IT'S FINALLY WORKING!! YAY!!"

在第一个UI中加载,然后在第二个UI中加载,我看到我的按钮,但是当我单击它时,我得到:

# Error: NameError: file <maya console> line 1: name 'please_print' is not defined #

如果有太多不需要的代码,或者我想尽可能地将其砍掉,我深表歉意。这是我的第一个问题!

任何使这些变量正常工作的帮助都将是惊人的! <3谢谢你!

非常感谢大家的帮助! Theodox能够完美解决此问题!

但是...。问题仍然存在于我的非简化脚本中!

我有一位艺术家莱昂纳多·莱齐(Leonardo Lezzi)的剧本。 “ https://www.linkedin.com/pulse/super-bool-tool-python-leonardo-iezzi/” 当我使用他的脚本并尝试将其实现到我的脚本中时,它将导致错误。首先没有定义pma,然后没有定义他的定义。

我已经尝试过制作他的UI(本教程和主要的UI)并将它们定义为命令,但这对我来说还没有解决。原因是因为(从我今天学到的知识:D),在调用Script_B(现在的布尔脚本)之后,maya不再具有该功能。

我发现唯一有效的方法是将布尔脚本放入我的主脚本中,使其与脚本一起使用。然后将其UI定义为命令,然后在 ScriptA 中单击我的按钮,列出这两个命令。然后运行它。但是,然后返回并删除脚本中的定义,然后取消缩进,然后重新运行脚本。因此,仍然可以从以前的运行中定义这些定义,但是现在正在全局创建ui。显然,这在您重新启动maya时会中断,并且我完全错过了如何进行定义的要点,同时仍然可以调用(is正确吗?)当我单击按钮时。

这显然是一种hack和愚蠢的做法,但是我不理解如何仅通过采购super_bool_tool.py来从脚本中运行“超级布尔工具”

下面是我到目前为止的内容,但是这里的想法是 NOT ,以便在我的界面ui脚本中运行它。我想调用python脚本,以便它可以独立运行。

import maya.cmds as mc
import maya.mel as mel
import pymel.all as pma

BOOLEANMODE_ADD = 1
BOOLEANMODE_SUBTRACT = 2
PRIMITIVE_CUBE = 0
PRIMITIVE_CYLINDER = 1
PRIMITIVE_SPHERE = 2
PRIMITIVE_CUSTOM = 3


def cleanUp ():
    pma.delete (constructionHistory=True)
    #pma.select ()
    pma.delete ("*_ctrl*")

def hider(option):
    if (option == 0):
        pma.hide ()
    elif (option == 1):
        pma.select ("*_ctrl*")
        pma.hide ()
    elif (option == 2):
        pma.select ("*_ctrl*")
        pma.showHidden ()
        pma.select (clear=True)

def fixMaterial():
    pma.hyperShade( assign="lambert1" )

def triangulate():
    pma.polyTriangulate()

def creator(primitives):
    selection = pma.ls(sl=True)
    for x in selection:

        if primitives == PRIMITIVE_CUBE:
            a = makeCube() #Create cube
        if primitives == PRIMITIVE_CYLINDER:
            a = makeCyl() #Create cyl 
        if primitives == PRIMITIVE_SPHERE:
            a = makeSphere() #Create sphere 
        if primitives == PRIMITIVE_CUSTOM:
            a = selection[1]  
            x = selection[0]
            pma.select (a)
        b = createController(a)
        meshConstrainer (b,a)
        operator(x,a) 
        pma.select (b)    


def operator(meshA, meshB):
   booleanmode = get_boolean_mode()
   pma.polyBoolOp( meshA, meshB, op=booleanmode, n="basemesh" )
   pma.hyperShade( assign="lambert1" )   #REMINDER: Need to be replaced with the actual assigned material and not with a lambert1 so for who is working with other materials can easyly keep using that


def get_boolean_mode():
    if pma.radioButton(addRadioB, query = True, select = True) :
        return BOOLEANMODE_ADD
    if pma.radioButton(subRadioB, query = True, select = True) :
        return BOOLEANMODE_SUBTRACT
    return None

def makeCube():
    cubeTransform = pma.polyCube(n="cubetobool", w=1, h=1, d=1, sx=1, sy=1, sz=1)[0]   
    return cubeTransform       

def makeCyl():
    cylTransform = pma.polyCylinder(n="cubetobool", r=1, h=2, sx=20)[0]   
    return cylTransform   

def makeSphere():
    sphereTransform = pma.polySphere(n="cubetobool", r=1, sx=20, sy=20, cuv=2)[0]   
    return sphereTransform    


def meshConstrainer(constrainer, constrained):   
    pma.scaleConstraint( constrainer, constrained, maintainOffset=True)
    pma.parentConstraint( constrainer, constrained, maintainOffset=True)


def createController(object):
    #object = pma.ls(sl=True) 
    pivotObj = pma.xform(object,query=True,t=True,worldSpace=True)
    edges = pma.filterExpand(pma.polyListComponentConversion(te=1),sm=32,ex=1) # convert edges to curve ancd create one object
    for edge in edges:
        vtx = pma.ls(pma.polyListComponentConversion(edge,fe=1,tv=1),fl=1)
        p1 = pma.pointPosition(vtx[0])
        p2 = pma.pointPosition(vtx[1])
        curves = pma.curve(n="line_ctrl_curve", d=1,p=(p1,p2))

    ctrl = pma.curve (n="bool_ctrl", d=1,ws=True, p=pivotObj)
    pma.xform (centerPivots=True)
    for curveEdge in pma.ls ("line_ctrl*"):
        pma.parent(curveEdge,ctrl, s=1, r=1)
        pma.rename(curveEdge, "shapeunused")


    transforms =  pma.ls(type='transform')
    deleteList = []
    for tran in transforms:
        if pma.nodeType(tran) == 'transform':
            children = pma.listRelatives(tran, c=True) 
            if children is None:
                #print '%s, has no childred' %(tran)
                deleteList.append(tran)

    if not deleteList:           
       pma.delete(deleteList)       
    return ctrl




#################TUTORIAL
def super_bool_tut():
    windowNameTut = "Tutorial"
    if (pma.window(windowNameTut , exists=True)):
        pma.deleteUI(windowNameTut) 
    windowTutorial = pma.window(windowNameTut, title = windowNameTut, width = 400, height = 300, backgroundColor = [0.2, 0.2, 0.2])
    pma.columnLayout( "testColumn", adjustableColumn = True)
    pma.text("intro", label = "This tool is a super tool to make booleans wrote by Leonardo Iezzi. To make it works correctly, you need to have your base mesh already even if just a cube. With your base mesh selected just press one of the three buttons on the windows to subtract or add those primitives. If you want to use a custom mesh for the operation: select your base mesh then the custom one (it's important to pick your base mesh first) and then press the 'Use custom mesh' button. After you have done, select your base mesh and press 'Clean Up.'",wordWrap= True, height = 100, backgroundColor = [0.2, 0.2, 0.2], align='left', parent = "testColumn")

     #pma.text("first", label = "1- Select always your main mesh first",wordWrap= True, height = 40, backgroundColor = [0.2, 0.2, 0.2], align='left', parent = "testColumn")
     #pma.text("secondo", label = "2- In case you want to use a custom mesh: Select first your main mesh then the mesh you want to add or subtract",wordWrap= True, height = 40, backgroundColor = [0.2, 0.2, 0.2], align='left', parent = "testColumn")
     #pma.text("third", label = "3- Everythong should works",wordWrap= True, height = 40, backgroundColor = [0.2, 0.2, 0.2], align='left', parent = "testColumn")



    pma.separator(parent = "testColumn", height=20)
    pma.button("goit", label = "Got it", width = 120, height = 40, backgroundColor = [0.5, 0.5, 0.5], parent = "testColumn", command = "pma.deleteUI(windowNameTut)")

    pma.showWindow()

################################################################################################UI################################################# 
# @@@@@@@    THIS IS POLYSHIFTER!! I HAVE ADDED THIS AS A FUNCTION INSTEAD OF LEAVING IT UNINDENTED
def super_bool_ui():
    windowName = "SuperBool"
    windowSize = (120, 200)
    if (pma.window(windowName , exists=True)):
        pma.deleteUI(windowName)
    window = pma.window( windowName, title= windowName, width = 120, height = 200 )
    pma.columnLayout( "mainColumn", adjustableColumn = True)

    ################################################################################################UI#################################################
    pma.gridLayout("nameGridLayout01", numberOfRowsColumns = (1,4), cellWidthHeight = (40,40), parent = "mainColumn")
    pma.symbolButton("nameButton1", image = "polyCube.png", width = 40, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout01", command = "creator(PRIMITIVE_CUBE)")
    pma.symbolButton("nameButton2", image = "polyCylinder.png", width = 40, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout01", command = "creator(PRIMITIVE_CYLINDER)")
    pma.symbolButton("nameButton3", image = "polySphere.png", width = 40, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout01", command = "creator(PRIMITIVE_SPHERE)")
    pma.columnLayout("columnLayoutName01", adjustableColumn = True, backgroundColor = [0.2, 0.2, 0.2])
    pma.radioCollection("collection10", parent = "columnLayoutName01")
    subRadioB = pma.radioButton("subRadio", select = True, label = "Sub")
    addRadioB = pma.radioButton("addRadio", label = "Add")
    pma.setParent( '..' )
    pma.setParent( '..' )
    ################################################################################################UI#################################################
    pma.separator(parent = "mainColumn", height=20)

    pma.button("customMeshB", label = "Use Custom Mesh", width = 120, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "mainColumn", command = "creator(PRIMITIVE_CUSTOM)")

    pma.separator(parent = "mainColumn", height=20)
    ################################################################################################UI#################################################
    pma.gridLayout("nameGridLayout03", numberOfRowsColumns = (1,3), cellWidthHeight = (53,40), parent = "mainColumn")
    pma.button("hidSelB", label = "Hide Sel",  height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout03", command = "hider(0)")
    pma.button("hidAllB", label = "Hide All",  height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout03", command = "hider(1)")
    pma.button("showAll", label = "Show All",  height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout03", command = "hider(2)")

    pma.separator(parent = "mainColumn", height=20)

    pma.button("clean", label = "Clean Up", width = 120, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "mainColumn", command = "cleanUp()")

    pma.separator(parent = "mainColumn", height=20)
    ################################################################################################UI#################################################
    ################################################################################################UI#################################################
    pma.gridLayout("nameGridLayout02", numberOfRowsColumns = (1,2), cellWidthHeight = (80,40), parent = "mainColumn")
    pma.button("triangB", label = "Triangulate", width = 120, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout02", command = "triangulate()")
    pma.button("fixMatB", label = "FixMaterial", width = 120, height = 40, backgroundColor = [0.2, 0.2, 0.2], parent = "nameGridLayout02", command = "fixMaterial()")
    ################################################################################################UI#################################################
    pma.showWindow()


###################################################################
##################                              ###################
##################    END OF SUPER BOOL TOOL    ###################
##################                              ###################
###################################################################
###################################################################
##################                              ###################
##################   BEGINNING OF MY UI SCRIPT  ###################
##################                              ###################
###################################################################

# Create a custom floating window with 
if mc.window('ToolsWindow', q=True, exists=True):
    mc.deleteUI('ToolsWindow')
if mc.workspaceControl('ToolsWorkspaceControl', q=True, exists=True):
    mc.deleteUI('ToolsWorkspaceControl')
mc.window('ToolsWindow')
mc.tabLayout('ToolsTabs')

#########################################################
##################    IMPORTING PANEL    ################
#########################################################
tabMenu = mc.columnLayout("Menu", adj=True)
separator_long = mc.separator(
                         height=10,
                         style='in')


mc.button(label="MyCustomScript", command = "my_custom_script_com()")

mc.setParent('..')
mc.showWindow()

#### My custom script ####
def my_custom_script_com(*args):
    super_bool_tool_ui()
    super_bool_tool_tut()

3 个答案:

答案 0 :(得分:1)

如果我的理解正确,那么可以通过移动功能来获得第二种方法。像这样:

def my_custom_script_com(*args):
    import maya.cmds as mc
    if mc.window('my_script_ui', q=True, exists=True):
        mc.deleteUI('my_script_ui')
    else:
        mc.window('my_script_ui')

    mc.columnLayout("Menu", adj=True)

    def please_print(): # define your function here
        print "OMG IT'S FINALLY WORKING!! YAY!!"

    mc.button(label="Please_print", command = "please_print()") # use the function

    mc.setParent('..')
    mc.showWindow()

这是因为必须先定义函数,然后才能调用它们。希望这有助于解决您的问题!我也从未使用过maya,但是我知道在tkinter中,该命令将是tkinter.Button(label="Please_print", command=please_print),在please_print上没有引号。不知道这是否适用于这里!

如果您希望将please_print()移至全局空间,则可以将该部分确定为自己的函数(与非常典型的函数的子函数相对)。看起来像:

# make a global function
def please_print():
    print "OMG IT'S FINALLY WORKING!! YAY!!"

def my_custom_script_com(*args):
    import maya.cmds as mc
    if mc.window('my_script_ui', q=True, exists=True):
        mc.deleteUI('my_script_ui')
    else:
        mc.window('my_script_ui')

    mc.columnLayout("Menu", adj=True)

    mc.button(label="Please_print", command = "please_print()") # use the function

    mc.setParent('..')
    mc.showWindow()

或者最好的(使用tkinter表示法)是:

# make a global function
def please_print():
    print "OMG IT'S FINALLY WORKING!! YAY!!"

def my_custom_script_com(*args):
    import maya.cmds as mc
    if mc.window('my_script_ui', q=True, exists=True):
        mc.deleteUI('my_script_ui')
    else:
        mc.window('my_script_ui')

    mc.columnLayout("Menu", adj=True)

    mc.button(label="Please_print", command = please_print) # assign function without quotes or parenthesis

    mc.setParent('..')
    mc.showWindow()

答案 1 :(得分:1)

这是玛雅人多年生的问题。问题是您正在使用命令的字符串名称:

command = "please_print()"

但是'please_print'在run_my_custom_script_ui内部,当函数运行时它不在范围内。单击按钮时,Maya没有调用“ please_print”功能。

如果您颠倒顺序并传递函数对象本身(不带引号),则应该没问题(通过添加 按钮的功能,请确保它不会 超出范围并消失:

# this import does not need to be inside the function
import maya.cmds as mc

def run_my_custom_script_ui():

    # define this up here so it's in scope
    # when you want to call it below.  The *_
    # argument lets you ignore the default
    # argument which buttons always fire in Python

    def please_print(*_):
        print "OMG IT'S FINALLY WORKING!! YAY!!"

    if mc.window('my_script_ui', q=True, exists=True):
        mc.deleteUI('my_script_ui')
    else:
        mc.window('my_script_ui')

    mc.columnLayout("Menu", adj=True)

    mc.button(label="Please_print", command = please_print)

    mc.setParent('..')
    mc.showWindow()

更多内容:https://theodox.github.io/2014/maya_callbacks_cheat_sheet

答案 2 :(得分:0)

我已纠正您脚本中的许多内容,请尝试一下。 您的脚本中发生了很多事情,我在下面放几个链接: How to use a slider value in calculations?

我可能没有在其他主题上说的一件事是,如果您只是将其用作maya.cmds,请不要使用pymel。 Pymel真的很酷,但是真的很慢。

此外,如果您将脚本分割为“ superbool.py”,则应该执行以下操作:

 #getNames.bat file
      C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Get-Date"

最后尝试避免使用字符串来建立命令或ui元素的链接。尝试使用变量,字典,类!


import superbool
superbool.super_bool_ui()