chanmod (lx_chanmod.hpp)

From The Foundry MODO SDK wiki
Jump to: navigation, search
There are security restrictions on this page


Channel Modifiers

Defining the Item Type

Channel Modifiers are implemented as item types with the addition of the two interfaces described below. The first step in writing a Channel Modifier is to define a new item type derived from the 'chanModify' type and to add channels that will be used as the inputs and outputs for the modifier.

(1) Deriving a new item type from the Channel Modifier type
 LXtTagInfoDesc   CMyChanModPackage::descInfo[] = {
         { LXsPKG_SUPERTYPE,     "chanModify" },
         { 0 }
 };

The following example shows three channels being added to the item, the first two will be used as inputs to the modifier, i.e. the values from these channels will be read in order to perform the operation. The third will be used to output the result of the modifier.

(2) Adding channels to the item
         LxResult
 CMyChanModPackage::pkg_SetupChannels (
         ILxUnknownID             addChan)
 {
         CLxUser_AddChannel       ac (addChan);
 
         ac.NewChannel ("inputA", LXsTYPE_FLOAT);
         ac.SetDefault (0.0, 0);
 
         ac.NewChannel ("inputB", LXsTYPE_FLOAT);
         ac.SetDefault (0.0, 0);
 
         ac.NewChannel ("output", LXsTYPE_FLOAT);
         ac.SetDefault (0.0, 0);
 
         return LXe_OK;
 }

See the ILxPackage interface for more information on creating new item types.

ILxChannelModManager Interface

The channel modifier manager is defined as an interface on the package implementing the item type. The manager provides methods to describe the channels it wants to use, and to allocate the actual operator object that performs the evaluation.

The Define() method is passed a ChannelModSetup interface and is expected to call AddChannel() or AddTime() methods on that object to add the channels it wants for reading and writing. The names are all for channels on items of this type, and may be set as inputs or outputs.

(3) SDK: ILxChannelModManager interface
         LXxMETHOD(  LxResult,
 Define) (
         LXtObjectID              self,
         LXtObjectID              cmod);

This example uses the AddInput and AddOutput functions from the ILxChannelModSetup interface described below.

(4) Example Define function
         LxResult
 CMyChanModPackage::cman_Define (
         ILxUnknownID             cmod)
 {
         CLxLoc_ChannelModSetup   setup (cmod);
 
         setup.AddChannel ("inputA", LXfCHMOD_INPUT);
         setup.AddChannel ("inputB", LXfCHMOD_INPUT);
         setup.AddChannel ("output", LXfCHMOD_OUTPUT);
         return LXe_OK;
 }

Channel Modifiers are represented graphically in the Schematic viewport as nodes with input and output connectors for linking the channels with items and other Channel Modifiers via Channel Links.

The flags passed with each channel provide information to the Schematic as to the role of the channels belonging to the modifier. For any given channel on the item the function can return some combination of the following flags. Note that zero is also a valid flag value and indicates a channel that's used as input but doesn't need to be added to schematic by default.

LXfCHMOD_OUTPUT
This flag is used to inform the Schematic that a channel is to be represented as an output from the modifier and will be drawn with a Channel Link connector on the righthand side of the node. Channels specified as outputs will be automatically added to the node when the modifier is added to the Schematic view.
LXfCHMOD_INPUT
Since all channels are treated as inputs by default this flag is used by the Schematic to identify 'primary' inputs that will be automatically added to a Channel Modifier node when it is first added to the Schematic.
LXfCHMOD_MULTILINK
This flag is used in combination with the input flag to specify that an input channel can accept multiple Channel Links connected to it. If this flag is not set then the Schematic will prevent more than one link being made to the channel.

(5) SDK: Declarations
 #define LXfCHMOD_INPUT          0x0001
 #define LXfCHMOD_OUTPUT         0x0002
 #define LXfCHMOD_MULTILINK      0x0004

The Allocate() method is also passed the setup object and will allocate the operator for this channel modifier.

(6) SDK: ILxChannelModManager interface
         LXxMETHOD(  LxResult,
 Allocate) (
         LXtObjectID              self,
         LXtObjectID              cmod,
         void                   **ppvObj);

Once the operator is allocated (usually with a spawner) it can store Value and ValueArray objects for the inputs and outputs. ValueArrays allow clients to read multiple inputs.

(7) Example Allocate function
         LxResult
 CMyChanModPackage::cman_Allocate (
         ILxUnknownID             cmod,
         void                   **ppvObj)
 {
         CLxLoc_ChannelModSetup   setup (cmod);
         CLxSpawner<CMyChanModOperator> spawner ("myOp");
         CMyChanModOperator      *op = spawner.Alloc (ppvObj);
 
         setup.ReadValue  ("inputA", op->inA);
         setup.ReadValue  ("inputB", op->inB);
         setup.WriteValue ("output", op->out);
         return LXe_OK;
 }

Once set up, the operator will be called to read inputs and set outputs. Ideally there will be no reason to do any queries during the evaluation.

(8) SDK: ILxChannelModOperator interface
         LXxMETHOD(  LxResult,
 Evaluate) (
         LXtObjectID              self);

(9) Example Evaluate function
         LxResult
 CMyChanModOperator::cmop_Evaluate ()
 {
         double                   dA, dB, dOut;
 
         inA.GetFlt (&dA);
         inB.GetFlt (&dB);
 
         dOut = dA + dB;
 
         out.SetFlt (dOut);
         return LXe_OK;
 }

(10) SDK: Declarations
 #define LXu_CHANNELMODMANAGER   "0F9981DD-C1F7-4D92-8D3D-6F3C64401162"
 #define LXa_CHANNELMODMANAGER   "channelmodmanager" 
 #define LXu_CHANNELMODOPERATOR  "B9D8203C-54D4-424C-B76F-339439803F1E"

ILxChannelModSetup Interface

This interface provides methods for setting up the desired modifier channels and linking to their values.

This function is used to assign a channel as part of the modifier operation, and can only be used from the Define() method.

(11) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LxResult,
 AddChannel) (
         LXtObjectID              self,
         const char              *name,
         unsigned int             flags);

Channel modifiers that need to know the current evaluation time can use the following function to add time as an input to the modifier. This can be read back in the Evaluate function as a floating point value.

(12) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LxResult,
 AddTime) (
         LXtObjectID              self);

Reading and writing is done by allocating Value and ValueArray interfaces from the setup object. These functions are called duirng the allocation stage for the operator, and return persistent objects for use in evaluation.

This returns a single Value for a given input index. If there are multiple inputs linked to this channel only the first is returned.

(13) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LxResult,
 ReadValue) (
         LXtObjectID              self,
         const char              *name,
         void                   **ppvObj);

This returns multiple values for an input index as a ValueArray object. The individual input links can be examined and processed separately.

(14) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LxResult,
 ReadArray) (
         LXtObjectID              self,
         const char              *name,
         void                   **ppvObj);

Time is read as a value as well.

(15) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LxResult,
 ReadTimeValue) (
         LXtObjectID              self,
         void                   **ppvObj);

This returns a single Value object for a given output index. There is no ability to individually address multiple outputs. If this is a matrix channel, then the value object can be queried for a Matrix interface and the output set using those methods.

(16) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LxResult,
 WriteValue) (
         LXtObjectID              self,
         const char              *name,
         void                   **ppvObj);

During channel binding the operator can also get a peek at the ILxEvalautionID for the modifier.

(17) SDK: ILxChannelModSetup interface
         LXxMETHOD(  LXtObjectID,
 GetEvaluation) (
         LXtObjectID              self);

(18) User Class: ChannelModSetup method

(19) SDK: Declarations
 #define LXu_CHANNELMODSETUP     "75D1C574-C10E-47A0-B6DA-96298AB267E7"