User locations for 32- and 64-bit Softimage


If you have both 32- and 64-bit Softimage installed, both versions will use the same User location. If you want separate User locations, you could modify the XSI.bat file that launches Softimage.

For example, setenv.bat defines an XSI_CPU environment variable, so you can check that and then reset XSI_USERHOME:

@echo off
call "C:\Program Files (x86)\Autodesk\Softimage 2012.SAP\Application\bin\setenv.bat"
if "%XSI_CPU%"=="nt-x86-32" set XSI_USERHOME=%XSI_USERHOME% (x86)
start "" "C:\Program Files (x86)\Autodesk\Softimage 2012.SAP\Application\bin\XSI.exe" %*

This will give you a User location like
C:\Users\blairs\Autodesk\Softimage_2012_Subscription_Advantage_Pack (x86)

Friday Flashback #44


This is a scan of a photocopy of an article that appeared in the November 1997 issue of Digital Magic magazine. If you didn’t know already, now you know where XSI got its UI 😉

November 1997 First Look: SOFTIMAGE|DS

SOFTIMAGE|DS is not like anything else out there–it’s the next step. Because of its nature and $100,000 price point, customers say the decision to purchase DS was a “no brainer”.

This is a huge, feature rich application–its full install consists of 1.9 million lines of code.

The interface has a beautiful, organic look. The ransport controls, although a conventional layout, look like little pillows, quite an inviting metaphor that begs you to dive in. The overall impression is one of friendly, all natural comfort.

Softimage does say that Sumatra, the code name for the company’s next-generation 3D animation system, will not only be available as a stand-alone system, but will also be built as an integral component of the final, shipping version of Softimage|DS.

Softimage users will recognize the “Rooms” concept of the interface, now carried foward with DS. On the left are buttons for NLE, Paint, Compositing, Audio, and Media I/O.

Scripting: Finding comment nodes in ICE compounds


Unless I missed something in the docs, you have to go through the old NestedObjects routine to do it.
Here’s a JScript version. Python to follow soon…

var n = Selection(0);

oEnum = new Enumerator( get_comments(n) ) ;
for (;!oEnum.atEnd();oEnum.moveNext() )
{
	var oComment = oEnum.item() ;
	LogMessage( oComment.Parameters("Text").Value );
}

//--------------------------------------
// Find comments
// Works with an ICENode or a compound
//--------------------------------------
function get_comments( node )
{
	var oComments = new ActiveXObject( "XSI.Collection" );
	if ( ClassName(node) == "ICENode" )
	{
		var oComment = node.NestedObjects("ICE Comment");
		if ( oComment != null ) oComments.Add( oComment );
	}
	else if ( ClassName(node) == "ICECompoundNode" )
	{
		var nested = Dictionary.GetObject( node.FullName + ".ContainedNodes" ).NestedObjects;
		oEnum = new Enumerator( nested ) ;
		for (;!oEnum.atEnd();oEnum.moveNext() )
		{
			var oItem = oEnum.item() ;
			if ( oItem.Type == "ICETreeComment" )
			{
				oComments.Add( oItem );
			}
		}
		
	}
	return oComments;
}
from siutils import si		# Application
from siutils import sidict	# Dictionary
from siutils import sisel	# Selection
from siutils import log		# LogMessage
from siutils import disp	# win32com.client.Dispatch
from siutils import C		# win32com.client.constants

def get_comments( node ):
	oComments = disp( "XSI.Collection" )
	
	if si.ClassName(node) == "ICENode":
		oComment = node.NestedObjects("ICE Comment")
		if ( oComment != None ):
			oComments.Add( oComment );

	elif si.ClassName(node) == "ICECompoundNode":
		nested = sidict.GetObject( node.FullName + ".ContainedNodes" ).NestedObjects
		for o in nested:
			if o.Type == "ICETreeComment":
				oComments.Add( o )

	return oComments
	
	
n = sisel(0)

# Get comments and print out the text
for c in get_comments(n):
	log( c.Parameters("Text").Value )

Using the PolygonArea ICE attribute to select similar polygons


After seeing this select similar post on xsibase, I wrote this Python example that uses the PolygonArea ICE attribute to find polygons with similar areas. I didn’t want to use a custom preference or any ppg, so this script looks for [more-or-less] equal areas rather than for a value range. It’d probably be more useful to look for areas within a certain range (but that would require user input).

To use this script, select a polygon and then run the script. It’ll select all polygons with the “same” area.

This ss_SelectSimilarPolys add-on uses a threshold to define an area range (and it uses PolygonArea too). RCTools also lets you specify an area range, along with a number of other things like number of edges and poly orientation, in its custom Polygon selection filter.

from siutils import si		# Application
from siutils import sidict	# Dictionary
from siutils import sisel	# Selection
from siutils import log		# LogMessage
from siutils import C		# win32com.client.constants

# Number of decimal places
# For example, do I match .776 or .78 ?
# With 2 decimal places, anything in the range (7.75, 7.85) will be caught by .78
gPrecision = 2

# Need this for .Polygons later...
def dispFix( badDispatch ):
	import win32com.client.dynamic
	# Re-Wraps a bad dispatch into a working one:
	return win32com.client.dynamic.Dispatch(badDispatch)


# Get selected polygons
polys = sisel(0).SubComponent.ComponentCollection

# Get index of first selected polygon
ix = polys(0).Index

# Get primitive of parent 3D object
prim = sisel(0).SubComponent.Parent3DObject.ActivePrimitive
prim = dispFix(prim)

# Get PolygonArea DataArray (which is a tuple)
attr = prim.GetICEAttributeFromName( "PolygonArea" )
areaData = attr.DataArray

# Round PolygonArea to the specified precision
roundedAreas = [round(x,gPrecision) for x in areaData]

# Get the area that you want to match
areaToMatch = roundedAreas[ ix ]

# Get all polys with a similar PolygonArea and select them
#
# Function findall from http://effbot.org/zone/python-list.htm
def findall(L, value, start=0):
        # generator version
        i = start - 1
        try:
			while 1:
				i = L.index(value, i+1)
				yield i
        except ValueError:
            pass
			
for ix in findall(roundedAreas, areaToMatch ):
	sisel.Add( prim.Geometry.Polygons( ix ) )

The case of Find in Array that didn’t find anything


So, the other day I was trying to use Find in Array , but it wasn’t finding anything. At first I thought there was wrong with the data I was feeding into Find in Array, but then I did a quick test of Find in Array and found out what was going on.

By default (in 2012 SAP at least), the Epsilon is 0 and Find in Array doesn’t find anything. For example, here Find in Array doesn’t find the vector (0, 0, 0) in the array, even though (0,0,0) is in the array three times:

If you bump up the epsilon to 0.001, then Find in Array does find the specified value:

It’s often a good idea to isolate a branch, or create a simple test ICE tree, to figure out how things work.

The case of the missing anchors


In this case, a customer reported that the Add to Menu list in the Command Wizard was empty. Normally, Add to Menu lists all anchor points for menus where you can add a custom command, but now it had just one entry: None.

The SDK wizards are JScript plugins, so it wasn’t hard to track down where things were going wrong. The Add to Menu list is built by parsing a header file (xsi_decl.h):

var oFSO = new ActiveXObject( "Scripting.FileSystemObject" ) ;
strFactoryPath = Application.InstallationPath( siFactoryPath ) ;
strDeclFile = XSIUtils.BuildPath(XSIUtils.Environment("XSISDK_ROOT"),"include","xsi_decl.h") ;

Based on this, it didn’t take to long to figure out the problem: the customer was starting Softimage with a shortcut to XSI.exe, so setenv.bat was never called, and XSISDK_ROOT was never set.

XSI.bat is the way to start Softimage. XSI.bat calls setenv.bat to set all the required environment variable, and then starts XSI.exe.