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
XML to Directory Structure
Here is a python snippet that creates a directory structure out of an XML file / data:
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.
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() |
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])) |
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.
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)) |
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)) |
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() |
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] |

