Skip to content

Instantly share code, notes, and snippets.

@Onefabis
Last active December 19, 2021 00:39
Show Gist options
  • Save Onefabis/e4ce7a8104366454d01bd0c602754977 to your computer and use it in GitHub Desktop.
Save Onefabis/e4ce7a8104366454d01bd0c602754977 to your computer and use it in GitHub Desktop.
align selected vertices in line #maya #align #script #vertices #mesh
import maya.api.OpenMaya as om2
import maya.cmds as mc
import math
import maya.mel as mel
'''
select two main vertices
and then select child vertices
that you need to align
in line between the main ones
all - will align in all axis
x - will align in 'y' and 'z' axis, leaving plane 'x' inactive in alignment
y - will align in 'x' and 'z' axis, leaving plane 'y' inactive in alignment
z - will align in 'x' and 'y' axis, leaving plane 'z' inactive in alignment
make sure you select at least 3 vertices
also note that script skip vertices that has no differences
in the plane axis
'''
def lineIt( planeAxis='all'):
if not mc.selectPref( q=1, trackSelectionOrder=1 ):
mel.eval('selectPref -trackSelectionOrder true;')
selVerts = om2.MGlobal.getActiveSelectionList(1)
dp, comp = selVerts.getComponent(0)
if comp.isNull():
mc.warning('Please, select any vertex')
return
ids = []
if selVerts.length() > 2:
for s in xrange( selVerts.length() ):
dp, comp = selVerts.getComponent(s)
compFn = om2.MFnSingleIndexedComponent(comp)
ids.extend( compFn.getElements() )
parentVerts = ids[0:2]
childVerts = ids[2:len(ids)]
parPoint0 = om2.MVector(mc.xform( '%s.vtx[%i]' %( dp.fullPathName(), parentVerts[0] ) , q=1, ws=1, t=1 ) )
parPoint1 = om2.MVector(mc.xform( '%s.vtx[%i]' %( dp.fullPathName(), parentVerts[1] ) , q=1, ws=1, t=1 ) )
objBBoxMin = mc.getAttr( dp.partialPathName() + '.boundingBoxMin' )
objBBoxMax = mc.getAttr( dp.partialPathName() + '.boundingBoxMax' )
bBoxMin = [ b1 - 1.0 for b1 in objBBoxMin[0] ]
bBoxMax = [ b2 + 1.0 for b2 in objBBoxMax[0] ]
for c in childVerts:
childPos = mc.xform( '%s.vtx[%i]' %( dp.fullPathName(), c ) , q=1, ws=1, t=1 )
t0 = t1 = t2 = None
if planeAxis == 'y':
if round( childPos[1], 3 ) != round( parPoint0[1], 3 ) or round( childPos[1], 3 ) != round( parPoint1[1], 3 ):
t0 = om2.MVector( bBoxMin[0], childPos[1], bBoxMin[2] )
t1 = om2.MVector( bBoxMin[0], childPos[1], bBoxMax[2] )
t2 = om2.MVector( bBoxMax[0], childPos[1], bBoxMax[2] )
else: return
elif planeAxis == 'z':
if round( childPos[2], 3 ) != round( parPoint0[2], 3 ) or round( childPos[2], 3 ) != round( parPoint1[2], 3 ):
t0 = om2.MVector( bBoxMin[0], bBoxMin[1], childPos[2] )
t1 = om2.MVector( bBoxMin[0], bBoxMax[1], childPos[2] )
t2 = om2.MVector( bBoxMax[0], bBoxMax[1], childPos[2] )
else: return
elif planeAxis == 'x':
if round( childPos[0], 3 ) != round( parPoint0[0], 3 ) or round( childPos[0], 3 ) != round( parPoint1[0], 3 ):
t0 = om2.MVector( childPos[0], bBoxMin[1], bBoxMin[2] )
t1 = om2.MVector( childPos[0], bBoxMin[1], bBoxMax[2] )
t2 = om2.MVector( childPos[0], bBoxMax[1], bBoxMax[2] )
else: return
if planeAxis == 'all':
pVec = parPoint0 - parPoint1
cVec = om2.MVector( childPos )
dotp = ( ( parPoint0 - om2.MVector( childPos ) ) * ( pVec ) ) / ( pVec ).length()
mc.xform( '%s.vtx[%i]' %( dp.fullPathName(), c ) , ws=1, t= ( cVec + ( parPoint0 - cVec ) - dotp * ( pVec ).normal() ) )
else:
if t0 and t1 and t2:
v1 = t1 - t0
v2 = t2 - t0
normal = (v2 ^ v1).normal()
denom = normal * ( parPoint1 - parPoint0 )
if denom <= 0.0:
denom += 0.000001
intersectPoint = parPoint0 + ( parPoint1 - parPoint0 ) * (( normal * (t0 - om2.MVector(parPoint0))) / denom )
mc.xform( '%s.vtx[%i]' %( dp.fullPathName(), c ) , ws=1, t=intersectPoint )
lineIt('all')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment