Page 1 of 1

any scripts can generate curves along the normal ?

Posted: 25 May 2012, 05:29
by anyheart
any scripts or plug-ins can generate curves along the normal ?(polygon face or vertices )
or ICE ?

thx~! :)

Re: any scripts can generate curves along the normal ?

Posted: 25 May 2012, 09:33
by ace63
Only thing I can tell you is that you can not generate curves with ICE at the moment.
You'd probably have to script that.

Re: any scripts can generate curves along the normal ?

Posted: 25 May 2012, 12:56
by EricTRocks
Good little exercise. Select object run script.

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


Re: any scripts can generate curves along the normal ?

Posted: 25 May 2012, 19:28
by anyheart
Thanks EricTRocks !
:D

any way to generate the curves along the polygon face normal ?

Re: any scripts can generate curves along the normal ?

Posted: 31 May 2012, 17:42
by anyheart
EricTRocks wrote:Good little exercise. Select object run script.

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


i extract some polygon from a model , and run this script , it generate some curves , but the curves are not along the normal ~ :-o

Re: any scripts can generate curves along the normal ?

Posted: 02 Jun 2012, 10:49
by EricTRocks
Not sure why that would happen. Do the normals look OK when displayed in the viewport? I tested on a sphere and it worked fine for me.

Re: any scripts can generate curves along the normal ?

Posted: 02 Jun 2012, 13:13
by myara
I haven't read the code yet but I've tried it with a few primitives and it only worked with spheres.

Re: any scripts can generate curves along the normal ?

Posted: 02 Jun 2012, 19:05
by anyheart
EricTRocks wrote:Not sure why that would happen. Do the normals look OK when displayed in the viewport? I tested on a sphere and it worked fine for me.

I tested on a sphere and it worked fine for me too . but it dosen't works fine on others objects , such as some polygons extract from objects.

here is the scene i test ...when you run the script on the object , it has some problem...

Re: any scripts can generate curves along the normal ?

Posted: 03 Jun 2012, 03:38
by EricTRocks
I see the issue now. easy to repro on a torus. Will have a go a little later today.

Re: any scripts can generate curves along the normal ?

Posted: 03 Jun 2012, 05:03
by EricTRocks
Yeah my maths aren't compensating for certain things. I've built an ICE Tree to figure it out. Just need to translate it into scripting now. I'm going to take another shot using the intrinsic ICE attributes that come with all meshes now. Will post a bit later.

Re: any scripts can generate curves along the normal ?

Posted: 03 Jun 2012, 06:19
by EricTRocks
Try this one. I tried it on a torus and the mesh that was posted and worked. Change bUsePolys to True to do polygons and change sNormalScale to resize the length of the curve.

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

Re: any scripts can generate curves along the normal ?

Posted: 03 Jun 2012, 18:14
by anyheart
EricTRocks wrote:Try this one. I tried it on a torus and the mesh that was posted and worked. Change bUsePolys to True to do polygons and change sNormalScale to resize the length of the curve.

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


Thanks EricTRocks ! it works fine ~ :D