我是一个相对新手脚本在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函数只是格式化清理命令的长而丑陋的标志字符串。