Loopin' Lizards, Part Deux: More Secrets and Some Advice on Filtering

Author: Bradley Gabe

My last post on property search techniques generated a bit of additional discussion, particularly on the use of wildcards. I've posted this "get XSI Collection by wildcard strings" technique a number of times to the XSI discussion list. What I'd never done was post a formal speed comparison.

When I was working in XSI 3.5 on Linux, there was no error handling. The GetValue and Dictionary.GetObject() methods would raise an error and bomb out if the object I was searching for didn't exist...kind of a bummer because you often need to test if something exists before you act on it.

I found an example of the wildcard technique in an obscure part of the XSI online scripting reference when searching for something completely unrelated. I started using it a lot simply because it never bombed out. If the items searched for didn't exist, it would return an empty collection. Turns out, it's pretty darn fast to boot!

I ran some more speed tests to compare it to other commonly used methods for getting nodes en masse and found it was still best in performance. For example, if you want to get all X3D nodes in a scene, compare the speed of findChildren()--the most commonly used technique-- to setting the XSICollection.items property:

var s1 = new Date();
var findColl = ActiveSceneRoot.FindChildren();
var e1 = new Date();

var s2 = new Date();
var oColl = new ActiveXObject("XSI.Collection");
oColl.Items = "*";
var e2 = new Date();

LogMessage("FindChildren: " + findColl.count + ": " + (e1-s1)/1000);
LogMessage("Collection: " + oColl.count + ": " + (e2-s2)/1000);

//INFO : FindChildren: 1829: 0.047
//INFO : Collection: 1829: 0.031

Setting the XSICollection.items property is much faster. It also comes in handy in situations where you only want to grab all the children of a specific Model, even when another Model is nested under the first. FindChildren won't discriminate for Model space.

var oColl = new ActiveXObject("XSI.Collection");
oColl.Items = "ModelA.*"

Furthermore, you can grab ANY object in XSI and dump it into an XSI collection, including properties, params, [shhh] even objects that aren't officially supported by the object model [/shhh]. This is particularly handy for scripted ops that need to access places the input channels don't allow. Use at your own risk, though.

var oColl = new ActiveXObject("XSI.Collection");
oColl.Items = "Preferences.SceneColors.backgroundcol";

LogMessage(oColl(0).value);


The word "ANY" above also refers to your own custom objects:

var myObj = new Object();
myObj.Type = "Custom Object";
myObj.GetInfo = function(){LogMessage("This is odd!")};

var oColl = new ActiveXObject("XSI.Collection");
oColl.Add(myObj);
oColl(0).GetInfo();


In my testing, I think my biggest surprise from all this is that often it's much faster to get everything in the scene using wildcards, then filter out to the specific using a second XSICollection and the RemoveItems() method. This is almost always significantly faster than a single test loop. I've been running more speed tests and have moved onto filtering techniques. So far I'm finding the new Application.Filters() objects are faster than testing by type:

// Fast
if(myObj.type=="#model")
// Faster
var f = Application.Filters("Model")if(f.Match(myObj))

This page was last modified 18:42, 30 Aug 2007.
This page has been accessed 6404 times.

© Copyright 2009 Autodesk Inc. All Rights Reserved. Privacy Policy | Legal Notices and Trademarks | Report Piracy