Chain UpVector Positioning
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | from win32com.client import constants as c from win32com.client import Dispatch as d xsi = Application log = xsi.LogMessage oSceneRoot = xsi.ActiveProject2.ActiveScene.Root collSel = xsi.Selection # Create rotation vectors vecHip = XSIMath.CreateVector3() vecKnee = XSIMath.CreateVector3() vecAnkle = XSIMath.CreateVector3() vec1 = XSIMath.CreateVector3() vec2 = XSIMath.CreateVector3() vecCross = XSIMath.CreateVector3() vecUpVectorPos = XSIMath.CreateVector3() collSel(0).Kinematics.Global.Transform.GetTranslation(vecHip) collSel(1).Kinematics.Global.Transform.GetTranslation(vecKnee) collSel(2).Kinematics.Global.Transform.GetTranslation(vecAnkle) vec1.Sub(vecHip, vecAnkle) vec2.Sub(vecHip, vecKnee) vecXUpVector = XSIMath.CreateVector3() vecYUpVector = XSIMath.CreateVector3() vecZUpVector = XSIMath.CreateVector3() vecUpVectorPos.LinearlyInterpolate( vecHip, vecAnkle, 0.5 ) vecXUpVector.Cross(vec2,vec1) vecYUpVector.Sub(vecUpVectorPos,vecHip) vecZUpVector.Sub(vecKnee,vecUpVectorPos) vecPosOffset = XSIMath.CreateVector3() vecPosOffset.Sub(vecKnee,vecUpVectorPos) vecPosOffset.Set(vecPosOffset.X * 2,vecPosOffset.Y,vecPosOffset.Z * 2) vecUpVectorPos.AddInPlace(vecPosOffset) vecXUpVector.NormalizeInPlace() vecYUpVector.NormalizeInPlace() vecZUpVector.NormalizeInPlace() xformUpVector = XSIMath.CreateTransform() xformUpVector.SetRotationFromXYZAxes(vecXUpVector,vecYUpVector,vecZUpVector) xformUpVector.SetTranslation(vecUpVectorPos) collSel(3).Kinematics.Global.PutTransform2("",xformUpVector) |
Write Clean XML
I've been working with XML for a while now and haven't found a solution to clean up the XML code in the written file until now. I searched for any articles about how to clean up the XML and finally fond some sample script here: http://snipplr.com/view/25657/indent-xml-using-elementtree/. I modified it a bit for my needs in XSI and it works great!
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | from xml.etree import ElementTree as ET from win32com.client import constants as c from win32com.client import Dispatch as d xsi = Application log = xsi.LogMessage collSel = xsi.Selection def indent(elem, level=0): i = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: indent(elem, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i def cleanxml(xml): elem = ET.fromstring(xml) indent(elem) strIndented = ET.tostring(elem) return strIndented def cleanWriteXML(strFilePath): fOpen = open(strFilePath,"r") fRead = fOpen.read() fWrite = open(strFilePath,"w") strPrettyXML = cleanxml(fRead) fWrite.write(strPrettyXML) fWrite.close() cleanWriteXML("C:\\Path\\To\\File.xml") |
ICE Kine – Drive From Particles Tutorial
This tutorial breaks down how to use particles to drive positions of objects using ICE Kinematics. This setup is essentially the same as if you went to the new ICE Module in 2011.5 and selected Kinematics > Effects > Transform Objects by Particles. However the built in setup is a bit more encapsulated. My tutorial shows you how to construct this from scratch in case you need to modify it to your needs.
Pickup v2.0
I just re-wrote the ET_Pickup plug-in / addon as it wasn't working with reference models. Strange how I find out years later that it doesn't work!
Either way, this should work since I changed it from keying the Active Parameter on constraints to the BlendWeight parameter.
Download (Right Click > Save Target As)
Python – Get Python and pywin32 version
This code gets the working Python and pywin32 version numbers.
import sys import os import distutils import distutils.sysconfig site_packages = distutils.sysconfig.get_python_lib(plat_specific=1) build_no = open(os.path.join(site_packages, "pywin32.version.txt")).read().strip() print "Python version: " + sys.version print "PyWin32 version: " + build_no
AnimStore v1.2
Just fixed a bug which wouldn't find the viewport manager in the layout if you're using a custom layout and changed the view manager frame's name to something other than "vm". I search for it now using the view's Type instead. Thanks to Florian Eberle from PiXABLE in Germany for the heads up!
Get Selected ICE Compound function
Needed to get the selected ICE Compounds via scripting today and finally got a working function that returns a dictionary { Name:FullName }. See below.
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 26 27 28 29 | from win32com.client import constants as c xsi = Application log = xsi.LogMessage def getSelectedICECompounds(): collViews = xsi.Desktop.ActiveLayout.Views oICETreeView = collViews("ICE Tree") if oICETreeView: strNodes = oICETreeView.GetAttributeValue("selection") if not strNodes: log("No nodes selected.") return lSelectedNodes = strNodes.split(",") dICECompounds = {} for eachNode in lSelectedNodes: oNode = xsi.Dictionary.GetObject(eachNode) if oNode.IsClassOf(c.siICECompoundNodeID): lFullNameSplit = oNode.FullName.rsplit(".") dICECompounds[lFullNameSplit[len(lFullNameSplit) - 1]] = oNode.FullName return dICECompounds else: log("ICE Tree view not found!",2) |
AnimStore v2 Started!
I decided to start working on the next version of my ET_AnimStore addon tonight. This past week I've been doodling around with some new Python toys that I found. One of particular interest is sqlite. This is a lightweight sql database that stores databases in files on hard disk. I found out while looking into it, that Python ships with the sqlite module used to communicate with sqlite databases natively. This means that if I choose to use sqlite for any aspect of ET_AnimStore v02 I won't have to worry about distributing Python modules with it, it will just work!
I have also started planning out a new file structure for the system too. I think I got a bit too carried away with the first implementation concerning the depth of the directory hierarchy. I need to keep it simple.
Tonight I made a small script that will allow me to pop open a window that has a camera view docked in the upper portion and a custom property loaded in the bottom portion. This will help keep an intuitive work flow for storing poses. Users won't have to worry about ensuring that a certain viewport is set to the pose cam. I actually found another fix / workaround for that while developing another iteration of my system on a recent job. None the less, it will be a much easier system to use this time around.
Control Setup 2.0
This is a preview of Control Tools, a completely re-written version of my ET_ControlSetup tool. It allows you to add / remove curve objects to the system dynamically and also combine sub-curves to make more sophisticated control objects.
PassManager 2.2
Another update. Now that I've been taking the CG Workshop's Python class with Raffaele Fragapane, I have seen the error of my ways. I should not expect users to hack their Python installs to get my plug-ins to work. This version fixes some weird syntax that I used in previous versions.
Also to note, you must have the default material library in the scene when exporting. Or one that is named "DefaultLib".
Download (Right Click > Save Target As)