重新创建 Maya 的"Mesh->Cleanup"以删除 Python 中的非流形几何



我是一个相对新手脚本在Python玛雅,我想知道是否有人可以帮助。我正在尝试通过一堆obj循环并减少它们的多边形计数。我已经让那部分工作了!问题是我偶尔会遇到读取"Cannot reduce polygonal object with non-manifold geometry. Cleanup the object using Mesh->Cleanup before reducing."的错误,虽然我当然可以使用Mesh->Cleanup手动解决问题,但我必须在数千个OBJ文件的某些部分中执行此操作。

我相信在MEL中命令应该是这样的:

polyCleanupArgList 3 { "0","1","1","0","0","0","0","0","0","1e-05","0","1e-05","0","1e-05","0","1","0" }

这是我在控制台中从菜单运行命令时返回的结果。我既找不到关于MEL命令的文档,也找不到关于如何将其转换为python的文档。我知道我可以用这个命令"找到"(但不清理)非流形地理(我认为):

cmds.polyInfo( nme=True )

但实际上做任何类似的清理工具目前超出了我的理解。有人在那里有一些见解如何运行Mesh->清理命令从脚本在Python?非常感谢!

编辑:这是我正在处理的一些代码片段,改编自网络上的其他一些地方(具体来说,一个减少了一堆maya文件,另一个显示了如何打开OBJ文件)。我添加了带有"ISSUE:"字样的注释,以指出我目前存在的问题。

import os
import maya.cmds as mc
import maya.mel
#creates the search UI                
def makeWindow():
    if mc.window('UI', query=True, exists=True): mc.deleteUI('UI')
    window = mc.window('UI', widthHeight=(346, 96),   title = 'Automated Poly Reduction Tool')
    mc.columnLayout()    
    mc.radioButtonGrp('myRadBtnGrp', labelArray2=['Save changes', 'Preview changes'], numberOfRadioButtons=2, select = 2)
    mc.floatFieldGrp( 'myFltFieldGrp', numberOfFields=1, label='Amount of Reduction', extraLabel='%', value1=50)
    mc.intFieldGrp( 'myIntFldGrp', numberOfFields=2, label='Select Image Dimensions', extraLabel='W / H', value1=1280, value2=960, )
    mc.button('directoryBtn', label='get directory', command = 'getDirectory()')
    mc.button('explorerBtn', label='open image folder', command = 'openFolder()')
    mc.showWindow(window)
def openFolder():
    outputDir = mc.workspace (query = True, fileRule = True)
    path =  (outputDir[3] + '/tmp')
    if os.path.exists(path) == 1:
        os.system('start ' + path)
    else :
        mc.warning ("folder doesn't exist yet - please run tool")

#finds all the files in a directory
def getFiles(dir):
    mayaFiles = []
    for root, dirs, files in os.walk(dir):
        for file in files:
            if file.endswith('.obj'):
                mayaFiles.append( os.path.join(root, file))
    #open the first file in the list without saving the currently open scene
    mc.file(save = False)
    mc.file(mayaFiles[0], i = True) 
    processScene(mayaFiles)           
#gets directory to process
def getDirectory():
    result = mc.fileDialog2(fm = 3, okc = 'Process!')
    #set the location for the renders to save  
    #mc.workspace(fileRule = ['png', result[0]])
    mc.workspace (fileRule = ['images', result[0]])
    getFiles(result[0])
#moves through the selected files and does the work
def processScene(mayaFiles):
    errorLog = ""
    errorCount = 0
    for i in range (0, len(mayaFiles), 1):    
        #are we saving the reduction or just testing?
        saveQuery = mc.radioButtonGrp('myRadBtnGrp', query = True, select = True)
        if saveQuery == 1:
            #mc.file(save = True)
            #ISSUE: I NEED TO OUTPUT TO A DIRECTORY TO EXPORT AN OBJ FILE, THE CODE IN THIS IF STATEMENT DOESN'T CURRENTLY WORK
            geo = mc.ls( geometry=True )
            mc.select( all=True )
            outputDir = mc.workspace (query = True, fileRule = True)
            path =  mayaFiles[i];
            mc.file(path,pr=1,typ="OBJexport",es=1,op="groups=0; ptgroups=0; materials=0; smoothing=0; normals=0")
            print path;
            mc.file(save = False)
            mc.file(mayaFiles[i], open = True, force = True) 
        if saveQuery == 2:
            mc.file(save = False)
            mc.file(mayaFiles[i], open = True, force = True) 
        print  'currently working on ' + mayaFiles[i]          
        #move camera to front view
        mc.setAttr ('persp.translateX', 0)
        mc.setAttr ('persp.translateY', 0)
        mc.setAttr ('persp.translateZ', 0)
        mc.setAttr ("persp.rotateX", 0)
        mc.setAttr ("persp.rotateY", 0)
        mc.setAttr ("persp.rotateZ", 0)
        #set to full perspective window
        maya.mel.eval('setNamedPanelLayout("Single Perspective View")')
        #set image resolution
        width = mc.intFieldGrp( 'myIntFldGrp', query = True, value1 = True )
        height = mc.intFieldGrp( 'myIntFldGrp', query = True, value2 = True )
        mc.setAttr ('defaultResolution.width', width)
        mc.setAttr ('defaultResolution.height', height)
        #select all geo
        geo = mc.ls( geometry=True )
        mc.select (geo, replace = True)
        #and fit to frame
        mc.viewFit( 'persp', all=False )
        #get name of file for use in image name
        fileName = os.path.splitext(mc.file(query = True, sceneName = True, shortName = True))
        imageNameBefore =  (str(i) + '_before_' + fileName[0])
        mc.setAttr('defaultRenderGlobals.imageFilePrefix', imageNameBefore, type = 'string')
        #set the render globals to png
        mc.setAttr('defaultRenderGlobals.imageFormat', 32) 
        #render
        mc.hwRender()
        #if more than one thing is selected, iterate over all selected objects individually
        if len(geo) != 1:
            for item in geo:
                #check the geo is polygonal
                if mc.nodeType(item) == 'mesh':
                    #ISSUE: I NEED TO RUN CLEANUP HERE SO I DON'T HAVE TO TRY/CATCH ANYMORE
                    #run reduction      
                    mc.select (item, replace = True)  
                    try:
                        reduction = mc.floatFieldGrp( 'myFltFieldGrp', query = True, value = True)
                        mc.polyReduce(percentage = reduction[0], uvWeights=False, colorWeights=False, keepQuadsWeight = True, keepBorder = True, keepMapBorder= True, keepOriginalVertices = True,keepHardEdge = True,compactness=0.5, triangulate = False, replaceOriginal = True, cachingReduce = True, ch = True)
                    except:
                        #print "ERROR ON FILE " + mayaFiles[i];
                        errorLog = errorLog + mayaFiles[i] + ", "
                        errorCount = errorCount + 1
                        pass
        else:
            try:
                reduction = mc.floatFieldGrp( 'myFltFieldGrp', query = True, value = True)
                mc.polyReduce(percentage = reduction[0], uvWeights=False, colorWeights=False, keepQuadsWeight = True, keepBorder = True, keepMapBorder= True, keepOriginalVertices = True,keepHardEdge = True,compactness=0.5, triangulate = False, replaceOriginal = True, cachingReduce = True, ch = True)
            except:
                errorLog = errorLog + mayaFiles[i] + ", "
                errorCount = errorCount + 1
                pass
        #store second screen shot
        imageNameAfter =  (str(i) + '_after_' + fileName[0])
        mc.setAttr('defaultRenderGlobals.imageFilePrefix', imageNameAfter, type = 'string')
        mc.hwRender()
    print "Error count is : " + str(errorCount) + " and files are " + errorLog
makeWindow()

这个工具真是个噩梦。

可以看到(Program Files or /Applications) /Autodesk/Maya20XX/scripts/others/polyCleanupArgList.mel的内部结构。然而,您想调用polyCleanup而不是polyCleanupArgList: argList函数只是格式化清理命令的长而丑陋的标志字符串。

相关内容

  • 没有找到相关文章

最新更新