Create Curves on Normals


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))