Writing 3D Plugins

How do I create a generator plugin?

A generator plugin is based on ObjectData and must implement ObjectData::GetVirtualObjects(). A spline generator must implement ObjectData::GetContour().

See also Generating.

How do I create a modifier/deformer plugin?

A generator plugin is based on ObjectData and must implement ObjectData::ModifyObject().

How do I create tools to edit the 3D scene or a 3D object?

Interactive tools to edit the 3D scene are based on ToolData and DescriptionToolData.

Editing the 3D Scene

How is the active document edited?

The active document can be obtained with GetActiveDocument(). It must only be edited from the main thread in the context of user interaction. After the document was edited, one must call EventAdd() to update the GUI (viewport, managers). See BaseDocument Manual.

Note that in certain versions (command line, team render client) there is no active document.

How can I detect changes to the active document?

After any change to the active document, EventAdd() should be called. This will add an event to the event queue. The event is EVMSG_CHANGE and can be detected either in a GeDialog or a MessageData plugin.

How do I edit parameters?

C4DAtom is the base class of most scene elements. It provides C4DAtom::GetParameter() and C4DAtom::SetParameter() to access the parameters of an element.

For each class there is typically a corresponding header file. E.g. for Ocube objects there is ocube.h and for the base class BaseObject (Obase) there is obase. These header files contain the parameter IDs. The parameter ID symbol can also be obtained by dragging parameter from the Attribute Manager onto the Python logger in the "Console" window.

For certain tasks (animation, takes) it is needed to use the full DescID which includes the parameter ID as well as the parameter type.

See C4DAtom Manual and DescID Manual.

What are generators and how do they work?

Generators create "virtual" objects that are stored in a cache. See Cache.

A custom generator can be created by implementing an ObjectData based plugin. See also How do I create a generator plugin?.

What are deformers and how do they work?

A deformer is an object that modifies the geometry of a given other object. The result of that deformation is stored in the deformed cache, see Cache. See also How do I create a modifier/deformer plugin?.

How does a document handle assets?

Objects, tags, materials and shaders can reference files on disc. To collect all these references one can use special functions on the BaseDocument. See Convert and Export.

How are scene objects identified?

A scene object can either be identified using its position in the object tree or using a unique GeMarker. See GeMarker Manual.

How do priorities in scenes work?

When a scene is evaluated, different functions are executed at different stages. The execution of some tags can be configured using a "Priority" parameter.

IK tags are a special case, they are evaluated twice, one time after the animation and one time after the expression. Dynamics have a priority of Generator + 400, this mean any object's will need to have a priority set at generator + 401 to execute after the dynamics. Hair is also a special case, the priority level is at Generator + 1. About Neutron, the execution of the node graph is determined by the graph's connections, there's no priorities. Capsule are managed by the classic system. They are treated as Generators/Deformers. Tag can have different priorities defined, the constrain tag for example have different priorities set internally for the PSR and target options. Since R25, the options' order in the list respect the order of execution.

See Scene Execution Pipeline and Thread.

How does the Undo system work?

A BaseDocument stores undo-steps. Such an undo-step can stores multiple operations like the change of a parameter or the creation of an object. See Undo System Manual.

How are references to scene elements are stored?

A reference to a scene object must be stored as a BaseLink object. Only with such a BaseLink object it is save to obtain the object even after undo-operations were executed. See BaseLink Manual.

How do scene hooks work?

A scene hook is an object attached to every BaseDocument. It can be used to store arbitrary data, to draw in the viewport or to execute code in the scene execution pipeline. Custom scene hooks are based on SceneHookData.


How does the render pipeline work?

The first step of the rendering pipeline is to execute the current frame of the given BaseDocument. Based on the result of that execution a VolumeData object is created. This VolumeData object represents the final scene and gives access to all objects in form of RayObject elements. Custom video post effects that are executed during or after rendering are based on VideoPostData.

How are multipasses handled?

Multipasses are defined in the render settings. They are represented as MultipassObject elements. See RenderData Manual and MultipassObject Manual.

Within the rendering pipeline multipasses are created and accessed with the Render class.

BaseVolumeData::multipass gives access to a Multipass object that is used by materials and shaders to write into a given multipass.

How do I implement a custom renderer?

A custom renderer can be based on VideoPostData. The plugin class must be registered with PLUGINFLAG_VIDEOPOST_ISRENDERER.

Why do custom lenses not work with post effects?

Custom lenses (VideoPostData::CreateRay()) define the ray to trace a given scene. So the effects of such a custom lens only applies to ray-tracing.

Many post effects like Hair or Sketch&Toon are based on 2D projections using the projection matrix. They cannot pay attention to the effect of custom lenses.