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.
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; } // |