RE: [scripting] hair in xsi

Date : Wed, 10 Oct 2007 14:36:33 +0100
To : <XSI(at)Softimage.COM>
From : "kim aldis" <xsi(at)kim-aldis.co.uk>
Subject : RE: [scripting] hair in xsi
Hair is just a geometry with no faces, just points. They're in order, 13
points to a strand so to get the first point of strand 'n' multiply n x 13.
The first point of each strand isn't on the surface so you have to find
which point on the mesh the strand is attached to and use that as the root
of the strand. It's all great fun.

Have a script. There's a function in there gets the hair emitter for you and
another that arranges everything into a more useable array. Or something
that I can't remember because it was a while back.

> -----Original Message-----
> From: owner-xsi(at)Softimage.COM [mailto:owner-xsi(at)Softimage.COM] On
> Behalf Of peter boeykens
> Sent: 10 October 2007 14:10
> To: XSI(at)Softimage.COM
> Subject: [scripting] hair in xsi
> 
> just trying to find info on how to access hair in XSI through
> scripting.
> 
> references to hair in the scripting docs are scarce to say it in very
> diplomatic terms.
> 
> are there any hair specific objects/methods? (such as a strand, a root,
> a
> tip?)
> I can access the points as one big linear collection, containing (14 x
> the
> amount of strands) points - is that all there is to it?
> 
> Isnt there an organisation per strand? (when selecting points in the UI
> it
> definitely looks like it - the points name is [strand,index on strand]
> - but
> this doesnt seem to be reflected in the pointcollection.
> 
> Is there a way to know what cluster a hair object is connected to?
> and is there a direct correspondence between the index of strands (if
> strands have such a thing as an index?) and the indices of points in
> the
> cluster the hair is generated from?
> 
> when selecting points I could find a way to select the root point
> itself, so
> it looks like there is none as part of the hair object? (with there
> being 14
> segments per strands and 14xthe number of strands points per hair
> object, it
> looks like the 15th point doesnt really exist!
> So are the hair strands using the cluster's points as root?
> 
> And is there any way to access the render hairs rather than the guide
> hairs?
> ...
> any hints appreciated
> 
> P
> 
> 
> 
> ---
> Unsubscribe? Mail Majordomo(at)Softimage.COM with the following text in
> body:
> unsubscribe xsi
// given a hair object, build an array LUT of indexes to the vertices at the root of each strand.
// get the strand number by dividing the hair vertex index number by 13.
//
// Kim Aldis, 2007
/////////////////////////////////////

var oHair = selection(0);
var aRootIndices = StrandIndices( oHair );

for ( var i=0; i<aRootIndices.length; i++ ) {
	logmessage(  "Point at Root of Strand " + i + " = " + aRootIndices[i] ); 
}

 
function StrandIndices( oHair ) { //{{{

	if ( oHair.type != "hair" ) {
		LogMessage( "StrandIndices(): must have a hair object. " + oHair.type + " Given", siWarning );
	}
	
	// find out what the hair is emitted from; cluster or mesh
	//
	 var oSubCmp = getGenerator( oHair );	


	// an array of geometry point indices, aligned with the strand array.
	//
	var RootsArray = new Array();
	 
	// the hair is emitted from a poly cluster
	//
	if ( oSubCmp.type == "poly" ) {
	 
	var oElements = oSubCmp.Elements;
	 	var oFacets = oSubCmp.Parent.Facets;

		var tagArray = new Array( oSubCmp.parent.Points.count );

		 for ( var i=0; i<oElements.count; i++ ) {
		 	 oFacet = oFacets(oElements(i) );
		 	 var oPoints = oFacet.points;
		 	 for ( var j=0; j<oPoints.count; j++ ) {
		 	 	 if ( tagArray[oPoints(j).index] == undefined ) {
		 	 	 	 tagArray[oPoints(j).index] = 0;
		 	 	 	 RootsArray.push( oPoints(j).index);
		 	 	 }
		 	 }
		 }
	// hair is directly on the object, in which case the strand comes direct from
	// the equivalent vertex
	//
	}	else if ( oSubCmp.type == "polymsh" || oSubCmp.type == "surfmsh" ) {
	
		var tagArray = new Array( oSubCmp.ActivePrimitive.Geometry.Points.count );

		var oPoints = oSubCmp.ActivePrimitive.Geometry.Points;
		for ( var i=0; i<oPoints.count; i++ ) {
			RootsArray.push( i );
		}
	} else {
		logmessage( "Unknown Hair Support type:" + oSubCmp.type, siWarning );
		return false;
	}

	
	return RootsArray;

} //}}}

// given a hair object, find out what's generating it.
//
function getGenerator( oHair ) {  //{{{

	var oGenerator = findPort0Target( Obj( oHair.fullname + ".hairGenOp" ) );
	if ( oGenerator ) {
		var oFaceIndices = oGenerator;
		return oFaceIndices;	
	} else { 
	 	return oHair.parent;
	}
} //}}}

function findPort0Target( oGenOp ) { //{{{
	
	for ( var i=0; i<oGenOp.InputPorts.count; i++ ) {
		if ( oGenOp.InputPorts(i).IsConnected ) {
			if ( oGenOp.InputPorts(i).GroupIndex == 1 ) {
			return oGenOp.InputPorts(i).target2;
			}
		}
	}
	return null;
} //}}}

//Util function, find an object given it's name.
//
function Obj( sArg ) { //{{{


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

	 if ( oColl.count == 1 ) {
	 	 return oColl(0);
	 }

	 return false;
	 

}//}}}

Search the XSI List archives here or use the advanced search form to search across mailing lists. Searching help is available.
This site supposedly brought to you by Benjamin Grosser and the Imaging Technology Group.