Interfaces

Topic: version 4 MAXScript New Features/Interfaces

The Function Publishing System, new to 3ds max version 4, is a system that allows plug-ins to publish their major functions and operations in such a way that code outside the plug-in can discover and make inquiries about these functions and is thus able to call them though a common calling mechanism. The whole system is very similar to Window's COM and OLE Automation systems and share many similar concepts in the architecture. However, the Function Publishing System is not based on COM and OLE but instead is a custom architecture more suited and optimized for MAX. The Function Publishing API serves a number of purposes, which allow 3rd party developers to open up important portions of their plug-ins for use by external sources, allowing for users to extend and control these directly.

Note: For complete details on the Function Publishing System, please see the 3ds max SDK help file topic "Function Publishing System".

Interfaces

Core Interfaces Other Interfaces

Functions are published in one or more Interfaces by a plug-in. Action functions must be published in their own set of interfaces. Each interface is represented by an instance of a class derived from the base class FPInterface. An external system can find out about the interfaces published by calling various query methods on ClassDesc that access these interface definition objects. As well as these enquiry or 'reflection' methods, an FPInterface also has the calling methods for actually invoking a particular function in the interface, so that if something has hold of one of your interfaces, it can call any of its published functions.

Action Interfaces

Action Manager

A special kind of interface is the Action Interface. These interfaces only contain UI Action Functions that provide a programmatic way of "pressing" buttons and keys in the UI for a plug-in.

Direct dot-notation properties

MAXScript exposes properties defined in this way as direct dot-notation properties on the interface. So, were before the Get/SetRadius in the example cylinder mixin would have been accessed as functions

Example:

r = $cyl01.cylMixin.getRadius()

$cyl01.cylMixin.setRadius 23

you now can use:

r = $cyl01.cylMixin.radius

$cyl01.cylMixin.radius = 23

This is true for all the types of FP interfaces that turn up in MAXScript, static, mixin and core. As a further optimization, MAXScript now effectively promotes all interface methods and properties to the level of the interface, so if individual methods and properties have unique names within all the interfaces of an object or class, you can elide the interface name. The above examples could now be written

Example:

r = $cyl01.getRadius()

$cyl01.setRadius 23

and:

r = $cyl01.radius

$cyl01.radius = 23

If there is a naming conflict, you can always include the interface name level to resolve this.

Published Functions and MAXScript

MAXScript automatically provides access to all functions published by a plug-in via the Function Publishing system. Each plug-in class appears in MAXScript as a MAX class object, which can be used to construct instances of the plug-in, do class tests, etc. If a plug-in publishes interfaces, they are visible in MAXScript as properties on this class object. The internal name for the interface is used as the property name. All the functions in the interface are accessible as named properties on the interface. So, if the above example interfaces were published by EditMesh, the following script fragments would work

Example:

EditMesh.faceOps.extrude $foo.mesh #{1,2,3} 10

The above script calls the Extrude function in the FaceOps interface on $foo's mesh, faces 1, 2 and 3, amount 10 units.

EditMesh.actions    

Retrieves and displays the action functions. Each interface is stored as a struct definition in the class object.

EditMesh.actions.create()    

Starts (or stops) the create mode. This would have the side-effect of highlighting/unhighlighting the Create button in the EditMesh rollups. Calls to Action functions in MAXScript return true if the function returns FPS_OK and false otherwise.

if EditMesh.actions.create.isChecked() then ...   

The predicate functions for an Action Function are available as properties on the action function object itself, as shown. You can determine if a predicate is supplied by asking:

if EditMesh.actions.create.isChecked != undefined

2 Ways of Accessing the Interface

There are 2 ways to access the interface - as a standalone interface and as an interface on a particular object. If you access the interface directly, you need to pass to it the object to work on.

Example:

m = Bitmaptexture fileName:"L:\mypath\scenes\2500hicon.JPG"
bitmapTex.viewImage m -- direct interface access, need to pass object
m.viewImage() -- accessing interface on object, object internally passed as arg 1.

Associated Method:

getCoreInterfaces()

Returns an array of core interface values.

Example:

The following will list all of the core interfaces.

core_interfaces = getcoreinterfaces()

for i in core_interfaces do (showinterface i;format"\n")

See also