Eric Thivierge The technical side of animation.

5Apr/13Off

robotArm rig

robotArm_rig

Just rigged up a simple robot arm / claw to share with everyone. Haven't rigged anything in a few months so I did this little rig to keep my skills fresh.

Rigged in Softimage 2012.5 and 2013 SP1

Download Here

Filed under: Daily, Rigging Comments Off
4Feb/13Off

XML to Directory Structure

Here is a python snippet that creates a directory structure out of an XML file / data:

 

Filed under: Daily, Scripting Comments Off
5Nov/12Off

2012 Election

Firstly, take this post as you will if you don't agree great move on no need to try to persuade me otherwise. I'm posting to give some perspective to those who may be undecided.

I'm so confused on why this presidential race is so close when the extreme measures Romney is going to go if elected.

1) Women's right are going to virtually disappear. Planned parenthood and the right for women to have abortions will be in the firing line and most likely get funding cut and Roe v. Wade will be overturned. Whatever your moral or political views are on the topic just remember that we are a nation of individuals from different walks of life. You can't enforce your views on people who have different moral and political views than you. The fact we are a nation of so many different types of people is what defines us as the USA.

2. Medical coverage. Seriously. Why would anyone think that letting insurance companies deny people because they have pre-existing conditions? Many Americans can't afford health care and thus, when they do get sick and need help they need to have insurance. We have come from an era where health care was not affordable. How are people supposed to get sufficient health care to cure them or maintain a decent life if they aren't allowed to get health care?

3. Gun control. Even after one of the worst cases of mass murder this past year people still think that automatic weapons should be allowed in the hands of people outside of the military. Automatic weapons have one purpose and that is to kill. Romney outlawed them when he was governor now has flopped to having no additional gun control reform.

4. Economy. Many don't think Obama is doing a good job with the economy. What do you expect with a republican majority that is hell bent on blocking all legislation and not compromising? It was only a month into his presidency when the republican party stated that their mission was to get him out of office. Who can we thank for the republican majority? Ourselves. Mid-term elections put the majority in the hands of the republicans. You really think anything is going to get done in that atmosphere?

You want hope and change? Look at what you're being offered with Romney.

Filed under: Daily Comments Off
20Oct/12Off

Undo with statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from win32com.client import constants as c
from win32com.client.dynamic import Dispatch as d
 
xsi = Application
log = xsi.LogMessage
collSel = xsi.Selection
 
 
class xsiUndo():
    def __enter__(self):
        xsi.BeginUndo()
 
    def __exit__(self, type, value, traceback):
        xsi.EndUndo()
 
 
def testFunc():
    log("running test")
 
 
with xsiUndo():
    testFunc()
Filed under: Scripting Comments Off
18Sep/12Off

Component selection via Object Model

from AL.xsi import xsi, log, c, utils
 
lSubCompSel = []
for eachObj in xsi.Selection:
 
    oGeo = eachObj.ActivePrimitive.Geometry
    oSubComp = oGeo.CreateSubcomponent(c.siPolygonCluster, range(4))
    lSubCompSel.append(oSubComp)
 
log(",".join([str(x) for x in lSubCompSel]))
xsi.Selection.SetAsText(",".join([str(x) for x in lSubCompSel]))
Filed under: Scripting Comments Off
18Jul/12Off

Some thoughts on tool dev

Some recent issues I've run into lately have sparked some thoughts on tool dev:

Firstly, when you're developing tools for many people on different teams you need to get input from all the teams and individuals. Some tool concepts and functionality may work for a larger group, but may cripple the smaller group's workflow. For generalized tools that are one off tools you may need to say that the smaller group has to fall to the way side and just continue using the 'majority rules' mentality. However, if the new tool is intrusive, changing normal functionality of the software, you HAVE to cater to all groups. You also should (read have) to make it an opt-in process.

Recent activities by Facebook and Google regarding new features and security settings illustrate the point well but particularly Facebook. If you change or add a privacy setting you should have it act as it did before while giving the users an option to activate it or allow it. Its fairly obvious why Facebook does this as their business on selling ads is based on sharing your data. Many people go and disable it automatically while others oblivious to the change carry on and unknowingly share their data. Not good and not legal in my eyes.

This is a practice you should stay away from. If you say, build a tool that overrides the default key mapping for the application and force it on people and disabling their existing ones, it's going to be a pretty invasive and opaque to the end users. This should not be the case. While you could add an option to disable this to solve the problem, it is still opaque to the users and takes effort to find out how to do so. Like-wise, the function to do this needs to be as global as possible. Don't make users go through tons of settings to disable all the changes.

Make 1 toggle to turn it on. Leave it off by default and educate people on the benefits of turning it on and how it may affect their workflow. Your users, leads, TD's, and all will love you for it silently.

Filed under: Daily, Scripting Comments Off
3Jun/12Off

ET_NormalCurves

Here is a script that will add a curve to each point or polygon aligned to its normal. Change the arguments according to what you need.

# 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.SetTranslationFromValues(aPositions[i][0],aPositions[i][1],aPositions[i][2])
            vecNormal.Set(aNormals[i][0],aNormals[i][1],aNormals[i][2])
 
            if 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))
Filed under: Daily Comments Off
25May/12Off

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))
Filed under: Daily, Scripting Comments Off
13Apr/12Off

Toggle Softimage Script Editor

This code toggles the Softimage script editor on and off. Useful to embed in a custom layout.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from win32com.client import constants as c
from win32com.client import Dispatch as d</code>
 
xsi = Application
log = xsi.LogMessage
collSel = xsi.Selection
 
def toggleScriptEditor():
oLayout = xsi.Desktop.ActiveLayout
collViews = oLayout.Views
oScriptEd = collViews("Script Editor")
 
if not oScriptEd:
oLayout.CreateView("Script Editor", "Script Editor")
return
 
oState = oScriptEd.State
 
if oState == c.siNormal:
oScriptEd.State = c.siClosed
elif oState == c.siMinimized:
log(oState)
oScriptEd.State = c.siNormal
 
toggleScriptEditor()
Filed under: Scripting Comments Off
15Feb/12Off

Extract deformer to weight map

This is a code snippet that you can use to extract the envelope weights of a deformer to a weight map.

xsi = Application
oWeightMap = xsi.Selection(0)
oObj = oWeightMap.Parent3DObject
oEnv = oObj.Envelopes(0)
defOneArray = oEnv.GetWeights2().Array[1] # Change Array index to get a different deformer
oWeightMap.Elements.Array = [x / 100 for x in defOneArray]
Filed under: Daily, Scripting Comments Off