v4.0
Creates a blank "runtime" scripted operator with the code specified. This makes it possible
to create an operator on-the-fly rather than using the the script operator editor. These
operators will have their code embedded in the scene file and have a different Callback convention
than Self-Installed CustomOperators.
Scripted operators define the following callbacks. If the operator has a user-specified name then the
name must prefix the Init, Term and Update callbacks:
CustomOperator_Init( ctx )
CustomOperator_Term( ctx )
CustomOperator_Update( ctx, out, in1, inN )
The Update function has 1 argument per input port. If the operator defines 2 groups with 2 input ports each
there must be 4 input arguments to the update method. The names of the input ports must be unique
as this will be used as the argument's name. The name 'in' is not considered a valid port name because it is also
a reserved word in some scripting langauges such as VBScript.
As of version 3.51, Init and Term are considered reserved function names. Softimage will check the helper
code of scripted operators created using the scripted operator editor or the SPDL file for Init(ctx) and
Term(ctx) callbacks. If the function names are found but specify the wrong number of arguments, Softimage will
issue a warning message. It is possible that a scripted operator created prior to version 3.51 defined
Init or Term helper functions with a signature that matches the callbacks, which may cause a runtime error
when the callback is executed. The only remedy is to modify the code of the operator and rename these helper
functions to something else.
CustomOperator XSIFactory.CreateScriptedOp( String Name, String scriptcode, String Language ); |
oReturn = XSIFactory.CreateScriptedOp( Name, [ScriptCode], [Language] ); |
Parameter | Type | Description |
---|---|---|
Name | String |
The name for the new scripted operator. Default Value: "" |
ScriptCode | String |
The logic that implements the scripted operator Default Value: "" |
Language | String |
The scripting language to use for the logic; for example "JScript" Default Value: The current scripting language user preference |
/* This example illustrates how to use the XSIFactory to create a multi-output operator which constrains the posx position of a number of objects to a single object. */ NewScene( null, false ); var null1 = GetPrim( "Null" ); var null2 = GetPrim( "Null" ); var polymsh1 = CreatePrim( "sphere", "MeshSurface" ); var op = XSIFactory.CreateScriptedOp( "myCns", myCns_Update.toString(), "JScript" ); // Allow a maximum of 2 nulls to be connected to the main group var group1 = op.AddPortGroup( "mainoutputgroup", 1, 2, siNullFilter ); // You only need to add 1 port to control 2 objects since the portgroup definition takes // care of that. The only thing you need to do here is to define what type of object/parameter // you would like to be connected to. op.AddOutputPort( null1.posx, "", group1.Index ); // Define the second input group that will accept only 1 polygon mesh as input var group2 = op.AddPortGroup( "inputgroup", 1, 1, siPolyMeshFilter ); op.AddInputPort( polymsh1.posx, "", group2.Index ); // Create a connection string. Use the semi-colon to delimit where the first group ends and // the second port group begins. var cnxstr = null1 + "," + null2 + ";" + polymsh1; // connect operator op.Connect( cnxstr ); function myCns_Update( ctx, out, inposx ) { out.Value = inposx.Value; } |
// The following code illustrates how to create a scripted operator // entirely from the COM API NewScene( null, false ); var oObject = ActiveSceneRoot.AddGeometry("Sphere","MeshSurface"); apply_splatter( oObject ); var oSplatterOperator = oObject.ActivePrimitive.ConstructionHistory.Find( "MySplatter" ); var oPort = oSplatterOperator.Port( "InGeom", "MainGroup", 0 ); var oInputGeometry = oPort.Target2; Application.LogMessage( "splatter is reading from the " + oInputGeometry.Parent.Name ); function apply_splatter( oObject ) { var op = XSIFactory.CreateScriptedOp( "MySplatter", MySplatter_Update.toString(), "JScript" ); // Define connections var group = op.AddPortGroup( "MainGroup" ); var ioport = op.AddIOPort( oObject.ActivePrimitive, "Geom", group.Index ); var inport = op.AddInputPort( oObject.kinematics.global.posy, "InGPosY", group.Index ); // Define parameters var pdef = XSIFactory.CreateParamDef2( "SquishFactor", siDouble, 0.5, 0, 1 ); op.AddParameter( pdef ); // Connect operator op.Connect(oObject); } function MySplatter_Update( ctx, out, InGeom, InGPosY ) { // Declare variables. var dSquishPnt, i; // Get the squish factor. var dSquish = ctx.Parameters("SquishFactor").Value // Get the array of point positions. var aPnts = InGeom.Value.Geometry.Points.PositionArray.toArray(); // Get the object//s global Y position. var dGPosYObj = InGPosY.Value; // For each point... for ( var i = 0; i < aPnts.length / 3; i++ ) { // Compute the point's global Y position. var dGPosYPnt = aPnts[1 + (i*3)] + dGPosYObj; // If the point is below the Y=0 plane... if ( dGPosYPnt < 0 ) { // Compute the squish factor for the point. var dSquishPnt = 1.0 - dGPosYPnt * dSquish; // Squish the point. aPnts[0 + (i*3)] = aPnts[0 + (i*3)] * dSquishPnt; aPnts[1 + (i*3)] = - dGPosYObj; aPnts[2 + (i*3)] = aPnts[2 + (i*3)] * dSquishPnt; } } // Update the object//s point positions. out.Value.Geometry.Points.PositionArray = aPnts; return; } // |