Developer Documentation
Plugin Programming

Quick references

Tutorials

Plugin Basics

As mentioned above OpenFlipper is a plugin based system. It uses the QT plugin implementation to load and unload plugins at runtime. Every algorithm should be added as one of these plugins.

The plugins have to be created as .so (or under windows : .dll) files which should be symlinked or copied to the Plugin sub folder. The cmake build system automatically places the plugins in the right folders on all supported platforms. The Plugins are then loaded on startup of the core application (they may also be loaded at runtime later).

OpenFlipper Startup and Plugin Initialization

The plugins are initialized as shown in the following flow diagram:

OpenFlipperStartup.png

Details of the startup process can be found here: Plugin Initialization

Plugin Programming

The interface between the core and the plugins is managed via simple interfaces based on the signal/slot metaphor of QT. Your plugins have to be derived from these interfaces. You don't have to implement all functions or signals of the interfaces you include. The BaseInterface has to be included in every plugin. See the BaseInterface Documentation for details.

Unimplemented functions will be left unconnected from the core and won't have any impact on the applications speed or stability. As stated above, every plugin has to be derived from the BaseInterface. This is the basic factory which makes the core aware of the plugin. The BaseInterface::name() and the BaseInterface::description() of the plugin is exported via the BaseInterface. The initialization of each plugin is done via this interface too. See Plugin Initialization for an overview of OpenFlipper's startup and initialization calls.

After this interface of the plugin is successfully processed all other interfaces will be initialized and connected to the core. For details about the individual interfaces see the Plugin Interfaces Documentation.

Handling geometry data within a plugin

Adding empty objects to the scene

To add empty objects to the scene, you have to use the LoadSaveInterface. The details are shown in the following example: Adding empty Objects in a plugin.

Loading data from files in OpenFlipper

Usually the user loads existing data via the Load Entry in the File menu. Nevertheless it is possible to load data from within a plugin( although it is not recommended).

If you want to load geometry data from a file or simply add objects to the scene from within a plugin, it has to implement the Load/Save Interface.

LoadSaveInterface::load( QString _file, DataType _type, int& _id) tries to load file with file name _file of type _type, _id contains the new created object's id or -1 if loading failed. OpenFlipper will then create all the necessary scene graph nodes such that the developer generally does not need to know in detail how to create and add the required nodes to the scene.

Otherwise if a file has been loaded externally, the slot LoadSaveInterface::openedFile (int _id) is called.

Removing data from the scene

When removing objects from the scene, the plugin simply has to emit signal
LoadSaveInterface::deleteObject(int _id)
or
LoadSaveInterface::deleteAllObjects() in order to clear the scene.

Getting and enumerating objects in the scene

Iterating over all objects is managed via the ObjectIterator.

See Iterators and their usage for details.

Another way to get handles to scene objects is to use the functions PluginFunctions::getObject() or PluginFunctions::getPickedObject(). These functions provide a pointer to either a BaseObjectData or BaseObject object. As in Implementing a mesh smoother plugin one can easily test the type of an object by calling:

// If you have a BaseObjectData or BaseObject pointer
DataType typeA = object->dataType()
// with an object iterator
DataType typeB = o_it->dataType()

There are also boolean function where you can check for a specific type:

// If you have a BaseObjectData or BaseObject pointer
bool isTriangleMesh = object->dataType(DATA_TRIANGLE_MESH)
// with an object iterator
bool isPolyMesh = o_it->dataType(DATA_POLY_MESH)

The mesh data itself can be obtained by calling the appropriate handle plugin function. For example if we consider a triangle mesh, we get a handle to the mesh itself by calling

TriMesh* mesh = PluginFunctions::triMesh(*o_it);

See PluginFunctions for a complete overview.

OpenFlipper's plugin functions

As a plugin in most cases operates on geometry data, developers might want to know how to gain access to mesh data from within a plugin. In our tutorial Implementing a mesh smoother plugin we roughly mentioned that the communication between OpenFlipper and it's plugins is accomplished through either one of the provided Plugin Interfaces or the PluginFunctions.

Modifying Objects in OpenFlipper

In the previous section we got objects from OpenFlippers object management system. These objects directly contain data in their original data structure (e.g. a pointer to an OpenMesh). In your plugin you can modify this data directly in the data structure. For a mesh, you can for example add new faces or remove faces,... . After you modified data, you have to inform OpenFlippers core system (and thereby the other plugins) what you did.

This information system is implemented in the BaseInterface. Additional information can be found here: Object Update Notification

Updating the current view

If you modified an object and informed the core that the object has changed, the scene will be automatically redrawn. A more detailed description can be found in the BaseInterface: Scene Update Notifications

Related pages