我是使用Python编写Maya脚本的相对新手,我想知道是否有人可以提供帮助。我正在尝试遍历一堆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 )
但实际上做类似于清理工具的任何东西目前都超出了我的理解范围。那里的任何人都有一些关于如何从Python中的脚本运行Mesh-> Cleanup命令的见解?非常感谢!
编辑:以下是我正在处理的代码的一些片段,改编自网络上的其他一些地方(具体来说,一个减少了一堆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()
答案 0 :(得分:2)
这个工具有点像噩梦。
你可以在(Program Files or /Applications) /Autodesk/Maya20XX/scripts/others/polyCleanupArgList.mel
中看到内脏。但是你要调用polyCleanup
而不是polyCleanupArgList
:argList函数只是格式化清理命令的长丑陋的标志字符串。