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).
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
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::deleteAllObjects() in order to clear the scene.
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
Possible restrictions are
ALL_OBJECTS (to iterate over all objects in the scene),
TARGET_OBJECTS (objects that were marked as target) and
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 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);
o_it once again is our object iterator. See PluginFunctions for a complete overview.
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
_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
_id once again is the object's id.
If a plugin changed an object's visibility (hide, show), it should emit
for the core to update the visibility state of object with identifier
Last, when changing an object's selection, it will be updated by emitting
_id as in the examples above is the object's identifier.
Also see BaseInterface.