Hair (XSISDK)
| Table of contents |
[edit]
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.
[edit]
Reference Examples
There are some Hair related examples in the reference:
- ClusterProperty.Elements (http://softimage.wiki.avid.com/sdkdocs/ClusterProperty_Elements.htm)
- ApplyHairOp (http://softimage.wiki.avid.com/sdkdocs/ApplyHairOp.htm)
[edit]
Examples
[edit]
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;
}
[edit]
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 5172 times.

