As mentioned in the Interface Querying topic, incorrect implementation of InterfaceServer::GetInterface() might lead to incorrect display of the plug-in in the Nitrous viewport.
Often a plug-in class inherits from multiple base classes, some of which are Mixin Interfaces while others are base classes representing the plug-ins main type (class SimpleObject, class Modifier, etc). The plug-in's implementation of InterfaceServer::GetInterface() needs to allow for correct handling of requests for:
A couple of examples of incorrect but typical implementations of InterfaceServer::GetInterface() are provided below:
// A mixin interface #define IID_SOME_MIXIN_INTERFACE Interface_ID (0x627c2f9c, 0x52671832) class SomeMixinInterface : public FPMixinInterface { // Does not implement GetInterface(Interface_ID iid) // Details elided for brevity } // A plugin class that derives from a non-mixin class and a mixin interface class class MyPlugin : public SimpleObject, public SomeMixinInterface { // details elided for brevity } // Incorrect GetInterface() implementation - does not handle requests for base mixin interfaces BaseInterface* MyPlugin::GetInterface(Interface_ID iid) { if (iid == IID_SOME_MIXIN_INTERFACE) return (SomeMixinInterface*)this; return SimpleObject::GetInterface(iid); } // Incorrect GetInterface() implementation - does not handle requests for // base mixin interfaces supported by the main parent class SimpleObject BaseInterface* MyPlugin::GetInterface(Interface_ID iid) { if (iid == IID_SOME_MIXIN_INTERFACE) return (SomeMixinInterface*)this; return FPMixinInterface::GetInterface(iid); }
A correct implementation of the plug-in's implementations of InterfaceServer::GetInterface() would look like this:
// Correct GetInterface() implementation BaseInterface* MyPlugin::GetInterface(Interface_ID iid) { // Handle request for specific mixin interface if (iid == IID_SOME_MIXIN_INTERFACE) return (SomeMixinInterface*)this; else { // Handle requests for base mixin interfaces BaseInterface* baseIfc = FPMixinInterface::GetInterface(iid); if (baseIfc) return intf; } // Handle requests for mixin interfaces supported by main base class return SimpleObject::GetInterface(iid); }
A simple test can be written in MAXScript to ensure that the plug-in overriding of InterfaceServer::GetInterface() is correct. The test works by querying a plug-in instance for a specific interface. The following MAXScript code shows the test for ensuring that requests for interface IObjectDislay identified by interface id IOBJECT_DISPLAY_INTERFACE_ID are serviced correctly by the Box plug-in:
-- create an instance of a box boxInstance = Box -- "Box" is the name of the class of the box plug-in object -- define the value of the interface id to query; see maxsdk\include\graphics\IObjectDisplay.h IOBJECT_DISPLAY_INTERFACE_ID = #(0x39820fa0,0x6311340d) -- query the box instance for IOBJECT_DISPLAY_INTERFACE_ID res = getInterface boxInstance IOBJECT_DISPLAY_INTERFACE_ID -- Use the MAXScript assertion mechanism to signal a test failure assert_true (res) message: ("Box failed to handle requests for IOBJECT_DISPLAY_INTERFACE_ID") -- Print all assertion messages for msg in AssertReporter.GetMessages() do print msg
The test uses an undocumented feature of the getInterface MAXScript method which interprets an array of two integers as an Interface_ID value and call the plug-in's override of InterfaceServer::GetInterface(Interface_ID) with it. It returns true if the plug-in returns a valid (non-NULL) pointer, false otherwise.