Пресъздаване на Mesh-›Cleanup на Maya за премахване на Non-Manifold Geometry в 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