View Full Version : Scripting teaser

08 August 2004, 09:50 AM
I'm trying to cobble together a script that will automatically translate the centre of a selected object to the object's minimum Y value, it should help with deforming objects along a curve. I know there is the Move Centre to Verticies tool, but this could shave a second or two off the time by not haveing to select the verts :)
The only trouble is that I "think" I have all the required elements for the script, but I can't seem to get it to work :sad:
Here's what I have -

Translate , 0, GetBBox ( "", True, ymin ) , 0, siRelative, siLocal, siCtr, siXYZ, , , siXYZ, , , , , , , 0

Any help appreciated.

08 August 2004, 10:25 AM
what you want to do, to set the center in the middle of the bottom face of the bbox, is this:

set oSelection = Selection
for each oItem in oSelection
GetBBox oItem, FALSE, xmin, ymin, zmin, xmax, ymax, zmax
newX = (xmin + xmax)/2
newZ = (zmin + zmax)/2
Translate , newX, ymin, newZ, siAbsolute, siGlobal, -1, siXYZ, , , , , , , , , , 0

but be warned that it's neither stylish nor very reliable, a Bounding box is very rarely representative of what in human thinking would be the most logical point to consider bottom, and a single vertex spiking somewhere would place the center way out of the mesh bonduaries.

last but not least.. commands are bad :)

08 August 2004, 11:02 AM
Thanks a lot Jaco, twas very useful.
I had tried it on multiple lines, but previously no better luck. So it looks as though the main things were missing the "oItem" identifier, plus I had assumed that the "ymin" was purely a command switch and didn't realise that it would be a returned value in it's own right. Shows how little I know about scripting :sad:

I fully appreciate the limitations you raise, but it shouldn't be a problem for my intended purpose. Basically I had a number of primitives (mainly cylinders) that I wanted to curve deform, and having the centre at ymin just made the scaling along the curve a lot easier.

BTW - Why did you say commands are bad ?

If nothing else, I've learnt something knew today, which is good :D
Thanks again :thumbsup:

08 August 2004, 11:31 AM
there are two different models in XSI.
the command model and the object model.

the object model is sort of low level (from a programming standpoint the lower you go, the closer you are to machine code and the faster the execution) and directly instances objects in the scene into SDK objects to manipulate them.

the command model is a superset of that, it interprets a command and then it manipulates objects, it also tends to refresh the interface at every operation and to work directly on the scene objects.

while a translate on a few object is no big deal, if you think of manipulating points the difference is more evident.
let's say you have a mesh with 10000 vertices (by all standards a very lightweight model for any hero) and you wanted to manipulate those points.

the command model would need 10000 commands, one for each point.
with the object model you could access the geometry of the object as one thing, store the pointpositions array always as one, manipulate it at leisure without ever touching the objects in the scene, and THEN storing this modified array in the geometry to create the modifications.
basically a couple of small operations and one quick large array operation instead of 10000.

the object model in these cases also scales up really well, while the command model doesn't.

the command model makes it really hard to structure your flow and doesn't return/operate on objects, while the object model can, at any given time, easily handle an object to the command model.

the command model isn't of any use in scripted operators, those only retrieve objects from the connections and only write into more objects.

these are just a few reasons.

08 August 2004, 12:17 PM
Ah, "I see said the blind man to the deaf begger" :thumbsup:

This could take a while, but I'm begining to really apprciate XSI's scripting ability.
Perhaps an opening for an enterprising tutorial/video producer. "101 Useful scripts made easy" perhaps ? :D

Just in case any other newbies are interested I added the following lines to the end of ThE_JacO's script to have the object end up sitting on the orgin instead of centred on it :

SetSelFilter "Object"
Translate , 0, 0, 0, siAbsolute, siPivot, siObj, siY, , , , , , , , , , 0
ResetTransform , siCtr, siSRT, siXYZ

08 August 2004, 04:15 AM
It's probably gonna take a while for new XSI users to switch into Object Model scripting, especially when folks are really comfy coming from a MEL or maxscript background.

Here's a glass half full, lemons from lemonade perspective. Command-based scripting in XSI is slow compared to other 3D apps. It's probably been the main motivator for many of us to switch over to the much faster Object Model scripting. It certainly has been for me :)

Here's a quick comparison of command line scripting and OM scripting to do something really simple. This creates two nulls, names them, makes one a child of the other, then sets a constraint:

GetPrim("Null", null, null);
SetValue("null.Name", "childNULL", "null);
GetPrim("Null", null, null);
SetValue("null1.Name", "parentNULL", "null);
ParentObj("parentNULL", "ChildNULL");
ApplyCns("Pose", "childNULL", "parentNULL", null);

What you may notice is that command line scripts rely entirely on string names to get most of the input. If you were trying to build a generic tool to do this, you can't be sure that you won't already have nodes in your scene that have these names. When you run a script that creates new scene nodes with names that already exist, their names get incremented, your script refers to the wrong items, and everything breaks down.

Object level scripting uses pointers to objects and doesn't depend on linking input with strings. Here's the same functionality using an OM script.

var oPar = ActiveSceneRoot.AddNull("parentNULL");
var oChild = oPar.AddNull("childNULL");
var oCns = oChild.kinematics.AddConstraint("Pose", par);

The variables oPar and oChild point to the newly created nulls, no matter what their names are. You can plug them into new commands, or methods to do things with them. Also, the oCns variable is a pointer to the new constraint that got created, so you have direct access to all its properties without knowing any names. Example:

oCns.parameters("active").value = false;

This type of thing is much harder to do with command based scripting! Here are a few more basic examples:

// Set the name of the par object = "newName";

// Print the parent of the child object
LogMessage( oChild.Parent );

// Print the parent's parent name
LogMessage( oChild.Parent.Parent );

// Make the oChild object a child of the scene root

For a list of all the methods and properties available to any scene object in XSI, just type "X3DObject" in the script editor, select the text with your cursor, and press F1. Make sure to select X3DObject and not X3DObjectCollection in the online help box that opens. At the bottom of the online help page, there's a big list of links to all the OM stuff you can do.

08 August 2004, 08:38 AM
Thanks ThE_JacO and Withanar, this has been VERY instructional.

Following TJ's post I went looking and found this tutorial by Micheal Isner which helps further explain the two concepts,

I'm further encouraged by the number of scripting tutorials to be found at . Whilst I have been able to acomplish my few simple needs with command based scripting, it's definately an area I would like to look more into when time permits (sounds like that elusive concept, free time ? :D )

It's also been a big help to see both of your script examples, as I always learn alot reverse engineering other's scripts (previously just Autocad scripts).

Ta guys.

CGTalk Moderation
01 January 2006, 01:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.