Coden Documentation

Documentation

  • Start Here
    • What is Coden
    • Installing Coden
    • Uninstalling Coden
    • Supported Operating Systems and Host Applications
    • Supported Plugin Types
    • Writing Your First Coden Plugin
    • Distributing Plugins to Users
  • License
    • Licenses Comparison
    • How Licensing Works
  • Plugin Types
    • Polyline Modifier
    • Force Field
    • Mesh Generator
    • Mesh Modifier
    • Polyline Generator
    • Texture Map
    • Scalar Function
    • Command
  • Programming Concepts
    • How It All Works
    • Ways to Write a Plugin
    • How to Specify a Plugin
    • Plugin and Parameter Attributes
  • Reference
    • Host Adapters
    • Samples Project
  • Troubleshooting
    • Verifying Installation
    • Error Logs


What is Coden?

Coden is a .NET-based framework of libraries and adapters with two main goals:

  • Goal 1: Simplify the process of writing plugins for various applications
  • Goal 2: Enable one plugin to simultaneously extend multiple software packages

Coden allows developers to write code without worrying about how it is integrated into one or more host programs. It provides a 'neutral' and intuitive setting for writing common tools and extensions to most popular software packages.

Can you give an example?

Consider three of Autodesk's popular computer graphics programs- 3dsmax, Maya, and Softimage. Each one of them is different in its usage and has its own user base. However, all three applications also share a lot of functionality. Each of them has a way of creating new objects (polygon meshes), modifying objects, using 2D and 3D textures, and many other similar functionalities.

However, APIs for each application are different. If, for example, a developer would want to write a plugin that creates their custom object in all three programs they would have to write it 3 times- once for each application.

This means that a developer would need to learn each API beforehand and also do the work 3 times and put three times the effort into maintaining it afterwards. In real world this splits developers up and they end up choosing their favorite API to write for and stick with it.

Coden does not discriminate between application APIs- it allows a developer to write their object creation plugin once and have it work in all three applications. A developer only needs to learn of Coden environment and not worry about maintaining their tools for specific versions of software, operating systems, or platform flavors- it is all done by the framework!

Great! So what can I write with it?

There are a number of plugins that can be written using Coden. These include (but are not limited to) mesh generators and modifiers, textures and image filters, commands, and custom functions/controllers. Please consult the plugins section to get a good overview of exactly what's supported at present time.

Not all applications support a particular plugin type. For example, certain image editing and compositing applications support textures but do not support geometry plugins. Other applications might support geometry plugins but don't provide support for pluggable textures.

Next: Write your first Coden tool!


Installing Coden

Downloading the installer

To install Coden you first need to download the installer for the desired version (latest version is recommended). You have a choice of doing online or offline installation. Online installation will result in a quicker and easier setup but it does require an internet connection. If you are not connected to the internet or want to install Coden on another computer use the offline installer.

Installing Coden automatically (recommended)

Once you have downloaded the installer simply run it and follow the instructions. You will be given an option to specify where Coden will look for its plugins and which hosts to install it for. Installer will automatically try to detect all compatible host applications on your computer, however, you can also specify a custom location for each host.

Please note that Coden will need to place an adapter plugin into each host. Therefore, if you are specifying the install path manually make sure that the adapter files (.dlls) go into the host's plugin directory. If you are updating Coden please close all of the host applications before performing the install to allow adapter plugins to be overwritten.

Installing Coden manually (dump-install)

While it is usually easier to let the installer do the work you might also need to access individual Coden files for either trouble-shooting or custom deployment purposes.


Uninstalling Coden

Should you wish to uninstall Coden, you can do so by running the provided uninstall program. You may find it in Windows Programs and Features dialog under the entry ephere.plugins.coden.

Simply right click and select "Uninstall/Change" and the uninstaller will do the rest.

Manual uninstallation is also possible. Please refer to our manual installation instructions and remove all of the files which were added during those steps.


Supported Operating Systems and Host Applications

Operating systems that run Coden

Currently Coden is only supported under Microsoft Windows with .NET 4.0 or later. We plan to expand our support to Linux and OSX in the near future. The following table illustrates Coden support on different operating systems:

 | Microsoft Windows (.NET 4.0) | Linux (Mono) | Mac OSX (Mono)
3dsmax 3ds Max | Yes, R9 and above, 32 bit, 64 bit |  |
Maya Maya | Yes, 2009 and above, 32 bit, 64 bit | No | No
XSI XSI | No, but will be available shortly Yes, 2010 and above, 32 bit, 64 bit | No | No
Houdini Houdini | No, but will be available shortly Yes, 10 and above, 32 bit, 64 bit | No | No
Photoshop Photoshop | No, but will be available shortly Yes, CS4 and above, 32 bit, 64 bit |  | No

.


Supported plug-in types

Coden provides support for a variety of different tools. You need to be aware of the functionality you require and preferably also the target "host" applications where you want your functionality to be available.

At present time Coden allows developers to write:

  • Mesh generators - used to generate a 3D polygonal mesh based on a set of parameters
  • Mesh modifiers - used to alter an existing 3D polygonal mesh structure based on a set of parameters
  • Polyline generators - generates 3D curves represented by polygon lines
  • Polyline modifiers - used to alter existing 3D curves represented by polygon lines
  • Value functions - generic functions that output basic value types (i.e. floating point values, integers, booleans, strings) based on a set of input parameters
  • Graph functions - 'command' functions used to alter a scene graph
  • 2D functions/maps - used to generate procedural textures based on a set of parameters

The following table illustrates Coden support and implementations of these plug-ins for different hosts:

3dsmax 3ds Max | Maya Maya | XSI Softimage|XSI | Houdini Houdini | Photoshop Photoshop
Mesh Generator | Geometry Object | DAG Surface Node | Topology Operator | Generator SOP
Mesh Modifier | Modifier | DAG Node | Geometry Operator | SOP
Polyline Generator Shape Object
Polyline Modifier Shape Modifier
Scalar Function | Float Controller | DAG Node | ICE Node | VEX Node
Command | MXS Function | MEL Command | Command | Command
Texture Map | 2D Texmap | 2D Texture | MR Texture Shader | Image Filter


Writing Your First Coden Plugin

  1. Install Coden

    Before starting to write you first Coden tool please download and install Coden. Optionally you can verify the installation.

  2. Create a Visual Studio project

    Open up Visual Studio (VS2010 used in this example) and choose to create a new Class Library project. C# is used as the language of choice throughout examples, however, you may use any .NET language such as VB, F#, or C++/CLI. Make sure .NET 4.0 is selected as the target framework.

  3. Add and setup assembly references

    To access some of Coden's hooks we need to add a reference to Ephere.Modeling.dll assembly. This assembly was installed with your version of Coden and will be located in C:\Users\USER\AppData\Local\Ephere\Library\bin\ directory by default.

    If you are developing a tool that deals with geometry you will also need to reference Ephere.Geometry.dll assembly located in the same directory.

  4. Write a plugin function

    Next step is to write our actual plugin code. To make things simple we reference the Ephere.Modeling and Ephere.Geometry namespaces with the using directive. We then add two assembly-level attributes. Pluggable attributes specifies that the whole assembly will be scanned for plugins (instead of on per-class basis). License attribute needs to be filled in using your licensing credentials obtained from us.

    [assembly: Pluggable]

namespace MyCompany.MyPlugin
{
    public static class MyPlugin
    {
        public static PolygonMesh3 MyMesh( float parameter )
        {
            return new PolygonMesh3();
        }
    }
}

    The namespace convention is important because it is used by some hosts to categorize your plugin. We define our plugin function MyMesh under a static class MyPlugin. Since it returns a PolygonMesh3 object it will be translated as a geometry generator. It will take one floating point parameter.

  5. Compile and copy into Coden directory

    Once you compile your plugin you need to copy it to Coden's /bin directory. This is the same directory as from where you referenced the Ephere.Modeling.dll assembly.

    Copy to Bin directory

  6. Test

    The final step is to launch your host application and make sure everything is loaded properly!


Distributing Plugins to Users

Distributing Coden plugins to end-users

If you have a Coden distribution license you may distribute your creations to end users outside of your company. To do this you will need to make sure that:

  1. The end-user has Coden installed on their computer. This can be done by either running the online installer from our website or using the redistributable offline installer. You may ask the user to run the installer manually or provide the installer and/or links for them.
  2. Place your plugin assembly into the Coden bin directory. You may ask the end-user to do this manually or provide an installer.

At this point the Coden plugin will run on all hosts present on the end-user's machine.


Licenses Comparison

Licensing Coden

You may evaluate Coden for 30 days free of charge. It may also be used freely for consuming external pre-compiled commercial Coden plugins. Please note that Coden binaries or any tools you create using Coden libraries come "as-is" and we do not guarantee any support or specific results with this license.

If you plan to develop commercial tools using Coden you may either acquire a Developer license or an Ultimate license.

Developer license allows you to develop tools using Coden for internal use within your company. You are not allowed to distribute these tools to other Coden users who are not within your company. We provide 1-year support with this license shall you require any assistance along the way. Any Coden updates within the same version are included free of charge.

Ultimate license allows you to develop commercial tools using Coden and distribute them to anyone in any way you want. This is the catch-all license which removes any boundaries and allows you to take full advantage of the Coden's cross-application support to reach a great user base. We provide a 1-year support with this license and any Coden updates within the same version are also included for free.

Licensing process is hassle free, however, please contact us regarding any inquires and we will get back to you promptly.

License Comparison

Name | Price | Load Plugins | Create Plugins | Distribute to Others
Consumer | Free | Yes | No | No
30-day Evaluation | Free (upon request) | Yes | Yes | No
Developer | Inquire | Yes | Yes | No
Ultimate |  | Yes | Yes | Yes


How Licensing Works

How Coden licensing works

When you purchase a Coden license or request a 30-day evaluation you will receive a special license Code. This request code can be easily incorporated into your plugins either directly in code or through a meta assembly.

Specifying a license inside code

Consider that you have created an assembly which you would like Coden to load. Once you have your activation code all you need to do is insert the License attribute anywhere inside your assembly. For example:

[assembly: License( Company = "xxxxxx", Code = "xxxxxxxxxxxxxxxxxxx" )]

For the Company property you need to insert the company name which you used to request your license. For the Code attribute you need to insert the license code itself. You do not have to specify the Company property if you already declared an AssemblyCompany attribute for your assembly elsewhere.

That's it, it is that easy!

Specifying a license through a meta assembly

If you do not have direct access to your assembly source code, or chose to use a meta assembly to define your Coden plugins for another reason, you may also specify the license code in the meta assembly file:

<MetaAssembly Name="MyAssembly" xmlns="http://www.ephere.com/modeling/dependency/metaassembly.xsd" LicenseCode="xxxxxxxxxxxxxxxxxx">
...
</MetaAssembly>

The LicenseCode attribute needs to contain your Coden license code. Note that for this to work the assembly referenced, in this case MyAssembly, must have AssemblyCompany attribute defined which contains the name of your company.


Polyline Modifier

Polygon line modifier plug-ins

  • 3dsmax 3ds Max

Polyline modifier plug-ins act on the same principle as mesh modifiers, except that they alter polygon lines instead of polygon meshes.

Specifying polygon line modifier plug-ins

Polyline plug-ins are distinguished by the fact that they accept PolylineMesh3 as their first parameter and return PolylineMesh3 as their result and that both of these input and output belong to the same port group.

[OutputPort( Group = "primary" )]
public static PolylineMesh3 MyPolylineModifier( [InputPort( Group = "primary" )] PolylineMesh3 polylineInput )
{
    // Take polylineInput, alter it, and return as result...
}

For more information on dealing with polylines refer to the polyline generator documentation.


Force Field

Force field plug-ins

A commonly used components in physics simulations and particle dynamics is a vector field. In computer graphics these functions are often referred to as force fields. The basic purpose of a force field is to provide a force vector for a given point in space, optionally knowing the velocity at that point.

Coden makes it easy to define force field plug-ins in a few lines of code. Consider the following example:

public static Vector3 ComputeForce( Vector3 position, Vector3 velocity )
{
    return Vector3.Zero;
}


Mesh Generator

Mesh generator plug-ins

  • 3dsmax 3ds Max
  • 3dsmax Maya

Mesh generator plug-ins generate a polygonal mesh given a set of input parameters. The plug-in's job is to act as a black box that defines and accepts a list of parameters of various types and outputs a PolygonMesh3 object.

For example, consider the following function:

PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
{
    return new PolygonMesh3();
}

This function generates a new PolygonMesh3 object given three parameters: width, height, and a flag. Coden will automatically classify this function as a mesh generator plug-in because its output type is a PolygonMesh3.

Writing mesh generators

As with the rest of Coden there are two main ways to define a mesh generator plugin: through the use of a function or a class. The choice is left up to you based on your needs.

Texture Coordinates

If you wish to accept texture coordinates of an input mesh or generate texture coordinates with an output mesh you will have to construct a separate "texture mesh" and output it inside the same port group as the geometry mesh. Consider this example:

[Output( Group = "output" )]
public static PolygonMesh3 MyMeshGenerator( float width, float height,
    [Output( Group = "output", Tags = CommonTags.TextureCoordinates )] out PolygonMesh3 resultTexCoords )
{
    // Generate and return result, generate result UV coordinates into resultTexCoords
}

The function now has an Output custom attribute which specifies a group "output". This is necessary so that we can pair the resulting PolygonMesh3 with another PolygonMesh3, which will contain the texture coordinates. We also add a parameter resultTexCoords. This is an output parameter which we mark to also belong to the group "output" and also contains the TextureCoordinates tag. This tag lets Coden know that your intention is to put UV coordinates for the generated mesh into this mesh. As stated before, resultTexCoords mesh must have exactly the same number of polygons each with the same number of vertices as the resulting mesh.

Note that the group name in this case can be arbitrary (doesn't have to be "output") as long as both Output attributes use the same one.

Please refer to the samples project TexturedPlane class to see how to output texture coordinates when defining your plug-in through a class instead of a function.

You may also wish to accept other meshes which contain texture coordinates as inputs for your mesh generator. Consider this example:

public static PolygonMesh3 MyMeshGenerator( float width, float length,
    [Input( Group = "mesh1" )] PolygonMesh3 meshInput,
    [Input( Group = "mesh1", Tags = CommonTags.TextureCoordinates )] PolygonMesh3 meshInputTexCoords )
{
    // meshInputTexCoords will contain UV coordinates for the meshInput parameter (if they are available)
}

This is very similar to the previous example, except we now take an input parameter and use Input attribute to mark the group for each polygon mesh. We also use the TextureCoordinates tag to mark the second polygon mesh parameter as the texture coordinates for the preceding mesh input. Coden will, in this case, pass UV coordinates of meshInput in the meshInputTexCoords parameter.

Examples

For examples of mesh generator plug-ins, see Cube.cs, Plane.cs, Pyramid.cs, Sphere.cs, and TexturedPlane.cs files available in the samples project.

>


Mesh Modifier

Mesh modifier plug-ins

  • 3dsmax 3ds Max
  • 3dsmax Maya

Mesh modifier plug-ins in Coden are very similar to mesh generator plug-ins with one exception that the first parameter must be a mesh. As such, the difference is purely conceptual: a mesh modifier is designed to alter an existing mesh in some way, where as mesh generator is designed to generate a new mesh from scratch. However, in some host applications this difference becomes more profound because they may treat mesh modifiers differently than other plug-in types. For example, in 3dsmax and XSI implementations mesh modifiers become modifier and operator plug-ins, respectively, while mesh generators in these hosts define new object types. However, other hosts such as Maya do not have such distinctions.

In either case, it makes a good practice to distinguish the intended purpose of your mesh plug-in and use the modifier distinction for anything intended for altering existing meshes.

Specifying mesh modifier plug-ins

Any function which accepts a PolygonMesh3 as its first input and produces a PolygonMesh3 as its first output, where both the input and output are part of the same port group, will be treated as a mesh modifier.

[OutputPort( Group = "primary" )]
public static PolygonMesh3 MyMeshModifier( [InputPort( Group = "primary" )] PolygonMesh3 meshInput )
{
    // Take meshInput, alter it, and return as result...
}

Please note that mesh modifier plug-ins must accept a PolygonMesh3 as its first parameter.

All other aspects of writing mesh modifiers such as accepting and returning texture coordinates and other extra mesh information are the same as with mesh generator plug-ins.

Examples

For examples of mesh modifier plug-ins see CloneAndOffsetMesh.cs, DirectedPointsOnSurface.cs, and Mirror.cs files available in the samples project.


Polyline Generator

Polyline generator plug-ins

  • 3dsmax 3ds Max

Polyline generator plug-ins generate a polyline mesh given a set of input parameters. Polyline meshes produce a set of polygonal curves. They differ from polygon meshes by the fact that they do not produce surfaces but curves instead. A polyline generator plug-in's job is to act as a black box that defines and accepts a list of parameters of various types and outputs a PolylineMesh3 object.

For example, consider the following function:

PolylineMesh3 MyPolylineGenerator( float width, float height, bool flag )
{
    return new PolylineMesh3();
}

This function generates a new PolylineMesh3 object given three parameters: width, height, and a flag. Coden will automatically classify this function as a polyline mesh generator plug-in because its output type is a PolylineMesh3.

Writing polyline plug-ins is similar in almost all respects to writing polygon mesh plug-ins. Therefore, for additional information please refer to the polygon mesh plug-in documentation.


Texture Map

Texture Maps

  • 3dsmax 3ds Max
  • 3dsmax Maya

Texture maps are 2d functions that produce a color when given a coordinate. The most common usage for these maps is to add detail to polygonal mesh surfaces. For example, one may use a wood texture on top of a box to create an illusion that a box is made of wood. Textures are also used to provide meta-information about a surface. For example, a normal or bump map provides information about which way a surface is pointing at any given location, or a hair length map might determine the length of hair at any point on a surface.

Coden allows developers a lot of freedom over how they define their maps. The simplest way to do it is through a function. For example:

public static Graphics.Color Checker( Vector2 coordinate, float cellWidth, float cellHeight, Color color1, Color color2 )
{
    bool oddX = (int)( coordinate.x / cellWidth ) % 2 == 0;
    bool oddY = (int)( coordinate.y / cellHeight ) % 2 == 0;
    return oddX ? ( oddY ? color1 : color2 ) : ( oddY ? color2 : color1 );
}

Here we define a function Checker that takes a Vector2 coordinate, some extra parameters, and outputs a color value. The resulting color value is calculated based on the coordinate, width and height, of the cells, and the colors used for alternating cells.

Coden will detect this function as a texture and use it to calculate values for each pixel (or sample) of a texture map:

Examples

For an example of a texture map plug-in see Checkers.cs file available in the samples project.


Scalar Function

What are scalar function plug-ins?

Perhaps the most simple plug-in type, scalar function plug-ins allow you to define a function which produces as an output a scalar value. As a plug-in, this function can be used to drive parameters within a host application or just act as a general math node where applicable. A typical example of a scalar function is a sine wave or a random function which we can use to alter an input parameter of some object within the host over time. Scalar functions can take zero or more inputs and process them in any desired way to produce the output. Consider the following example:

public static float Multiply( float a, float b )
{
    return a * b;
}

What we have here is a basic multiplication function. Inside a host application, this can be used as a controller or a node which takes two other scalar inputs and produces a single output which can be used to specify a parameter for another object or, perhaps, specify the position of an object inside the world. All of the standard Coden conventions when it comes to specifying plug-ins apply.

Examples

For an example of a scalar function plug-in see Multiply.cs file available in the samples project.


Command

Command plug-ins

  • 3dsmax 3ds Max
  • 3dsmax Maya

Coden provides a rich specification for creating various types of plug-ins for numerous hosts. In addition to defining the plug-ins, however, it is also important to properly expose them to the end user. This might mean simply creating an instance of your custom plug-in inside a scene or, more involved, performing some operations on objects already existing within a scene to incorporate your custom functionality into it.

The scene graph

As with all the other plug-in types, Coden defines a high level abstraction when it comes to accessing and manipulating scenes. We do this through a generalized acyclic dependency graph which represents an instance of a file currently being edited by a user. Each node within this graph represents a specific object within a scene. For example, a node could represent a polygon mesh, its transform, or some animation controller. The nodes are then inter-connected between each other to define their relationships.

For example, an animation data node might be connectable to a polygon mesh node to give it movement. The nodes are specified in a way to be abstract enough for every host application which Coden supports. While the node itself might not map directly to a specific object within a host application the overall structure of the graph will be applicable to that host and will produce the expected behaviour.

Types of nodes

There are numerous types of nodes present within a Coden scene graph. Each node has its own purpose and is only connectable to a specific set of other nodes. To learn more about each node type please click on a more detailed description from this list:

  • World object node: An object which appears inside a view of a host application. This node specifies information about what the displayed object is, its location, its material, and other information.
  • Object node: Represents some data which can be passed to a scene node. Object nodes can take other object nodes as input and modify them.
  • Function node: Returns simple values as opposed to complex values returned by object nodes. These can be simple scalar values or things like transformation to control a scene node's position.

Creating a command plug-in

Defining a command plug-in in Coden is very trivial: create a pluggable function returning a boolean value and taking first parameter of type IGraph. You can then specify more parameters for the function for your needs. Here is a simple example of a function plug-in:

public static bool MyCommand( IGraph graph, float parameter1, int parameter2 )
{
    // Do stuff to graph here...
    return true;
}

For more complex examples please download our samples project and browse the "Commands" directory.

Using IGraph to create nodes

To create a new instance of a node use IGraph.CreateNode command as illustrated in the following example: The string parameter you pass is the full name of the Coden plug-in you want to create or a predefined name such a world object node. The following predefined names can be created: While creating a node you must also assign it a unique name.

Accessing existing scene nodes

IGraph interface provides a Nodes property which allows you to browse through all currently available scene nodes. Note that some of these nodes may be instances of Coden plug-ins but all of the nodes will either directly or indirectly represent objects inside a host application. You may perform a number of operations on existing scene nodes such as renaming, deleting or connecting them. You may also use these nodes to access their properties and other nodes connected to them.

Getting and setting node selection

If you provide a second parameter for your pluggable command function which has an integer array type and a "selection" tag you will be passed the indices of currently selected nodes within the graph's Nodes array. These are the nodes which have been selected by a user inside the host application's UI. Having access to the current selection can be used to perform some action on just the currently selected nodes within the scene. Following example demonstrates a sample usage of node selection:

public static bool MyCommand( IGraph graph, [Input( Tags = "selection" )] int[] graphSelection )
{
    foreach( var selectedIndex in graphSelection )
    {
        var selectedNode = graph.Nodes[selectedIndex];
        // Do stuff to selectedNode...
    }
    return true;
}

Executing other commands

Your command can execute other commands defined either by you as a plug-in or present within a host application. To execute a command use IGraph.ExecuteCommand function. As with node creation be careful to make sure that all hosts that you want to potentially run your command will have the commands you want to execute within them. A good practice is to only call other commands which you have defined through Coden and provided within the same plug-in. This guarantees their availability within the same host application.

Examples

For examples of command plug-ins see CenterSelectedNodes.cs, CreateCube.cs, and EnumerateSceneNodes.cs files available in the samples project.


How It All Works

Hosts and Models

You can think of Coden as a bridge between a "host" application and Ephere's proprietary modeling framework. A "host" is a program which you want your plug-in to extend or be exposed to. Our modeling framework is a set of libraries that interpret managed code you write and understand how to use it as a plug-in in a whole array of such host applications. We do that hard work of making sure plug-ins you write once stay compatible in all supported host applications so you can concentrate on functionality rather than integration.

The Adapters

Each host application supported by Coden has a special adapter extension written for it. This adapter is usually a plug-in that the host can load. In turn the adapter is responsible for loading all Coden plug-ins and passing them opaquely to the host as its own native tools. As a result the host application does not distinguish Coden plug-ins from any other native plug-ins which it supports. Native GUI and plug-in structure is used for each host.

Ephere Modeling Framework

Whenever you write code that you intend to use as a Coden plug-in you need to follow certain guidelines to ensure that it is properly understood by our modeling library (the term "modeling" here relates to programming and is not to be confused with 3d modeling). We outline these guidelines in a separate document.

This can be achieved using different approaches, and you determine which method to use based on your preference. For example, one way uses a special "pluggable" attribute which you specify inside your code at a class, function, or assembly level. In such a case, if you want to expose just one function in your plug-in assembly as a plug-in (with the rest of the assembly containing code that complements that function) you would mark it as pluggable. Conversely, if you wanted each function in your assembly to be a separate plug-in you can mark the whole assembly as pluggable. Another approach allows you to define an external file responsible for specifying pluggable components in some existing plug-in assembly.

You can find more details about exposing your plug-ins to Coden in a separate document.

Our modeling framework scans and "picks up" all pluggable methods and classes. It then categorizes and adds them to its plug-in library. The plug-in library is accessed by a host adapter whenever the host loads and plug-ins that can be adapted to that particular host are processed. The rest of the plug-ins are ignored by the adapter but they can be used by another adapter that supports the plug-in type.


Ways to Write a Plugin

Native .NET constructs

Coden gives developers the freedom of semantics they choose to write their plugins. It uses native .NET language constructs such as classes and methods to define what a plug-in does. There are no special steps involved and no interfaces or classes to be derived from. Indeed, you can take already existing non-Coden assemblies and make them into plugins.

Many ways to write a plug-in

A Coden plug-in conceptually boils down to an "operator" that takes a number of inputs, does something, and then produces an output. Programming-wise the closest definition to this is a function, however, classes and other methods can have their benefits for defining plugins.

As an example we will be looking at a plug-in that generates a mesh based on some parameters. Following are all the different methods for defining such a plug-in.

1. As a function

The simplest way to define a plug-in is through a static function:

public static PolygonMesh3 Cube( float width, float length, float height )
{
    var result = new PolygonMesh3();

    // Edit result's vertex and face list to define a 3d cube...

    return result;
}

Our function takes three inputs (width, length, and height) and produces a PolygonMesh3 object as a result. Coden will look at this function, see that its output is a PolygonMesh3 and automatically assume and use it as a mesh generator plug-in.

NOTE: The function must be static and be defined inside a static class that is marked as pluggable (unless the whole assembly is marked as pluggable).

2. As a derived class

public class Cube : PolygonMesh3
{
    public void ValidateClass()
    {
        // Edit this class' vertex and face list to define a 3d cube...
    }

    public float width, length, height;
}

Our Cube class is derived from PolygonMesh3 so, in essence, it represents an instance of our plug-in. This can have a number of benefits over using the previous example of function approach. For example, you can store persistent parameters or cache in your class that can be reused between evaluations.

ValidateClass() function is called whenever our cube needs to be regenerated, usually after parameter changes.

3. As a class constructor

public class Cube : PolygonMesh3
{
    public Cube( float width, float length, float height )
    {
        // Edit this class' vertex and face list to define a 3d cube...
    }
}

Class constructors can also be used for defining a plug-in. Whenever an instance of our cube mesh is requested the parameters will be passed into the constructor of our class and we can generate the mesh there.

4. As a class function

public class Cube
{
    public PolygonMesh3 Generate( float additionalParameter )
    {
        var result = new PolygonMesh3();

        // Edit this class' vertex and face list to define a 3d cube...

        return result;
    }

    public float width, length, height;
}

In addition to all of the above methods we may also define a plug-in as a member function of a class. In the above example, our plug-in will be called Generate and it will take four parameters (width, length, height, additionalParameter). Note how additionalParameter is appended to the end of class' parameters. This provides all benefits of defining a plug-in as a class plus the simplicity of defining a function.


How to Specify a Plugin

How to specify plug-ins (Pluggable Vs. Non-Pluggable)

Coden relies on properly translating functions and classes from .NET assemblies into plug-ins compatible with these host applications. To allow this translation to happen the developer needs to specify exactly which .NET assemblies are meant to be pluggable (translatable). There are two main ways to do so and this document describes exactly how.

The Coden mechanism scans an assembly and picks out publicly defined classes and functions that fit certain criteria. For example, a function taking a Vector2 typed parameter producing a Color will be assumed to be a texture generator. Or a class derived from PolygonMesh3 that has another PolygonMesh3-typed (first) parameter will be assumed to be a mesh modifier. A typical plug-in assembly, however, will most likely have more classes and functions fitting such criteria which are not meant to be pluggable. These, for example, may be utility functions.

Using Ephere.Modeling library to define pluggable entities

Once referenced, Ephere.Modeling.dll library contains Ephere.Modeling.Attributes namespace which defines a number of attributes useful for adding meta data to your plug-ins. The attribute you can use to expose your functions and classes as plug-ins is Ephere.Modeling.Attributes.PluggableAttribute. To use it simply add the Pluggable attribute to a class or function definition meant to be a plug-in. Note that you must also specify a "plugin" tag inside the Pluggable attribute.

Alternatively you may add this attribute to the whole assembly to mark all entities within it as pluggable by default. Following are the rules for using the Pluggable attribute for marking entities as pluggable:

  • Coden will scan all classes and functions in an assembly that has a global Ephere.Modeling.Attributes.PluggableAttribute

    For example:
    // Marks whole assembly as pluggable
[assembly: Ephere.Modeling.Attributes.Pluggable( Tags = "plugin" )]

public static partial class MyPlugins
{
    // Will be a plugin
    public PolygonMesh3 GenerateMesh( float width, float height, bool flag )
    {
        return new PolygonMesh3();
    }

    // Will be a plugin
    public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
    {
        return GenerateMesh( width, height, flag );
    }
}

  • Coden will ignore all non-public functions and classes
    For example, if you have a private method and a public method like example below, Coden will only detect MyMeshGenerator function and will ignore GenerateMesh method:
    // Will be ignored (because it is private)
private PolygonMesh3 GenerateMesh( float width, float height, bool flag )
{
    return new PolygonMesh3();
}

// Will be a plugin
public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
{
    return GenerateMesh( width, height, flag );
}
  • Coden will skip all classes and functions that have Ephere.Modeling.Attributes.IgnoredAttribute

    The following will behave just like the example above:
    // Will be ignored (ignored attribute)
[Ignored]
public PolygonMesh3 GenerateMesh( float width, float height, bool flag )
{
    return new PolygonMesh3();
}

// Will be a plug-in (if Pluggable attribute is defined at assembly level)
public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
{
    return GenerateMesh( width, height, flag );
}
  • If Ephere.Modeling.Attributes.PluggableAttribute with a "plugin" tag is not defined at an assembly level it will only include classes and functions that have Ephere.Modeling.Attributes.PluggableAttribute with a "plugin" tag defined

    The following will behave just like the example above:
    // Will be ignored (if Pluggable attribute is not defined at assembly level)
public PolygonMesh3 GenerateMesh( float width, float height, bool flag )
{
    return new PolygonMesh3();
}

// Will be a plug-in
[Pluggable( Tags = "plug-in" )]
public PolygonMesh3 MyMeshGenerator( float width, float height, bool flag )
{
    return GenerateMesh( width, height, flag );
}

Using a meta assembly file

To specify meta information about assemblies without using Ephere.Modeling.dll assembly within them you can create an external meta assembly (.maxml extension) file and specify pluggable entities in it. This may be useful if you did not write the assembly containing pluggable methods (for example, you may create a meta assembly for a built-in .NET library like System.Math.dll) or if you cannot reference Ephere.Modeling assembly for some other reason.

Meta assemblies are XML files with .maxml extension and residing in the same directory as the binary .NET dlls used by Coden. This is typically the C:\Users\USERNAME\AppData\Local\Ephere\Library\bin directory. To create a new meta assembly which specifies pluggable types simply create a new XML file, for example, MyAssembly.maxml and follow this format:

<?xml version="1.0" encoding="utf-8" ?>
<MetaAssembly Name="Binary.Assembly.Name" xmlns="http://www.ephere.com/modeling/dependency/metaassembly.xsd">
    <Pluggable Type="MyNamespace.MyPluginClass"/>
    <Pluggable Type="MyNamespace.MyPluginFunctions" Function="PluginFunctionName"/>
</MetaAssembly>

The meta assembly above defines two plug-ins existing in Binary.Assembly.Name.dll file, present inside the same directory as the above meta assembly file. First plug-in is a class MyPluginClass located inside MyNamespace namespace. Second plugin is a function named PluginFunctionName defined inside MyPluginFunctions class located inside MyNamespace namespace.

And voila, it is that simple to specify plug-ins for Coden!


Plugin and Parameter Attributes

Specifying additional attributes

While it is often quickest to just allow Coden to translate a native function or class into a plug-in sometimes you might want to add extra information to them. To make your plug-in more user friendly and generally useful Coden contains a set of attributes that can be applied to each plug-in and its parameters.

All of these attributes are located inside the Ephere.Modeling.Attributes namespace.

Pluggable attribute

Pluggable attribute has two functions- it marks a class or function as a plug-in for Coden to scan and it also specifies some additional parameters such as a user-friendly, localized, plug-in title.

[Pluggable( Title = "Ephere Mesh Generator!" )]
public PolygonMesh3 MeshGenerator( float width, float height, bool flag )
{
    //...
}
  • Title parameter allows you to specify a user-friendly name for your plug-in. It can contain spaces and Unicode characters

Input attribute

Input attribute has two functions: first, to explicitly mark a parameter as an input (as opposed to an output) and, second, to provide additional information about an input. Consider the following example:

public PolygonMesh3 MeshGenerator(
    [Input( Title = "Mesh Width", Category = "Dimensions", Default = 10.0f, Minimum = 0.0f, Maximum = 99.0f, AffectsOutputs = new string[] { "output" } )]
    float width,
    [Input( Title = "Mesh Height", Category = "Dimensions", Default = 10.0f, Minimum = 0.0f, Maximum = 99.0f )]
    float height,
    [Input( Title = "Optional Flag", Category = "Flags", Default = true )]
    bool flag )
{
    //...
}

Each function argument has an Input attribute specified along with it. This attribute tells Coden that following argument is meant to be an input and provides additional information about the argument.

  • Title property specifies a localized user-friendly title of the input
  • Category property allows you to group inputs together into categories
  • Default property specifies a default value of the input
  • Minimum property specifies a minimum value (only applies to float, double, and integer inputs)
  • Maximum property specifies a maximum value (only applies to float, double, and integer inputs)
  • AffectsOutputs property explicitly provides a list of outputs that depend on this input. If not specified it is assumed that all outputs are affected.

Output attribute

Output attribute allows you to explicitly specify a field, property, or a parameter as an output. For example:

public PolygonMesh3 MeshGenerator( float width, float height, [Output( Title = "Optional Flag" )] out bool flag )
{
    //...
}

Here we have two function arguments acting as inputs and one out argument. Because it is marked with an out keyword, Coden will automatically scan it as an output. However, we can also provide some additional data about it such as its user-friendly title.

Input and output groups and tags

Coden plug-ins are defined as a set of inputs and outputs. These, in turn, specify the type of the plug-in, its parameters, and what it produces as a result. In the simplest scenario a parameter is defined using a name and its type. For example, if you want to accept a polygon mesh as an input for your plug-in, you specify PolygonMesh3 input type and give it some name.

However, many times a need arises to pass additional information along with a parameter. For example, you might want to also accept texture coordinates for a PolygonMesh3 input. Inside Coden texture coordinates are provided as a separate polygon mesh input. You, therefore, need to group the two ports, one for the mesh data and one for texture coordinates, to specify that this information represents the same input. This can be done by using named input groups.

To use an input group add a Group parameter with a name unique for that group inside the Input attribute placed on your function argument or class member. Multiple inputs can be grouped by reusing the same group name. For example, the mesh and texture coordinate example described above can be presented as:

Note that there is also an additional Tags parameter for the Input attribute. Tags allow you to specify the function of each input or output within a group. In the above example we mark that input to produce texture coordinates by assigning it the "textureCoordinates" tag.

The exact same logic is applied to outputs. So, consider an example where you want to produce an object with a mesh and its texture coordinates:

Tags can also be used to specify special inputs such as the current scene time:

Please read the tags reference for a full list of tags which can be specified within a port group.


Host Adapters

Adapter documentation for supported hosts

  • 3dsmax 3ds max adapter
  • Maya Maya adapter
  • XSI Softimage|XSI adapter (Coming soon)
  • Houdini Houdini adapter (Coming soon)
  • Photoshop Photoshop adapter (Coming soon)


Samples Project

Solution with samples

To help you get started with Coden and have reference to its abilities we maintain a samples project containing plugins that can be used as reference and tests. Please click the link below to download this Visual Studio 2012 solution:

Download Coden Samples Solution (Version 1.0.0.0, May, 2013)

Using the samples project

You may open the samples project in Microsoft Visual Studio 2012. Alternatively you can use other integrated development environments (IDEs), however, you will need to set up a library assembly project and include the sample source files into it.

There are two non-System assemblies which must be referenced for you to compile the samples project. These are:

  1. Ephere.Geometry.dll
  2. Ephere.Modeling.dll

Both of these assemblies are installed by Coden and can be commonly found in "C:\Users\USERNAME\AppData\Local\Ephere\Library\bin" directory. It is a good idea to know about their location because they could be useful to reference in your future Coden plugins.


Verifying Installation

In some cases it might be needed to make sure that the installer has done its job properly and all of the files have been properly installed on your system. Each operating system will have a slightly different install procedure so please follow the section for your operating system below.

Windows (XP/Vista/7)

Upon installation Coden will perform multiple operations:

  1. Create a program directory entry for Ephere at Windows user AppData directory. For example: C:\Users\USERNAME\AppData\Local\Ephere

    This directory might be different if you change it as option during installation.

  2. Add an "EPHERE" environment variable that contains program directory as its value.

  1. Put the following Coden-related .dll's into the program directory directory:
    • Ephere.Modeling.dll
    • Ephere.Modeling.Dependency.dll
    • Ephere.Plugins.Coden.dll
    These three libraries are the heart of Coden and must be present for Coden to function properly
  2. Install any adapters that you select during installation. Following links will help you to verify that each adapter was installed properly:
    • 3dsmax 3ds max
    • Maya Maya
    • XSI XSI
    • Houdini Houdini
    • Photoshop Photoshop


Error Logs

Error logging

To assist you in developing your Coden tools a set of log files are written out during Coden usage. Depending on the installation, these files can be found inside <LocalAppData>\Ephere\Library\logs directory.

Most interesting is the Coden.log file, which records all activity of your Coden plugins including any unhandled exceptions. You may find other log files in this directory. These logs reflect operations of other components of Coden and as such are of less interest.

Writing to the log

There are a few ways to output messages to the log file. You may find these useful to track and display extra information from inside your plugin for debugging or informative purposes. If your clients experience issues with your tools you may ask them to collect the Coden.log file and send it to you for analysis. Consider the following example:

// System.Diagnostics namespace contains methods useful for logging
using System.Diagnostics;

namespace MyPlugins
{
    public static partial class Commands
    {
        public static bool MyCommand()
        {
            // Writes a message to the host application's UI and logs it to Coden.log
            Trace.TraceInformation( "Some useful message" );

            // Writes a warning message to the host application's UI and logs it to Coden.log
            Trace.TraceWarning( "This is a warning" );

            // Writes an error message to the host application's UI and logs it to Coden.log
            int myNumber = 1;
            Trace.TraceError( string.Format( "An error has occurred: {0}", myNumber ) );

            return true;
        }
    }
}

We first include the System.Diagnostics namespace to be able to reference the Trace class. We are then able to use the TraceInformation, TraceWarning, and TraceError methods, depending on the current need, to log the appropriate information. This information will be presented to the user inside the current host application's GUI and also written to Coden.log file for reference.


Ephere | Registration

At Ephere, we greatly value your time, opinions, and privacy. To allow us to serve you better please provide some information about yourself.

Fill in as many fields as you can. Fields with an asterisk (*) are required. Upon completion you will be sent an email to activate your account. After you receive the email follow the instructions within it to complete your registration process.


Coden Downloads

Note to customers: please log in for your download
You need to register and log in to download files for this project.


Downloads

Error: Project does not exist or is not accessible to you
Note to customers: please log in for your download
You need to register and log in to download files for this project.