Snippets

John Martini Maya align objects to vert normals

Created by John Martini
import maya.cmds as cmds
import maya.mel as mel
import math

target = 'mySphere'
# cmds.delete(target) 
# cmds.polyPlane(n=target)
# cmds.polySphere(n=target, sx=4, sy=4, r=5)
cmds.select(target)
vertCount = cmds.polyEvaluate(v=True ) 

for i in range(vertCount):
	vPos = cmds.xform( target+".pnts["+str(i)+"]", query=True, translation=True, worldSpace=True )

	# select vert
	cmds.select(target+".pnts["+str(i)+"]")

	# returns list of XYZ normals
	vNormals = cmds.polyNormalPerVertex( query=True, xyz=True )
	
	cmds.select()

	cnt = len(vNormals)
	numNormals = cnt/3

	X = 0
	Y = 0
	Z = 0

	for n in range(0, cnt, 3):
		X += vNormals[n]
		Y += vNormals[n+1] 
		Z += vNormals[n+2]

	X /= numNormals
	Y /= numNormals
	Z /= numNormals

	# normalize vector
	str_cmd = 'unit <<{}, {}, {}>>'.format(X, Y, Z)
	vec = list(mel.eval(str_cmd))
	
	# calculate the rotations
	xyLength = math.sqrt(vec[0] * vec[0] + vec[1] * vec[1])
	vecLength = math.sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2])
	
	xAngle = 0
	zAngle = 0

	# radians: converts degrees to radians 
	# degrees: converts radians to degrees
	# xyLength will be zero when $vec is pointing along the +z or -z axis
	if (xyLength == 0):
		zAngle = math.radians(90) if (vec[0] > 0) else math.radians(-90)
	else:
	    zAngle = math.acos((vec[1])/vecLength)
	  
	xAngle = math.acos(xyLength/vecLength)
	xAngle = xAngle if (vec[2] > 0) else -xAngle
	zAngle = -zAngle if (vec[0] > 0) else zAngle

	xRot = math.degrees(xAngle)
	zRot = math.degrees(zAngle)

	cmds.polyCone(r=.5, sx=1, sy=1, sz=3)
	cmds.rotate(xRot, x=True, r=True) #-r $a[0] 0  0;
	cmds.rotate(zRot, z=True, r=True) # -r 0 0  $a[1];
	cmds.xform(t=vPos)

	cmds.select( clear=True ) 
	print 'test'

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.