Good little exercise. Select object run script.
Code:
# Python
from win32com.client import constants as c
from win32com.client import Dispatch as d
xsi = Application
log = xsi.LogMessage
collSel = xsi.Selection
def xformFromDirection(vecBase, vecTgt, vecUpV):
"""Creates a transform for base object pointing to target with an upvector upV."""
vecX = XSIMath.CreateVector3()
vecY = XSIMath.CreateVector3()
vecZ = XSIMath.CreateVector3()
vecToTgt = XSIMath.CreateVector3()
vecBaseToUpV = XSIMath.CreateVector3()
vecX.Sub(vecBase,vecTgt)
vecX.NormalizeInPlace()
vecBaseToUpV.Sub(vecUpV,vecBase)
vecBaseToUpV.NormalizeInPlace()
vecZ.Cross(vecX,vecBaseToUpV)
vecZ.NormalizeInPlace()
vecY.Cross(vecZ,vecX)
vecY.NormalizeInPlace()
return vecX,vecY,vecZ
def createCurveNormals(oTgtObj):
lNormalCurveData = [[0.0, 0.0], [0.0, 1.0], [0.0, 0.0], [1.0, 1.0]]
oTgtGeo = oTgtObj.ActivePrimitive.Geometry
collPoints = oTgtGeo.Points
aNormals = [[y for y in x] for x in list(oTgtGeo.Points.NormalArray)]
aPositions = [[y for y in x] for x in list(oTgtGeo.Points.PositionArray)]
xformUtil = XSIMath.CreateTransform()
for i in xrange(collPoints.Count):
oNormalCrv = oTgtObj.AddNurbsCurve(lNormalCurveData,None,True,1,c.siNonUniformParameterization,c.siSINurbs)
oNormalCrv.Name = oTgtObj.Name + "_Normal" + str(i).zfill(len(str(collPoints.Count))) + "_Crv"
xformUtil.SetTranslationFromValues(aPositions[0][i],aPositions[1][i],aPositions[2][i])
if aNormals[1][i] >= 0.001:
vecUpV = XSIMath.CreateVector3(0,1,0)
rotUtil = XSIMath.CreateRotation()
rotUtil.SetFromXYZAnglesValues(0,0,XSIMath.DegreesToRadians(-90))
else:
vecUpV = XSIMath.CreateVector3(0,-1,0)
rotUtil = XSIMath.CreateRotation()
rotUtil.SetFromXYZAnglesValues(0,XSIMath.DegreesToRadians(-180),XSIMath.DegreesToRadians(-90))
vecX, vecY, vecZ = xformFromDirection(xformUtil.Translation, XSIMath.CreateVector3(aNormals[0][i],aNormals[1][i],aNormals[2][i]), vecUpV)
xformUtil.SetRotationFromXYZAxes(vecX,vecY,vecZ)
xformUtil.AddLocalRotation(rotUtil)
xformUtil.MulInPlace(oTgtObj.Kinematics.Global.GetTransform2(None))
oNormalCrv.Kinematics.Global.PutTransform2(None,xformUtil)
createCurveNormals(collSel(0))