Finding where an operator reads from the construction history


For example, suppose you want to know exactly where a TextureOp is located in the construction history (aka the operator stack).

A TextureOp object is nested under a cluster, not under the primitive, so you can’t use Primitive.ConstructionHistory.

Try it, and you’ll see that the TextureOp does not show up.

from siutils import sisel	# Selection
from siutils import log		# LogMessage

for x in sisel(0).ActivePrimitive.ConstructionHistory:
	if x.BelongsTo( "MarkerOperators" ):
		sMarker = x.type

	log( "%s -> %s" %(sMarker,x.name) )

Instead, you’ll have to use DataRepository.GetConnectionStackInfo, which returns an XML description of the operator stack. The XML looks something like this (note that I had to use <_object> to stop wordpress from removing the <object> tag in my XML):

<?xml version="1.0"?>
<connections>
 	<connection>
 		<datacopy>0x000000001D7B7330</datacopy>
 		<hidden>false</hidden>
 		<_object>sphere.polymsh.modelingmarker</_object>
 		<objectid>533</objectid>
 		<region>2</region>
 		<type>out</type>
 	</connection>
 	<connection>
 		<datacopy>0x000000001F4C9F40</datacopy>
 		<hidden>false</hidden>
 		<_object>sphere.polymsh.cls.sample.clslist.Texture_Coordinates_AUTO.localprops.ClsProp.Texture_Projection.TextureOp</_object>
 		<objectid>571</objectid>
 		<region>2</region>
 		<type>out</type>
 	</connection>
 	<connection>
 		<datacopy>0x000000001C215310</datacopy>
 		<hidden>false</hidden>
 		<_object>sphere.polymsh.bulgeop</_object>
 		<objectid>532</objectid>
 		<region>2</region>
 		<type>in</type>
 	</connection>
</connections>

Here’s a Python snippet that uses ElementTree to parse the connectionstack XML and then log the TextureOp tooltip that says where the op reads from the stack:

from siutils import si		# Application
from siutils import sidict	# Dictionary
from siutils import sisel	# Selection
from siutils import siuitk	# XSIUIToolkit
from siutils import siut	# XSIUtils
from siutils import log		# LogMessage
from siutils import disp	# win32com.client.Dispatch
from siutils import C		# win32com.client.constants

from xml.etree import ElementTree as ET

prim = sisel(0).ActivePrimitive if si.ClassName(sisel(0)) ==  'X3DObject' else sisel(0)


stackInfo = siut.DataRepository.GetConnectionStackInfo( prim )
#log( stackInfo )
connections = ET.XML(stackInfo)
currentMarker =''

#
# Read XML into a list of tuples that looks like this:
# ('sphere.polymsh.secondaryshapemarker', 'sphere.polymsh.secondaryshapemarker')
# ('sphere.polymsh.postsimulationmarker', 'sphere.polymsh.postsimulationmarker')
# ('sphere.polymsh.simulationmarker', 'sphere.polymsh.simulationmarker')
# ('sphere.polymsh.ICETree', 'sphere.polymsh.simulationmarker')
# ('sphere.polymsh.animationmarker', 'sphere.polymsh.animationmarker')
# ('sphere.polymsh.shapemarker', 'sphere.polymsh.shapemarker')
# ('sphere.polymsh.modelingmarker', 'sphere.polymsh.modelingmarker')
# ('sphere.polymsh.cls.sample.clslist.Texture_Coordinates_AUTO.localprops.ClsProp.Texture_Projection.TextureOp', 'sphere.polymsh.modelingmarker')
# ('sphere.polymsh.geom', 'sphere.polymsh.modelingmarker')
#
currentMarker = '%s.%s' %(prim.FullName, 'above-secondaryshapemarker')
ops = []
for connection in connections:
		o = connection.find('object').text
		bHidden = connection.find('hidden').text == 'true'
		
		if o == currentMarker or bHidden:
			continue
	
		if o.endswith('marker'):
			currentMarker = o

		ops.append( (o, currentMarker ) )
	
	
#
# Go through list of tuples and find 
# where TextureOp reads
#
for i in range( len(ops) ):
	oOp = sidict.GetObject( ops[i][0] )
	if oOp.type == 'TextureOp':
		print oOp.Name
		if i == len(ops):
			sRead = "(reading from bottom of primitive stack)"
		else:
			sRead = '(reading just above %s)' %(sidict.GetObject( ops[i+1][0] ).Name)
			
		print '%s %s' %(oOp.Name,sRead)
		# TextureOp (reading just above Bulge Op)

Copying and pasting fcurve keys in a script


To copy and paste keys in a script, you have to also call SelectKeysInTimespan() to select the keys you want to copy.

If you copy and paste keys in the fcurve editor, SelectKeysInTimespan() is not logged, so it’s easy to get fooled into thinking you don’t need it (SelectKeysInTimespan is logged by the Dopesheet, however). hat tip luceric

SelectKeysInTimespan("null.kine.local.posx", siSetKeySelection, 65, 93, siInputParameters);
CopyKeys("null.kine.local.posx", 65, 93, null, true, siInputParameters);
PasteKeys("null1.kine.local.posx", 55, 83, false, null, siInputParameters, null, null, false, false);

Here’s some OM code that does about the same thing:

var x = Dictionary.GetObject("Model.null.kine.local");
var fcv = x.roty.Source;
LogMessage(ClassName(fcv));

var y = Dictionary.GetObject("null.kine.local");
var fcv1 = y.roty.AddFcurve();
fcv1.Set(fcv);
// Keep keys from 20-50
fcv1.RemoveKeys(1,19);
fcv1.RemoveKeys(51,null);
// Move to 0-30
fcv1.OffsetKeys(fcv1.Keys, -20);

Friday Flashback #38


Red Creates Cityscape for Kylie Minogue With Discreet Tools, Softimage XSI
(August 23, 2001)

“Can’t Get You Out of my Head,” the first single to be taken from Kylie’s forthcoming album, features the pop princess driving and strutting her stuff in a futuristic Manga-esque city. Pretty run of the mill stuff until you discover that the only things that were shot for real were Kylie, a handful of dancers and a static car. Black Dog tasked Soho-based visual communications facility Red, with creating the rest from scratch to designs developed by director Dawn Shadforth.

Red utilised the full gamut of its Discreet arsenal – 3ds max, fire, flame and inferno – to create and animate the backgrounds with some SoftImage XSI thrown in for good measure.

The video:

The full article from Digital Producer Magazine
Continue reading

Effets spéciaux: la banlieue québécoise d’Hollywood


Special effects: the quebecoise suburb of Hollywood

Montréal –Avec une cinquantaine de productions hollywoodiennes à son actif, dont Avatar, Sin City et 300, la boîte québécoise deffets spéciaux Hybride sest hissée aux plus hauts sommets. Au point où certains studios pensent que son code régional 450 à Piedmont est celui dune banlieue de Los Angeles. «Cest la boîte deffets spéciaux qui men donne le plus pour mon argent», dit le cinéaste Robert Rodriguez, qui a réalisé les effets spéciaux de 11 films avec Hybride. Pas mal pour une entreprise née des suites dune faillite il y a 20 ans.

via Effets spéciaux: la banlieue québécoise dHollywood | La Presse.

Activating the Paint tool in scripting


Easy. You do it like this:

# Python
Application.PaintTool()
# JScript
PaintTool();

The real question is “how would you know about this undocumented command?”.

There’s several ways.

  • Maybe you grepped through Application\DSScripts\*.vbs for “Paint” or “Tool” and found %XSI_HOME%\Application\DSScripts\tools.vbs
  • Maybe you searched Application.Commands for the regular expression /Tool/ig.
  • Maybe you searched the XSI mailing list (Paint Tool by script )