Hair (XSISDK)

Table of contents

Reading Hair Data

You can read the data about guide hairs using the SDK via the Point collection of the hair primitive. There are 14 points for each guide hair, so the data in the point collection is ordered as follows:

0-13 first guide 
14-27 second guide

See the JScript example below for an example that reads the Point collection.

Reference Examples

There are some Hair related examples in the reference:

Examples

Scripted Operator

// JScript of a scripted operator on hair

var oObjWithHair = BuildExampleScene() ;
var oHair = oObjWithHair.Children.Item( "Hair" ) ;
var op = apply_randomhair( oHair ) ;
InspectObj( op ) ;

function BuildExampleScene()
{
	NewScene(null,false);
	
	var oGrid = ActiveSceneRoot.AddGeometry( "Grid", "MeshSurface", "HairyObj" ) ;
	
	
	ApplyHairOp( oGrid.FullName, null ) ;
	
	return oGrid ;		
}

function apply_randomhair( oObject )
{
	var op = XSIFactory.CreateScriptedOp( 
				"MyRandomHair", 
				MyRandomHair_Update.toString(), 
				"JScript" );

	// define connections
	var group = op.addportgroup( "MainGroup" );
	var ioport = op.addioport( oObject.activeprimitive, "Geom", group.index );

	// define parameters
	var pdef = XSIFactory.CreateParamDef2( "RandomFactor", siDouble, 0.1, 0.0, 2 );
	op.addparameter(pdef);

	// connect operator
	op.connect(oObject);
	
	return op ;
}

function MyRandomHair_Update( ctx, out, InGeom )
{
		
	var PointsPerGuideHair = 14 ; // This is always true
	var valuesPerPosition = 3 ; // x,y,z
	
	var dRandomFactor = ctx.Parameters("RandomFactor").Value
	
	var aAllPositions = InGeom.Value.Geometry.Points.PositionArray.toArray();

	var cntGuideHairs = aAllPositions.length / ( valuesPerPosition * PointsPerGuideHair ) ;
	
	for ( i = 0 ; i < cntGuideHairs ; i++ )
	{
		indexHairRoot = i * valuesPerPosition * PointsPerGuideHair ;
		
		
		// We will only randomize the end section of the hair (near the tip)
		for ( k = 8 ; k < PointsPerGuideHair ; k++ )
		{					
			xIndex = k*valuesPerPosition + indexHairRoot ;

			// x					
			aAllPositions[xIndex ] = aAllPositions[xIndex] - dRandomFactor + ( 2 * dRandomFactor * Math.random() ) ;
												
			// z
			aAllPositions[xIndex+2] = aAllPositions[xIndex+2] - dRandomFactor + ( 2 * dRandomFactor * Math.random() ) ;
			
		}
		
	}

	out.Value.Geometry.Points.PositionArray = aAllPositions;
	
	return;
}


Manipulation of Guide Hairs

// JScript demonstration of manipulating Guide Hairs with the Object Model

var g_PointsPerGuideHair = 14 ; // This is always true

var oObjWithHair = BuildExampleScene() ;
 
var oHair = oObjWithHair.Children.Item( "Hair" ) ;

var oHairGeom = oHair.ActivePrimitive.Geometry

// These are the points on the original geometry
var oSrcPoints = oObjWithHair.ActivePrimitive.Geometry.Points
	
// The points on the hair are a list of all the points on
// all the guide hairs
var oGuideHairPoints = oHairGeom.Points

for ( var i = 0 ; i < oSrcPoints.Count ; i++ )
{
	// The Guide hair starts at the Vertex of the source 
	// object.
	
	// NOTE: In this case the points on the geometry
	// directly correspond to the Guide Hairs.  However
	// in some cases, such as nurbs or subdivided surfaces this
	// assumption is not true.
	var oSrcPoint = oSrcPoints.Item( i ) ;		
		
	logmessage( "Guide Root " + PointAsStr( oSrcPoint ) ) ;

	// The rest of the guide hair is defined by the following points
	var guideHairRootIndex = i * g_PointsPerGuideHair ;

	for ( var k = 0 ; k < g_PointsPerGuideHair ; k++ )
	{
		var indexOfPointOnGuideHair = guideHairRootIndex + k ;
		logmessage( "\tGuide point " + k + " is " + 
					PointAsStr( oGuideHairPoints.Item( indexOfPointOnGuideHair  ) ) ) ;	
	}			
}

// Given a position in the guidepoint collection you can
// determine everything you need to know about which guide hair it is on 
// and what position on that guide hair.

logmessage( "Guidepoint 5 is at position " + GetPositionOnHair( 5 ) + 
	" on the hair that starts at pnt[" + GetSrcPointIndex( 5 ) + "] on the geometry" ) ;

logmessage( "Guidepoint 14 is at position " + GetPositionOnHair( 14 ) + 
	" on the hair that starts at pnt[" + GetSrcPointIndex( 14 ) + "] on the geometry" ) ;

logmessage( "Guidepoint 39 is at position " + GetPositionOnHair( 39 ) + 
	" on the hair that starts at pnt[" + GetSrcPointIndex( 39 ) + "] on the geometry" ) ;



// Set the selection to show our modified hair

SelectObj( oObjWithHair + ".pnt[2]," + oHair + ".pnt[(2,0-13)]" ) ;
FrameSelection(null,null,true) 


function PointAsStr( in_point )
{
	var oPos = in_point.Position ;	
	return "<" + oPos.x + "," + oPos.y + "," + oPos.z + ">" ;
}

function BuildExampleScene()
{
	NewScene(null,false);
	
	var oGrid = ActiveSceneRoot.AddGeometry( "Grid", "MeshSurface", "HairyObj" ) ;
	
	// For the sake of clairity use a very small geometry
	// This grid has 4 polygons, 9 points and hence 9 guide hairs
	oGrid.subdivu = 2 ;
	oGrid.subdivv = 2 ;
	
	ApplyHairOp( oGrid.FullName, null ) ;
	
	return oGrid ;		
}

// Find the index on the hairy object
// given the index of a guide point
function GetSrcPointIndex( in_GuideIndex )
{
	return Math.floor( in_GuideIndex / g_PointsPerGuideHair ) ;
}

// Determine the position along the guide hair of a particular
// point.  Index 0 is the first point (closes to the root of the hair)
// Index g_PointsPerGuideHair-1 is the very tip of the hair
function GetPositionOnHair( in_GuideIndex )
{
	return in_GuideIndex % g_PointsPerGuideHair ;
}


This page was last modified 11:07, 30 Dec 2005.
This page has been accessed 9165 times.

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