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 subfolder. OpenFlipper distinguishes between 32/64-bit plugin versions and max or dbg (release/debug) versions. So the compiled plugins have to reside in the right subdir of Plugins. The Plugins are loaded on startup of the application (they may also be loaded at runtime later).

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 dont have to implement all functions or signals of the interfaces you include. This has only to be done for the BaseInterface which must be implemented by every plugin. See the BaseInterface Documentation for details.

Unimplemented functions will be left unconnected from the core and wont 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 name and the description of the plugin is exported via the baseinterface. The initialization of each plugin is done via this interface too. See Dataflow for an overview of OpenFlipper's data flow and interface function calls.

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

Handling geometry data within a plugin

Adding and removing mesh objects in OpenFlipper

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, slot

LoadSaveInterface::openedFile (int _id) is called.

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.

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.

For example iterating over all objects that have been marked as source objects is done via

for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::SOURCE_OBJECTS);
o_it != PluginFunctions::objectsEnd(); ++o_it) { ... }

Possible restrictions are ALL_OBJECTS (to iterate over all objects in the scene), TARGET_OBJECTS (objects that were marked as target) and SOURCE_OBJECTS.

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

o_it->dataType(DATA_TYPE)

where o_it is an object iterator and DATA_TYPE is one of the data types specified in OpenFlipper/common/Types.hh. o_it->dataType(DATA_TRIANGLE_MESH) for example will return true if the object is a triangle 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);

where o_it once again is our object iterator. See PluginFunctions for a complete overview.

Updating objects

Once your plugin has manipulated object data we have to inform OpenFlipper's core about the changes. When doing this, OpenFlipper distinguishes between four fundamental types of changes:

When changing geometry, OpenFlipper's core will be forced to redraw the object that has been changed by emitting signal

BaseInterface::updatedObject(int _id)

where _id is the object's id.

When changing object properties it won't be necessary to redraw the scene since it can be expensive in computation power. In this case, one should emit

BaseInterface::objectPropertiesChanged(int _id)

where _id once again is the object's id.

If a plugin changed an object's visibility (hide, show), it should emit

BaseInterface::visibilityChanged(int _id)

for the core to update the visibility state of object with identifier _id.

Last, when changing an object's selection, it will be updated by emitting

BaseInterface::objectSelectionChanged(int _id)

where _id as in the examples above is the object's identifier.

Also see BaseInterface.

pages

Programming examples for OpenFlipper plugins Programming examples for OpenFlipper plugins Plugin Interfaces Plugin Interfaces


acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .