MetaBox/Scripts/Modeling/Edit/UnBevel.py

179 lines
6.4 KiB
Python
Raw Normal View History

2025-01-14 02:17:16 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import maya.cmds as cmds
import math
import re
def run():
selEdge = cmds.filterExpand(expand=True ,sm=32)
if selEdge:
#cmds.ConvertSelectionToVertices()
#cmds.ConvertSelectionToEdges()
#cmds.select(selEdge,d=1)
if cmds.objExists('saveSel'):
cmds.delete('saveSel')
cmds.sets(name="saveSel", text= "saveSel")
sortGrp = getEdgeRingGroup()
for e in sortGrp:
cmds.select(e)
unBevelEdgeLoop()
cmds.select(selEdge)
cmds.ConvertSelectionToVertices()
cmds.polyMergeVertex(d=0.001, am=0, ch=1)
cmds.select('saveSel')
cmds.delete('saveSel')
def unBevelEdgeLoop():
listVtx = vtxLoopOrder()
#get angles
checkA = angleBetweenThreeP(listVtx[1],listVtx[0],listVtx[-1])
angleA = math.degrees(checkA)
checkB = angleBetweenThreeP(listVtx[-2],listVtx[-1],listVtx[0])
angleB = math.degrees(checkB)
angleC = 180 - angleA -angleB
distanceC = distanceBetween(listVtx[0],listVtx[-1])
#solve distanceA and distanceB
distanceA = distanceC / math.sin(math.radians(angleC)) * math.sin(math.radians(angleA))
distanceB = distanceC / math.sin(math.radians(angleC)) * math.sin(math.radians(angleB))
oldDistA = distanceBetween(listVtx[-2],listVtx[-1])
oldDistB = distanceBetween(listVtx[0],listVtx[1])
#scalarA = distanceA / oldDistA
scalarB = distanceB / oldDistB
pA = cmds.pointPosition(listVtx[0], w =1)
pB = cmds.pointPosition(listVtx[1], w =1)
newP = [0,0,0]
newP[0] = ((pB[0]-pA[0])*scalarB) + pA[0]
newP[1] = ((pB[1]-pA[1])*scalarB) + pA[1]
newP[2] = ((pB[2]-pA[2])*scalarB) + pA[2]
for i in range(1,len(listVtx)-1):
#for i in range(len(listVtx)):
cmds.move(newP[0],newP[1],newP[2],listVtx[i],absolute = 1)
def distanceBetween(p1,p2):
pA = cmds.pointPosition(p1, w =1)
pB = cmds.pointPosition(p2, w =1)
dist = math.sqrt( ((pA[0] - pB[0])**2) + ((pA[1] - pB[1])**2) + ((pA[2] - pB[2])**2) )
return dist
def angleBetweenThreeP(pA, pB, pC):
a = cmds.pointPosition(pA, w =1)
b = cmds.pointPosition(pB, w =1)
c = cmds.pointPosition(pC, w =1)
# Create vectors from points
ba = [ aa-bb for aa,bb in zip(a,b) ]
bc = [ cc-bb for cc,bb in zip(c,b) ]
# Normalize vector
nba = math.sqrt ( sum ( (x**2.0 for x in ba) ) )
ba = [ x/nba for x in ba ]
nbc = math.sqrt ( sum ( (x**2.0 for x in bc) ) )
bc = [ x/nbc for x in bc ]
# Calculate scalar from normalized vectors
scalar = sum ( (aa*bb for aa,bb in zip(ba,bc)) )
# calculate the angle in radian
angle = math.acos(scalar)
return angle
def vtxLoopOrder():
selEdges = cmds.ls(sl=1,fl=1)
shapeNode = cmds.listRelatives(selEdges[0], fullPath=True , parent=True )
transformNode = cmds.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 = cmds.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)
vftOrder = []
vftOrder.append(getHeadTail[0])
count = 0
while len(dup)> 0 and count < 100:
checkVtx = transformNode[0]+'.vtx['+ vftOrder[-1] + ']'
velist = cmds.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 = cmds.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
vftOrder.append(getHeadTail[1])
finalList = []
for v in vftOrder:
finalList.append(transformNode[0]+'.vtx['+ v + ']' )
return finalList
def getEdgeRingGroup():
selEdges = cmds.ls(sl=1,fl=1)
trans = selEdges[0].split(".")[0]
e2vInfos = cmds.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= map(lambda x: (trans +".e["+ str(x) +"]"), f)
retEdges.append(f)
return retEdges