Class XTCObject
See Also: Class InterfaceServer, Class Class_ID, Class ModContext, Class ObjectState, Class INode, Class Object, Class Modifier, Class GraphicsWindow, Class FPInterface, List of Channel Bits., Class XTCContainer, Class IXTCAccess
class XTCObject : public InterfaceServer
Description:
This class is available in release 4.0 and later only.
This is the base class for an Extension Channel plug-in. These plug-ins are used to allow a developer defined object to flow down the geometry pipeline. This class provides an interface to the extension object. This is the virtual base class that developers can derive objects from, that should be inserted into the extension channel of the object flowing up the stack. Extension Channels will expand the geometry pipeline by allowing one to add a custom object to the pipeline object that can flow down the pipeline. This object will get notified whenever something in the pipeline changes. For example, if you want to indicate when a certain object becomes invalid for export to their game engine, invalid skin-vertex assignments, bound patches etc. By inserting an Extension Channel Object (XTCObject, for short) into the pipeline you can accomplish this, by constantly checking the structure of the object and displaying wrong faces/vertices etc. in the viewport.
You can specify which other channels it depends on using DependsOn(). The extension object has callback methods that get called before and after a modifier modifies a channel that the extension object depends on using PreChanChangedNotify() and PostChanChangedNotify(). The extension object can declare additional channels that it modifies using ChannelsChanged(), so that it can make any changes to the mesh before and after the modification by the modifier.
In general, the Extension Channel is a transient data structure that gets recreated on every pipeline evaluation. So the object that adds an extension channel to the modifier stack automatically makes it persistent. However, when the user collapses the stack, the user might want the Extension Channel to be preserved as well. In order to accomplish that, please refer to the Class BaseObject and the methods NotifyPreCollapse() and NotifyPostCollapse(). These methods will be called by the collapse code. It will give the modifier or BaseObject, that adds an XTC object to the stack the possibility to apply a modifier, that inserts these XTC objects onto the stack after the collapse. Through this mechanism, the XTC will survive a stack collapse. The Pre and Post notifications will be called through a pipeline enumeration downstream (for more info see Class GeomPipelineEnumProc). Developers, who are collapsing the stack programmatically, have to call this method. In case this method is not called, the XTC objects will by default be copied as well, since they are part of the object in the wsCache. However, they won't survive a save/load operation. In addition to all this, XTC objects also have the possibility to display their data in the viewports. Any Extension Channel Object can disable the display of the object itself and take over the entire display itself, by returning true in the method SuspendObjectDisplay().
Note: Modifiers which change the type of object that flows up the stack have to copy the Extension Channel from the old object into the new one using CopyAdditionalChannels() (e.g. the extrude modifier has to copy the XTC from the incoming spline to the Mesh, Patch or NURBS object).
Note: Compound objects have to merge the Extension Channel of the branched pipelines into the resulting pipeline. This is in general a simple copy of the Extension Channel Object into the new Extension Channel. When the CompoundObject evaluates is branches it would call CopyAdditionalChannels(os->obj), so that the Extension Channels of the branches are copied over. In the ConvertToType() method it then has to copy the Extension Channels from itself to the converted object using obj->CopyAdditionalChannels(this).
Also note that the Extension Channel itself is implemented in Class Object. This means, that it will be available for all pipeline objects that get implemented in 3ds max. For additional methods related to extension objects see the methods in Class Object -> Extension Channel Access.
All methods of this class are implemented by the plug-in. Default implementations are shown.
Methods:
public:
Prototype:
virtual Class_ID ExtensionID()=0;
Remarks:
This method returns the unique identifier for the object.
Prototype:
virtual XTCObject *Clone()=0;
Remarks:
This method is called to create a cloned copy of the object. The object should create a copy of itself and return a pointer to it.
Prototype:
virtual ChannelMask DependsOn();
Remarks:
This method returns a ChannelMask which specifies the channels that the XTCObject depends on. If a modifier changes a channel that a XTCObject depends on, its PreChanChangedNotify() and PostChanChangedNotify() methods will be called.
Return Value:
See the List of Channel Bits.
Default Implementation:
{ return 0; }
Prototype:
virtual ChannelMask ChannelsChanged();
Remarks:
This method is available in release 4.0 and later only.
This method returns a ChannelMask which specifies the channels that the extension object changes in the PreChanChangedNotify() and PostChanChangedNotify() methods.
Return Value:
See the List of Channel Bits.
Default Implementation:
{ return 0; }
Prototype:
virtual ChannelMask ChannelsUsed();
Remarks:
This method is available in release 4.0 and later only.
This method returns a ChannelMask which specifies the channels that the extension object uses in the PreChanChangedNotify() and PostChanChangedNotify() methods.
Return Value:
See the List of Channel Bits.
Default Implementation:
{ return 0; }
Prototype:
virtual int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags,Object *pObj);
Remarks:
If an XTCObject wants to display itself in the viewport it can overwrite this method.
Parameters:
TimeValue t
The time at which the object is to be displayed.
INode* inode
Points to the node for the object.
ViewExp *vpt
Points to the viewport interface for the object.
int flags
Object *pObj
Points to the object that the extension object is a part of.
Return Value:
The return value is not currently used.
Default Implementation:
{ return 0; }
Prototype:
virtual void PreChanChangedNotify(TimeValue t, ModContext &mc, ObjectState* os, INode *node, Modifier *mod, bool bEndOfPipeline);
Remarks:
This method is called before a modifier is applied that changes a channel that the XTCObject depends on.
Parameters:
TimeValue t
The time at which the channel will be modified.
ModContext &mc
The modifier context.
ObjectState* os
The objectstate of the object.
INode *node
A pointer to the node.
Modifier *mod
A pointer to the modifier being applied.
bool bEndOfPipeline
TRUE to indicate that this is the last change before the wsCache.
Default Implementation:
{ }
Prototype:
virtual void PostChanChangedNotify(TimeValue t, ModContext &mc, ObjectState* os, INode *node,Modifier *mod, bool bEndOfPipeline);
Remarks:
This method will be called after a modifier is applied that changes a channel that the XTC object depends on.
Parameters:
TimeValue t
The time at which the channel will be modified.
ModContext &mc
The modifier context.
ObjectState* os
The objectstate of the object.
INode *node
A pointer to the node.
Modifier *mod
A pointer to the modifier being applied.
bool bEndOfPipeline
TRUE to indicate that this is the last change before the wsCache.
Default Implementation:
{ }
Prototype:
virtual BOOL SuspendObjectDisplay();
Remarks:
If the XTCObject returns TRUE from this method the object is not displayed in the viewport; if FALSE is returned the Display() method will be called to display the object.
Default Implementation:
{ return false; }
Prototype:
virtual void DeleteThis()=0;
Remarks:
This method is called to delete the extension object.
Prototype:
virtual void MaybeEnlargeViewportRect(GraphicsWindow *gw, Rect &rect);
Remarks:
This method allows the object to enlarge its viewport rectangle if it wants to. The system will call this method for all XTCObjects when calculating the viewport rectangle; the XTCObject can enlarge the rectangle if desired.
Parameters:
GraphicsWindow *gw
Points to the GraphicsWindow instance associated with the viewport the object is displayed in.
Rect &rect
The viewport rectangle for the object which may be modified.
Default Implementation:
{ }
Prototype:
virtual bool RemoveXTCObjectOnMergeBranches(Object *obFrom, Object *obTo);
Remarks:
By default the existing XTCObjects will be deleted if a branch updates In case the XTCObject wants to do more intelligent branching (not simply delete and add), it can return false from this method so that it can later (see MergeXTCObject() below) copy the data from this and other branches into an existing XTCObject.
Parameters:
Object *obFrom
Points to the source object.
Object *obTo
Points to the destination object.
Return Value:
Returns true if the object will be deleted; false to do more processing via MergeXTCObject.
Default Implementation:
{ return true; }
Prototype:
virtual bool MergeXTCObject(Object *obFrom, Object *obTo, int prio, int branchID);
Remarks:
The default implementation just adds the XTCObject to the to object. In case the XTCObject should do a more intelligent merge with already existing XTCObjects in the obTo, it has to overwrite this method.
Parameters:
Object *obFrom
Points to the source object.
Object *obTo
Points to the destination object.
int prio
The priority to set.
int branchID
The branch identifier to set.
Return Value:
TRUE if successful, otherwise FALSE.
Default Implementation:
{ obTo->AddXTCObject(this,prio,branchID); return true;}
Prototype:
virtual bool RemoveXTCObjectOnBranchDeleted(Object *ComObj,int branchID, bool branchWillBeReordered);
Remarks:
In case a branch of a compound object is deleted the XTCObject will be asked if the XTCObject should be deleted as well. In case the XTCObject represents a merge of all branches the XTCObject might want to return false to this method and reassign itself to another branch, so that the merged information is not lost.
Parameters:
Object *ComObj
A pointer to the compound object.
int branchID
The branch identifier to set.
bool branchWillBeReordered
TRUE if the branch should be reordered, otherwise FALSE.
Return Value:
TRUE if successful, otherwise FALSE.
Default Implementation:
{ return true; }