Free Electron

Agnostic Plugins

October 2011

Purpose

The goal of this task is to demonstrate the ability write a plugin once and allow the same compiled binary to run on Maya, Houdini, and any other similar package.

The dso supplying the functional plugin is not linked against any of these other package's libraries or use any of their includes. This is achieved through of a single package-aware meta-plugin written for each package that interfaces to any agnostic plugin.

Additional packages can be supported without changing or even recompiling the functional plugins. A newly supported package only needs to provide its own version of the meta-plugin.

The declaration of inputs and outputs to a plugin, as well as their GUI representation, is done through a simple calls to a double dictionary structure called a "Catalog". The same catalog function syntax can read and write values as though the attributes were simple variables. The catalog automatically updates, and is updated by, the meta-plugin.

Surface manipulation can be done using an "accessible surface" interface. This presents the surface in a manner similar to Houdini with point, vertices, primitives, and detail using the notion that you often don't need to know exactly what sort of surface they represent. As an alternative, a drawing interface is also provided to each operator so that an operator can use pre-existing objects that think they are drawing to the screen and instead trick them into generating geometry for an operator output.

This is not ...

This is not a port. Making a plugin for one package and then converting all the package-specific API calls to the other packages means that you have to maintain a parallel version for every package.

This is not a dual-code abstraction using numerous conditionals like ifdefs and/or switches. While that might be better than maintaining parallel ports, it requires prior knowledge of every package you will be able to support and results in a littering of confusing constructs throughout your code.

This is not basic direct abstraction where relevant operations are directed to different code paths inside includes and static libraries. This should make for cleaner plugin source code than a dual-code abstraction, but it still requires the packages to be known and those abstractions to implemented ahead of time. Any change to any of those abstractions require a rebuild of every functional plugin.

This is not a dual-exposure plugin. It is plausible to write a single binary with multiple entry points, one for each package supported. This is hardly different than using one of the above techniques and concatenating libraries together (and overcoming the technical difficulties). Even with an API abstraction, you would need to have prior knowledge of all packages you would support and then compile that support into your binary.

Examples

These two files are essentially all the source needed for a simple additive wave. Note the double-key catalog for easy setup of the parameters and related GUI.

The default Component is a surface, so "Input Surface" doesn't need any further specification.

If no output surface is explicitly specified, an output surface is automatically set up and configured to copy the first input surface, if one exists, prior to running the handle method each time. Since this output surface may not exist in the catalog, it is provided on the signal passed to the handler.

The single compiled binary for the wave runs on both Houdini and Maya (the 'Test Toggle' and 'Test Int' attributes were removed from source above for brevity).
(click for full size)

Here is an example of rerouting an operator's rendering output to repurpose it as a geometry generator. (see stand-alone version)
(click for full size)

Here is an example of adding arbitrary attributes to mesh points in Maya, in this case a floating point value called 'test',
defaulting to 17.0 (this is already a trivial operation in Houdini).
A mesh summary node confirms the value.

In a second attribute called 'milliIndex', each point gets a value of their point index divided by 1000.
This confirms that the value is independent for each point.

Note that pointCount, primitiveCount, and probeValue are outputs.
We will make that clearer in the future.
(click for full size)

Here is an example of a dodging node and a length correction node, run agnostic in both Houdini and Maya.
The Maya graph also has an added curve generator and a template copy node, both of which are already natively available in Houdini.
(click for full size)

Here is the multi-curve geometry ramped up to 40000 curves in Maya.
The grid is selected to show the number of root points in the HUD.
(click for full size)


Web page, Copyright 2011, Free Electron Organization