Edit: Fixed an issue with the scaling being doubled with each curve if the Target mesh was scaled.
Code: Select all
# Python
from win32com.client import constants as c
from win32com.client import Dispatch as d
xsi = Application
log = xsi.LogMessage
collSel = xsi.Selection
def axesFromNormal(vecNormal, vecUpV):
"""Creates vectors for each axis of a transform."""
vecX = XSIMath.CreateVector3()
vecY = XSIMath.CreateVector3()
vecZ = XSIMath.CreateVector3()
vecToTgt = XSIMath.CreateVector3()
vecBaseToUpV = XSIMath.CreateVector3()
vecX.Cross(vecUpV, vecNormal)
vecX.NormalizeInPlace()
vecY.Copy(vecNormal)
vecY.NormalizeInPlace()
vecZ.Cross(vecX, vecNormal)
vecZ.NormalizeInPlace()
return vecX,vecY,vecZ
def ET_NormalCurves(oTgtObj, bUsePolys=False, sNormalScale=1.0):
try:
xsi.BeginUndo("ET_NormalCurves")
lNormalCurveData = [[0.0, 0.0], [0.0, sNormalScale], [0.0, 0.0], [1.0, 1.0]]
oTgtGeo = oTgtObj.ActivePrimitive.Geometry
if bUsePolys:
aPolygonPositionICEData = oTgtGeo.ICEAttributes("PolygonPosition").GetDataArrayChunk(0,0)
aPositions = [[i.X,i.Y,i.Z] for i in aPolygonPositionICEData]
aPolygonNormalICEData = oTgtGeo.ICEAttributes("PolygonNormal").GetDataArrayChunk(0,0)
aNormals = [[i.X,i.Y,i.Z] for i in aPolygonNormalICEData]
else:
aPointPositionICEData = oTgtGeo.ICEAttributes("PointPosition").GetDataArrayChunk(0,0)
aPositions = [[i.X,i.Y,i.Z] for i in aPointPositionICEData]
aPointNormalICEData = oTgtGeo.ICEAttributes("PointNormal").GetDataArrayChunk(0,0)
aNormals = [[i.X,i.Y,i.Z] for i in aPointNormalICEData]
xformUtil = XSIMath.CreateTransform()
vecNormal = XSIMath.CreateVector3()
vecUpV = XSIMath.CreateVector3()
for i in xrange(len(aPositions)):
oNormalCrv = oTgtObj.AddNurbsCurve(lNormalCurveData, None, True, 1, c.siNonUniformParameterization, c.siSINurbs)
oNormalCrv.Name = oTgtObj.Name + "_Normal" + str(i).zfill(len(str(len(aPositions)))) + "_Crv"
xformUtil.SetIdentity()
xformUtil.SetTranslationFromValues(aPositions[i][0],aPositions[i][1],aPositions[i][2])
vecNormal.Set(aNormals[i][0],aNormals[i][1],aNormals[i][2])
vecNormal.NormalizeInPlace()
if aNormals[i][1] >= 0.999:
vecUpV.Set(aPositions[i][0],aPositions[i][1],aPositions[i][2])
vecUpV.NormalizeInPlace()
elif aNormals[i][1] <= -0.999:
vecUpV.Set(aPositions[i][0],aPositions[i][1],aPositions[i][2])
vecUpV.NormalizeInPlace()
elif aNormals[i][1] >= 0.000 and aNormals[i][1] < 0.999:
vecUpV.Set(0,1,0)
vecUpV.NormalizeInPlace()
elif aNormals[i][1] < 0.000 and aNormals[i][1] > -0.999:
vecUpV.Set(0,-1,0)
vecUpV.NormalizeInPlace()
vecX, vecY, vecZ = axesFromNormal(vecNormal, vecUpV)
xformUtil.SetRotationFromXYZAxes(vecX,vecY,vecZ)
xformUtil.MulInPlace(oTgtObj.Kinematics.Global.GetTransform2(None))
oNormalCrv.Kinematics.Global.PutTransform2(None,xformUtil)
finally:
xsi.EndUndo()
ET_NormalCurves(collSel(0))