Class ImageFilter
See Also: Class ImageFilterInfo, Class Bitmap, Class ITrackViewNode, Class TimeChange, Class UndoNotify, Working with Bitmaps.
class ImageFilter
Description:
Image processing filter plug-ins are derived from ImageFilter. This class has virtual methods the developer implements to provide information about the plug-in version, and description. The developer also implements the Capability() method to indicate the properties of the plug-in such as if it is a one pass filter or compositor, and whether it has a control dialog to be displayed.
The Render() method is the one that actually alters the source image to perform the work of the application.
Filter plug-ins have access to several bitmaps associated with the video post data stream. All filter plug-ins will have at least a pointer to data member srcmap. This is Video Post's main image pipeline. Composition and transition (layer) filters will also receive a second bitmap (frgmap) which should be composited above the main bitmap (srcmap). If mskmap is not NULL, it will contain a pointer to a grayscale image to be used as a mask for the process. Note that developers should not delete these bitmaps as they are maintained by 3ds max.
If a plug-in is both a filter and a compositor, the plug-in can tell if it is running as a filter when the frgmap pointer is NULL.
Note: If changes are made to an ImageFilter plug-in, the system will not automatically put up the 'The scene has been modified. Do you want to save your changes?' dialog if the user attempts to exit without saving. So that your plug-in does not go unsaved, you should call the following global function if you make changes. This will indicate to the system that the save requester needs to be brought up:
void SetSaveRequired(int b=TRUE);
Sets the 'save dirty bit'. This will indicate to the system that the save requester needs to be presented to the user.
Method Groups:
The hyperlinks below jump to beginning of related methods within the class:
Description/Copyright/Author/Version Methods
Parameter Block Configuration Data Methods
Filter Control Dialog Interactivity
Data Members:
protected:
BOOL interactive;
This data member is available in release 2.0 and later only.
TRUE if the setup dialog is interactive; otherwise FALSE.
HWND vpSetuphWnd;
The window handle of the video post setup dialog.
HWND vphWnd;
The window handle of the Video Post dialog.
HWND dlghWnd;
The window handle of the filter's setup dialogue when in "Interactive" mode.
Bitmap *srcmap
The Source Bitmap (background). Note: The Video Post output resolution may be retrieved using this pointer. The width is srcmap->Width() and the height is srcmap->Height().
Bitmap *mskmap
The Image Mask Bitmap (for grayscale masking). This bitmap is at the Video Post output resolution size when the developer needs to access it in the Render() method.
Bitmap *frgmap
The Foreground Bitmap (for layering/transitions). This bitmap is at the Video Post output resolution size when the developer needs to access it in the Render() method.
ImageFilterInfo *ifi
A pointer to an instance of the class that provides information about this filter and the video post queue.
public:
TimeChange timeChange;
This data member is available in release 2.0 and later only.
This class maintains this time change object so it may send FLT_TIMECHANGED messages.
UndoNotify* undonotify;
This data member is available in release 2.0 and later only.
Points to an instance of the class that can be used so an ImageFilter plug-in can get notified on a change to its Track View Node.
Methods:
Prototype:
ImageFilter();
Remarks:
Constructor. The srcmap, mskmap and frgmap are set to NULL. The undo notify pointer is set to NULL and the interactive flag is set to FALSE.
Prototype:
virtual ~ImageFilter();
Remarks:
Destructor.
Prototype:
virtual Interface *Max();
Remarks:
Implemented by the System.
This method returns an interface pointer for calling methods implemented in 3ds max. See Class Interface.
Description/Copyright/Author/Version
Prototype:
virtual const TCHAR *Description() = 0;
Remarks:
Implemented by the Plug-In.
Returns an ASCII description of the filter plug-in (i.e. "Convolution Filter").
Prototype:
virtual const TCHAR *AuthorName() = 0
Remarks:
Implemented by the Plug-In.
Returns the name of the plug-in's author.
Prototype:
virtual const TCHAR *CopyrightMessage() = 0
Remarks:
Implemented by the Plug-In
Returns the plug-in ASCII Copyright message.
Prototype:
virtual UINT Version() = 0;
Remarks:
Implemented by the Plug-In.
Returns the plug-in version number * 100 (i.e. v3.01 = 301).
Prototype:
virtual DWORD Capability() = 0
Remarks:
Implemented by the Plug-In.
This method returns a set of flags that describe the capabilities of this filter plug-in. These capabilities indicate if the plug-in is a filter, compositor, or has a control panel. To create a flag, "OR" the capabilities together, ie. (IMGFLT_CONTROL | IMGFLT_COMPOSITOR). Note: It is valid for a plug-in to both a Filter and a Compositor. If both flags are set, the user will be able to select it from both the Filter list and from the Compositor list. The plug-in will know it is running as a filter when the foreground map pointer, frgmap, is NULL.
Return Value:
See List of Image Filter Capability Flags.
Prototype:
virtual void ShowAbout(HWND hWnd) = 0;
Remarks:
Implemented by the Plug-In.
This method is called by the system to display the About Box of the plug-in. This dialog is mandatory so the developer must implement this method.
Parameters:
HWND hWnd
The parent window handle of the dialog.
Prototype:
virtual BOOL ShowControl(HWND hWnd)
Remarks:
Implemented by the Plug-In.
This method is called by the system to display the control panel for the plug-in. This control panel is optional and its existence should be flagged by the capability flag returned from Capability() (IMGFLT_CONTROL). If a plug-in does not have a control panel, don't implement this method and let it default to FALSE.
Parameters:
HWND hWnd
The parent window handle of the dialog.
Return Value:
TRUE if the user selects OK to exit the dialog, and FALSE if the user selects Cancel.
Default Implementation:
{ return FALSE; }
Prototype:
virtual BOOL Render(HWND hWnd) = 0
Remarks:
Implemented by the Plug-In.
This is the method the plug-in implements to alter the image. This method performs the work of the filter or compositor.
Parameters:
HWND hWnd
The window handle to which the plug-in will be sending progress and abort check messages.
Return Value:
TRUE if the render was completed; otherwise FALSE (error or canceled by user).
Sample Code:
Below is an example of a render loop through each horizontal band of the image demonstrating the posting of messages. At the start of the loop the progress and check abort messages are sent. The progress message updates the Execute Video Post dialog with how much of the image has been processed. The check abort message allows the plug-in to detect if the user has canceled the operation.
BOOL result = TRUE;
BOOL abort = FALSE;
for (int iy = 0; iy < srcmap->Height(); iy++) {
// Progress Report
SendMessage(hWnd,FLT_PROGRESS,iy,srcmap->Height()-1);
// Check for Abort
SendMessage(hWnd,FLT_CHECKABORT,0,(LPARAM)(BOOL *)&abort);
if (abort) {
result = FALSE;
break;
}
}
return(result);
Messages are sent via the Window API SendMessage() function. See List of ImageFilter Related Messages.
Parameter Block Configuration Data
Parameter Block Load and Save. A 'parameter block' is really nothing more than data a developer wants to load and save. See the sample code below to see how these methods are used to save the data in the UserSettable structure.
typedef struct userSettable {
int data1;
float data2;
} UserSettable;
DWORD MyFilter::EvaluateConfigure () {
return sizeof (UserSettable);
}
BOOL MyFilter::LoadConfigure (void *ptr) {
UserSettable *buf = (UserSettable *) ptr;
memcpy (&userSettings, ptr, sizeof(UserSettable));
return TRUE;
}
BOOL MyFilter::SaveConfigure (void *ptr) {
if (ptr) {
memcpy (ptr, &userSettings, sizeof(UserSettable));
return TRUE;
} else
return FALSE;
}
Prototype:
virtual DWORD EvaluateConfigure()
Remarks:
Implemented by the Plug-In.
The system will call this method to determine the buffer size required by the plug-in. The plug-in can save its parameter block in this buffer by implementing the SaveConfigure() method.
Return Value:
The number of bytes required by the plug-in's parameter block.
Default Implementation:
{ return 0; }
Prototype:
virtual BOOL LoadConfigure(void *ptr)
Remarks:
Implemented by the Plug-In.
This method will be called so the plug-in can load its parameter block. Memory management is performed by 3ds max using standard LocalAlloc() and LocalFree().
Parameters:
void *ptr
A pre-allocated buffer.
Return Value:
TRUE if the data was loaded OK; otherwise FALSE.
Default Implementation:
{ return (FALSE) };
Prototype:
virtual BOOL SaveConfigure(void *ptr)
Remarks:
Implemented by the Plug-In.
This method will be called so the plug-in can transfer its parameter block to the host.
Parameters:
void *ptr
A pre-allocated buffer the plug-in may write to.
Return Value:
TRUE if the data was saved OK; otherwise FALSE.
Default Implementation:
{ return (FALSE); }
Prototype:
virtual int Lerp(int a, int b, int l);
Remarks:
This method is used internally.
Prototype:
virtual int Lerp(int a, int b, float f);
Remarks:
This method is used internally.
Prototype:
virtual BOOL CreatePreview(HWND hWnd, Bitmap **back, int frame, int width, int height, float aspect, Bitmap **fore = NULL, DWORD flag = PREVIEW_UP);
Remarks:
Implemented by the System.
This method provides a preview facility for use by plug-ins. This can be used by plug-ins that want to have a preview bitmap while displaying a control dialog.
Note: When you add a new Video Post event, an event object is created and it is added to the event queue when you hit the OK button. However, because the event is added to the queue only when you exit the dialogue, you cannot create a preview at that stage. Later, when you "Edit" the event, it is part of the queue and you can create a preview. Internally, there is no way for 3ds max to tell if the "Setup" button was called from an "Add" event or from an "Edit" event. Plug-In developers can tell if they are in the "Add" event mode by looking at the return value from this method. It will be FALSE if in "Add" mode since the call will fail.
Parameters:
HWND hWnd
This window handle will receive progress notification messages. The messages are defined in both BITMAP.H and FILTERS.H:
FLT_PROGRESS
wParam: Current
lParam: Total
FLT_CHECKABORT
wParam: 0
lParam: BOOL*
FLT_TEXTMSG
wParam: 0
lParam: LPCTSTR
BMM_PROGRESS
wParam: Current
lParam: Total
BMM_CHECKABORT
wParam: 0
lParam: *BOOL
BMM_TEXTMSG
wParam: 0
lParam: LPCTSTR
Bitmap **back
A pointer to the Bitmap Pointer (the Background). If the Bitmap pointer is NULL, a new bitmap is created using the given dimensions. This pointer must be NULL the first time this function is called as the bitmap must be created by Video Post. Once this function is called and a bitmap is returned, it is OK to call it again using this map. In this case, Video Post will simply use it instead of creating a new one. Note: You must NOT delete the bitmap when done -- Video Post will take care of it.
int frame
The desired frame in TICKS. Note that this is the position of the Video Post frame slider (in TICKS) and not the main 3ds max frame slider. See the Advanced Topics section on Time for details on ticks.
int width
The desired width of the preview.
int height
The desired height of the preview.
Float aspect
The desired aspect ratio of the preview.
Bitmap **fore = NULL
A pointer to the Bitmap Pointer (the Foreground). For layer plug-ins, this points to the foreground image. This is only valid if flag is set to PREVIEW_BEFORE. In this case back will hold Video Post main queue and fore will have the foreground image to be composited. This is useful if you, a layer plug-in, want to collect the images and run a realtime preview. If flag is not PREVIEW_BEFORE, fore will be a NULL pointer indicating there is no bitmap.
DWORD flag = PREVIEW_UP
The flag controls how much of the queue to run. The options are:
PREVIEW_BEFORE
The queue is run up to the event before the filter calling it.
PREVIEW_UP
The queue is run up to the event (filter) calling this function.
PREVIEW_WHOLE
The whole queue is run including events after this filter.
Return Value:
TRUE if the creation was successful; otherwise FALSE.
Prototype:
virtual DWORD ChannelsRequired();
Remarks:
Implemented by the Plug-In.
If a filter wants to work with the G-buffer (geometry/graphics buffer) it implements this method. It is used to indicate what image channels this plug-in requires. Prior to rendering 3ds max will scan the plug-ins in the chain of events and find out all the channels being requested. At the time the plug-in's Render() method is called, it will have access to these channels. The methods of class Bitmap may be used to access the channels.
Note: The generation of these channels should not normally be a default setting for the plug-in. These channels are memory intensive and if the plug-in won't use the channel it should not ask for it. Normally the plug-in would ask the user which channels to use and only then set the proper flags.
Return Value:
Default Implementation:
{ return BMM_CHAN_NONE; }
Filter Control Dialog Interactivity
Prototype:
void MakeDlgInteractive(HWND hWnd);
Remarks:
Implemented by the System.
This method is available in release 2.0 and later only.
This method may be used to allow a filter's dialog to operate interactively. This means that a user can have the filter's control dialog up and still operate 3ds max and Track View at the same time. This method should be called from the filter's Control() method as part of the WM_INITDIALOG code.
Note that even though this method can be called safely for any reason, developers should only call it when using animated parameters. It doesn't make sense to use it for filters with non-animated or no parameters. For sample code using this method see \MAXSDK\SAMPLES\POSTFILTERS\NEGATIVE\NEGATIVE.CPP.
Parameters:
HWND hWnd
The parent window handle.
Sample Code:
BOOL ImageFilter_Negative::Control(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) {
switch (message) {
case WM_INITDIALOG: {
//-- Make Dialogue Interactive
MakeDlgInteractive(hWnd);
...
Prototype:
virtual void FilterUpdate();
Remarks:
This method is available in release 2.0 and later only.
Whenever a filter instance is created or updated (i.e. the user went through the Filter Edit Control dialog) this method is called. The filter may use it to create or update its node controls. For an example see \MAXSDK\SAMPLES\POSTFILTERS\NEGATIVE\NEGATIVE.CPP.
Default Implementation:
{}
Prototype:
BOOL IsInteractive();
Remarks:
This method is available in release 2.0 and later only.
Implemented by the System.
Returns TRUE if the control dialog is interactive; otherwise FALSE. This means a user can have the filter's control dialog up and still operate 3ds max and Track View at the same time.
Prototype:
virtual ITrackViewNode *CreateNode();
Remarks:
This method is available in release 2.0 and later only.
Implemented by the System.
This method may be called to create a new Track View Node.
Prototype:
virtual ITrackViewNode *Node();
Remarks:
This method is available in release 2.0 and later only.
Implemented by the System.
This method is used to return the Track View node for this filter.