Воссоздание Maya Mesh-›Cleanup для удаления неманифолдной геометрии в Python

Я относительный новичок в написании сценариев на 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 )

Но на самом деле делать что-то похожее на инструмент очистки в настоящее время я не понимаю. Кто-нибудь знает, как запустить команду Mesh->Cleanup из скрипта в Python? Спасибо большое!

Изменить: вот некоторые фрагменты кода, над которым я работаю, адаптированные из некоторых других мест в Интернете (в частности, один, который уменьшил кучу файлов Maya, а другой, который показал, как открывать файлы OBJ) . Я добавил комментарии со словом "ПРОБЛЕМА:", чтобы указать на проблемные места, которые у меня есть в настоящее время.

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()

person justinhpatterson    schedule 04.06.2015    source источник


Ответы (1)


Этот инструмент - своего рода кошмар.

Вы можете увидеть внутренности в (Program Files or /Applications) /Autodesk/Maya20XX/scripts/others/polyCleanupArgList.mel. Однако вы хотите вызвать polyCleanup, а не polyCleanupArgList: функция argList просто форматирует длинную уродливую строку флагов для команды очистки.

person theodox    schedule 04.06.2015
comment
Согласовано! Большинство этих инструментов довольно сомнительны. Это для очень грязного захвата 3D-видео, поэтому хорошая топология и прочее для меня в данный момент не важны. Я просто хочу просмотреть все файлы и получить супер грязную очистку и уменьшить до тысячи файлов в папке. Документация Maya для Python-стороны Mesh Reduce немного разочаровала. Я продолжу исследования! - person justinhpatterson; 05.06.2015
comment
если вы хотите повторно реализовать, прочитайте SelectionConstraints. Базовый рабочий процесс выбирает все компоненты, затем применяет ограничение, чтобы ограничить выбор типами проблем (не многообразными, пластинчатыми и т. д.), а затем циклически выполняет выбор, выполняя исправления. Только не забудьте сбросить их после - person theodox; 05.06.2015