220 lines
8.5 KiB
Python
220 lines
8.5 KiB
Python
|
#!/usr/bin/env python
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import maya.cmds as mc # type: ignore
|
||
|
import maya.mel as mel # type: ignore
|
||
|
import math
|
||
|
import re
|
||
|
|
||
|
def evenEdgeLoopDoitRun(smoothType):
|
||
|
sel=mc.ls(sl=1,fl=1)
|
||
|
if sel:
|
||
|
shape = mc.listRelatives(sel,p=1 )
|
||
|
mc.displaySmoothness(divisionsU=0, divisionsV=0, pointsWire=4, pointsShaded=1, polygonObject=1)
|
||
|
sortEdgeLoopGrp = getEdgeRingGroup(0,'')
|
||
|
for s in sortEdgeLoopGrp:
|
||
|
mc.select(s)
|
||
|
evenEdgeLoopDoit(smoothType)
|
||
|
mc.select(sel)
|
||
|
cmd = 'doMenuComponentSelection("' + shape[0] +'", "edge");'
|
||
|
mel.eval(cmd)
|
||
|
mc.select(sel)
|
||
|
|
||
|
def run():
|
||
|
if mc.window("evenEdgeLoopDoitUI", exists = True):
|
||
|
mc.deleteUI("evenEdgeLoopDoitUI")
|
||
|
|
||
|
evenEdgeLoopDoitUI = mc.window("Even Edge Loop", w = 230, s = 1 ,mxb = False,mnb = False)
|
||
|
mc.columnLayout(adj=1)
|
||
|
mc.rowColumnLayout(nc= 5 ,cw=[(1,75),(2,10),(3,75),(4,10),(5,75)])
|
||
|
mc.button( l= "Average", c = lambda x: evenEdgeLoopDoitRun("even") )
|
||
|
mc.text(l='')
|
||
|
mc.button( l= "Arc", c = lambda x: evenEdgeLoopDoitRun("2P") )
|
||
|
mc.text(l='')
|
||
|
mc.button( l= "Straighten ", c = lambda x: evenEdgeLoopDoitRun("straighten") )
|
||
|
mc.showWindow(evenEdgeLoopDoitUI)
|
||
|
|
||
|
def evenEdgeLoopDoit(smoothType):
|
||
|
if mc.objExists('tempEvenCurve'):
|
||
|
mc.delete('tempEvenCurve')
|
||
|
sel =mc.ls(sl=1,fl=1)
|
||
|
|
||
|
getCircleState,listVtx = vtxLoopOrderCheck()
|
||
|
mc.polyToCurve(form=2, degree=1, conformToSmoothMeshPreview=1)
|
||
|
mc.rename('tempEvenCurve')
|
||
|
curveCVs =mc.ls('tempEvenCurve.cv[*]',fl=1)
|
||
|
posCurve = mc.xform(curveCVs[0], a=1,ws=1, q=1, t=1)
|
||
|
posEdge = mc.xform(listVtx[0], a=1,ws=1, q=1, t=1)
|
||
|
if posCurve == posEdge:
|
||
|
pass
|
||
|
else:
|
||
|
listVtx = listVtx[::-1]
|
||
|
if len(curveCVs)>2:
|
||
|
if smoothType == '2P':
|
||
|
if len(curveCVs)>3:
|
||
|
mc.delete(curveCVs[1:-1])
|
||
|
mc.rebuildCurve('tempEvenCurve',ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s = 2 , d=2, tol=0)
|
||
|
midA = len(listVtx)/3
|
||
|
midB = len(listVtx)/3*2
|
||
|
midA = int(midA)
|
||
|
midB = int(midB)
|
||
|
posA = mc.xform(listVtx[midA], q=1, ws=1, t=1)
|
||
|
posB = mc.xform(listVtx[midB], q=1, ws=1, t=1)
|
||
|
mc.xform('tempEvenCurve.cv[1]', a=1, ws=1, t = (posA[0],posA[1],posA[2]) )
|
||
|
mc.xform('tempEvenCurve.cv[2]', a=1, ws=1, t = (posB[0],posB[1],posB[2]) )
|
||
|
mc.rebuildCurve('tempEvenCurve',ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s = (len(listVtx)-1) , d=1, tol=0)
|
||
|
curveCVs =mc.ls('tempEvenCurve.cv[*]',fl=1)
|
||
|
elif smoothType == 'straighten ':
|
||
|
mc.delete(curveCVs[1:-1])
|
||
|
newNumber = (len(listVtx)-1)
|
||
|
mc.rebuildCurve('tempEvenCurve',ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s = newNumber , d=1, tol=0)
|
||
|
if newNumber == 2:
|
||
|
mc.delete('tempEvenCurve.cv[1]','tempEvenCurve.cv[3]')
|
||
|
curveCVs =mc.ls('tempEvenCurve.cv[*]',fl=1)
|
||
|
else:
|
||
|
mc.rebuildCurve('tempEvenCurve',ch=1, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s = 0 , d=1, tol=0)
|
||
|
if len(curveCVs)< 4:
|
||
|
mc.delete( 'tempEvenCurve.cv[1]', 'tempEvenCurve.cv[3]')
|
||
|
curveCVs =mc.ls('tempEvenCurve.cv[*]',fl=1)
|
||
|
posCurve = mc.xform(curveCVs[0], a=1,ws=1, q=1, t=1)
|
||
|
posEdge = mc.xform(listVtx[0], a=1,ws=1, q=1, t=1)
|
||
|
posEdge[0] = round(posEdge[0],3)
|
||
|
posEdge[1] = round(posEdge[1],3)
|
||
|
posEdge[2] = round(posEdge[2],3)
|
||
|
posCurve[0] = round(posCurve[0],3)
|
||
|
posCurve[1] = round(posCurve[1],3)
|
||
|
posCurve[2] = round(posCurve[2],3)
|
||
|
for i in range(len(curveCVs)):
|
||
|
pos = mc.xform(curveCVs[i], a=1,ws=1, q=1, t=1)
|
||
|
mc.xform(listVtx[i], a=1, ws=1, t = (pos[0],pos[1],pos[2]) )
|
||
|
mc.delete('tempEvenCurve')
|
||
|
|
||
|
def getEdgeRingGroup(listSort,listInput):
|
||
|
selEdges = mc.ls(sl=1,fl=1)
|
||
|
trans = selEdges[0].split(".")[0]
|
||
|
e2vInfos = mc.polyInfo(selEdges, ev=True)
|
||
|
e2vDict = {}
|
||
|
fEdges = []
|
||
|
for info in e2vInfos:
|
||
|
evList = [ int(i) for i in re.findall('\\d+', info) ]
|
||
|
e2vDict.update(dict([(evList[0], evList[1:])]))
|
||
|
while True:
|
||
|
try:
|
||
|
startEdge, startVtxs = e2vDict.popitem()
|
||
|
except:
|
||
|
break
|
||
|
edgesGrp = [startEdge]
|
||
|
num = 0
|
||
|
for vtx in startVtxs:
|
||
|
curVtx = vtx
|
||
|
while True:
|
||
|
|
||
|
nextEdges = []
|
||
|
for k in e2vDict:
|
||
|
if curVtx in e2vDict[k]:
|
||
|
nextEdges.append(k)
|
||
|
if nextEdges:
|
||
|
if len(nextEdges) == 1:
|
||
|
if num == 0:
|
||
|
edgesGrp.append(nextEdges[0])
|
||
|
else:
|
||
|
edgesGrp.insert(0, nextEdges[0])
|
||
|
nextVtxs = e2vDict[nextEdges[0]]
|
||
|
curVtx = [ vtx for vtx in nextVtxs if vtx != curVtx ][0]
|
||
|
e2vDict.pop(nextEdges[0])
|
||
|
else:
|
||
|
break
|
||
|
else:
|
||
|
break
|
||
|
num += 1
|
||
|
fEdges.append(edgesGrp)
|
||
|
retEdges =[]
|
||
|
for f in fEdges:
|
||
|
f= list(map(lambda x: (trans +".e["+ str(x) +"]"), f))
|
||
|
retEdges.append(f)
|
||
|
if listSort == 1:
|
||
|
sortEdgeLoopOrder=[]
|
||
|
getCircleState,listVtx = vtxLoopOrderCheck(listInput)
|
||
|
for l in listVtx:
|
||
|
for r in retEdges:
|
||
|
checkCvList = mc.ls(mc.polyListComponentConversion( r,fe=True, tv=True), fl=True,l=True)
|
||
|
if l in checkCvList:
|
||
|
sortEdgeLoopOrder.append(r)
|
||
|
return sortEdgeLoopOrder
|
||
|
else:
|
||
|
return retEdges
|
||
|
|
||
|
|
||
|
def vtxLoopOrderCheck():
|
||
|
selEdges = mc.ls(sl=1,fl=1)
|
||
|
shapeNode = mc.listRelatives(selEdges[0], fullPath=True , parent=True )
|
||
|
transformNode = mc.listRelatives(shapeNode[0], fullPath=True , parent=True )
|
||
|
edgeNumberList = []
|
||
|
for a in selEdges:
|
||
|
checkNumber = ((a.split('.')[1]).split('\n')[0]).split(' ')
|
||
|
for c in checkNumber:
|
||
|
findNumber = ''.join([n for n in c.split('|')[-1] if n.isdigit()])
|
||
|
if findNumber:
|
||
|
edgeNumberList.append(findNumber)
|
||
|
getNumber = []
|
||
|
for s in selEdges:
|
||
|
evlist = mc.polyInfo(s,ev=True)
|
||
|
checkNumber = ((evlist[0].split(':')[1]).split('\n')[0]).split(' ')
|
||
|
for c in checkNumber:
|
||
|
findNumber = ''.join([n for n in c.split('|')[-1] if n.isdigit()])
|
||
|
if findNumber:
|
||
|
getNumber.append(findNumber)
|
||
|
dup = set([x for x in getNumber if getNumber.count(x) > 1])
|
||
|
getHeadTail = list(set(getNumber) - dup)
|
||
|
checkCircleState = 0
|
||
|
if not getHeadTail: #close curve
|
||
|
checkCircleState = 1
|
||
|
getHeadTail.append(getNumber[0])
|
||
|
vftOrder = []
|
||
|
vftOrder.append(getHeadTail[0])
|
||
|
count = 0
|
||
|
while len(dup)> 0 and count < 1000:
|
||
|
checkVtx = transformNode[0]+'.vtx['+ vftOrder[-1] + ']'
|
||
|
velist = mc.polyInfo(checkVtx,ve=True)
|
||
|
getNumber = []
|
||
|
checkNumber = ((velist[0].split(':')[1]).split('\n')[0]).split(' ')
|
||
|
for c in checkNumber:
|
||
|
findNumber = ''.join([n for n in c.split('|')[-1] if n.isdigit()])
|
||
|
if findNumber:
|
||
|
getNumber.append(findNumber)
|
||
|
findNextEdge = []
|
||
|
for g in getNumber:
|
||
|
if g in edgeNumberList:
|
||
|
findNextEdge = g
|
||
|
edgeNumberList.remove(findNextEdge)
|
||
|
checkVtx = transformNode[0]+'.e['+ findNextEdge + ']'
|
||
|
findVtx = mc.polyInfo(checkVtx,ev=True)
|
||
|
getNumber = []
|
||
|
checkNumber = ((findVtx[0].split(':')[1]).split('\n')[0]).split(' ')
|
||
|
for c in checkNumber:
|
||
|
findNumber = ''.join([n for n in c.split('|')[-1] if n.isdigit()])
|
||
|
if findNumber:
|
||
|
getNumber.append(findNumber)
|
||
|
gotNextVtx = []
|
||
|
for g in getNumber:
|
||
|
if g in dup:
|
||
|
gotNextVtx = g
|
||
|
dup.remove(gotNextVtx)
|
||
|
vftOrder.append(gotNextVtx)
|
||
|
count += 1
|
||
|
if checkCircleState == 0:
|
||
|
vftOrder.append(getHeadTail[1])
|
||
|
else:#close curve remove connected vtx
|
||
|
if vftOrder[0] == vftOrder[1]:
|
||
|
vftOrder = vftOrder[1:]
|
||
|
elif vftOrder[0] == vftOrder[-1]:
|
||
|
vftOrder = vftOrder[0:-1]
|
||
|
finalList = []
|
||
|
for v in vftOrder:
|
||
|
finalList.append(transformNode[0]+'.vtx['+ v + ']' )
|
||
|
|
||
|
return checkCircleState, finalList
|
||
|
#edge
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
run()
|