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).
The plugins are initialized as shown in the following flow diagram:
Details of the startup process can be found here: Plugin Initialization
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.
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.
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:
There are also boolean function where you can check for a specific type:
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
See PluginFunctions for a complete overview.
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.
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.
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