\hypertarget{a00232_quickref_plugin_programming}{}\section{Quick references}\label{a00232_quickref_plugin_programming}

\begin{DoxyItemize}
\item \hyperlink{a00232_plugin_sec}{Plugin Basics}
\item \hyperlink{a00232_plugin_startup}{Open\+Flipper Startup and Plugin Initialization}
\item \hyperlink{a00232_plugin_prog_sec}{Plugin Programming}
\item \hyperlink{a00232_plugin_prog_geometryData}{Handling geometry data within a plugin}
\begin{DoxyItemize}
\item \hyperlink{a00232_addingEmptyObjects}{Adding empty objects to the scene}
\item \hyperlink{a00232_LoadingExistingObjects}{Loading data from files in Open\+Flipper}
\item \hyperlink{a00232_RemovingObjectsFromScene}{Removing data from the scene}
\end{DoxyItemize}
\item \hyperlink{a00232_modifyingObjects}{Modifying Objects in Open\+Flipper} 
\end{DoxyItemize}\hypertarget{a00232_tuts}{}\section{Tutorials}\label{a00232_tuts}

\begin{DoxyItemize}
\item \hyperlink{ex1}{A simple plugin}
\item \hyperlink{a00238_ex1c}{How to build the plugin with C\+Make}
\item \hyperlink{ex2}{Implementing a mesh smoother plugin}
\item \hyperlink{ex3}{Implementing mouse and keyboard interaction}
\item \hyperlink{tutorial_thread}{Using threads from within a plugin}
\end{DoxyItemize}\hypertarget{a00232_plugin_sec}{}\section{Plugin Basics}\label{a00232_plugin_sec}
As mentioned above Open\+Flipper is a plugin based system. It uses the Q\+T 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).\hypertarget{a00232_plugin_startup}{}\section{Open\+Flipper Startup and Plugin Initialization}\label{a00232_plugin_startup}
The plugins are initialized as shown in the following flow diagram\+:



Details of the startup process can be found here\+: \hyperlink{a00138_baseInterfacePluginInitialization}{Plugin Initialization}\hypertarget{a00232_plugin_prog_sec}{}\section{Plugin Programming}\label{a00232_plugin_prog_sec}
The interface between the core and the plugins is managed via simple interfaces based on the signal/slot metaphor of Q\+T. 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 \hyperlink{a00322}{Base\+Interface} has to be included in every plugin. See the \hyperlink{baseInterfacePage}{Base\+Interface 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 \hyperlink{a00322}{Base\+Interface}. This is the basic factory which makes the core aware of the plugin. The \hyperlink{a00322_a2b351aa6ef0eb368bce735e243235958}{Base\+Interface\+::name()} and the \hyperlink{a00322_a43f0d3612695b53c848c14f48fea9a7a}{Base\+Interface\+::description()} of the plugin is exported via the \hyperlink{a00322}{Base\+Interface}. The initialization of each plugin is done via this interface too. See \hyperlink{a00138_baseInterfacePluginInitialization}{Plugin Initialization} for an overview of Open\+Flipper'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 \hyperlink{interfaces}{Plugin Interfaces Documentation}.\hypertarget{a00232_plugin_prog_geometryData}{}\section{Handling geometry data within a plugin}\label{a00232_plugin_prog_geometryData}
\hypertarget{a00232_addingEmptyObjects}{}\subsection{Adding empty objects to the scene}\label{a00232_addingEmptyObjects}
To add empty objects to the scene, you have to use the \hyperlink{a00778}{Load\+Save\+Interface}. The details are shown in the following example\+: \hyperlink{adding_empty_objects}{Adding empty Objects in a plugin}.\hypertarget{a00232_LoadingExistingObjects}{}\subsection{Loading data from files in Open\+Flipper}\label{a00232_LoadingExistingObjects}
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 \hyperlink{loadSaveInterfacePage}{Load/\+Save Interface}.

\hyperlink{a00778_a152541b680116d103397e2c2a92d049e}{Load\+Save\+Interface\+::load(        Q\+String \+\_\+file, Data\+Type \+\_\+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. Open\+Flipper 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 Load\+Save\+Interface\+::opened\+File (int \+\_\+id) is called.\hypertarget{a00232_RemovingObjectsFromScene}{}\subsection{Removing data from the scene}\label{a00232_RemovingObjectsFromScene}
When removing objects from the scene, the plugin simply has to emit signal~\newline
 \hyperlink{a00778_a6c5ae74820943d0a571ca6e8b85a69cc}{Load\+Save\+Interface\+::delete\+Object(int \+\_\+id)}~\newline
or ~\newline
 \hyperlink{a00778_afb361d8553ecfb0ad373d505c2de4ba7}{Load\+Save\+Interface\+::delete\+All\+Objects()} in order to clear the scene.\hypertarget{a00232_GettingObjectsFromScene}{}\subsection{Getting and enumerating objects in the scene}\label{a00232_GettingObjectsFromScene}
Iterating over all objects is managed via the Object\+Iterator.


\begin{DoxyCode}
\textcolor{keywordflow}{for} ( \hyperlink{a00895}{PluginFunctions::ObjectIterator} o\_it(
      \hyperlink{a03393_a997c364a51707ba883ee346bc38bcea4}{PluginFunctions::SOURCE\_OBJECTS});<br />
o\_it != \hyperlink{a03393_a25c8015c612b1aaf3a840ca072ce68ca}{PluginFunctions::objectsEnd}(); ++o\_it) \{ ... \}
\end{DoxyCode}


See \hyperlink{OpenFlipperIterators}{Iterators and their usage} for details.

Another way to get handles to scene objects is to use the functions {\ttfamily \hyperlink{a03393_ac20ce4f5c004657788cc10f4ad465de0}{Plugin\+Functions\+::get\+Object()}} or \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{Plugin\+Functions\+::get\+Picked\+Object()}. These functions provide a pointer to either a \hyperlink{a00330}{Base\+Object\+Data} or \hyperlink{a00329}{Base\+Object} object. As in \hyperlink{ex2}{Implementing a mesh smoother plugin} one can easily test the type of an object by calling\+:


\begin{DoxyCode}
\textcolor{comment}{// If you have a BaseObjectData or BaseObject pointer}
\hyperlink{a00477}{DataType} typeA =  \textcolor{keywordtype}{object}->dataType()

\textcolor{comment}{// with an object iterator}
\hyperlink{a00477}{DataType} typeB =  o\_it->dataType()
\end{DoxyCode}


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


\begin{DoxyCode}
\textcolor{comment}{// If you have a BaseObjectData or BaseObject pointer}
\textcolor{keywordtype}{bool} isTriangleMesh =  \textcolor{keywordtype}{object}->dataType(\hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH})

\textcolor{comment}{// with an object iterator}
\textcolor{keywordtype}{bool} isPolyMesh =  o\_it->dataType(\hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH})
\end{DoxyCode}


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


\begin{DoxyCode}
TriMesh* mesh = \hyperlink{a03393_a11d22dc1c64537f87c014241cacc4340}{PluginFunctions::triMesh}(*o\_it);
\end{DoxyCode}


See \hyperlink{a03393}{Plugin\+Functions} for a complete overview.\hypertarget{a00232_pluginFunctions}{}\subsection{Open\+Flipper's plugin functions}\label{a00232_pluginFunctions}
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 \hyperlink{ex2}{Implementing a mesh smoother plugin} we roughly mentioned that the communication between Open\+Flipper and it's plugins is accomplished through either one of the provided \hyperlink{interfaces}{Plugin Interfaces} or the \hyperlink{a03393}{Plugin\+Functions}.\hypertarget{a00232_modifyingObjects}{}\section{Modifying Objects in Open\+Flipper}\label{a00232_modifyingObjects}
In the previous section we got objects from Open\+Flippers object management system. These objects directly contain data in their original data structure (e.\+g. a pointer to an \hyperlink{a03368}{Open\+Mesh}). 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 Open\+Flippers core system (and thereby the other plugins) what you did.

This information system is implemented in the \hyperlink{a00322}{Base\+Interface}. Additional information can be found here\+: \hyperlink{a00138_baseInterfaceObjectUpdateNotification}{Object Update Notification}\hypertarget{a00232_sceneUpdate}{}\section{Updating the current view}\label{a00232_sceneUpdate}
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 \hyperlink{a00322}{Base\+Interface}\+: \hyperlink{a00138_baseInterfaceSceneUpdateNotification}{Scene Update Notifications}\hypertarget{a00232_pluginProgramming_related_pages}{}\section{Related pages}\label{a00232_pluginProgramming_related_pages}

\begin{DoxyItemize}
\item \hyperlink{pluginExamples}{Programming examples for Open\+Flipper plugins}
\item \hyperlink{interfaces}{Plugin Interfaces}
\item \hyperlink{objectDataStructure}{Object Data Structures}
\item \hyperlink{OpenFlipperSceneGraph}{Open\+Flipper Scene\+Graph}
\item \hyperlink{OpenFlipperIterators}{Iterators and their usage}
\item \hyperlink{perObjectDataPage}{Per Object Data}
\item \hyperlink{adding_empty_objects}{Adding empty Objects in a plugin} 
\end{DoxyItemize}\hypertarget{pluginExamples}{}\section{Programming examples for Open\+Flipper plugins}\label{pluginExamples}

\begin{DoxyItemize}
\item \hyperlink{ex1}{A simple Plugin}
\item \hyperlink{ex2}{Implementing a mesh smoother plugin}
\item \hyperlink{ex3}{Implementing mouse and keyboard interaction}
\item \hyperlink{tutorial_thread}{Using threads from within a plugin} 
\end{DoxyItemize}\hypertarget{ex1}{}\subsection{A simple plugin}\label{ex1}
In this tutorial we are going to build our own Open\+Flipper plugin step by step. The goal of this tutorial is to build a simple plugin that is loaded by Open\+Flipper at launch.

We start by creating the plugin directory in Open\+Flipper's root directory, naming it e.\+g. {\ttfamily Plugin-\/\+Simple\+Plugin}. The interface definition should contain the following header includes\+:

 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <\hyperlink{a02437}{OpenFlipper/BasePlugin/BaseInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02511}{OpenFlipper/common/Types.hh}>}

\end{DoxyCodeInclude}


As we know the plugin class has to be derived from at least {\ttfamily \hyperlink{a00322}{Base\+Interface}}, the class definition will look like\+:

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{class }\hyperlink{a01178}{SimplePlugin} : \textcolor{keyword}{public} QObject, \hyperlink{a00322}{BaseInterface}

\end{DoxyCodeInclude}


(Since we implement a Qt-\/class, our base object is Q\+Object which provides some basic functionality and type definitions.) We then use the macros {\ttfamily Q\+\_\+\+O\+B\+J\+E\+C\+T} and {\ttfamily Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S} in order to make accessible the signals and slots which have to be overridden later on. See \hyperlink{a00322}{Base\+Interface} documentation for signals and slots that can be overriden.

 
\begin{DoxyCodeInclude}
Q\_OBJECT
Q\_INTERFACES(\hyperlink{a00322}{BaseInterface})

\end{DoxyCodeInclude}


For now, the only thing we override from our base class is {\ttfamily name()} and {\ttfamily description()} which each returns the name and description of our plugin, respectively. The override of these two functions is mandatory, all other slots/signals are optional. Each of the functions returns a Q\+String (see Qt documentation for information on Qt types).

 
\begin{DoxyCodeInclude}
  QString \hyperlink{a01178_a37d0aaa86a289cba0daadb8ff375d795}{name}() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"SimplePlugin"}); \};
  QString \hyperlink{a01178_ad40b437817dc50a20e424760ebd8163b}{description}() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"Does actually nothing but works!"}); \};

\end{DoxyCodeInclude}


If you made it to this point, don't give up, we're almost there! Looks like this is it for the interface definition. We're now considering our implementation which consists of only a few lines. (Since we don't want to implement any functionality at this point).

The implementation only contains the macro

 
\begin{DoxyCodeInclude}
Q\_EXPORT\_PLUGIN2( simplePlugin , \hyperlink{a01178}{SimplePlugin} );

\end{DoxyCodeInclude}


which exports the plugin class {\ttfamily \hyperlink{a01178}{Simple\+Plugin}} with the name {\ttfamily simple\+Plugin} (note that our class name is with a capital s whereas the export name is lower case). An important constraint is that the export name has to be unique (in case there exist multiple plugins).

The complete source code of the plugin looks like this\+:

\hyperlink{a02550_source}{simple\+Plugin.\+hh} 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#ifndef SIMPLEPLUGIN\_HH\_INCLUDED}
\textcolor{preprocessor}{#define SIMPLEPLUGIN\_HH\_INCLUDED}

\textcolor{preprocessor}{#include <\hyperlink{a02437}{OpenFlipper/BasePlugin/BaseInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02511}{OpenFlipper/common/Types.hh}>}

\textcolor{keyword}{class }\hyperlink{a01178}{SimplePlugin} : \textcolor{keyword}{public} QObject, \hyperlink{a00322}{BaseInterface}
\{
Q\_OBJECT
Q\_INTERFACES(\hyperlink{a00322}{BaseInterface})

public :
  
  ~\hyperlink{a01178}{SimplePlugin}() \{\};
  
  QString \hyperlink{a01178_a37d0aaa86a289cba0daadb8ff375d795}{name}() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"SimplePlugin"}); \};
  
  QString \hyperlink{a01178_ad40b437817dc50a20e424760ebd8163b}{description}() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"Does actually nothing but works!"}); \};
  
\};


\textcolor{preprocessor}{#endif}
\end{DoxyCodeInclude}


\hyperlink{a02549_source}{simple\+Plugin.\+cc} 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include "simplePlugin.hh"}
\textcolor{preprocessor}{#include "\hyperlink{a02452}{OpenFlipper/BasePlugin/PluginFunctions.hh}"}

Q\_EXPORT\_PLUGIN2( simplePlugin , \hyperlink{a01178}{SimplePlugin} );
\end{DoxyCodeInclude}
\hypertarget{a00238_ex1c}{}\subsubsection{How to build the plugin with C\+Make}\label{a00238_ex1c}
The only thing that's still left to be created is our cmake project file that is used to generate the Makefiles for the plugin. This step is very easy, so let's start. In your plugin's root directory create a C\+Make\+Lists.\+txt file.

Our first line includes Open\+Flipper's predefined cmake plugin functions. This allows us to simply call the {\ttfamily openflipper\+\_\+plugin()} macro in order to build our code as a plugin. Our project file then looks like this\+:

C\+Make\+Lists.\+txt 
\begin{DoxyCodeInclude}
include (plugin)
openflipper\_plugin ()
\end{DoxyCodeInclude}


Note that you have several options that can be passed to the openflipper\+\_\+plugin() function, see \hyperlink{a00194_cmake_plugin}{Building Open\+Flipper Plugins with C\+Make} for details. For our example project we just have to leave this line as it is.

Now, when building Open\+Flipper with cmake, your plugin should be found and built automatically.

To test if our plugin has been successfully loaded, we launch Open\+Flipper and select {\ttfamily Plugins-\/$>$Unload} {\ttfamily Plugin}. If our plugin {\ttfamily \hyperlink{a01178}{Simple\+Plugin}} is listed, everything is fine. If it's not listed, read Open\+Flippers log to see what went wrong.

See \hyperlink{dataFlow}{Dataflow} for further information on interface function calls. \hypertarget{ex2}{}\subsection{Implementing a mesh smoother plugin}\label{ex2}
The last tutorial dealt with the implementation of a first plugin without any functionality at all. This tutorial will show you how to progam a simple mesh smoother. We are assuming that you have read \hyperlink{ex1}{A simple plugin} and will only explain parts that have to be added in order to include new functionality.\hypertarget{a00240_ex2Header}{}\subsubsection{Definition of the header}\label{a00240_ex2Header}
To start off we first have to add two additional header files. The first one is the {\ttfamily \hyperlink{a01311}{Toolbox\+Interface}}. We need this interface because we want to add a Toolbox to our plugin in order to be able to set parameters. Additionally, we want to use the {\ttfamily \hyperlink{a00784}{Logging\+Interface}} so that we can inform the user of our plugin when something went wrong.

 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <\hyperlink{a02472}{OpenFlipper/BasePlugin/ToolboxInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02444}{OpenFlipper/BasePlugin/LoggingInterface.hh}>}

\end{DoxyCodeInclude}


In order to work with the Interfaces we have to define that the plugin will implement the additional interfaces. The class definition then looks as follows\+:

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{class }\hyperlink{a01204}{SmootherPlugin} : \textcolor{keyword}{public} QObject, \hyperlink{a00322}{BaseInterface}, 
      \hyperlink{a01311}{ToolboxInterface}, \hyperlink{a00784}{LoggingInterface}

\end{DoxyCodeInclude}


Furthermore we have to insert the {\ttfamily Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S} macro. This makes the signals and slots from both interfaces available.

 
\begin{DoxyCodeInclude}
  Q\_INTERFACES(\hyperlink{a01311}{ToolboxInterface})
  Q\_INTERFACES(\hyperlink{a00784}{LoggingInterface})

\end{DoxyCodeInclude}


Now that we have defined which Interfaces to implement, we can look at which signals and slots we want to implement. Firstly, we need two additional signals from the {\ttfamily \hyperlink{a00322}{Base\+Interface}} \+:

 
\begin{DoxyCodeInclude}
    \textcolor{keywordtype}{void} updateView();
    \textcolor{keywordtype}{void} updatedObject(\textcolor{keywordtype}{int} \_identifier, \textcolor{keyword}{const} \hyperlink{a01393}{UpdateType}& \_type);

\end{DoxyCodeInclude}


The first signal update\+View() is emitted when we have finished computing the smoothed mesh. The signal tells Open\+Flipper to redraw its viewer(s). The second signal updated\+Objects() is emitted to inform all other plugins that an object has changed and therfore allows each plugin to react on this change.

Since we also want to use the {\ttfamily \hyperlink{a00784}{Logging\+Interface}} we have to define the following signals which allow us to send log messages to the Open\+Flipper Loggers.

 
\begin{DoxyCodeInclude}
    \textcolor{keywordtype}{void} log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7c}{Logtype} \_type, QString \_message);
    \textcolor{keywordtype}{void} log(QString \_message);

\end{DoxyCodeInclude}


The last Interface that's left over is the {\ttfamily \hyperlink{a01311}{Toolbox\+Interface}} from which we are only implementing one signal\+:

 
\begin{DoxyCodeInclude}
    \textcolor{keywordtype}{void} addToolbox( QString \_name, QWidget* \_widget );

\end{DoxyCodeInclude}


As we will see later, this function is used to add a Tool\+Box (i.\+e. a {\ttfamily Q\+Widget} ) to the Open\+Flipper user interface.

As a last step we have to add to include additional class members to control the parameter for the smoothing and to actually compute the smoothed mesh.

 
\begin{DoxyCodeInclude}
   \textcolor{keyword}{private}:

    QSpinBox* \hyperlink{a01204_ae8739b32abce7aed26946c4c162c43e9}{iterationsSpinbox\_};

   \textcolor{keyword}{private} slots:

    \textcolor{comment}{// BaseInterface}
    \textcolor{keywordtype}{void} initializePlugin();


    \textcolor{keywordtype}{void} \hyperlink{a01204_aa1921cbedff24c0b01d45a9890af5c84}{simpleLaplace}();

\end{DoxyCodeInclude}


That's it for the header of the plugin. The complete header looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#ifndef SMOOTHERPLUGIN\_HH}
\textcolor{preprocessor}{#define SMOOTHERPLUGIN\_HH}

\textcolor{preprocessor}{#include <\hyperlink{a02437}{OpenFlipper/BasePlugin/BaseInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02472}{OpenFlipper/BasePlugin/ToolboxInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02444}{OpenFlipper/BasePlugin/LoggingInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02511}{OpenFlipper/common/Types.hh}>}

\textcolor{keyword}{class }\hyperlink{a01204}{SmootherPlugin} : \textcolor{keyword}{public} QObject, \hyperlink{a00322}{BaseInterface}, 
      \hyperlink{a01311}{ToolboxInterface}, \hyperlink{a00784}{LoggingInterface}
\{
  Q\_OBJECT
  Q\_INTERFACES(\hyperlink{a00322}{BaseInterface})
  Q\_INTERFACES(\hyperlink{a01311}{ToolboxInterface})
  Q\_INTERFACES(\hyperlink{a00784}{LoggingInterface})

  signals:
    \textcolor{comment}{//BaseInterface}
    \textcolor{keywordtype}{void} updateView();
    \textcolor{keywordtype}{void} updatedObject(\textcolor{keywordtype}{int} \_identifier, const \hyperlink{a01393}{UpdateType}& \_type);

    \textcolor{comment}{//LoggingInterface}
    \textcolor{keywordtype}{void} log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7c}{Logtype} \_type, QString \_message);
    \textcolor{keywordtype}{void} log(QString \_message);

    \textcolor{comment}{// ToolboxInterface}
    \textcolor{keywordtype}{void} addToolbox( QString \_name, QWidget* \_widget );

  public:

    \hyperlink{a01204}{SmootherPlugin}();

    \textcolor{comment}{// BaseInterface}
    QString \hyperlink{a01204_a47e0b61cc8695c3cd5e1abdd62ab0d69}{name}() \{ \textcolor{keywordflow}{return} (QString(\textcolor{stringliteral}{"Simple Smoother"})); \};
    QString \hyperlink{a01204_a563f0454d1b416932c46a9288db2f57e}{description}( ) \{ \textcolor{keywordflow}{return} (QString(\textcolor{stringliteral}{"Smooths the active Mesh"})); \};

   \textcolor{keyword}{private}:

    QSpinBox* \hyperlink{a01204_ae8739b32abce7aed26946c4c162c43e9}{iterationsSpinbox\_};

   \textcolor{keyword}{private} slots:

    \textcolor{comment}{// BaseInterface}
    \textcolor{keywordtype}{void} initializePlugin();


    \textcolor{keywordtype}{void} \hyperlink{a01204_aa1921cbedff24c0b01d45a9890af5c84}{simpleLaplace}();

   \textcolor{keyword}{public} slots:
      QString version() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"1.0"}); \};
\};

\textcolor{preprocessor}{#endif //SMOOTHERPLUGIN\_HH}
\end{DoxyCodeInclude}
\hypertarget{a00240_ex2Implemenation1}{}\subsubsection{Implemention of the G\+U\+I}\label{a00240_ex2Implemenation1}
As we have already mentioned in \hyperlink{a00240_ex2Header}{Definition of the header}, the tool box is generated inside the plugins\+Initialized() function and then added by the add\+Toolbox() signal passing a reference to our toolbox. So we begin by creating the elements of the Tool\+Box\+:

 
\begin{DoxyCodeInclude}
  QWidget* toolBox = \textcolor{keyword}{new} QWidget();

  QPushButton* smoothButton = \textcolor{keyword}{new} QPushButton(\textcolor{stringliteral}{"&Smooth"}, toolBox);

  iterationsSpinbox\_ = \textcolor{keyword}{new} QSpinBox(toolBox);
  iterationsSpinbox\_->setMinimum(1);
  iterationsSpinbox\_->setMaximum(1000);
  iterationsSpinbox\_->setSingleStep(1);

  QLabel* label = \textcolor{keyword}{new} QLabel(\textcolor{stringliteral}{"Iterations:"});

\end{DoxyCodeInclude}


Later, the smooth\+Button is used to start the mesh smoothing and the iterations\+Spinbox\+\_\+ allows the user to control the number of smoothing iterations that should be performed.

The created Toolbox elements are then combined into a Layout

 
\begin{DoxyCodeInclude}
  QGridLayout* layout = \textcolor{keyword}{new} QGridLayout(toolBox);

\end{DoxyCodeInclude}


Here, the Spacer\+Item, which is added last, only helps aligning the elements at the top of the toolbox.

We have to connect the smooth\+Button to the simple\+Laplace() slot of our class, so that after clicking the button the slot is called. Finally, when the tool box has been entirely created, we emit the signal to add the tool box to Open\+Flipper\+:

 
\begin{DoxyCodeInclude}
  connect(smoothButton, SIGNAL(clicked()), \textcolor{keyword}{this}, SLOT(simpleLaplace()));

\end{DoxyCodeInclude}
\hypertarget{a00240_ex2Implemenation2}{}\subsubsection{Implemention of the Smoother}\label{a00240_ex2Implemenation2}
Now that the Toolbox is completely setup, we can start implementing the smoother. We begin with searching objects on which we have to compute the smoothing. The algorithm takes all objects marked as target and tries to apply the smoothing.

To find all these Objects we use an Object\+Iterator. This iterator can be found in the \hyperlink{a03393}{Plugin\+Functions}. Every communication between Open\+Flipper and its Plugins is accomplished through either an interface or the \hyperlink{a03393}{Plugin\+Functions}. So these are the places to look for if you want to add additional functionality and therefore need to communicate with Open\+Flipper.

We initialize the \hyperlink{a00895}{Plugin\+Functions\+::\+Object\+Iterator} with \hyperlink{a03393_ae60d693ef9114d80221eea2454195526}{Plugin\+Functions\+::\+T\+A\+R\+G\+E\+T\+\_\+\+O\+B\+J\+E\+C\+T\+S} and thereby make sure that the iteration is restricted to target objects only.

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


In the next line we test if we have to deal with a triangle mesh. Since computation on triangle meshes is in many cases more efficient than on arbitrary polygonal meshes \hyperlink{a03368}{Open\+Mesh} treats them seperately (see \hyperlink{a03368}{Open\+Mesh} documentation for further information on this topic). See also \hyperlink{a02511}{Open\+Flipper/common/\+Types.\+hh} for data types in Open\+Flipper.

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


First off, we backup the current vertex positions by adding a custom property to our mesh. We assume that you already made yourself familiar with \hyperlink{a03368}{Open\+Mesh}. Otherwise we recommend you to read the \hyperlink{a03368}{Open\+Mesh} documentation first since we use many of Open\+Meshes's core functions in this tutorial.

 
\begin{DoxyCodeInclude}
      \textcolor{comment}{// Get the mesh to work on}

\end{DoxyCodeInclude}


The smoothing algorithm itself depends on the number of iterations that one can adjust in the plugin's toolbox.

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


In a few words the algorithm iterates over each vertex of the mesh, accumulates the positions of it's neighboring vertices, devides the sum by it's valence and updates it's position to the computed value. If the current vertex is a boundary vertex, we skip over to the next one without updating the position.

Now that the smoothing operation is done, we want to get rid of the original vertex positions. Since we changed vertices, we also have to update the normals.

 
\begin{DoxyCodeInclude}
      \textcolor{comment}{// Remove the property}
      mesh->remove\_property(origPositions);

      mesh->update\_normals();

\end{DoxyCodeInclude}


We now implement the same procedure for arbitrary polygonal meshes using the template types of \hyperlink{a03368}{Open\+Mesh}. Starting at line (see \hyperlink{a00240_com_src_ex2}{The complete source code of the example} for the complete source code of this example plugin)\+:

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


The next step is to tell the Open\+Flipper core that our plugin has updated an object in the scene. The affected object will then be redrawn.

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


The smoothing algorithm on arbitrary polygonal meshes in this case works analogously. See \hyperlink{a00240_com_src_ex2}{The complete source code of the example} for the complete source code.

If the object's type is neither triangle nor polygonal mesh, we make use of the implemented \hyperlink{a00784}{Logging\+Interface} by dumping an error log message to Open\+Flipper's log widget.

 
\begin{DoxyCodeInclude}
    \} \textcolor{keywordflow}{else} \{

      emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca39fe22d7b704805a8e30697a4a07d8fc}{LOGERR}, \textcolor{stringliteral}{"Data type not supported."});

    \} \textcolor{comment}{// Switch data type}

\end{DoxyCodeInclude}
\hypertarget{a00240_com_src_ex2}{}\subsubsection{The complete source code of the example}\label{a00240_com_src_ex2}
Smoother\+Plugin.\+hh 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#ifndef SMOOTHERPLUGIN\_HH}
\textcolor{preprocessor}{#define SMOOTHERPLUGIN\_HH}

\textcolor{preprocessor}{#include <\hyperlink{a02437}{OpenFlipper/BasePlugin/BaseInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02472}{OpenFlipper/BasePlugin/ToolboxInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02444}{OpenFlipper/BasePlugin/LoggingInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02511}{OpenFlipper/common/Types.hh}>}

\textcolor{keyword}{class }SmootherPlugin : \textcolor{keyword}{public} QObject, \hyperlink{a00322}{BaseInterface}, 
      \hyperlink{a01311}{ToolboxInterface}, \hyperlink{a00784}{LoggingInterface}
\{
  Q\_OBJECT
  Q\_INTERFACES(\hyperlink{a00322}{BaseInterface})
  Q\_INTERFACES(\hyperlink{a01311}{ToolboxInterface})
  Q\_INTERFACES(\hyperlink{a00784}{LoggingInterface})

  signals:
    \textcolor{comment}{//BaseInterface}
    \textcolor{keywordtype}{void} updateView();
    \textcolor{keywordtype}{void} updatedObject(\textcolor{keywordtype}{int} \_identifier, const \hyperlink{a01393}{UpdateType}& \_type);

    \textcolor{comment}{//LoggingInterface}
    \textcolor{keywordtype}{void} log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7c}{Logtype} \_type, QString \_message);
    \textcolor{keywordtype}{void} log(QString \_message);

    \textcolor{comment}{// ToolboxInterface}
    \textcolor{keywordtype}{void} addToolbox( QString \_name, QWidget* \_widget );

  public:

    SmootherPlugin();

    \textcolor{comment}{// BaseInterface}
    QString name() \{ \textcolor{keywordflow}{return} (QString(\textcolor{stringliteral}{"Simple Smoother"})); \};
    QString \hyperlink{a01204_a563f0454d1b416932c46a9288db2f57e}{description}( ) \{ \textcolor{keywordflow}{return} (QString(\textcolor{stringliteral}{"Smooths the active Mesh"})); \};

   \textcolor{keyword}{private}:

    QSpinBox* \hyperlink{a01204_ae8739b32abce7aed26946c4c162c43e9}{iterationsSpinbox\_};

   \textcolor{keyword}{private} slots:

    \textcolor{comment}{// BaseInterface}
    \textcolor{keywordtype}{void} initializePlugin();


    \textcolor{keywordtype}{void} \hyperlink{a01204_aa1921cbedff24c0b01d45a9890af5c84}{simpleLaplace}();

   \textcolor{keyword}{public} slots:
      QString version() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"1.0"}); \};
\};

\textcolor{preprocessor}{#endif //SMOOTHERPLUGIN\_HH}
\end{DoxyCodeInclude}


Smoother\+Plugin.\+cc 
\begin{DoxyCodeInclude}
\textcolor{comment}{//=============================================================================}
\textcolor{comment}{//}
\textcolor{comment}{//                               OpenFlipper}
\textcolor{comment}{//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen}
\textcolor{comment}{//                           www.openflipper.org}
\textcolor{comment}{//}
\textcolor{comment}{//-----------------------------------------------------------------------------}
\textcolor{comment}{//}
\textcolor{comment}{//                                License}
\textcolor{comment}{//}
\textcolor{comment}{//  OpenFlipper is free software: you can redistribute it and/or modify}
\textcolor{comment}{//  it under the terms of the GNU Lesser General Public License as published by}
\textcolor{comment}{//  the Free Software Foundation, either version 3 of the License, or}
\textcolor{comment}{//  (at your option) any later version.}
\textcolor{comment}{//}
\textcolor{comment}{//  OpenFlipper is distributed in the hope that it will be useful,}
\textcolor{comment}{//  but WITHOUT ANY WARRANTY; without even the implied warranty of}
\textcolor{comment}{//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the}
\textcolor{comment}{//  GNU Lesser General Public License for more details.}
\textcolor{comment}{//}
\textcolor{comment}{//  You should have received a copy of the GNU Lesser General Public License}
\textcolor{comment}{//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.}
\textcolor{comment}{//}
\textcolor{comment}{//-----------------------------------------------------------------------------}
\textcolor{comment}{//}
\textcolor{comment}{//   $Revision$}
\textcolor{comment}{//   $Author$}
\textcolor{comment}{//   $Date$}
\textcolor{comment}{//}
\textcolor{comment}{//=============================================================================}



\textcolor{preprocessor}{#include "SmootherPlugin.hh"}


\textcolor{preprocessor}{#include <\hyperlink{a02346}{ObjectTypes/PolyMesh/PolyMesh.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02424}{ObjectTypes/TriangleMesh/TriangleMesh.hh}>}

\textcolor{preprocessor}{#include "\hyperlink{a02452}{OpenFlipper/BasePlugin/PluginFunctions.hh}"}

SmootherPlugin::SmootherPlugin() :
        iterationsSpinbox\_(0)
\{

\}

\textcolor{keywordtype}{void} SmootherPlugin::initializePlugin()
\{
  \textcolor{comment}{// Create the Toolbox Widget}
  QWidget* toolBox = \textcolor{keyword}{new} QWidget();

  QPushButton* smoothButton = \textcolor{keyword}{new} QPushButton(\textcolor{stringliteral}{"&Smooth"}, toolBox);

  iterationsSpinbox\_ = \textcolor{keyword}{new} QSpinBox(toolBox);
  iterationsSpinbox\_->setMinimum(1);
  iterationsSpinbox\_->setMaximum(1000);
  iterationsSpinbox\_->setSingleStep(1);

  QLabel* label = \textcolor{keyword}{new} QLabel(\textcolor{stringliteral}{"Iterations:"});

  QGridLayout* layout = \textcolor{keyword}{new} QGridLayout(toolBox);

  layout->addWidget(label, 0, 0);
  layout->addWidget(smoothButton, 1, 1);
  layout->addWidget(iterationsSpinbox\_, 0, 1);

  layout->addItem(\textcolor{keyword}{new} QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding), 2, 0, 1, 2);

  connect(smoothButton, SIGNAL(clicked()), \textcolor{keyword}{this}, SLOT(\hyperlink{a01204_aa1921cbedff24c0b01d45a9890af5c84}{simpleLaplace}()));

  emit addToolbox(tr(\textcolor{stringliteral}{"Smoother"}), toolBox);
\}

\textcolor{keywordtype}{void} \hyperlink{a01204_aa1921cbedff24c0b01d45a9890af5c84}{SmootherPlugin::simpleLaplace}()
\{

  \textcolor{keywordflow}{for} (\hyperlink{a00895}{PluginFunctions::ObjectIterator} o\_it(
      \hyperlink{a03393_ae60d693ef9114d80221eea2454195526}{PluginFunctions::TARGET\_OBJECTS}); o\_it != 
      \hyperlink{a03393_a25c8015c612b1aaf3a840ca072ce68ca}{PluginFunctions::objectsEnd}();
      ++o\_it) \{

    \textcolor{keywordflow}{if} (o\_it->dataType(\hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH})) \{

      \textcolor{comment}{// Get the mesh to work on}
      TriMesh* mesh = \hyperlink{a03393_a11d22dc1c64537f87c014241cacc4340}{PluginFunctions::triMesh}(*o\_it);

      \textcolor{comment}{// Property for the active mesh to store original point positions}
      \hyperlink{a01470}{OpenMesh::VPropHandleT<TriMesh::Point>} origPositions;

      \textcolor{comment}{// Add a property to the mesh to store original vertex positions}
      mesh->add\_property(origPositions, \textcolor{stringliteral}{"SmootherPlugin\_Original\_Positions"});

      \textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0; i < iterationsSpinbox\_->value(); ++i) \{

        \textcolor{comment}{// Copy original positions to backup ( in vertex property )}
        TriMesh::VertexIter v\_it, v\_end = mesh->vertices\_end();
        \textcolor{keywordflow}{for} (v\_it = mesh->vertices\_begin(); v\_it != v\_end; ++v\_it) \{
          mesh->property(origPositions, v\_it) = mesh->point(v\_it);
        \}

        \textcolor{comment}{// Do one smoothing step (For each point of the mesh ... )}
        \textcolor{keywordflow}{for} (v\_it = mesh->vertices\_begin(); v\_it != v\_end; ++v\_it) \{

          TriMesh::Point point = TriMesh::Point(0.0, 0.0, 0.0);

          \textcolor{comment}{// Flag, to skip boundary vertices}
          \textcolor{keywordtype}{bool} skip = \textcolor{keyword}{false};

          \textcolor{comment}{// ( .. for each outgoing halfedge .. )}
          TriMesh::VertexOHalfedgeIter voh\_it(*mesh, v\_it);

          \textcolor{keywordflow}{for} (; voh\_it; ++voh\_it) \{

            \textcolor{comment}{// .. add the (original) position of the neighbour ( end of the outgoing halfedge )}
            point += mesh->property(origPositions, mesh->to\_vertex\_handle(voh\_it));

            \textcolor{comment}{// Check if the current Halfedge is a boundary halfedge}
            \textcolor{comment}{// If it is, abort and keep the current vertex position}
            \textcolor{keywordflow}{if} (mesh->is\_boundary(*voh\_it)) \{
              skip = \textcolor{keyword}{true};
              \textcolor{keywordflow}{break};
            \}
          \}

          \textcolor{comment}{// Devide by the valence of the current vertex}
          point /= mesh->valence(v\_it);

          \textcolor{keywordflow}{if} (!skip) \{
            \textcolor{comment}{// Set new position for the mesh if its not on the boundary}
            mesh->point(v\_it) = point;
          \}
        \}

      \}     \textcolor{comment}{// Iterations end}

      \textcolor{comment}{// Remove the property}
      mesh->remove\_property(origPositions);

      mesh->update\_normals();

      emit updatedObject(o\_it->id(),\hyperlink{a03407_ga01c97b7f74b26bfb8701f9dba7806b40}{UPDATE\_GEOMETRY});

    \} \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (o\_it->dataType(\hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH})) \{

      \textcolor{comment}{// Get the mesh to work on}
      PolyMesh* mesh = \hyperlink{a03393_afe48c8dedf9bf541678277213548d61a}{PluginFunctions::polyMesh}(*o\_it);

      \textcolor{comment}{// Property for the active mesh to store original point positions}
      \hyperlink{a01470}{OpenMesh::VPropHandleT<PolyMesh::Point>} origPositions;

      \textcolor{comment}{// Add a property to the mesh to store original vertex positions}
      mesh->add\_property(origPositions, \textcolor{stringliteral}{"SmootherPlugin\_Original\_Positions"});

      \textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0; i < iterationsSpinbox\_->value(); ++i) \{

        \textcolor{comment}{// Copy original positions to backup ( in Vertex property )}
        PolyMesh::VertexIter v\_it, v\_end = mesh->vertices\_end();
        \textcolor{keywordflow}{for} (v\_it = mesh->vertices\_begin(); v\_it != v\_end; ++v\_it) \{
          mesh->property(origPositions, v\_it) = mesh->point(v\_it);
        \}

        \textcolor{comment}{// Do one smoothing step (For each point of the mesh ... )}
        \textcolor{keywordflow}{for} (v\_it = mesh->vertices\_begin(); v\_it != v\_end; ++v\_it) \{

          \hyperlink{a00994_aed10fb4dfb536b53a5e20c8f2442eadf}{PolyMesh::Point} point = \hyperlink{a00994_aed10fb4dfb536b53a5e20c8f2442eadf}{PolyMesh::Point}(0.0, 0.0, 0.0);

          \textcolor{comment}{// Flag, to skip boundary vertices}
          \textcolor{keywordtype}{bool} skip = \textcolor{keyword}{false};

          \textcolor{comment}{// ( .. for each Outoing halfedge .. )}
          PolyMesh::VertexOHalfedgeIter voh\_it(*mesh, v\_it);
          \textcolor{keywordflow}{for} (; voh\_it; ++voh\_it) \{
            \textcolor{comment}{// .. add the (original) position of the Neighbour ( end of the outgoing halfedge )}
            point += mesh->property(origPositions, mesh->to\_vertex\_handle(voh\_it));

            \textcolor{comment}{// Check if the current Halfedge is a boundary halfedge}
            \textcolor{comment}{// If it is, abort and keep the current vertex position}
            \textcolor{keywordflow}{if} (mesh->is\_boundary(*voh\_it)) \{
              skip = \textcolor{keyword}{true};
              \textcolor{keywordflow}{break};
            \}

          \}

          \textcolor{comment}{// Devide by the valence of the current vertex}
          point /= mesh->valence(v\_it);

          \textcolor{keywordflow}{if} (!skip) \{
            \textcolor{comment}{// Set new position for the mesh if its not on the boundary}
            mesh->point(v\_it) = point;
          \}
        \}

      \}     \textcolor{comment}{// Iterations end}

      \textcolor{comment}{// Remove the property}
      mesh->remove\_property(origPositions);

      mesh->update\_normals();

      emit updatedObject(o\_it->id(),\hyperlink{a03407_ga01c97b7f74b26bfb8701f9dba7806b40}{UPDATE\_GEOMETRY});

    \} \textcolor{keywordflow}{else} \{

      emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca39fe22d7b704805a8e30697a4a07d8fc}{LOGERR}, \textcolor{stringliteral}{"Data type not supported."});

    \} \textcolor{comment}{// Switch data type}
  \}
\}

Q\_EXPORT\_PLUGIN2( smootherplugin, SmootherPlugin);

\end{DoxyCodeInclude}


We use the cmake project file presented in \hyperlink{a00238_ex1c}{How to build the plugin with C\+Make} to build this plugin. \hypertarget{ex3}{}\subsection{Implementing mouse and keyboard interaction}\label{ex3}
\hypertarget{a00242_overview_ex3}{}\subsubsection{Overview}\label{a00242_overview_ex3}
Mouse interaction (especially object picking) and keyboard shortcuts form essential and often used functionality in Open\+Flipper. In this tutorial we will learn how to use picking modes, context menus and simple keyboard shortcuts. The plugin will provide the following functions\+:


\begin{DoxyItemize}
\item Hide object by right-\/clicking at it and selecting our defined action
\item Select an object by entering user defined pick mode and double-\/clicking at object in the scene
\item Rotate selected object by hitting the j,k,h,l keys on the keyboard
\end{DoxyItemize}

For this purpose we will make use of the following \hyperlink{interfaces}{Plugin Interfaces}


\begin{DoxyItemize}
\item \hyperlink{baseInterfacePage}{Base Interface}
\item \hyperlink{mouseInterfacePage}{Mouse Interface}
\item \hyperlink{pickingInterfacePage}{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars}
\item \hyperlink{keyInterfacePage}{Key Interface}
\item \hyperlink{contextMenuInterfacePage}{Context Menu Interface}
\item \hyperlink{toolboxInterfacePage}{Toolbox Interface}
\item \hyperlink{loggingInterfacePage}{Logging Interface}
\end{DoxyItemize}

Since we outlined the details of overriding the \hyperlink{a00322}{Base\+Interface} methods in the previous tutorials (\hyperlink{ex1}{A simple plugin} and \hyperlink{ex2}{Implementing a mesh smoother plugin}) we can directly switch over to what happens within these methods. When initializing our plugin we set the active object identifier to -\/1 since no object has been selected yet. We initialize the axis vectors that we'll need for the rotation later on. Then we tell Open\+Flipper that we will use the j, k, h and l key on the keyboard (so it'll call slot\+Key\+Event() each time one of the keys has been pressed). Note\+: Open\+Flipper will show up a warning message in the log widget if the desired keys are already assigned to another plugin or core function.

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::initializePlugin() \{

        \textcolor{comment}{// Register keys}
        emit registerKey(Qt::Key\_J,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object down"});
        emit registerKey(Qt::Key\_K,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object up"});
        emit registerKey(Qt::Key\_H,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object left"});
        emit registerKey(Qt::Key\_L,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object right"});

  tool\_ = \textcolor{keyword}{new} QWidget();
  QSize size(300, 300);
  tool\_->resize(size);

  \textcolor{comment}{// Create button that can be toggled}
  \textcolor{comment}{// to (de)activate plugin's picking mode}
  pickButton\_ = \textcolor{keyword}{new} QPushButton(tr(\textcolor{stringliteral}{"Select object"}));
  pickButton\_->setCheckable(\textcolor{keyword}{true});

  \textcolor{comment}{// Create label}
  QLabel* label = \textcolor{keyword}{new} QLabel();
  label->setText(\textcolor{stringliteral}{"(De)activate pick mode"});

  \textcolor{comment}{// Set label to be above the button}
  QGridLayout* grid = \textcolor{keyword}{new} QGridLayout;
  grid->addWidget(label, 0, 0);
  grid->addWidget(pickButton\_, 1, 0);

  tool\_->setLayout(grid);

  \textcolor{comment}{// Connect button to slotButtonClicked()}
  connect(pickButton\_, SIGNAL(clicked()), \textcolor{keyword}{this}, SLOT(slotButtonClicked()));

  \textcolor{comment}{// Add the Toolbox}
  emit addToolbox(tr(\textcolor{stringliteral}{"Mouse and Key"}), tool\_);

\} \textcolor{comment}{// End initializePlugin}

\end{DoxyCodeInclude}


If all plugins have been initialized, we add our own pick mode named \char`\"{}\+Mouse\+And\+Key\+Plugin\char`\"{} to Open\+Flipper and create the context menu entry (which is actually a Q\+Menu object containing one (or generally multiple) object(s) of type Q\+Action) which we connect to context\+Menu\+Item\+Selected().

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::pluginsInitialized() \{

        \textcolor{comment}{// Add pickmode}
        emit addPickMode(\textcolor{stringliteral}{"MouseAndKeyPlugin"});

        \textcolor{comment}{// Add context menu entry}

        \textcolor{comment}{// Create submenu}
        contextMenuEntry\_ = \textcolor{keyword}{new} QMenu(\textcolor{stringliteral}{"Mouse and key plugin"});

        QAction* lastAction;

        \textcolor{comment}{// Add action to recently created menu}
        lastAction = contextMenuEntry\_->addAction( \textcolor{stringliteral}{"Hide object"} );
        lastAction->setToolTip(\textcolor{stringliteral}{"Hide selected object"});
        lastAction->setStatusTip( lastAction->toolTip() );

        \textcolor{comment}{// Finally insert created context submenu to OpenFlipper's context menu}
        \textcolor{comment}{// We want our action to be visible for triangle and polygon meshes}
        emit addContextMenuItem(contextMenuEntry\_->menuAction() , 
      \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} , \hyperlink{a02438_a238952a111d7daede783625350d7b287aa9f1dad0ebec85ff7a0601f62be8084d}{CONTEXTOBJECTMENU} );
        emit addContextMenuItem(contextMenuEntry\_->menuAction() , \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH} , 
      \hyperlink{a02438_a238952a111d7daede783625350d7b287aa9f1dad0ebec85ff7a0601f62be8084d}{CONTEXTOBJECTMENU} );

        \textcolor{comment}{// Connect the created context menu entry to local function contextMenuItemSelected(QAction*)}
        connect(contextMenuEntry\_, SIGNAL(triggered(QAction*)), \textcolor{keyword}{this}, SLOT(contextMenuItemSelected(QAction
      *)));

\} \textcolor{comment}{// End pluginsInitialized}

\end{DoxyCodeInclude}


In intialize\+Toolbox() we create a simple toolbox containing a label and a push-\/button. We connect the button to our method slot\+Button\+Clicked() which will then be called each time the button is clicked.

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


Now each time the button in our toolbox is clicked we want to activate the picking mode, such that if the button is checked pick mode \char`\"{}\+Mouse\+And\+Key\+Plugin\char`\"{} that we defined at the beginning will be active and Open\+Flipper switches over from Examine\+Mode to Picking\+Mode (see \hyperlink{a03393}{Plugin\+Functions} for details). Clicking once more at the button will return to Examine\+Mode (in which the user can navigate through the scene).

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotButtonClicked() \{

        \textcolor{keywordflow}{if}(pickButton\_->isChecked()) \{
                \textcolor{comment}{// Picking mode of our plugin shall be activated}
                \textcolor{comment}{// set OpenFlipper's action mode to picking}
                \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}( Viewer::PickingMode );

                \textcolor{comment}{// Now activate our picking mode}
                \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}( \textcolor{stringliteral}{"MouseAndKeyPlugin"} );
        \} \textcolor{keywordflow}{else} \{
                \textcolor{comment}{// Picking mode shall be deactivated}
                \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}( Viewer::ExamineMode );
        \}

\} \textcolor{comment}{// End slotButtonClicked}

\end{DoxyCodeInclude}


If the pick mode has been changed externally, we want our button in the toolbox to appear pressed (or unpressed respectively). \+\_\+mode holds the name of the currently selected pick mode.

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotPickModeChanged(\textcolor{keyword}{const} std::string& \_mode) \{

        \textcolor{comment}{// Set button checked if pick mode is our}
        \textcolor{comment}{// plugin's pick mode}
        pickButton\_->setChecked(\_mode == \textcolor{stringliteral}{"MouseAndKeyPlugin"});

\} \textcolor{comment}{// End slotPickModeChanged}

\end{DoxyCodeInclude}


In the next method we describe how mouse actions are to be handled by the plugin. We want our plugin only to react to mouse events if our pick mode is active otherwise don't do anything. If Open\+Flipper is in Picking\+Mode and the currently active pick mode is \char`\"{}\+Mouse\+And\+Key\+Plugin\char`\"{} we try to get the object on that the user has double clicked. If the object can be found, we'll show up a dialog window displaying the picked object's identifier and assign it to the member variable that holds the active object. Otherwise we display \char`\"{}\+Picking failed\char`\"{} in the log widget. Note that the mouse event has to be traversed through the rest of the scene graph after intercepting and treating the desired mouse action.

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotMouseEvent(QMouseEvent* \_event) \{

        \textcolor{keywordflow}{if} ( \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}() == \textcolor{stringliteral}{"MouseAndKeyPlugin"} &&
                \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}() == Viewer::PickingMode ) \{

                \textcolor{comment}{// If double click has been performed}
                \textcolor{keywordflow}{if} (\_event->type() == QEvent::MouseButtonDblClick) \{

                        \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} node\_idx, target\_idx;
                        \hyperlink{a01409}{OpenMesh::Vec3d} hitPoint;

                        \textcolor{comment}{// Get picked object's identifier}
                        \textcolor{keywordflow}{if} ( \hyperlink{a03393_a0ae515c8553f9e7f671bd2627bbecf6a}{PluginFunctions::scenegraphPick}(
      \hyperlink{a03343_af5fad41dadeca314c2077f897377dbd0a16466d3b836973188ef3426feda66fcd}{ACG::SceneGraph::PICK\_ANYTHING},\_event->pos(), node\_idx, target\_idx, &hitPoint
      ) ) \{

                                \hyperlink{a00330}{BaseObjectData}* object;

                                \textcolor{comment}{// Get picked object}
                                \textcolor{keywordflow}{if} ( \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{PluginFunctions::getPickedObject}(
      node\_idx, \textcolor{keywordtype}{object}) ) \{

                                        \textcolor{comment}{// Show small dialog window}
                                        QDialog* dlg = \textcolor{keyword}{new} QDialog;

                                        QGridLayout* grid = \textcolor{keyword}{new} QGridLayout;
                                        QLabel* label = \textcolor{keyword}{new} QLabel;
                                        QString str = QString(\textcolor{stringliteral}{"You selected object "});
                                        str += QString::number(node\_idx);
                                        label->setText(str);
                                        grid->addWidget(label, 0,0);

                                        dlg->setLayout(grid);

                                        dlg->show();

                                        \textcolor{comment}{// Set last selected object}
                                        activeObject\_ = node\_idx;
                                \}
                                \textcolor{keywordflow}{else} \{
                                        emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"Picking failed"});
                                \}
                        \}

                        \textcolor{keywordflow}{return};
                \}

                \textcolor{comment}{// Continue traversing scene graph}
                \hyperlink{a00859}{ACG::SceneGraph::MouseEventAction} action(\_event, 
      \hyperlink{a03393_a341db97dfd8cf625b4d914481028c25a}{PluginFunctions::viewerProperties}().glState());
                \hyperlink{a03393_a95bf07301b5f4e367e9d6909acbaf7fd}{PluginFunctions::traverse}(action);
        \}

\} \textcolor{comment}{// End slotMouseEvent}

\end{DoxyCodeInclude}


Next method is called whenever any of the keys j, k, h or l is pressed. If an object has been selected (accordingly the member variable active\+Object\+\_\+ holds a valid objects identifier -\/as described before-\/) we try to get its handle by calling \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{Plugin\+Functions\+::get\+Picked\+Object()}. We then set the rotation matrix of the selected object's transform node (manipulator\+Node) to hold a matrix that describes a rotation around the x (if j or k is pressed) or y axis (if h or l is pressed) by +/-\/ 10 degrees. We then call the method transform\+Mesh and pass the recently calculated matrix and a handle to the mesh (triangle or polygon). We have to inform Open\+Flipper's core about the changes by emitting the updated\+Object signal and specifying that the geometry has changed.

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* \_event ) \{

        \hyperlink{a00330}{BaseObjectData}* object;

        \textcolor{comment}{// Get last clicked object (selected in pick mode)}
        \textcolor{keywordflow}{if} ( \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{PluginFunctions::getPickedObject}(activeObject\_, \textcolor{keywordtype}{object}) ) \{

                \textcolor{comment}{// Switch pressed keys}
                \textcolor{keywordflow}{switch} (\_event->key())
                \{
                        \textcolor{keywordflow}{case} Qt::Key\_J:

                                \textcolor{keywordtype}{object}->\hyperlink{a00330_adf4fdd191347abb3d104c8f740b7cbfd}{manipulatorNode}()->
      \hyperlink{a01320_a29d9dbfbaaf43140b9fb1eb121246af3}{loadIdentity}();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(10.0, axis\_x\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{case} Qt::Key\_K :

                                \textcolor{keywordtype}{object}->manipulatorNode()->loadIdentity();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(-10.0, axis\_x\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{case} Qt::Key\_H :

                                \textcolor{keywordtype}{object}->manipulatorNode()->loadIdentity();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(10.0, axis\_y\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{case} Qt::Key\_L :

                                \textcolor{keywordtype}{object}->manipulatorNode()->loadIdentity();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(-10.0, axis\_y\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{default}:
                        \textcolor{keywordflow}{break};
                \}

                \textcolor{comment}{// Perform rotation}
                \textcolor{keywordflow}{if} ( object->\hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{dataType}( \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} ) )
                        transformMesh(object->\hyperlink{a00330_adf4fdd191347abb3d104c8f740b7cbfd}{manipulatorNode}()->
      \hyperlink{a01320_a241c7bcd838b7825acd2db84a4f1c4f5}{matrix}(), (*\hyperlink{a03393_a11d22dc1c64537f87c014241cacc4340}{PluginFunctions::triMesh}(\textcolor{keywordtype}{object})));
                \textcolor{keywordflow}{if} ( object->\hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{dataType}( \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH} ) )
                        transformMesh(object->\hyperlink{a00330_adf4fdd191347abb3d104c8f740b7cbfd}{manipulatorNode}()->
      \hyperlink{a01320_a241c7bcd838b7825acd2db84a4f1c4f5}{matrix}(), (*\hyperlink{a03393_afe48c8dedf9bf541678277213548d61a}{PluginFunctions::polyMesh}(\textcolor{keywordtype}{object})));

                \textcolor{comment}{// Tell core that object has been modified}
                emit updatedObject(object->\hyperlink{a00329_a043f52f3105d646af193d4974482869d}{id}(), \hyperlink{a03407_ga01c97b7f74b26bfb8701f9dba7806b40}{UPDATE\_GEOMETRY});

                \textcolor{comment}{// Update view}
                emit updateView();
        \} \textcolor{keywordflow}{else} \{
                emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"No object has been selected to rotate! Select object first."});
        \}

\} \textcolor{comment}{// End slotKeyEvent}

\end{DoxyCodeInclude}


This template method transforms the given mesh\+:

 
\begin{DoxyCodeInclude}

\end{DoxyCodeInclude}


Last but not least, the method that is called each time our context menu has been clicked. We get the object's id on which the user has performed a right click from the action data. Then we try to get the node and its \hyperlink{a00330}{Base\+Object\+Data} handle. If successfully passed to this point we hide the object by calling its hide() method.

 
\begin{DoxyCodeInclude}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::contextMenuItemSelected(QAction* \_action) \{

        \textcolor{comment}{// Get object id from QAction object}
        QVariant contextObject = \_action->data();
        \textcolor{keywordtype}{int} objectId = contextObject.toInt();

        \textcolor{keywordflow}{if} (objectId == -1) \{

                log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"Could not get associated object id."});
                \textcolor{keywordflow}{return};
        \}

        \textcolor{comment}{// Get node associated to object id}
        \hyperlink{a00327}{ACG::SceneGraph::BaseNode}* node = 
      \hyperlink{a03343_a1299f77548fd1f3541aeb9096c4b4b22}{ACG::SceneGraph::find\_node}(
                        \hyperlink{a03393_adb9160f9b0e24053d577b42efe1d37d4}{PluginFunctions::getSceneGraphRootNode}(), 
      objectId);

        \textcolor{comment}{// Return if node id was not valid}
        \textcolor{keywordflow}{if} (!node) \{

                log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"Could not find associated object."});
                \textcolor{keywordflow}{return};
        \}

        \hyperlink{a00330}{BaseObjectData}* obj;
        \textcolor{keywordflow}{if} (!\hyperlink{a03393_ac20ce4f5c004657788cc10f4ad465de0}{PluginFunctions::getObject}(objectId, obj))
                \textcolor{keywordflow}{return};

        \textcolor{comment}{// Hide object}
        obj->\hyperlink{a00330_a9d48ae4e906a01d1aed3e061799adfe4}{hide}();

\} \textcolor{comment}{// End contextMenuItemSelected}

\end{DoxyCodeInclude}
\hypertarget{a00242_ex3_source}{}\subsubsection{The complete source code of this example}\label{a00242_ex3_source}
We use the same project file as before.

\hyperlink{a02548_source}{Mouse\+And\+Key\+Plugin.\+hh} 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#ifndef MOUSEANDKEYPLUGIN\_HH}
\textcolor{preprocessor}{#define MOUSEANDKEYPLUGIN\_HH}

\textcolor{preprocessor}{#include <\hyperlink{a02437}{OpenFlipper/BasePlugin/BaseInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02447}{OpenFlipper/BasePlugin/MouseInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02449}{OpenFlipper/BasePlugin/PickingInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02442}{OpenFlipper/BasePlugin/KeyInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02438}{OpenFlipper/BasePlugin/ContextMenuInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02472}{OpenFlipper/BasePlugin/ToolboxInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02444}{OpenFlipper/BasePlugin/LoggingInterface.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02511}{OpenFlipper/common/Types.hh}>}

\textcolor{keyword}{class }\hyperlink{a00857}{MouseAndKeyPlugin}: \textcolor{keyword}{public} QObject,
                \hyperlink{a00322}{BaseInterface},
                \hyperlink{a00860}{MouseInterface},
                \hyperlink{a00957}{PickingInterface},
                \hyperlink{a00460}{ContextMenuInterface},
                \hyperlink{a01311}{ToolboxInterface},
                \hyperlink{a00756}{KeyInterface},
                \hyperlink{a00784}{LoggingInterface} \{
        Q\_OBJECT
        Q\_INTERFACES(\hyperlink{a00322}{BaseInterface})
        Q\_INTERFACES(\hyperlink{a00860}{MouseInterface})
        Q\_INTERFACES(\hyperlink{a00957}{PickingInterface})
        Q\_INTERFACES(\hyperlink{a00756}{KeyInterface})
        Q\_INTERFACES(\hyperlink{a00460}{ContextMenuInterface})
        Q\_INTERFACES(\hyperlink{a01311}{ToolboxInterface})
        Q\_INTERFACES(\hyperlink{a00784}{LoggingInterface})

        signals:

        \textcolor{comment}{//BaseInterface}
        \textcolor{keywordtype}{void} updateView();
        \textcolor{keywordtype}{void} updatedObject(\textcolor{keywordtype}{int} \_identifier, const \hyperlink{a01393}{UpdateType}& \_type);
        \textcolor{comment}{//LoggingInterface}
        \textcolor{keywordtype}{void} log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7c}{Logtype} \_type, QString \_message);
        \textcolor{keywordtype}{void} log(QString \_message);
        \textcolor{comment}{//ContextMenuInterface}
        \textcolor{keywordtype}{void} addContextMenuItem(QAction* \_action , \hyperlink{a02438_a238952a111d7daede783625350d7b287}{ContextMenuType} \_type);
        \textcolor{keywordtype}{void} addContextMenuItem(QAction* \_action , \hyperlink{a00477}{DataType} \_objectType , 
      \hyperlink{a02438_a238952a111d7daede783625350d7b287}{ContextMenuType} \_type );
        \textcolor{comment}{//PickingInterface}
        \textcolor{keywordtype}{void} addPickMode(const \hyperlink{a03398}{std}::\textcolor{keywordtype}{string}& \_mode);
        \textcolor{keywordtype}{void} addHiddenPickMode(const \hyperlink{a03398}{std}::\textcolor{keywordtype}{string}& \_mode);
        \textcolor{comment}{//KeyInterface}
        \textcolor{keywordtype}{void} registerKey(\textcolor{keywordtype}{int} \_key, \hyperlink{a03394}{Qt}::KeyboardModifiers \_modifiers, QString \_description, \textcolor{keywordtype}{bool} \_multiUse
       = false);

  \textcolor{comment}{// ToolboxInterface}
  \textcolor{keywordtype}{void} addToolbox(QString \_name, QWidget* \_widget);

        private slots:

        \textcolor{comment}{// BaseInterface}
        \textcolor{keywordtype}{void} initializePlugin();
        \textcolor{keywordtype}{void} pluginsInitialized();
        \textcolor{comment}{//MouseInterface}
        \textcolor{keywordtype}{void} slotMouseEvent( QMouseEvent* \_event );
        \textcolor{comment}{//KeyInterface}
        \textcolor{keywordtype}{void} slotKeyEvent( QKeyEvent* \_event );
        \textcolor{comment}{//PickingInterface}
        \textcolor{keywordtype}{void} slotPickModeChanged( const \hyperlink{a03398}{std}::\textcolor{keywordtype}{string}& \_mode);

        public:

        \textcolor{comment}{// BaseInterface}
        QString name() \{\textcolor{keywordflow}{return} (QString(\textcolor{stringliteral}{"Mouse and Keyboard Plugin"}));\};
        QString \hyperlink{a00857_ac79d05c55652fa4e2478def1b8b6d836}{description}() \{\textcolor{keywordflow}{return} (QString(\textcolor{stringliteral}{"Shows some basic mouse and key embedding"}));\};

        \hyperlink{a00857}{MouseAndKeyPlugin}();

        \textcolor{keyword}{private}:

        \textcolor{comment}{// Transform geometry with given Matrix}
        \textcolor{keyword}{template} <\textcolor{keyword}{typename} MeshT>
        \textcolor{keywordtype}{void} transformMesh(\hyperlink{a00797}{ACG::Matrix4x4d} \_mat , MeshT& \_mesh );

        \textcolor{comment}{// The context menu action}
        QMenu* contextMenuEntry\_;

        \textcolor{comment}{// The toolbox widget and the button in it}
        QWidget* tool\_;
        QPushButton* pickButton\_;

        \textcolor{comment}{// Last picked object}
        \textcolor{keywordtype}{int} activeObject\_;

        \textcolor{comment}{// Rotation axes}
        \hyperlink{a01409}{ACG::Vec3d} axis\_x\_;
        \hyperlink{a01409}{ACG::Vec3d} axis\_y\_;

        \textcolor{keyword}{private} slots:

        \textcolor{comment}{// Is called each time the button in the toolbox is clicked}
        \textcolor{keywordtype}{void} slotButtonClicked();

        \textcolor{comment}{// Is called if context menu item has been selected}
        \textcolor{keywordtype}{void} contextMenuItemSelected(QAction* \_action);

        \textcolor{keyword}{public} slots:
        QString version() \{ \textcolor{keywordflow}{return} QString(\textcolor{stringliteral}{"1.0"}); \};
\};

\textcolor{preprocessor}{#endif //MOUSEANDKEYPLUGIN\_HH}
\end{DoxyCodeInclude}


\hyperlink{a02547_source}{Mouse\+And\+Key\+Plugin.\+cc} 
\begin{DoxyCodeInclude}
\textcolor{comment}{//=============================================================================}
\textcolor{comment}{//}
\textcolor{comment}{//                               OpenFlipper}
\textcolor{comment}{//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen}
\textcolor{comment}{//                           www.openflipper.org}
\textcolor{comment}{//}
\textcolor{comment}{//-----------------------------------------------------------------------------}
\textcolor{comment}{//}
\textcolor{comment}{//                                License}
\textcolor{comment}{//}
\textcolor{comment}{//  OpenFlipper is free software: you can redistribute it and/or modify}
\textcolor{comment}{//  it under the terms of the GNU Lesser General Public License as published by}
\textcolor{comment}{//  the Free Software Foundation, either version 3 of the License, or}
\textcolor{comment}{//  (at your option) any later version.}
\textcolor{comment}{//}
\textcolor{comment}{//  OpenFlipper is distributed in the hope that it will be useful,}
\textcolor{comment}{//  but WITHOUT ANY WARRANTY; without even the implied warranty of}
\textcolor{comment}{//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the}
\textcolor{comment}{//  GNU Lesser General Public License for more details.}
\textcolor{comment}{//}
\textcolor{comment}{//  You should have received a copy of the GNU Lesser General Public License}
\textcolor{comment}{//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.}
\textcolor{comment}{//}
\textcolor{comment}{//-----------------------------------------------------------------------------}
\textcolor{comment}{//}
\textcolor{comment}{//   $Revision$}
\textcolor{comment}{//   $Author$}
\textcolor{comment}{//   $Date$}
\textcolor{comment}{//}
\textcolor{comment}{//=============================================================================}

\textcolor{preprocessor}{#include "MouseAndKeyPlugin.hh"}


\textcolor{preprocessor}{#include <\hyperlink{a02346}{ObjectTypes/PolyMesh/PolyMesh.hh}>}
\textcolor{preprocessor}{#include <\hyperlink{a02424}{ObjectTypes/TriangleMesh/TriangleMesh.hh}>}

\textcolor{preprocessor}{#include "\hyperlink{a02452}{OpenFlipper/BasePlugin/PluginFunctions.hh}"}

\textcolor{comment}{/*}
\textcolor{comment}{ * Constructor}
\textcolor{comment}{ */}
MouseAndKeyPlugin::MouseAndKeyPlugin() :
        contextMenuEntry\_(0),
        tool\_(0),
        pickButton\_(0),
        activeObject\_(-1),
        axis\_x\_(\hyperlink{a03336}{ACG}::Vec3d(1.0, 0.0, 0.0)),
        axis\_y\_(\hyperlink{a03336}{ACG}::Vec3d(0.0, 1.0, 0.0))
\{

\}

\textcolor{comment}{/*}
\textcolor{comment}{ * Initialize plugin}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::initializePlugin() \{

        \textcolor{comment}{// Register keys}
        emit registerKey(Qt::Key\_J,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object down"});
        emit registerKey(Qt::Key\_K,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object up"});
        emit registerKey(Qt::Key\_H,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object left"});
        emit registerKey(Qt::Key\_L,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object right"});

  tool\_ = \textcolor{keyword}{new} QWidget();
  QSize size(300, 300);
  tool\_->resize(size);

  \textcolor{comment}{// Create button that can be toggled}
  \textcolor{comment}{// to (de)activate plugin's picking mode}
  pickButton\_ = \textcolor{keyword}{new} QPushButton(tr(\textcolor{stringliteral}{"Select object"}));
  pickButton\_->setCheckable(\textcolor{keyword}{true});

  \textcolor{comment}{// Create label}
  QLabel* label = \textcolor{keyword}{new} QLabel();
  label->setText(\textcolor{stringliteral}{"(De)activate pick mode"});

  \textcolor{comment}{// Set label to be above the button}
  QGridLayout* grid = \textcolor{keyword}{new} QGridLayout;
  grid->addWidget(label, 0, 0);
  grid->addWidget(pickButton\_, 1, 0);

  tool\_->setLayout(grid);

  \textcolor{comment}{// Connect button to slotButtonClicked()}
  connect(pickButton\_, SIGNAL(clicked()), \textcolor{keyword}{this}, SLOT(slotButtonClicked()));

  \textcolor{comment}{// Add the Toolbox}
  emit addToolbox(tr(\textcolor{stringliteral}{"Mouse and Key"}), tool\_);

\} \textcolor{comment}{// End initializePlugin}

\textcolor{comment}{/*}
\textcolor{comment}{ * Is called after all plugins have been initialized}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::pluginsInitialized() \{

        \textcolor{comment}{// Add pickmode}
        emit addPickMode(\textcolor{stringliteral}{"MouseAndKeyPlugin"});

        \textcolor{comment}{// Add context menu entry}

        \textcolor{comment}{// Create submenu}
        contextMenuEntry\_ = \textcolor{keyword}{new} QMenu(\textcolor{stringliteral}{"Mouse and key plugin"});

        QAction* lastAction;

        \textcolor{comment}{// Add action to recently created menu}
        lastAction = contextMenuEntry\_->addAction( \textcolor{stringliteral}{"Hide object"} );
        lastAction->setToolTip(\textcolor{stringliteral}{"Hide selected object"});
        lastAction->setStatusTip( lastAction->toolTip() );

        \textcolor{comment}{// Finally insert created context submenu to OpenFlipper's context menu}
        \textcolor{comment}{// We want our action to be visible for triangle and polygon meshes}
        emit addContextMenuItem(contextMenuEntry\_->menuAction() , 
      \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} , \hyperlink{a02438_a238952a111d7daede783625350d7b287aa9f1dad0ebec85ff7a0601f62be8084d}{CONTEXTOBJECTMENU} );
        emit addContextMenuItem(contextMenuEntry\_->menuAction() , \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH} , 
      \hyperlink{a02438_a238952a111d7daede783625350d7b287aa9f1dad0ebec85ff7a0601f62be8084d}{CONTEXTOBJECTMENU} );

        \textcolor{comment}{// Connect the created context menu entry to local function contextMenuItemSelected(QAction*)}
        connect(contextMenuEntry\_, SIGNAL(triggered(QAction*)), \textcolor{keyword}{this}, SLOT(contextMenuItemSelected(QAction
      *)));

\} \textcolor{comment}{// End pluginsInitialized}


\textcolor{comment}{/*}
\textcolor{comment}{ * Is called when button in toolbox has been clicked}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotButtonClicked() \{

        \textcolor{keywordflow}{if}(pickButton\_->isChecked()) \{
                \textcolor{comment}{// Picking mode of our plugin shall be activated}
                \textcolor{comment}{// set OpenFlipper's action mode to picking}
                \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}( Viewer::PickingMode );

                \textcolor{comment}{// Now activate our picking mode}
                \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}( \textcolor{stringliteral}{"MouseAndKeyPlugin"} );
        \} \textcolor{keywordflow}{else} \{
                \textcolor{comment}{// Picking mode shall be deactivated}
                \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}( Viewer::ExamineMode );
        \}

\} \textcolor{comment}{// End slotButtonClicked}

\textcolor{comment}{/*}
\textcolor{comment}{ * Is called when pick mode is changed in OpenFlipper}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotPickModeChanged(\textcolor{keyword}{const} std::string& \_mode) \{

        \textcolor{comment}{// Set button checked if pick mode is our}
        \textcolor{comment}{// plugin's pick mode}
        pickButton\_->setChecked(\_mode == \textcolor{stringliteral}{"MouseAndKeyPlugin"});

\} \textcolor{comment}{// End slotPickModeChanged}

\textcolor{comment}{/*}
\textcolor{comment}{ * Is called each time the mouse has moved or been clicked}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotMouseEvent(QMouseEvent* \_event) \{

        \textcolor{keywordflow}{if} ( \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}() == \textcolor{stringliteral}{"MouseAndKeyPlugin"} &&
                \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}() == Viewer::PickingMode ) \{

                \textcolor{comment}{// If double click has been performed}
                \textcolor{keywordflow}{if} (\_event->type() == QEvent::MouseButtonDblClick) \{

                        \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} node\_idx, target\_idx;
                        \hyperlink{a01409}{OpenMesh::Vec3d} hitPoint;

                        \textcolor{comment}{// Get picked object's identifier}
                        \textcolor{keywordflow}{if} ( \hyperlink{a03393_a0ae515c8553f9e7f671bd2627bbecf6a}{PluginFunctions::scenegraphPick}(
      \hyperlink{a03343_af5fad41dadeca314c2077f897377dbd0a16466d3b836973188ef3426feda66fcd}{ACG::SceneGraph::PICK\_ANYTHING},\_event->pos(), node\_idx, target\_idx, &hitPoint
      ) ) \{

                                \hyperlink{a00330}{BaseObjectData}* object;

                                \textcolor{comment}{// Get picked object}
                                \textcolor{keywordflow}{if} ( \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{PluginFunctions::getPickedObject}(
      node\_idx, \textcolor{keywordtype}{object}) ) \{

                                        \textcolor{comment}{// Show small dialog window}
                                        QDialog* dlg = \textcolor{keyword}{new} QDialog;

                                        QGridLayout* grid = \textcolor{keyword}{new} QGridLayout;
                                        QLabel* label = \textcolor{keyword}{new} QLabel;
                                        QString str = QString(\textcolor{stringliteral}{"You selected object "});
                                        str += QString::number(node\_idx);
                                        label->setText(str);
                                        grid->addWidget(label, 0,0);

                                        dlg->setLayout(grid);

                                        dlg->show();

                                        \textcolor{comment}{// Set last selected object}
                                        activeObject\_ = node\_idx;
                                \}
                                \textcolor{keywordflow}{else} \{
                                        emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"Picking failed"});
                                \}
                        \}

                        \textcolor{keywordflow}{return};
                \}

                \textcolor{comment}{// Continue traversing scene graph}
                \hyperlink{a00859}{ACG::SceneGraph::MouseEventAction} action(\_event, 
      \hyperlink{a03393_a341db97dfd8cf625b4d914481028c25a}{PluginFunctions::viewerProperties}().glState());
                \hyperlink{a03393_a95bf07301b5f4e367e9d6909acbaf7fd}{PluginFunctions::traverse}(action);
        \}

\} \textcolor{comment}{// End slotMouseEvent}

\textcolor{comment}{/*}
\textcolor{comment}{ * Is called when a key on the keyboard is pressed}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* \_event ) \{

        \hyperlink{a00330}{BaseObjectData}* object;

        \textcolor{comment}{// Get last clicked object (selected in pick mode)}
        \textcolor{keywordflow}{if} ( \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{PluginFunctions::getPickedObject}(activeObject\_, \textcolor{keywordtype}{object}) ) \{

                \textcolor{comment}{// Switch pressed keys}
                \textcolor{keywordflow}{switch} (\_event->key())
                \{
                        \textcolor{keywordflow}{case} Qt::Key\_J:

                                \textcolor{keywordtype}{object}->\hyperlink{a00330_adf4fdd191347abb3d104c8f740b7cbfd}{manipulatorNode}()->
      \hyperlink{a01320_a29d9dbfbaaf43140b9fb1eb121246af3}{loadIdentity}();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(10.0, axis\_x\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{case} Qt::Key\_K :

                                \textcolor{keywordtype}{object}->manipulatorNode()->loadIdentity();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(-10.0, axis\_x\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{case} Qt::Key\_H :

                                \textcolor{keywordtype}{object}->manipulatorNode()->loadIdentity();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(10.0, axis\_y\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{case} Qt::Key\_L :

                                \textcolor{keywordtype}{object}->manipulatorNode()->loadIdentity();
                                \textcolor{keywordtype}{object}->manipulatorNode()->rotate(-10.0, axis\_y\_);

                                \textcolor{keywordflow}{break};

                        \textcolor{keywordflow}{default}:
                        \textcolor{keywordflow}{break};
                \}

                \textcolor{comment}{// Perform rotation}
                \textcolor{keywordflow}{if} ( object->\hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{dataType}( \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} ) )
                        transformMesh(object->\hyperlink{a00330_adf4fdd191347abb3d104c8f740b7cbfd}{manipulatorNode}()->
      \hyperlink{a01320_a241c7bcd838b7825acd2db84a4f1c4f5}{matrix}(), (*\hyperlink{a03393_a11d22dc1c64537f87c014241cacc4340}{PluginFunctions::triMesh}(\textcolor{keywordtype}{object})));
                \textcolor{keywordflow}{if} ( object->\hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{dataType}( \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH} ) )
                        transformMesh(object->\hyperlink{a00330_adf4fdd191347abb3d104c8f740b7cbfd}{manipulatorNode}()->
      \hyperlink{a01320_a241c7bcd838b7825acd2db84a4f1c4f5}{matrix}(), (*\hyperlink{a03393_afe48c8dedf9bf541678277213548d61a}{PluginFunctions::polyMesh}(\textcolor{keywordtype}{object})));

                \textcolor{comment}{// Tell core that object has been modified}
                emit updatedObject(object->\hyperlink{a00329_a043f52f3105d646af193d4974482869d}{id}(), \hyperlink{a03407_ga01c97b7f74b26bfb8701f9dba7806b40}{UPDATE\_GEOMETRY});

                \textcolor{comment}{// Update view}
                emit updateView();
        \} \textcolor{keywordflow}{else} \{
                emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"No object has been selected to rotate! Select object first."});
        \}

\} \textcolor{comment}{// End slotKeyEvent}

\textcolor{comment}{/*}
\textcolor{comment}{ * Transform a mesh with the given transformation matrix}
\textcolor{comment}{ *}
\textcolor{comment}{ * \_mat : transformation matrix}
\textcolor{comment}{ * \_mesh : the mesh}
\textcolor{comment}{ */}
\textcolor{keyword}{template}<\textcolor{keyword}{typename} MeshT>
\textcolor{keywordtype}{void} MouseAndKeyPlugin::transformMesh(\hyperlink{a00797}{ACG::Matrix4x4d} \_mat, MeshT& \_mesh) \{

        \textcolor{keyword}{typename} MeshT::VertexIter v\_it = \_mesh.vertices\_begin();
        \textcolor{keyword}{typename} MeshT::VertexIter v\_end = \_mesh.vertices\_end();

        \textcolor{comment}{// Iterator over all vertices and transform them by \_mat}
        \textcolor{comment}{// Update normals}
        \textcolor{keywordflow}{for} (; v\_it != v\_end; ++v\_it) \{
                \_mesh.set\_point(v\_it, (\textcolor{keyword}{typename} MeshT::Point) \_mat.
      \hyperlink{a00797_aa3876968d35e1e7f6024ef19a1600743}{transform\_point}(
                                (\hyperlink{a01409}{OpenMesh::Vec3d})(\_mesh.point(v\_it))));
                \_mesh.set\_normal(v\_it, (\textcolor{keyword}{typename} MeshT::Point) \_mat.
      \hyperlink{a00797_a6286265568983d35eeea28c0c840b36c}{transform\_vector}(
                                (\hyperlink{a01409}{OpenMesh::Vec3d})(\_mesh.normal(v\_it))));
        \}

        \textcolor{keyword}{typename} MeshT::FaceIter f\_it = \_mesh.faces\_begin();
        \textcolor{keyword}{typename} MeshT::FaceIter f\_end = \_mesh.faces\_end();

        \textcolor{comment}{// Iterate over all faces and update face normals}
        \textcolor{keywordflow}{for} (; f\_it != f\_end; ++f\_it)
                \_mesh.set\_normal(f\_it, (\textcolor{keyword}{typename} MeshT::Point) \_mat.
      \hyperlink{a00797_a6286265568983d35eeea28c0c840b36c}{transform\_vector}(
                                (\hyperlink{a01409}{OpenMesh::Vec3d})(\_mesh.normal(f\_it))));

\} \textcolor{comment}{// End transformMesh}

\textcolor{comment}{/*}
\textcolor{comment}{ * Is called when context menu entry has been clicked}
\textcolor{comment}{ */}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::contextMenuItemSelected(QAction* \_action) \{

        \textcolor{comment}{// Get object id from QAction object}
        QVariant contextObject = \_action->data();
        \textcolor{keywordtype}{int} objectId = contextObject.toInt();

        \textcolor{keywordflow}{if} (objectId == -1) \{

                log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"Could not get associated object id."});
                \textcolor{keywordflow}{return};
        \}

        \textcolor{comment}{// Get node associated to object id}
        \hyperlink{a00327}{ACG::SceneGraph::BaseNode}* node = 
      \hyperlink{a03343_a1299f77548fd1f3541aeb9096c4b4b22}{ACG::SceneGraph::find\_node}(
                        \hyperlink{a03393_adb9160f9b0e24053d577b42efe1d37d4}{PluginFunctions::getSceneGraphRootNode}(), 
      objectId);

        \textcolor{comment}{// Return if node id was not valid}
        \textcolor{keywordflow}{if} (!node) \{

                log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca83500e26ef5eacbffbeb2b8e847ea5ae}{LOGINFO}, \textcolor{stringliteral}{"Could not find associated object."});
                \textcolor{keywordflow}{return};
        \}

        \hyperlink{a00330}{BaseObjectData}* obj;
        \textcolor{keywordflow}{if} (!\hyperlink{a03393_ac20ce4f5c004657788cc10f4ad465de0}{PluginFunctions::getObject}(objectId, obj))
                \textcolor{keywordflow}{return};

        \textcolor{comment}{// Hide object}
        obj->\hyperlink{a00330_a9d48ae4e906a01d1aed3e061799adfe4}{hide}();

\} \textcolor{comment}{// End contextMenuItemSelected}

Q\_EXPORT\_PLUGIN2( mouseandkeyplugin , \hyperlink{a00857}{MouseAndKeyPlugin} );

\end{DoxyCodeInclude}
 \hypertarget{tutorial_thread}{}\subsection{Using threads from within a plugin}\label{tutorial_thread}
When developing plugins for Open\+Flipper it is possible to start certain functions in a new thread. Note that when using threading there are a few things the developer has to be aware of\+:


\begin{DoxyItemize}
\item Using threads can cause Open\+Flipper to crash since the threading interface is {\bfseries still under development} at the moment.
\item The developer should be aware of the fact that threads run necessarily independent from the main thread (handling all of Qt's user interface elements). So accessing any of these gui objects won't be possible from within a thread. This means in general all signals to the Open\+Flipper core and all \hyperlink{a03393}{Plugin\+Functions}, always has to be done via a queued signal/slot connection between the thread function and the plugin.
\item In general, you cannot emit any Open\+Flipper signal from other threads than the main thread. However, some functions can be safely emitted. In this case, you will find a special remark in the documentation, e.\+g. {\ttfamily \hyperlink{a00784_a7c755e4f595b6c64aa1c33910ff0cc6f}{Logging\+Interface\+::log()}} or {\ttfamily \hyperlink{a00322_ace0d6b943ce94f48c40e8c0e17a8413e}{Base\+Interface\+::update\+View()}} 
\item The developer will have to pay special attention to avoid race conditions and dead-\/lock situations himself since Open\+Flipper can obviously not keep track of this.
\end{DoxyItemize}\hypertarget{a00244_OFT}{}\subsubsection{Open\+Flipper\+Threads in theory and practice}\label{a00244_OFT}
Using threads in Open\+Flipper is quite simple. All necessary class definitions are already available to plugins. So the first thing we have to do is instanciate an \hyperlink{a00920}{Open\+Flipper\+Thread} object and tell the core that we just launched a thread via start\+Job()\+:


\begin{DoxyCode}
\hyperlink{a00920}{OpenFlipperThread}* thread = \textcolor{keyword}{new} \hyperlink{a00920}{OpenFlipperThread}(\textcolor{stringliteral}{"My thread"});
emit startJob( \textcolor{stringliteral}{"My thread"}, \textcolor{stringliteral}{"My thread's description"} , 0 , 100 , \textcolor{keyword}{false});
\end{DoxyCode}


The first parameter of the constructor of the \hyperlink{a00920}{Open\+Flipper\+Thread} class denotes the identifier of the thread. We will use this id to reference our thread later on. The signal start\+Job() just tells the core that we are about to add a new thread named \char`\"{}\+My thread\char`\"{} and having \char`\"{}\+My thread's description\char`\"{} as the description (Open\+Flipper displays this in the process manager). The third and fourth parameter determine the progress scale (here going from 0 to 100). This should ideally correspond to the number of steps the thread's process consists of with desireably equal computation time per step. This is later used to inform the user about the progress of our process. The last parameter indicates whether the process should be blocking or not. If it is declared as blocking, all input to Open\+Flipper will be ignored until the processing has finished. If a thread is declared as non-\/blocking, the thread will appear in Open\+Flipper's process manager and the user will be able to normally use Open\+Flipper while the thread is running in the background.

The next thing we do is connecting the thread's signal to local signals/slots in order to keep track of updates concering the processing of our thread\+:


\begin{DoxyCode}
connect(thread, SIGNAL(finished(QString)),   \textcolor{keyword}{this}, SIGNAL(finishJob(QString)));

connect(thread, SIGNAL(\textcolor{keyword}{function}(QString)),   \textcolor{keyword}{this}, SLOT(testFunctionThread(QString)), Qt::DirectConnection)
      ;
\end{DoxyCode}


The thread emits the finished() signal when processing is done and the thread has been destroyed. We need to make sure to at least connect this signal to the global finish\+Job() signal of the \hyperlink{a01017}{Process\+Interface} so that the thread is removed from the process manager window. Additionally, if we want to do additional steps after the processing has finished (e.\+g. call updated\+Object() so that our change to an object are made visible), we can connect finished() to a function that takes care of that.

The function() signal needs to be connected to the function that will actually be processed in the thread. Once having connected these signals, we're about to start our thread\+:


\begin{DoxyCode}
\textcolor{comment}{// Launch the thread}
thread->start();

\textcolor{comment}{// Start processing of the function code (connected via signal OpenFlipperThread::function())}
thread->\hyperlink{a00920_a007c870b15292d058ac2faf4975f14f5}{startProcessing}();
\end{DoxyCode}


Now our function is processed within a new thread and either Open\+Flipper's process manager or a blocking widget showing the thread's progress pops up (depending on whether the thread is declared to be blocking or not). So the only thing that is still left to take core of is the continuous update of the thread's progress state. Assuming we run the following function in a separate thread\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} testFunctionThread(QString \_jobId) \{

    \textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0 ; i < 1000000; ++i) \{
       
        \textcolor{comment}{// Emit new progress state}
        \textcolor{keywordflow}{if}(i % 10000 == 0)
            emit setJobState(\_jobId, (\textcolor{keywordtype}{int})(i / 10000));
        
        \textcolor{keywordflow}{if}(i == 500000) \{
            \textcolor{comment}{// When half of the processing is finished}
            \textcolor{comment}{// change the job's description}
            emit setJobDescription(\_jobId, \textcolor{stringliteral}{"Half way done"});
        \}
    \}
\}
\end{DoxyCode}


This function contains a loop incrementing variable i one million times. Each 10000-\/th iteration we emit the signal set\+Job\+State(\+Q\+String,int) where we set the second parameter to an integer value between 0 and 100 (remember that we set these limits at the beginning when emitting the start\+Job() signal). Open\+Flipper now updates its progress bar state to the new value (scaled to a percentage of the interval that was defined in start\+Job). If half of the loop is processed (i == 500000), we additionally want to update the progresses' description that is also displayed in Open\+Flipper's progress manager or the blocking widget of the thread, respectively. \hypertarget{interfaces}{}\section{Plugin Interfaces}\label{interfaces}
\hypertarget{a00206_pluginInterfacesIntro}{}\subsection{Introduction}\label{a00206_pluginInterfacesIntro}
Open\+Flipper provides a flexible plugin interface. Plugins can implement various interfaces.~\newline
 Each interface provides special signals/slots or functions to communicate with the core or to react on special events. The most important interface is the \hyperlink{a00322}{Base\+Interface}. This Interface provides the core functionality for the plugin. E.\+g. loading the plugin, specifying its name and basic communication regarding object changes or view updates ( See \hyperlink{a00322}{Base\+Interface} for further details).~\newline
 Additional functionality is provided by the other interfaces. For user interaction one typically uses the \hyperlink{a00860}{Mouse\+Interface} or \hyperlink{a00756}{Key\+Interface} which will provide events based on mouse or keyboard interaction.~\newline
 The user interface of Open\+Flipper can also be used by plugins. The Menubar\+Interface provides functions to add additional icons to the menubar while the \hyperlink{a01311}{Toolbox\+Interface} can add widgets to the toolbox on the right of the Open\+Flipper screen.\hypertarget{a00206_pluginInterfacesUsage}{}\subsection{Usage of plugin interfaces}\label{a00206_pluginInterfacesUsage}
To use functions from one of the interfaces you have to do the following steps\+: 
\begin{DoxyItemize}
\item Include the interface header file in your plugins header file 
\item derive your plugin from the Interface class defined in the interface header file 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S( Interface\+Name ) macro to your plugin class containing only the name of the interface to be used 
\item Add the signature of the signals you want to use to the signals of your class definition. 
\item Add the signature of a slot you want to implement to the {\bfseries private} {\bfseries slots} of your class definition. 
\end{DoxyItemize}It is not necessary to implement all signals or slots from one of the interfaces (Except some functions from \hyperlink{a00322}{Base\+Interface}). The core application will only use the slots you define in the plugins header file and ignore all other functions.~\newline
 If you recognize that an interface function of your plugin is not called, check if it is defined correctly in your plugin class and the signature is the same as in the interface.~\newline
 \hypertarget{a00206_pluginInterfacesBaseInterface}{}\subsection{Open\+Flipper Base Interface}\label{a00206_pluginInterfacesBaseInterface}
\hyperlink{baseInterfacePage}{Base Interface}

All plugins in Open\+Flipper have to implement some basic functions from \hyperlink{a00322}{Base\+Interface}. They are used to integrate and manage the plugins by the core application. See \hyperlink{baseInterfacePage}{Base Interface} for details.\hypertarget{a00206_pluginInterfacesGroups}{}\subsection{Interfaces}\label{a00206_pluginInterfacesGroups}
The following groups of Interfaces are available\+:

\hyperlink{pluginInterfacesUIOverview}{User Interface control}

\hyperlink{pluginInterfacesDataHandling}{Object and Data Handling}

\hyperlink{pluginInterfacesInputDevices}{Input Devices}

\hyperlink{pluginInterfacesRendering}{Rendering Interface}

\hyperlink{pluginInterfacesOtherInterfaces}{Other Interfaces}\hypertarget{a00206_todoInterfaces}{}\subsection{Interfaces T\+O\+D\+O for documentation\+:}\label{a00206_todoInterfaces}
\hypertarget{a00206_TexturePlugin}{}\subsubsection{Texture Interface}\label{a00206_TexturePlugin}
 Allows your plugin to provide a texture. ( \hyperlink{a01298}{Texture\+Interface} )\hypertarget{a00206_ViewPlugin}{}\subsubsection{View Interface}\label{a00206_ViewPlugin}
 This interface is used to add additional view widgets ( \hyperlink{a01457}{View\+Interface} ).\hypertarget{a00206_INIPlugin}{}\subsubsection{Use Inifiles to store information}\label{a00206_INIPlugin}
 Receive an event if an ini file is opened by the application. ( \hyperlink{a00727}{I\+N\+I\+Interface} )~\newline
\hypertarget{baseInterfacePage}{}\subsection{Base Interface}\label{baseInterfacePage}
The \hyperlink{a00322}{Base\+Interface} has to be used by every plugin in Open\+Flipper. As the minimum a plugin has to implement the \hyperlink{a00322_a2b351aa6ef0eb368bce735e243235958}{Base\+Interface\+::name()} and \hyperlink{a00322_a43f0d3612695b53c848c14f48fea9a7a}{Base\+Interface\+::description()} functions from this interface.

To use the \hyperlink{a00322}{Base\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02437}{Base\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00322}{Base\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Base\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them except \hyperlink{a00322_a43f0d3612695b53c848c14f48fea9a7a}{Base\+Interface\+::description()} and \hyperlink{a00322_a2b351aa6ef0eb368bce735e243235958}{Base\+Interface\+::name()} ) 
\end{DoxyItemize}\hypertarget{a00138_baseInterfacePluginInitialization}{}\subsubsection{Plugin Initialization}\label{a00138_baseInterfacePluginInitialization}
The Open\+Flipper startup process consists of several steps, which are shown in this image\+:  Open\+Flipper first starts its core system. Therefore it loads the settings, parses command line options and initializes the Q\+T library. Afterwards the object and scenegraph management are initialized. The next step creates the core user interface and the logging system. Now the plugins are loaded in the following way\+:
\begin{DoxyEnumerate}
\item All the plugins are loaded into memory.
\item For each plugin, the interfaces get connected to the plugin and afterwards the \hyperlink{a00322_a705fdf2e221af47198aed689b0da7a32}{Base\+Interface\+::initialize\+Plugin()} function is called. (Here you can setup your internal variables). After execution of this slot your plugin should be fully functional. Only gui elements may be uninitialized and should be created in \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()}. The order how plugins are loaded is not fixed. So you should not rely or communicate with other plugins in this slot.
\item For each plugin the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function is called. Here you can setup your gui elements and start sending signals to the core.
\item For each plugin the \hyperlink{a00727_a3b8ae0e16b554c4b96a6e2c6071dbebb}{I\+N\+I\+Interface\+::load\+Ini\+File\+Options()} slot is called (if the interface is implemented). This slot can be used to load additional options from I\+N\+I files. (D\+E\+P\+R\+E\+C\+A\+T\+E\+D! Use the \hyperlink{a02495_aed11a5e83be5401cb8c2860fd9db6734}{Open\+Flipper\+Settings()} class instead)
\end{DoxyEnumerate}

\begin{DoxyNote}{Note}
-\/ Do not create objects via add\+Empty or load objects during Open\+Flipper startup, as the rendering system is not ready yet! 

-\/ The ini interface is deprecated for loading or storing plugin options. Please use \hyperlink{a02495_aed11a5e83be5401cb8c2860fd9db6734}{Open\+Flipper\+Settings()} instead.
\end{DoxyNote}
Afterwards the plugin initialization is complete and the core sets up the final gui.\hypertarget{a00138_baseInterfaceObjectUpdateNotification}{}\subsubsection{Object Update Notification}\label{a00138_baseInterfaceObjectUpdateNotification}
The objects in Open\+Flippers scene are stored and managed in Open\+Flippers core. If a plugin changes one of the objects, it has to notify the core about that change. In turn Open\+Flipper will then notify all other plugins about this change. This functionality is provided by the signals and slots for \hyperlink{a00322_BaseInterfaceUpdateSlots}{update handling} .\hypertarget{a00138_baseInterfacegeneralObjectUpdates}{}\paragraph{General update notifications}\label{a00138_baseInterfacegeneralObjectUpdates}


If you change data you have to emit one of \hyperlink{a00322_a287b9cdde5984fae3e19b051284cdaa2}{Base\+Interface\+::updated\+Object(int)} or \hyperlink{a00322_a49a38de5185d75fc95e7932b06416b55}{Base\+Interface\+::updated\+Object(int,const Update\+Type\&)}.~\newline
 \hyperlink{a00322_a287b9cdde5984fae3e19b051284cdaa2}{Base\+Interface\+::updated\+Object(int)} forces an update of the whole object while \hyperlink{a00322_a49a38de5185d75fc95e7932b06416b55}{Base\+Interface\+::updated\+Object(int,const Update\+Type\&)} can be restricted to a part of the object ( Geometry,Selection, ... ; see \hyperlink{a01393}{Update\+Type} ) and is therefore faster and should be preferred.

Both signals get the id of the object that has been updated or -\/1 if all should be updated( you should not use -\/1 if you know what object changed!).

If the signal is emitted, the core calls \hyperlink{a00322_a1bd91e2e79467c2fff4d595fcdaffdf3}{Base\+Interface\+::slot\+Object\+Updated( int , const Update\+Type\& )} of every plugin. You can implement this slot if you need to react on object changes.

\begin{DoxyNote}{Note}
Don't emit updated\+Object from within slot\+Object\+Updated as this will cause an endless loop! 

If the object id passed to the functions is -\/1 all objects should be treated as updated.
\end{DoxyNote}
After all plugins have been informed, the node itself gets updated. This means that for the corresponding object the update function is called (\hyperlink{a00330_a26063c9234d22ec1306e4f163e3f88be}{Base\+Object\+Data\+::update()} ). This function is implemented by every object type in Open\+Flipper and has to take care of reacting to modifications of the object. E.\+g. the \hyperlink{a01339}{Tri\+Mesh\+Object}, this could mean, that the \hyperlink{a03368}{Open\+Mesh} data has changed (U\+P\+D\+A\+T\+E\+\_\+\+G\+E\+O\+M\+E\+T\+R\+Y). The object would than trigger an update of the rendering buffers which are used to draw the mesh. \begin{DoxyNote}{Note}
You should not call the update functions of an object directly as this means unnecessary overhead (As the core will call the function anyway on an update).
\end{DoxyNote}
For more details about the \hyperlink{a01393}{Update\+Type} read the documentation about \hyperlink{a01393}{Update\+Type} and \hyperlink{a03407}{predefined update types}. A description for adding custom update types at runtime is available \hyperlink{a03408}{here}.

\begin{DoxyNote}{Note}
If you do not specify an \hyperlink{a01393}{Update\+Type}, it will fall back to the default value U\+P\+D\+A\+T\+E\+\_\+\+A\+L\+L for compatibility reasons which actually updates each of the types. Unless it is really necessary this should generally be avoided since it consumes a lot of computation time. So try to narrow the updated properties as uch as possible!
\end{DoxyNote}
\hypertarget{a00138_baseInterfaceNodeUpdates}{}\paragraph{Node updates}\label{a00138_baseInterfaceNodeUpdates}
It is also possible to insert custom nodes into the scenegraph. If you changed these nodes, you also have to inform the core. This is achieved by the \hyperlink{a00322_a38b332c6d6faf5f1c6336199e7a9933e}{Base\+Interface\+::node\+Visibility\+Changed()} function. As nodes are usually attached to objects in the scene, you should pass the id of the object to the function or -\/1 if its a global node.\hypertarget{a00138_baseInterfaceObjectRemoval}{}\paragraph{Object Removal notifications}\label{a00138_baseInterfaceObjectRemoval}
If the complete scene gets cleared, the slot \hyperlink{a00322_aa00a3111da5d92c9d001a0a8272c5a91}{Base\+Interface\+::slot\+All\+Cleared()} will be executed after all objects have been removed from the scene. A more fine grained information about objects added or removed from the scene is available via the \hyperlink{loadSaveInterfacePage}{Load/\+Save Interface} .\hypertarget{a00138_baseInterfaceSpecialNotifications}{}\paragraph{Special Notifications}\label{a00138_baseInterfaceSpecialNotifications}
There are three additional slots that are called by the core, if the object selection(source/target \hyperlink{a00322_ac8e436c6df44130c1696069754bfc685}{Base\+Interface\+::slot\+Object\+Selection\+Changed()} ), the object visibility(Show/\+Hide \hyperlink{a00322_aca92d1efce421f6a6d4272083f6631d7}{Base\+Interface\+::slot\+Visibility\+Changed()}) or other properties changed (e.\+g. name \hyperlink{a00322_aa7832a19f7fc5be5280035f688583fda}{Base\+Interface\+::slot\+Object\+Properties\+Changed()} )\hypertarget{a00138_baseInterfaceSceneUpdateNotification}{}\subsubsection{Scene Update Notifications}\label{a00138_baseInterfaceSceneUpdateNotification}
Open\+Flipper manages the scene updates in its core. If objects get updated the scene will be automatically redrawn. Nevertheless, you can force an update of the scene by emitting the signal \hyperlink{a00322_ace0d6b943ce94f48c40e8c0e17a8413e}{Base\+Interface\+::update\+View()}. Open\+Flipper restricts the number of redraws to avoid useless updates. In the Options you can set a maximal frame rate or disable the restriction. The following image shows how the updates process is managed\+:



If the view (viewer position /viewing direction) has been changed, the slot \hyperlink{a00322_a0e44db8563463a86bd9f125d3cdf7fc2}{Base\+Interface\+::slot\+View\+Changed()} will be called, before anything gets rendered. If you need to modify renderings or anything else depending on the current view, you can use this slot and adapt to the new view (e.\+g. modifying a shader). \begin{DoxyNote}{Note}
Be careful, not to change the view in this function or you get an endless loop! After the complete scene has been drawn, the core will inform the plugins via the Base\+I\+Nterface\+::slot\+Scene\+Redrawn().
\end{DoxyNote}
\hypertarget{a00138_baseInterfaceManagementFunctions}{}\subsubsection{Management Functions}\label{a00138_baseInterfaceManagementFunctions}
There are some basic functions for managing plugins. The \hyperlink{a00322_a43f0d3612695b53c848c14f48fea9a7a}{Base\+Interface\+::description()} function can be used to provide a description for the plugin which will be printed along with the plugin name. The \hyperlink{a00322_a2b351aa6ef0eb368bce735e243235958}{Base\+Interface\+::name()} function has to return the name of the plugin. This name will also be used inside the scripting system. Additionally it is possible to provide a plugin version number with \hyperlink{a00322_a1223005ae02b961eb515823343811adc}{Base\+Interface\+::version()}.

Open\+Flippers scripting system can use all public slots defined in your plugin. If it should also provide a small text description for your functions, you could set them with \hyperlink{a00322_a0a559d28f41b730c5130ffc84f4a9480}{Base\+Interface\+::set\+Slot\+Description()}. Even if you do not implement scripting functions in your plugin, the core will then be able to provide this information to the user.

Along with the scripting, Open\+Flipper provides a batch mode, running without any user interface. If your plugin will work without an user interface (e.\+g. only scripting functions), you can define a slot \hyperlink{a00322_a79ba17f1f9aca08b95ec56f85d2d1204}{Base\+Interface\+::nogui\+Supported()}. This empty slot is used to tell the core, that the plugin can work in batch mode. Otherwise it will not be loaded when running a batch file. \hypertarget{pluginInterfacesUIOverview}{}\subsection{User Interface control}\label{pluginInterfacesUIOverview}
This page gives an overview over the available interfaces which control Open\+Flippers User interface.

\hyperlink{contextMenuInterfacePage}{Context Menu Interface}  Add context menu entries in your plugin. ( \hyperlink{contextMenuInterfacePage}{Context Menu Interface} ) ~\newline
 \hyperlink{loggingInterfacePage}{Logging Interface}  This is an Interface for Logging to the included log widget. You can log to different levels (L\+O\+G\+O\+U\+T,L\+O\+G\+W\+A\+R\+N,L\+O\+G\+E\+R\+R,L\+O\+G\+I\+N\+F\+O) ( \hyperlink{loggingInterfacePage}{Logging Interface} ). ~\newline
 \hyperlink{menuInterfacePage}{Menu Interface}  Provides a function to create entries in the menubar ( \hyperlink{menuInterfacePage}{Menu Interface} ). ~\newline
 \hyperlink{optionsInterfacePage}{Options Widget Interface}  This Interface is used by plugins which will provide their own options by integrating an options widget into Open\+Flipper's options window ( \hyperlink{optionsInterfacePage}{Options Widget Interface} ). ~\newline
 \hyperlink{pickingInterfacePage}{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars} ~\newline
 ~\newline
Handle pick modes in your plugin ( \hyperlink{pickingInterfacePage}{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars} ) ~\newline
 \hyperlink{statusbarInterfacePage}{Statusbar Interface}  This interface is used to display messages in the status bar or adding widgets to it ( \hyperlink{statusbarInterfacePage}{Statusbar Interface} ). ~\newline
 \hyperlink{toolboxInterfacePage}{Toolbox Interface}  Provides functions to create a separate widget in the toolbox on the right ( \hyperlink{toolboxInterfacePage}{Toolbox Interface} ). ~\newline
 \hyperlink{toolbarInterfacePage}{Toolbar Interface}  Provides a function to add toolbar buttons. ( \hyperlink{toolbarInterfacePage}{Toolbar Interface} ) ~\newline


\hyperlink{viewModeInterfacePage}{View Mode Interface}  Specify own view modes setting which toolboxes/toolbars/context menus will be visible( \hyperlink{viewModeInterfacePage}{View Mode Interface} )

\hyperlink{AboutInfoInterfacePage}{About Info interface}  Add own information to Open\+Flippers abouot dialog \hypertarget{contextMenuInterfacePage}{}\subsection{Context Menu Interface}\label{contextMenuInterfacePage}
 ~\newline
The \hyperlink{a00460}{Context\+Menu\+Interface} can be used by plugins to add menu entries to Open\+Flippers U\+I. The entries will be added to Open\+Flippers context\+Menus in the gl\+View (see image). You can choose between context menus for objects, nodes or the background.~\newline
 The given context menu entries will be shown when the user right clicks on the corresponding primitive (node,object) in the G\+L viewer.

To use the \hyperlink{a00460}{Context\+Menu\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02438}{Context\+Menu\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00460}{Context\+Menu\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Context\+Menu\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

Usually you should implement the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function from \hyperlink{a00322}{Base\+Interface}. In this function you can setup your menus.~\newline
 You have to create a Q\+Action. The signals and slots of your actions have to be connected to your plugin. Just connect them as usual. Only visibility of the menu is handled by the core. You can also add submenus to the context menus. Just add the action for the menu ( menu-\/$>$menu\+Action() )

Before a menu of the requested type is shown, an update function for the specific type will be invoked by the core depending on your type of context menu ( \hyperlink{a00460_a74cbe2257620672cbc565cc6536c0332}{Context\+Menu\+Interface\+::slot\+Update\+Context\+Menu()}, \hyperlink{a00460_a5f04c1c620257db8a0b45b41265bdf37}{Context\+Menu\+Interface\+::slot\+Update\+Context\+Menu\+Node()}, \hyperlink{a00460_a4ef981a842558cedae3b6c882af11416}{Context\+Menu\+Interface\+::slot\+Update\+Context\+Menu\+Background()} ). In this function you can update entries based on the object that was clicked on. The id of the node or the object is provided by these update functions.

The following code shows a simple example to create a menu entry in the context menu. 
\begin{DoxyCode}
\textcolor{comment}{// Setup the menus in initialize plugins}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized()
\{
  \textcolor{comment}{// create a global QMenu in the plugin that contains our menu}
  \textcolor{comment}{// in the header is: }
  \textcolor{comment}{// QMenu* contextMenu\_}
  contextMenu\_ = \textcolor{keyword}{new} QMenu(tr(\textcolor{stringliteral}{"Select"}));
  
  \textcolor{comment}{// Create a menu action called all in the Selection context menu}
  \textcolor{comment}{// in the header is:   }
  \textcolor{comment}{// QAction* menuAction\_}
  menuAction\_ = contextMenu\_->addAction( tr(\textcolor{stringliteral}{"All Mesh vertices"}) );
  menuAction->setToolTip(tr(\textcolor{stringliteral}{"Select all"}));
  
  \textcolor{comment}{// Add the new menu to OpenFlippers context menu fot objects}
  \textcolor{comment}{// Show the context menu for triangle meshes}
  emit addContextMenuItem(contextMenu\_->menuAction() , \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} , 
      \hyperlink{a02438_a238952a111d7daede783625350d7b287aa9f1dad0ebec85ff7a0601f62be8084d}{CONTEXTOBJECTMENU} );
  
  \textcolor{comment}{// Show the context menu for poly meshes meshes}
  emit addContextMenuItem(contextMenu\_->menuAction() , \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH}     , 
      \hyperlink{a02438_a238952a111d7daede783625350d7b287aa9f1dad0ebec85ff7a0601f62be8084d}{CONTEXTOBJECTMENU} );
  \}
  
  
\textcolor{comment}{// Example function to update the context menu based on the given object id}
\textcolor{keywordtype}{void} ExamplePlugin::slotUpdateContextMenu( \textcolor{keywordtype}{int} \_objectId )\{
  
  \textcolor{comment}{// Get the corresponding object of the given id or return}
  \hyperlink{a00330}{BaseObjectData}* \textcolor{keywordtype}{object} = 0;
  \textcolor{keywordflow}{if} ( !\hyperlink{a03393_ac20ce4f5c004657788cc10f4ad465de0}{PluginFunctions::getObject}( \_objectId, \textcolor{keywordtype}{object} ) ) \{
    \textcolor{keywordflow}{return};
  \}
  
  \textcolor{comment}{// If its a triangle mesh, rename the to triangle mesh selection}
  \textcolor{keywordflow}{if} (object->\hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{dataType}( \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} ) ) 
    menuAction\_->setText(\textcolor{stringliteral}{"All Triangle mesh vertices"});
  
  \textcolor{comment}{// If its a triangle mesh, rename the to poly mesh selection}
  \textcolor{keywordflow}{if} ( object->\hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{dataType}( \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH} ) )  
    menuAction\_->setText(\textcolor{stringliteral}{"All Triangle mesh vertices"});    
  
\}


\}
\end{DoxyCode}


Signals and slots of your menus (e.\+g. from an action inside it) can be directly connected to signals and slots in your plugin. Therefore the embedding of your menus into the Open\+Flippers context menu list is fully transparent. \hypertarget{loggingInterfacePage}{}\subsection{Logging Interface}\label{loggingInterfacePage}
 The Logging interface can be used by plugins to print messages in Open\+Flippers log widget below the gl viewer (See image). The log widget can apply filters to visualize only the messages of a certain importance. The widget has 3 different modes, which can be toggled by pressing Ctrl + L\+: 
\begin{DoxyItemize}
\item Docked automatic mode\+: In this mode the widget is at the bottom and will hide itself if not used. 
\item Docked mode\+: The widget is always visible and docked at the bottom 
\item Undocked\+: The widget is undocked into a separate window 
\end{DoxyItemize}

The message importance level can be specified by the Logtype enum. There are four different levels which describe the importance and are represented by different colors in the log widget. 
\begin{DoxyItemize}
\item Out\+: Simple output messages in black 
\item Info\+: Information messages printed in green 
\item Warn\+: Warnings in yellow 
\item Errors\+: Error messages printed in red 
\end{DoxyItemize}

To use the \hyperlink{a00784}{Logging\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02444}{Logging\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00784}{Logging\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Logging\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

If you use the interface, all messages printed from that plugin will be prepended with the name of the plugin to identify the origin of the message.~\newline
The following code sends a log message 
\begin{DoxyCode}
emit log(\hyperlink{a02444_a595b2880f3ae74561ba390e3fd8c0e7ca39fe22d7b704805a8e30697a4a07d8fc}{LOGERR},tr(\textcolor{stringliteral}{"Error message"}));
\end{DoxyCode}
 \hypertarget{menuInterfacePage}{}\subsection{Menu Interface}\label{menuInterfacePage}
 ~\newline
The \hyperlink{a00804}{Menu\+Interface} can be used by plugins to add menu entries to Open\+Flippers U\+I. The entries will be added to Open\+Flippers menubar or submenus (See image).

To use the \hyperlink{a00804}{Menu\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02445}{Menu\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00804}{Menu\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Menu\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

Usually you should implement the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function from \hyperlink{a00322}{Base\+Interface}. In this function you can setup your menus.

The following code shows a simple example to create a menu entry in the file menu. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} PrintPlugin::pluginsInitialized()
\{
  \textcolor{comment}{// Create a submenu called printing}
  QMenu *printMenu = \textcolor{keyword}{new} QMenu(tr(\textcolor{stringliteral}{"&Printing"}));
  
  \textcolor{comment}{// Set an icon for this submenu}
  printMenu->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+\textcolor{stringliteral}{"
      document-print.png"}));
  
  \textcolor{comment}{// Add the new submenu to OpenFlippers file menu}
  emit addMenubarAction(printMenu->menuAction(), \hyperlink{a02445_ad39130383a83ab4f6ceb37c50b36b269}{FILEMENU} );
  
  \textcolor{comment}{// Create an action to be added to the submenu}
  QAction* AC\_Print = \textcolor{keyword}{new} QAction(tr(\textcolor{stringliteral}{"&Print"}), \textcolor{keyword}{this});
  
  \textcolor{comment}{// Set status tip for this entry}
  AC\_Print->setStatusTip(tr(\textcolor{stringliteral}{"Print the current view"}));
  
  \textcolor{comment}{// Set icon for the entry}
  AC\_Print->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+\textcolor{stringliteral}{"
      document-print.png"}));
  
  \textcolor{comment}{// connect the actions triggered slot to a local slot in this plugin.}
  connect(AC\_Print, SIGNAL(triggered()), \textcolor{keyword}{this}, SLOT(printView()));
  
  \textcolor{comment}{// add the new action to the print submenu}
  printMenu->addAction(AC\_Print);
\}
\end{DoxyCode}


If you want to create a toplevel menu you can use the following code snippet\+: 
\begin{DoxyCode}
\textcolor{comment}{//Pointer to the new menu}
QMenu *topLevelMenu;

\textcolor{comment}{// This function checks if a menu called "Toplevel" exists and returns it in the pointer.}
\textcolor{comment}{// If it does not exist, it is automatically created.}
emit getMenubarMenu(tr(\textcolor{stringliteral}{"Toplevel"}), topLevelMenu, \textcolor{keyword}{true} );
\end{DoxyCode}


Signals and slots of your menus (e.\+g. from an action inside it) can be directly connected to signals and slots in your plugin. Therefore the embedding of your menus into the Open\+Flippers menu list is fully transparent. \hypertarget{optionsInterfacePage}{}\subsection{Options Widget Interface}\label{optionsInterfacePage}
 ~\newline
The \hyperlink{a00943}{Options\+Interface} can be used by plugins to add an own widget to Open\+Flippers Options dialog.

This Interface should be used by plugins which will provide their own options widget in Open\+Flippers Options Dialog. For your options to show up in Open\+Flippers Options window implement the initialize\+Options\+Widget() function.

The widget you return with this slot will be integrated into the options window and when the user hits the apply-\/ or ok-\/button in the options window the slot apply\+Options() is called and thus enables you to store the changes in your options.

To use the \hyperlink{a00943}{Options\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02448}{Options\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00943}{Options\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Options\+Interface) to your plugin class 
\item Implement all functions from this interface 
\end{DoxyItemize}


\begin{DoxyCode}
\textcolor{keywordtype}{bool} ExamplePlugin::initializeOptionsWidget(QWidget*& \_widget)\{

  \textcolor{comment}{// Global variable .. in header file: QWidget* optionswidget\_;}
  optionsWidget\_ = \textcolor{keyword}{new} QWidget();

  \textcolor{comment}{// Setup widget here}

  \textcolor{comment}{//connect the signals}
  connect(optionsWidget\_->setA,      SIGNAL( clicked() ), \textcolor{keyword}{this}, SLOT( slotSetA() ) );

  \_widget = optionsWidget\_;

  \textcolor{keywordflow}{return} \textcolor{keyword}{true};
\}

\textcolor{keywordtype}{void} ExamplePlugin::applyOptions()\{

  \textcolor{comment}{// Get some value from the widget}
  \textcolor{keywordtype}{int} value = optionsWidget\_->getValue();

  \textcolor{comment}{//}
  ...

\}
\end{DoxyCode}
 \hypertarget{pickingInterfacePage}{}\subsection{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars}\label{pickingInterfacePage}
~\newline
 ~\newline
\hypertarget{a00160_pickingInterface_functionality}{}\paragraph{Functionality}\label{a00160_pickingInterface_functionality}
Open\+Flipper uses several different Action\+Modes. These include, Light interaction (Changing lights), Move interaction (navigating through the scene) and the picking interaction. The picking interaction is separated into different pick modes. These modes are usually defined by plugins and are used to restrict the mouse interaction to one plugin. E.\+g. if the current picking mode is \char`\"{}vertex selection\char`\"{}, all other plugins that react on mouse events, but are not responsible for the \char`\"{}vertex selection\char`\"{} will ignore these events.\hypertarget{a00160_pickingInterface_managing}{}\paragraph{Managing Pick Modes}\label{a00160_pickingInterface_managing}
Pick modes can be created in your plugin initialization. You can add them as visible pick modes (visible in the context menus of objects) or as hidden pick modes \hyperlink{a00957_a253fb435408607bea3e4507833fe81c4}{Picking\+Interface\+::add\+Hidden\+Pick\+Mode()} ( This should be preferred! ). You can also set a special cursor that will be used when your pick mode is active via \hyperlink{a00957_a05a636ef566e849d32a97a4ba2e03121}{Picking\+Interface\+::set\+Pick\+Mode\+Cursor()}. If you need to enable mouse tracking in your mode, you can use \hyperlink{a00957_ae0b47da43aca269001f2eec53bdb1345}{Picking\+Interface\+::set\+Pick\+Mode\+Mouse\+Tracking()}. This will result in mouse events even if no button is pressed.


\begin{DoxyCode}
\textcolor{comment}{// When the plugin gets initialized}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized() \{

 \textcolor{comment}{// Add pick mode}
 emit addPickMode(\textcolor{stringliteral}{"ExamplePlugin Pick Mode"});

\}

\textcolor{comment}{// Triggered when the pick mode got changed.}
\textcolor{keywordtype}{void} ExamplePlugin::slotPickModeChanged(\textcolor{keyword}{const} std::string& \_mode) \{

  \textcolor{comment}{// Enable a button depending on the current pick mode}
  button\_->setEnabled(\_mode == \textcolor{stringliteral}{"ExamplePlugin Pick Mode"});

\}

\textcolor{comment}{// From MouseInterface}
\textcolor{keywordtype}{void} ExamplePlugin::slotMouseEvent(QMouseEvent* \_event) \{

  \textcolor{comment}{// Check if your pick mode is currently active}
  \textcolor{keywordflow}{if} ( \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}() == \textcolor{stringliteral}{"ExamplePlugin Pick Mode"} && 
      \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}() == Viewer::PickingMode ) \{

    \textcolor{comment}{// Do something}

  \}

\}
\end{DoxyCode}


A change of the current pick mode can be detected by the \hyperlink{a00957_a5bf0bf6559d2b5411d0f3270415242c1}{Picking\+Interface\+::slot\+Pick\+Mode\+Changed()} function.\hypertarget{a00160_pickingInterface_toolbars}{}\paragraph{Pick\+Mode Toolbars}\label{a00160_pickingInterface_toolbars}
~\newline
 ~\newline
Additionally it is possible to show a special toolbar in Open\+Flippers viewer when your pick mode is active. This is especially Useful, when you can change the interaction type by buttons in the bar, e.\+g. select vertices or faces. Every time your pick mode is activated, your toolbar will be visible at the top of the viewer. Use the functions \hyperlink{a00957_a90ba1e0b2ccf751f33dac49c757b9276}{Picking\+Interface\+::set\+Pick\+Mode\+Toolbar()} and \hyperlink{a00957_a82e4afc52fd1d2e0222b605f1e926ec4}{Picking\+Interface\+::remove\+Pick\+Mode\+Toolbar()} for controlling these toolbars. The embedding is fully transparent so that you can manage your toolbar and connect signals and slots as usual.


\begin{DoxyCode}
\textcolor{comment}{// When the plugin gets initialized}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized() \{

  \textcolor{comment}{// Global variable QToolBar* pickToolbar\_}
  pickToolbar\_ = \textcolor{keyword}{new} QToolBar(tr(\textcolor{stringliteral}{"Example Pickmode Toolbar"}));
  pickToolbar\_->setAttribute(Qt::WA\_AlwaysShowToolTips, \textcolor{keyword}{true});

  QActionGroup* pickToolBarActions = \textcolor{keyword}{new} QActionGroup(pickToolbar\_);

  QAction* action = \textcolor{keyword}{new} QAction(tr(\textcolor{stringliteral}{"Action"}),pickToolBarActions);
  action->setStatusTip(tr(\textcolor{stringliteral}{"Action description"}));
  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+\textcolor{stringliteral}{"icon.png"})
       );
  action->setCheckable(\textcolor{keyword}{true});
  pickToolbar\_->addAction(action);

  \textcolor{comment}{// Connect to a local slot. The embedding is transparent, so you can connect all your actions and
       toolbars as usual.}
  connect(pickToolBarActions, SIGNAL(triggered(QAction*)), \textcolor{keyword}{this}, SLOT(slotPickToolbarAction(QAction*)) );

  emit setPickModeToolbar (\textcolor{stringliteral}{"ExamplePlugin Pick Mode"}, pickToolbar\_);
\}
\end{DoxyCode}
\hypertarget{a00160_pickingInterface_usage}{}\paragraph{Usage}\label{a00160_pickingInterface_usage}
To use the \hyperlink{a00957}{Picking\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02449}{Picking\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00957}{Picking\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Picking\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{statusbarInterfacePage}{}\subsection{Statusbar Interface}\label{statusbarInterfacePage}
 ~\newline
The \hyperlink{a01237}{Statusbar\+Interface} can be used by plugins to send messages to Open\+Flippers statusbar. The statusbar is located below the G\+L viewer.

Messages can be controlled via \hyperlink{a01237_a835c95b99470312bb2e325040202077f}{Statusbar\+Interface\+::set\+Status()},\hyperlink{a01237_acd7fc9bb1de4e3e2765bff653d5a7ee7}{Statusbar\+Interface\+::clear\+Status\+Message()}

Additionally it is possible to add small widgets to it ( \hyperlink{a01237_acde7d8b8db9294287030f545061edb3d}{Statusbar\+Interface\+::add\+Widget\+To\+Statusbar}).

A small icon can be controlled to indicate Open\+Flippers status via \hyperlink{a01237_a835c95b99470312bb2e325040202077f}{Statusbar\+Interface\+::set\+Status()}.

To use the \hyperlink{a01237}{Statusbar\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02469}{Statusbar\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01237}{Statusbar\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Statusbar\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

The following code shows a simple example to send a message to the statusbar. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} ExamplePlugin::function()
\{
  ...

  \textcolor{comment}{// Print the text "Your Status Message" for 4 seconds in the statusBar}
  emit showStatusMessage( tr(\textcolor{stringliteral}{"Your Status Message"}), 4000 );

  ...
\}
\end{DoxyCode}


The following code shows a simple example to add a widget to the statusbar. Usually you should implement the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function from \hyperlink{a00322}{Base\+Interface}. In this function you can setup your widget for the status bar. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized()
\{

  \textcolor{comment}{// Create the widget}
  QWidget* infoBar = \textcolor{keyword}{new} QWidget();

  \textcolor{comment}{// Setup buttons or anything else in your widget}
  ...

  \textcolor{comment}{// Add the new widget to the statusBar}
  emit addWidgetToStatusbar(infoBar);

\}
\end{DoxyCode}
 \hypertarget{toolboxInterfacePage}{}\subsection{Toolbox Interface}\label{toolboxInterfacePage}


The \hyperlink{a01311}{Toolbox\+Interface} can be used by plugins to add widgets to the list of toolboxes in Open\+Flippers U\+I. The toolboxes are located left or right of the G\+L viewer (See image).

The list can be hidden by pressing Ctrl + t.

To use the \hyperlink{a01311}{Toolbox\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02472}{Toolbox\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01311}{Toolbox\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Toolbox\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

Usually you should implement the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function from \hyperlink{a00322}{Base\+Interface}. In this function you can setup your toolbox ( some kind of Q\+Widget, can also be any widget created with Q\+T-\/designer). Optionally you can also add an icon to the toolbox.

The following code shows a simple example to create an empty toolbox. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized()
\{
  \textcolor{comment}{// Create the Toolbox Widget}
  QWidget* toolBox = \textcolor{keyword}{new} QWidget();
  
  \textcolor{comment}{// Create an icon which is shown along with the toolbox}
  QIcon* toolIcon = \textcolor{keyword}{new} QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+\textcolor{stringliteral}{"
      exampleIcon.png"});
  
  \textcolor{comment}{// Tell the core to include the new toolbox widget with the name Simple Smoother, a pointer to the widget
       and a pointer to the icon}
  emit addToolbox( tr(\textcolor{stringliteral}{"Example Plugin Toolbox"}) , toolBox, toolIcon );
\}
\end{DoxyCode}


Signals and slots of your toolbox (e.\+g. from a Q\+Push\+Button inside it) can be directly connected to signals and slots in your plugin. Therefore the embedding of the widget into the toolbox list is fully transparent. \hypertarget{toolbarInterfacePage}{}\subsection{Toolbar Interface}\label{toolbarInterfacePage}
 ~\newline
The \hyperlink{a01309}{Toolbar\+Interface} can be used by plugins to add toolbars to Open\+Flippers U\+I. The toolbars are located above the G\+L viewer (See image).

To use the \hyperlink{a01309}{Toolbar\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a01309}{Toolbar\+Interface} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01309}{Toolbar\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Toolbar\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

Usually you should implement the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function from \hyperlink{a00322}{Base\+Interface}. In this function you can setup your toolbars.

The following code shows a simple example to create a simple toolbar. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized()
\{

  \textcolor{comment}{// Create your toolbar}
  QToolBar* toolbar = \textcolor{keyword}{new} QToolBar(tr(\textcolor{stringliteral}{"Example Toolbar"}));

  \textcolor{comment}{// Create an action for the toolbar}
  QAction* exampleAction = \textcolor{keyword}{new} QAction(tr(\textcolor{stringliteral}{"&Toolbar Button"}), \textcolor{keyword}{this});

  \textcolor{comment}{// Create an icon which is shown for the action}
  exampleAction->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+\textcolor{stringliteral}{"
      exampleIcon.png"}));

  \textcolor{comment}{// Add the action to the toolbar}
  toolbar->addAction(exampleAction);

  \textcolor{comment}{// Integrate the new toolbar into OpenFlipper}
  emit addToolbar( toolbar );
\}
\end{DoxyCode}


Signals and slots of your toolbar (e.\+g. from an action inside it) can be directly connected to signals and slots in your plugin. Therefore the embedding of the toolbar is fully transparent. \hypertarget{viewModeInterfacePage}{}\subsection{View Mode Interface}\label{viewModeInterfacePage}
 ~\newline
 This Interface can be used to configure visible widgets and menus in the viewer. A given view mode contains a list of toolbars, toolboxes and context menus which should be visible if the mode is active. Therefore you can define a subset of the full interface for special tasks.\hypertarget{a00186_ViewModeExample}{}\paragraph{Example using custom view modes}\label{a00186_ViewModeExample}
Open\+Flipper comes along with a lot of plugins each offering a wide variety of G\+U\+I elements such as toolboxes and toolbars. In order to constrain Open\+Flipper's interface to a certain number of toolboxes and/or toolbar elements, the \hyperlink{a01460}{View\+Mode\+Interface} offers means to filter these elements.

So, for example, if we only wanted the toolboxes of the Data Control and the Selection plugin to be visible, we have to emit signal \hyperlink{a01460_a5a89cc13257d4ba5d95b18c4a424a79e}{View\+Mode\+Interface\+::define\+View\+Mode\+Toolboxes(\+Q\+String, Q\+String\+List)} in order to hide out everything else\+:


\begin{DoxyCode}
\textcolor{comment}{// In your plugin initialization, define the view modes:}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized() \{

  \textcolor{comment}{// Generate the list of toolboxes to use:}
  QStringList toolBoxes = QString(\textcolor{stringliteral}{"Data Control,Selection"}).split(\textcolor{stringliteral}{","});

  \textcolor{comment}{// Define the view mode.}
  emit defineViewModeToolboxes(\textcolor{stringliteral}{"My Custom View Mode"}, toolBoxes);

  \textcolor{comment}{//define the viewMode Toolbars}
  QStringList toolBars;
  toolBars.push\_back( \textcolor{stringliteral}{"Selection"} );

  emit defineViewModeToolbars(\textcolor{stringliteral}{"My Custom View Mode"}, toolBars);
\}
\end{DoxyCode}


When the user selects \char`\"{}\+My Custom View Mode\char`\"{} out of the view modes menu, all toolboxes except for Data Control and Selection will disappear. This works analogously for toolbar elements via the signal \hyperlink{a01460_a9215d604bcb5eec19db02ca7893a8ab2}{View\+Mode\+Interface\+::define\+View\+Mode\+Toolbars(\+Q\+String, Q\+String\+List)}.\hypertarget{a00186_Defaults}{}\paragraph{Defaults}\label{a00186_Defaults}
The Main Toolbar and the Viewer Toolbar will always be included in the list of toolbars and will be the default when you define a View Mode with only toolboxes and context menus. If you do not define context menus for your View Mode, they will default to all.\hypertarget{a00186_Icons}{}\paragraph{Icons}\label{a00186_Icons}
Additionally, if we wanted the \char`\"{}\+My Custom View Mode\char`\"{} entry in the view modes menu to appear with a fancy icon, we just have to call \hyperlink{a01460_aaf0da29262adac10ecca33e7c2e6e039}{View\+Mode\+Interface\+::define\+View\+Mode\+Icon(\+Q\+String, Q\+String)}\+:


\begin{DoxyCode}
emit defineViewModeIcon(\textcolor{stringliteral}{"My Custom View Mode"}, \textcolor{stringliteral}{"myIconFile.png"});
\end{DoxyCode}
\hypertarget{a00186_view_mode_interface_usage}{}\paragraph{Usage}\label{a00186_view_mode_interface_usage}
To use the \hyperlink{a01460}{View\+Mode\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02475}{View\+Mode\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01460}{View\+Mode\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+View\+Mode\+Interface) to your plugin class 
\item And add the signals you want to use to your plugin class 
\end{DoxyItemize}\hypertarget{AboutInfoInterfacePage}{}\subsection{About Info interface}\label{AboutInfoInterfacePage}
 ~\newline
The \hyperlink{a00274}{About\+Info\+Interface} can be used by plugins to add an additional tab to Open\+Flippers about dialog. This is especially useful, if you use an external library which requires you to publish the license information in the application.

You can add multiple tabs by additional calls to this interface

To use the \hyperlink{a00274}{About\+Info\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02435}{About\+Info\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00274}{About\+Info\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+About\+Info\+Interface) to your plugin class 
\item Implement the signal of this interface 
\end{DoxyItemize}


\begin{DoxyCode}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized()\{
  \textcolor{comment}{// Simply emit the signal with the text}
  emit addAboutInfo(\textcolor{stringliteral}{"Info Text"},\textcolor{stringliteral}{"Example Plugin License"});
\}
\end{DoxyCode}
 \hypertarget{pluginInterfacesDataHandling}{}\subsection{Object and Data Handling}\label{pluginInterfacesDataHandling}
This page shows interfaces for controlling and adding Objects.

\hyperlink{fileInterfacePage}{File Interface}  Provides an interface to read and write file types. All load/save plugins need to implement this interface ( \hyperlink{fileInterfacePage}{File Interface} )

\hyperlink{loadSaveInterfacePage}{Load/\+Save Interface}  Provides functions to control loading/saving of files and generate new objects. Additionally this interface informs plugins, when objects get added or removed( \hyperlink{loadSaveInterfacePage}{Load/\+Save Interface} ).

\hyperlink{metaDataInterfacePage}{Meta\+Data Interface}  This interface provides functions for serializing and deserializing Meta\+Data which is stored in screenshots or other files( \hyperlink{metaDataInterfacePage}{Meta\+Data Interface} ).

\hyperlink{selectionInterfacePage}{Selection Interface}  This interface provides functions which control Open\+Flippers selection system. Selection plugins can use this interface to react on selection events and add selections for different primitives ( \hyperlink{selectionInterfacePage}{Selection Interface} ).

\hyperlink{typeInterfacePage}{Type Interface}  Allows plugins to specify custom data types and makes them available to other plugins ( \hyperlink{typeInterfacePage}{Type Interface} ).

\hyperlink{informationInterfacePage}{Information Interface}  Allows plugins to provide information on objects of a specific data type ( \hyperlink{informationInterfacePage}{Information Interface} ).

\hyperlink{backupInterfacePage}{Backup Interface}  Use this interface to backup data ( \hyperlink{backupInterfacePage}{Backup Interface} ) \hypertarget{fileInterfacePage}{}\subsection{File Interface}\label{fileInterfacePage}
~\newline
 ~\newline
\hypertarget{a00142_fileInterface_Functionality}{}\paragraph{Functionality}\label{a00142_fileInterface_Functionality}
This interface class has to be fully implemented. When you want to support save and load for an object type you have to implement all functions in this class in a file plugin. The plugin has to be named Plugin-\/\+File$<$File\+Extension$>$. The plugins are loaded directly after the Type Plugins.

Open\+Flipper manages loading and saving of files from the core.\hypertarget{a00142_fileInterface_filters}{}\paragraph{Load/\+Save filters and Type Support}\label{a00142_fileInterface_filters}
In these functions you have to return filters for your supported type. Use the standard format of Qt and return your filters within the functions \hyperlink{a00570_a804009a394ded7436b43c624af9cc44d}{File\+Interface\+::get\+Load\+Filters()} and \hyperlink{a00570_a86b79f14fef9913720c6456df43de7df}{File\+Interface\+::get\+Save\+Filters()}. Open\+Flipper will decide based on the filters, if your plugin is used to handle a load or save request. Additionally you have to define, which Data\+Types your plugin supports via \hyperlink{a00570_add81abf9277dae44167763da4371fb28}{File\+Interface\+::supported\+Type()}.


\begin{DoxyCode}
\textcolor{comment}{// File types you support when loading files}
QString ExamplePlugin::getLoadFilters() \{
    \textcolor{keywordflow}{return} QString( tr(\textcolor{stringliteral}{"Your FileType ( *.ext )"}) );
\}

\textcolor{comment}{// File types you support when saving files}
QString ExamplePlugin::getSaveFilters() \{
    \textcolor{keywordflow}{return} QString( tr(\textcolor{stringliteral}{"Your FileType ( *.ext )"}) );
\}

\textcolor{comment}{// Data types you support in your plugin}
\hyperlink{a00477}{DataType}  ExamplePlugin::supportedType() \{
    \hyperlink{a00477}{DataType} type = \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH} | \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} | 
      \hyperlink{a02488_aa404cecc33a95757fc7f8220d7d0eb79}{DATA\_GROUP};

    \textcolor{keywordflow}{return} type;
\}
\end{DoxyCode}
\hypertarget{a00142_fileInterface_widgets}{}\paragraph{Widgets}\label{a00142_fileInterface_widgets}
When an object is loaded or saved via your file plugin, you can present an additional dialog, used to control your reader/writer. You have to implement the following functions. If you don't need such a widget, just return a 0.


\begin{DoxyCode}
\textcolor{comment}{// In your plugin initialization}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized() \{
  \textcolor{comment}{// Global variable:}
  \textcolor{comment}{// QWidget* saveOptionsWidget\_;}

  \textcolor{comment}{// Create widget}
  saveOptionsWidget\_ = \textcolor{keyword}{new} QWidget(0);

  \textcolor{comment}{// Setup widget afterwards}

  \textcolor{comment}{// Global variable:}
  \textcolor{comment}{// QWidget* loadOptionsWidget\_;}

  \textcolor{comment}{// Create widget}
  loadOptionsWidget\_ = \textcolor{keyword}{new} QWidget(0);

  \textcolor{comment}{// Setup widget afterwards}
\}


\textcolor{comment}{// Return your widget for save options}
QWidget* ExamplePlugin::saveOptionsWidget(QString \_currentFilter) \{

  \textcolor{comment}{// Modify widget based on the filter}
  \textcolor{comment}{// ...}

  \textcolor{comment}{// Return widget}
  \textcolor{keywordflow}{return} saveOptionsWidget\_;
\}

\textcolor{comment}{// Return your widget for load options}
QWidget* ExamplePlugin::loadOptionsWidget(QString \_currentFilter) \{

  \textcolor{comment}{// Modify widget based on the filter}
  \textcolor{comment}{// ...}

  \textcolor{comment}{// Return widget}
  \textcolor{keywordflow}{return} loadOptionsWidget\_;
\}
\end{DoxyCode}
\hypertarget{a00142_fileInterface_loading}{}\paragraph{Loading Files}\label{a00142_fileInterface_loading}
The \hyperlink{a00570}{File\+Interface} defines two functions for loading files. The first one ( \hyperlink{a00570_a0efbab4d230207cfa77fac0523add4eb}{File\+Interface\+::load\+Object(\+Q\+String \+\_\+filename)} ) has to be implemented. It has to load the data from the given file. The return value of this function has to be the id of the new object. Additionally you have to 
\begin{DoxyCode}
emit \hyperlink{a00570_a92fc756dcb00772a23a09fb598e311b0}{FileInterface::openedFile}( \textcolor{keywordtype}{int} \_id );
\end{DoxyCode}
 with the id of every object you loaded from the file.

If the file contains multiple objects, create a \hyperlink{a00663}{Group\+Object} and add all loaded objects to that group. Than return the id of the group here. Don't forget the \hyperlink{a00570_a92fc756dcb00772a23a09fb598e311b0}{File\+Interface\+::opened\+File()} signal for every newly loaded object from the file.

One function that can be implemented is \hyperlink{a00570_aac6acc4ff271420c30d6608dbc4d3665}{File\+Interface\+::load\+Object(\+Q\+String \+\_\+filename, Data\+Type \+\_\+type)}. This function gets a \hyperlink{a00477}{Data\+Type} along with the filename. This can be used to force a specific \hyperlink{a00477}{Data\+Type} when loading objects. E.\+g. A plugin loading obj files which handles triangle and polygonal meshes which can than be forced to triangulate every input data.\hypertarget{a00142_fileInterface_saving}{}\paragraph{Saving Files}\label{a00142_fileInterface_saving}
The \hyperlink{a00570}{File\+Interface} defines two functions for loading files. The first one ( \hyperlink{a00570_acc96b2af7bbc2e1dc9b9a2f344523939}{File\+Interface\+::save\+Object(int \+\_\+id, Q\+String \+\_\+filename)} ) has to be implemented. It has to save the object with the given id to the file specified by the filename. The return value of this function has to be true if it succeeded, otherwise false. Open\+Flipper will choose your plugin to save the data if two prerequisites are fulfilled. Your File\+Interface\+::supported\+Types() has to support the \hyperlink{a00477}{Data\+Type} of the object and your save filters have to contain the extension of the file to use. These checks are done within Open\+Flipper such that you only get information that can be handled by the plugin.

Additionally there is a function \hyperlink{a00570_a5d8d9b8cb42f182213217194a557e854}{File\+Interface\+::save\+Objects(\+Id\+List \+\_\+ids, Q\+String \+\_\+filename)} which does the same as the above but saves a set of objects to a file.\hypertarget{a00142_fileInterface_usage}{}\paragraph{Usage}\label{a00142_fileInterface_usage}
To use the \hyperlink{a00570}{File\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02439}{File\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00570}{File\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+File\+Interface) to your plugin class 
\item And implement the required slots and functions 
\end{DoxyItemize}

T\+O\+D\+O\+: Deprecated here? In \hyperlink{a01357}{Type\+Interface}? virtual int add\+Empty() \{ return -\/1; \}; \hypertarget{loadSaveInterfacePage}{}\subsection{Load/\+Save Interface}\label{loadSaveInterfacePage}
~\newline
 ~\newline
 The \hyperlink{a00778}{Load\+Save\+Interface} can be used by plugins to add new objects to the scene either by creating empty objects or by loading them from files. The interface also triggers saving of existing objects to files.\hypertarget{a00148_loadSaveInterface_load_save}{}\paragraph{Load/\+Save Files}\label{a00148_loadSaveInterface_load_save}
You can load a file from within your plugin via 
\begin{DoxyCode}
emit \hyperlink{a00778_a152541b680116d103397e2c2a92d049e}{LoadSaveInterface::load}(QString \_filename, \hyperlink{a00477}{DataType} \_type, \textcolor{keywordtype}{int}& \_id);
\end{DoxyCode}
 and to save an object to a file, call \hyperlink{a00778}{Load\+Save\+Interface}\+:\+: 
\begin{DoxyCode}
emit \hyperlink{a00778_ab0ff1379c8613bfbac7ecd48e9456bef}{LoadSaveInterface::save}(\textcolor{keywordtype}{int} \_id , QString \_filename );
\end{DoxyCode}


The corresponding File Plugin will than be activated and load or save the object. for load, the id of the new object is returned.\hypertarget{a00148_loadSaveInterface_createObjects}{}\paragraph{Creating/\+Copying Objects}\label{a00148_loadSaveInterface_createObjects}
To add objects to the scene you can use the following two functions\+: 
\begin{DoxyCode}
emit \hyperlink{a00778_a088846b57b3ed0ec478afcda31b64596}{LoadSaveInterface::addEmptyObject}( 
      \hyperlink{a00477}{DataType} \_type, \textcolor{keywordtype}{int}& \_id);
\end{DoxyCode}
 This will create a new object of the given \hyperlink{a00477}{Data\+Type} and return the id of it, while 
\begin{DoxyCode}
emit \hyperlink{a00778_a7ceb0b3f5651a3bc23ef8bc3009ff5cd}{LoadSaveInterface::copyObject}( \textcolor{keywordtype}{int} \_oldId, \textcolor{keywordtype}{int}& \_newId);
\end{DoxyCode}
 will copy the given object and return the new object id.\hypertarget{a00148_loadSaveInterface_deleteObjects}{}\paragraph{Deleting Objects}\label{a00148_loadSaveInterface_deleteObjects}
You can delete a specific object via 
\begin{DoxyCode}
emit \hyperlink{a00778_a6c5ae74820943d0a571ca6e8b85a69cc}{LoadSaveInterface::deleteObject}( \textcolor{keywordtype}{int} \_id );
\end{DoxyCode}
 or clear the whole scene with\+: 
\begin{DoxyCode}
emit \hyperlink{a00778_afb361d8553ecfb0ad373d505c2de4ba7}{LoadSaveInterface::deleteAllObjects}();
\end{DoxyCode}
\hypertarget{a00148_loadSaveInterface_callbacks}{}\paragraph{Object Information}\label{a00148_loadSaveInterface_callbacks}
Additionally the interface informs plugins if new objects have been added to the scenes or if previous objects have been removed. \hyperlink{a00778_a715c23643892f4938aae8ea771ac6e3b}{Load\+Save\+Interface\+::file\+Opened( int \+\_\+id )} will be triggered each time an object is loaded from a file. If simply an empty object has been added, the slot \hyperlink{a00778_acb0f81b08c31541abdc572f2fa400bf1}{Load\+Save\+Interface\+::added\+Empty\+Object( int \+\_\+id )} will be called. If an object gets deleted, the \hyperlink{a00778_a0ab70c4ae3c08f298ecefa58f0bb8b2f}{Load\+Save\+Interface\+::object\+Deleted( int \+\_\+id )} will be called immediately before the object is removed from the scenegraph. So if this function is invoked, the object still exists. All plugins get informed via this slot.

If you want to know if the whole scene got cleared, use \hyperlink{a00322_aa00a3111da5d92c9d001a0a8272c5a91}{Base\+Interface\+::slot\+All\+Cleared( )}.\hypertarget{a00148_loadSaveInterface_usage}{}\paragraph{Usage}\label{a00148_loadSaveInterface_usage}
To use the \hyperlink{a00778}{Load\+Save\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02443}{Load\+Save\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00778}{Load\+Save\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Load\+Save\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{metaDataInterfacePage}{}\subsection{Meta\+Data Interface}\label{metaDataInterfacePage}
~\newline
 ~\newline
 Using functions such as \hyperlink{a00329_aef84cff271df1537425cba7e3ac54e55}{Base\+Object\+::get\+Comment\+By\+Key()} plugins can attach meta data to objects. This meta data is currently only serialized when taking viewer snapshots. \char`\"{}\+Plugin-\/\+Deserialize\+Screenshot\+Metadata\char`\"{} allows deserializing this metadata from a viewer snapshot. (In the future serialization and deserialization of meta data may occur in other contexts as well.)

Whenever meta gets deserialized the slots in this interface will get triggered. Please refer to the documentation of the individual slots to find out which specific signal suits your needs. \hypertarget{selectionInterfacePage}{}\subsection{Selection Interface}\label{selectionInterfacePage}


The \hyperlink{a01144}{Selection\+Interface} can be used to provide selection functions. Selection works as follows. Open\+Flipper basically contains the \hyperlink{a01141}{Selection\+Base\+Plugin} which offers some graphical tools (such as selection sphere, lasso tools, etc.) that can be used for selecting entities.

Now each object type (poly/triangle meshes, skeletons, splines, whatever) has to implement its own selection functionality. Say we wanted to implement selection for poly/tri mesh objects. For this purpose we derive a plugin from \hyperlink{a01144}{Selection\+Interface} and create a new selection environment via the add\+Selection\+Environment() signal, naming it e.\+g. \char`\"{}\+Mesh Object Selection\char`\"{}.

After having created the necessary selection environment, we have to register our specific data type, that is tell the Selection\+Base plugin which data types will be handled (selected) by our plugin. In the example from above we would register D\+A\+T\+A\+\_\+\+P\+O\+L\+Y\+\_\+\+M\+E\+S\+H as well as D\+A\+T\+A\+\_\+\+T\+R\+I\+A\+N\+G\+L\+E\+\_\+\+M\+E\+S\+H. We do this by calling the signal register\+Type(). Now we have to determine which primitive type should be selectable. For poly/tri meshes we would determine vertices, edges, halfedges and faces to be selectable. This is performed via emission of the signal add\+Primitive\+Type().

We can then choose which of the default selection tools should be available for this environment. We could, for example, request the toggle, flood fill and the sphere selection tool by calling the signals show\+Toggle\+Selection\+Mode(), and so on. Additionally, it's possible to create custom selection tools that can be completely different from the default ones.

After having requested the desired selection tools, each time a selection tool has been used, the appropriate slot is called for further processing, that is the actual selection of the primitives.

\hyperlink{a01144}{Selection\+Interface} also provides means to add operations for a specific primitive type (such as, for example, \char`\"{}\+Clear Vertex Selection\char`\"{} or \char`\"{}\+Select All Vertices\char`\"{} for vertex selections). We can tell Selection\+Base to add there operations by emitting add\+Selection\+Operations(). Each time an operation button has been clicked, slot slot\+Selection\+Operation() is called.

The overall idea is to separate the U\+I and control elements from actual implementations of selection functionality for a specific data type. So, in general Selection\+Base manages all U\+I control elements and and the rendering of the selection tools whereas the specific type selection plugins manage the real selection of their entities as well as scripting functions. \hypertarget{typeInterfacePage}{}\subsection{Type Interface}\label{typeInterfacePage}
~\newline
 ~\newline
 This interface is used to register new types in Open\+Flipper. The type plugins are loaded before all other plugins. They have only the register\+Type function which registers the type to the core and a function to create objects of the new type. The type itself has to be defined in the Object\+Types subdirectory.\hypertarget{a00184_TypeExample}{}\paragraph{Example using custom data types}\label{a00184_TypeExample}
Adding a custom data type to Open\+Flipper needs the following requirements in order to work\+:


\begin{DoxyItemize}
\item The definition of the type\+Id constant, e.\+g.\+: 
\begin{DoxyCode}
\textcolor{preprocessor}{#define DATA\_MY\_DATA typeId("MyDataType")}
\end{DoxyCode}
 Note\+: Your data type is then referenced as D\+A\+T\+A\+\_\+\+M\+Y\+\_\+\+D\+A\+T\+A during runtime.
\item The specification of an object class for your object type that is derived from \hyperlink{a00330}{Base\+Object\+Data}.
\item The specification of helper functions (usually within the \hyperlink{a03393}{Plugin\+Functions} namespace) allowing the casting from \hyperlink{a00330}{Base\+Object\+Data} to your object type class.
\end{DoxyItemize}

See detailed examples for each of the three points for already existing data types in Open\+Flipper\+Root/\+Object\+Types.

Once the object class is specified, the type plugin will be responsible for its handling including


\begin{DoxyItemize}
\item Adding new objects to the scenegraph
\item Setting the initial name of an object
\item Etc.
\end{DoxyItemize}

So, type plugins usually consist of only few lines of code. Here an example of a type plugin handling an example object data type as mentioned above\+:


\begin{DoxyCode}
\textcolor{keywordtype}{bool} MyDataTypePlugin::registerType() \{

    \hyperlink{a02488_a1bf2a9d155a029c5a37e9341d30a4589}{addDataType}(\textcolor{stringliteral}{"MyDataType"},tr(\textcolor{stringliteral}{"MyDataType"}));
    \hyperlink{a02488_ad665808a88085c8d50a2f0c3863885f6}{setTypeIcon}( \textcolor{stringliteral}{"MyDataType"}, \textcolor{stringliteral}{"myDataType.png"});

    \textcolor{keywordflow}{return} \textcolor{keyword}{true};
\}

\textcolor{keywordtype}{int} MyDataTypePlugin::addEmpty() \{

    \textcolor{comment}{// Create new object}
    MyObject* \textcolor{keywordtype}{object} = \textcolor{keyword}{new} MyObject();

    \textcolor{keywordtype}{object}->setName( QString(\textcolor{stringliteral}{"My Object %1.mob"}).arg(objectCount) );
    \textcolor{keywordtype}{object}->update();
    \textcolor{keywordtype}{object}->show();

    \textcolor{comment}{// Tell core that an object has been added}
    emit emptyObjectAdded ( object->id() );

    \textcolor{keywordflow}{return} \textcolor{keywordtype}{object}->id();
\}
\end{DoxyCode}


Now, each time a plugin emits add\+Empty\+Object(\+D\+A\+T\+A\+\_\+\+M\+Y\+\_\+\+D\+A\+T\+A), the add\+Empty() function will add the object to the scenegraph and return the newly created object's id.\hypertarget{a00184_Backups}{}\paragraph{Backups}\label{a00184_Backups}
Backups are very specific to the underlying data structures of certain types. Therefore the type plugins also manage backups. Backups itself are managed by per\+Object\+Data objects based on the \hyperlink{a00307}{Backup\+Data} class. When the slot gets called, we first have to check, if an \hyperlink{a00307}{Backup\+Data} is already available. If not, we create one. Than the backup is generated and passed to the backup data attached to the object.

You have to derive your backups from the \hyperlink{a00310}{Base\+Backup} class, where you only need to implement the apply function and your constructor. In the following example, this class is named \hyperlink{a01338}{Tri\+Mesh\+Backup}.


\begin{DoxyCode}
\textcolor{keywordtype}{void} \hyperlink{a01372_a1fc7e5f0c7f4218f06984be93c2185a2}{TypeTriangleMeshPlugin::generateBackup}( \textcolor{keywordtype}{int} \_id, QString \_name, 
      \hyperlink{a01393}{UpdateType} \_type )\{

 \textcolor{comment}{// Get the object corresponding to the id}
 \hyperlink{a00330}{BaseObjectData}* \textcolor{keywordtype}{object} = 0;
 \hyperlink{a03393_ac20ce4f5c004657788cc10f4ad465de0}{PluginFunctions::getObject}(\_id, \textcolor{keywordtype}{object});
 \hyperlink{a01339}{TriMeshObject}* meshObj = \hyperlink{a03393_a1f03569cd9ea2c79069f362b84c42661}{PluginFunctions::triMeshObject}(\textcolor{keywordtype}{object})
      ;

 \textcolor{comment}{// Safety check}
 \textcolor{keywordflow}{if} ( meshObj != 0 )\{

   \textcolor{comment}{//get backup object data}
   \hyperlink{a00307}{BackupData}* backupData = 0;

   \textcolor{comment}{// If a backup data has already been attached, get it, otherwise create it.}
   \textcolor{keywordflow}{if} ( object->\hyperlink{a00329_aa5b773c721abdf3273b55eacbeb8488d}{hasObjectData}( OBJECT\_BACKUPS ) )
     backupData = dynamic\_cast< BackupData* >(object->\hyperlink{a00329_a64c9fbbfa9225b718474667da04b7dba}{objectData}(OBJECT\_BACKUPS));
   \textcolor{keywordflow}{else}\{
     \textcolor{comment}{//add backup data}
     backupData = \textcolor{keyword}{new} \hyperlink{a00307}{BackupData}(\textcolor{keywordtype}{object});
     \textcolor{keywordtype}{object}->setObjectData(OBJECT\_BACKUPS, backupData);
   \}

   \textcolor{comment}{// Create a new backup}
   \hyperlink{a01338}{TriMeshBackup}* backup = \textcolor{keyword}{new} \hyperlink{a01338}{TriMeshBackup}(meshObj, \_name, \_type);

   \textcolor{comment}{// Store it in the backup data}
   backupData->\hyperlink{a00307_a81908c9c016fb443925d8321316d4998}{storeBackup}( backup );
 \}
\}
\end{DoxyCode}


To use the \hyperlink{a01357}{Type\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02473}{Type\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01357}{Type\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Type\+Interface) to your plugin class 
\item Implement all slots of this Interface 
\end{DoxyItemize}\hypertarget{informationInterfacePage}{}\subsection{Information Interface}\label{informationInterfacePage}
~\newline
 ~\newline
 Click \hyperlink{a00723}{Information\+Interface} for a detailed overview of all provided slots in the interface.

Derive from the information interface in order to provide information on objects of a specific data type. To clarify this, we will give a short example. Assuming we want to provide information on all mesh objects (namely objects of type D\+A\+T\+A\+\_\+\+T\+R\+I\+A\+N\+G\+L\+E\+\_\+\+M\+E\+S\+H and D\+A\+T\+A\+\_\+\+P\+O\+L\+Y\+\_\+\+M\+E\+S\+H). In our plugin, we first have to override the slot that fetches the supported data types\+:


\begin{DoxyCode}
\hyperlink{a00477}{DataType} MyInfoPlugin::supportedDataTypes() \{

    \textcolor{keywordflow}{return} \hyperlink{a00477}{DataType}(\hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH} | 
      \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH});
\}
\end{DoxyCode}


It's as simple as that. Now, each time an object is clicked in identifier mode, slot slot\+Information\+Requested() is called. We ovveride this slot in order to do the actual picking and displaying the gathered information in a dialog box\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} MyInfoPlugin::slotInformationRequested(\textcolor{keyword}{const} QPoint \_clickedPoint, \textcolor{keyword}{const} 
      \hyperlink{a00477}{DataType} \_type) \{

    \textcolor{comment}{// We only respond to requests for our data type}
    \textcolor{keywordflow}{if}((\_type != \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH}) && (\_type != 
      \hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH})) \textcolor{keywordflow}{return};

    \textcolor{comment}{// Do the picking...}

    \textcolor{comment}{// Display dialog box with all the information...}
\}
\end{DoxyCode}
 \hypertarget{backupInterfacePage}{}\subsection{Backup Interface}\label{backupInterfacePage}
~\newline
 ~\newline
 \hypertarget{a00136_BackupInterfacePage_Overview}{}\paragraph{Overview}\label{a00136_BackupInterfacePage_Overview}
The Backup interface can be used to manage backups within Open\+Flipper. It provides abstractions for backup and redo operations which get managed by the backup plugin.\hypertarget{a00136_backupInterfacePage_generatingBackups}{}\paragraph{Generating Backups}\label{a00136_backupInterfacePage_generatingBackups}
To generate a backup of a specific object, you just have to derive from the \hyperlink{a00308}{Backup\+Interface} and emit the \hyperlink{a00308_a9fbd0ffaeb95aa9bb2bc508e606501b6}{Backup\+Interface\+::create\+Backup()} signal. A simple example looks like this\+:


\begin{DoxyCode}
emit createBackup(object->\hyperlink{a00329_a043f52f3105d646af193d4974482869d}{id}(),\textcolor{stringliteral}{"Smoothing"}, \hyperlink{a03407_ga01c97b7f74b26bfb8701f9dba7806b40}{UPDATE\_GEOMETRY} );
\end{DoxyCode}


We create a backup of the object with the given id. The Backup will be named \char`\"{}\+Smoothing\char`\"{} and the backup system is informed that only the geometry has changed.

It is also possible to create backup groups. This is required, if you change several objects at once and they should be restored only together.\hypertarget{a00136_backupInterfacePage_restoringBackups}{}\paragraph{Restoring Backups}\label{a00136_backupInterfacePage_restoringBackups}
Backups can be restored and re-\/applied. You can simply emit the \hyperlink{a00308_ab1eb32ddefd829029c1c4222feda9842}{Backup\+Interface\+::undo()} signal and the last backup will be restored. \hyperlink{a00308_aae94a5b7d3b9ddcd5a7bb3626074d4f7}{Backup\+Interface\+::redo()} will re apply the last operation stored. It is also possible to restore backups of a specific object via \hyperlink{a00308_a670586bc8351ce57b47997ce18d1b0c9}{Backup\+Interface\+::undo(int)} and \hyperlink{a00308_a3d716b85310573b344550f6aa8eba108}{Backup\+Interface\+::redo(int)}, if they are not blocked by a group backup which can only be reverted as one operation.~\newline
 The other plugins will be informed about a restore operation by \hyperlink{a00308_a7af78b46b21dfcac5e94464417257372}{Backup\+Interface\+::slot\+About\+To\+Restore(int)} and \hyperlink{a00308_afc886c900fcda4e0bddf8483b0ccb151}{Backup\+Interface\+::slot\+Restored(int)} which will be emitted directly before and after the restore operation.\hypertarget{a00136_backupInterfacePage_usage}{}\paragraph{Usage}\label{a00136_backupInterfacePage_usage}
To use the \hyperlink{a00308}{Backup\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02436}{Backup\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00308}{Backup\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Backup\+Interface) to your plugin class 
\item And implement the required slots and functions 
\end{DoxyItemize}\hypertarget{pluginInterfacesInputDevices}{}\subsection{Input Devices}\label{pluginInterfacesInputDevices}
This page shows interfaces which could be used to get data from input devices.

\hyperlink{mouseInterfacePage}{Mouse Interface} ~\newline
 ~\newline
This interface is used to deliver mouse events to a plugin ( \hyperlink{mouseInterfacePage}{Mouse Interface} ).~\newline
~\newline
 \hyperlink{pickingInterfacePage}{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars} ~\newline
 ~\newline
Handle pick modes in your plugin ( \hyperlink{pickingInterfacePage}{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars} ) ~\newline
 \hyperlink{keyInterfacePage}{Key Interface} ~\newline
 ~\newline
You have to implement this interface if you want to get key events in your plugin ( \hyperlink{keyInterfacePage}{Key Interface} ).~\newline
~\newline
\hypertarget{mouseInterfacePage}{}\subsection{Mouse Interface}\label{mouseInterfacePage}
~\newline
 ~\newline


The mouse interface can be used to receive mouse events which occur in the \hyperlink{a00652}{gl\+Viewer}.

There are 4 main viewer modes\+: 
\begin{DoxyItemize}
\item {\bfseries Move Mode} events are never passed to one of the plugins and is only used for scene navigation inside the viewers. 
\item {\bfseries Picking Mode} events where passed through the \hyperlink{a00860_ad998de7699f7f6ea0e60de3ba5a5503d}{Mouse\+Interface\+::slot\+Mouse\+Event()} and \hyperlink{a00860_aa421d325c2298c063609ab657fe3a528}{Mouse\+Interface\+::slot\+Mouse\+Wheel\+Event()} to the plugins. This is usually the mode, that plugins use to implement mouse interaction. 
\item {\bfseries Light Mode} events where passed through the \hyperlink{a00860_adcbc518b37eb99caab2f46982048fb88}{Mouse\+Interface\+::slot\+Mouse\+Event\+Light()}. Plugins modifying light sources use that mode to get mouse events.  
\item {\bfseries Info Mode} events are passed through the Information interface \hyperlink{informationInterfacePage}{Information Interface}. This mode is used to provide information about clicked objects only. 
\end{DoxyItemize}

You can add handlers for these mouse events in your plugin. Remember that all plugins receive these signals.~\newline
 The picking action is only a global mode which is divided into several other picking modes that can be managed through the \hyperlink{a00957}{Picking\+Interface}. If you react on mouse events, you should check if the current picking mode is yours and of course define such a mode for your plugin. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} MousePlugin::slotMouseEvent(QMouseEvent* \_event) \{

  \textcolor{comment}{// Check if your pick mode is currently active}
  \textcolor{keywordflow}{if} ( \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}() == \textcolor{stringliteral}{"YourPickMode"} && 
      \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}() == Viewer::PickingMode ) \{

    \textcolor{comment}{// If double click has been performed}
    \textcolor{keywordflow}{if} (\_event->type() == QEvent::MouseButtonDblClick) \{
      \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} node\_idx, target\_idx;
      \hyperlink{a01409}{OpenMesh::Vec3d} hitPoint;

      \textcolor{comment}{// Get picked object's identifier by picking in scenegraph}
      \textcolor{keywordflow}{if} ( \hyperlink{a03393_a0ae515c8553f9e7f671bd2627bbecf6a}{PluginFunctions::scenegraphPick}(
      \hyperlink{a03343_af5fad41dadeca314c2077f897377dbd0a16466d3b836973188ef3426feda66fcd}{ACG::SceneGraph::PICK\_ANYTHING},\_event->pos(), node\_idx, target\_idx, &hitPoint
      ) ) \{

        \hyperlink{a00330}{BaseObjectData}* object;

        \textcolor{comment}{// Get picked object}
        \textcolor{keywordflow}{if} ( \hyperlink{a03393_af54bc387d31df6054829e57377bb617d}{PluginFunctions::getPickedObject}(node\_idx, \textcolor{keywordtype}{object}) ) \{

          \textcolor{comment}{// Do something with the object}

        \}
      \}
    \}
  \}


\}
\end{DoxyCode}


See our tutorial \hyperlink{ex3}{Implementing mouse and keyboard interaction} for an example of how to use mouse and keyboard events within a plugin.

To use the \hyperlink{a00860}{Mouse\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02447}{Mouse\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00860}{Mouse\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Mouse\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{pickingInterfacePage}{}\subsection{Picking Interface/\+Mouse Picking/\+Pick Mode Toolbars}\label{pickingInterfacePage}
~\newline
 ~\newline
\hypertarget{a00160_pickingInterface_functionality}{}\paragraph{Functionality}\label{a00160_pickingInterface_functionality}
Open\+Flipper uses several different Action\+Modes. These include, Light interaction (Changing lights), Move interaction (navigating through the scene) and the picking interaction. The picking interaction is separated into different pick modes. These modes are usually defined by plugins and are used to restrict the mouse interaction to one plugin. E.\+g. if the current picking mode is \char`\"{}vertex selection\char`\"{}, all other plugins that react on mouse events, but are not responsible for the \char`\"{}vertex selection\char`\"{} will ignore these events.\hypertarget{a00160_pickingInterface_managing}{}\paragraph{Managing Pick Modes}\label{a00160_pickingInterface_managing}
Pick modes can be created in your plugin initialization. You can add them as visible pick modes (visible in the context menus of objects) or as hidden pick modes \hyperlink{a00957_a253fb435408607bea3e4507833fe81c4}{Picking\+Interface\+::add\+Hidden\+Pick\+Mode()} ( This should be preferred! ). You can also set a special cursor that will be used when your pick mode is active via \hyperlink{a00957_a05a636ef566e849d32a97a4ba2e03121}{Picking\+Interface\+::set\+Pick\+Mode\+Cursor()}. If you need to enable mouse tracking in your mode, you can use \hyperlink{a00957_ae0b47da43aca269001f2eec53bdb1345}{Picking\+Interface\+::set\+Pick\+Mode\+Mouse\+Tracking()}. This will result in mouse events even if no button is pressed.


\begin{DoxyCode}
\textcolor{comment}{// When the plugin gets initialized}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized() \{

 \textcolor{comment}{// Add pick mode}
 emit addPickMode(\textcolor{stringliteral}{"ExamplePlugin Pick Mode"});

\}

\textcolor{comment}{// Triggered when the pick mode got changed.}
\textcolor{keywordtype}{void} ExamplePlugin::slotPickModeChanged(\textcolor{keyword}{const} std::string& \_mode) \{

  \textcolor{comment}{// Enable a button depending on the current pick mode}
  button\_->setEnabled(\_mode == \textcolor{stringliteral}{"ExamplePlugin Pick Mode"});

\}

\textcolor{comment}{// From MouseInterface}
\textcolor{keywordtype}{void} ExamplePlugin::slotMouseEvent(QMouseEvent* \_event) \{

  \textcolor{comment}{// Check if your pick mode is currently active}
  \textcolor{keywordflow}{if} ( \hyperlink{a03393_a6126bc44ec7c4091f0b87f6ca87e7c77}{PluginFunctions::pickMode}() == \textcolor{stringliteral}{"ExamplePlugin Pick Mode"} && 
      \hyperlink{a03393_aa7ad2d5b69ca3cc449a3e702fb4e5d4f}{PluginFunctions::actionMode}() == Viewer::PickingMode ) \{

    \textcolor{comment}{// Do something}

  \}

\}
\end{DoxyCode}


A change of the current pick mode can be detected by the \hyperlink{a00957_a5bf0bf6559d2b5411d0f3270415242c1}{Picking\+Interface\+::slot\+Pick\+Mode\+Changed()} function.\hypertarget{a00160_pickingInterface_toolbars}{}\paragraph{Pick\+Mode Toolbars}\label{a00160_pickingInterface_toolbars}
~\newline
 ~\newline
Additionally it is possible to show a special toolbar in Open\+Flippers viewer when your pick mode is active. This is especially Useful, when you can change the interaction type by buttons in the bar, e.\+g. select vertices or faces. Every time your pick mode is activated, your toolbar will be visible at the top of the viewer. Use the functions \hyperlink{a00957_a90ba1e0b2ccf751f33dac49c757b9276}{Picking\+Interface\+::set\+Pick\+Mode\+Toolbar()} and \hyperlink{a00957_a82e4afc52fd1d2e0222b605f1e926ec4}{Picking\+Interface\+::remove\+Pick\+Mode\+Toolbar()} for controlling these toolbars. The embedding is fully transparent so that you can manage your toolbar and connect signals and slots as usual.


\begin{DoxyCode}
\textcolor{comment}{// When the plugin gets initialized}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized() \{

  \textcolor{comment}{// Global variable QToolBar* pickToolbar\_}
  pickToolbar\_ = \textcolor{keyword}{new} QToolBar(tr(\textcolor{stringliteral}{"Example Pickmode Toolbar"}));
  pickToolbar\_->setAttribute(Qt::WA\_AlwaysShowToolTips, \textcolor{keyword}{true});

  QActionGroup* pickToolBarActions = \textcolor{keyword}{new} QActionGroup(pickToolbar\_);

  QAction* action = \textcolor{keyword}{new} QAction(tr(\textcolor{stringliteral}{"Action"}),pickToolBarActions);
  action->setStatusTip(tr(\textcolor{stringliteral}{"Action description"}));
  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+\textcolor{stringliteral}{"icon.png"})
       );
  action->setCheckable(\textcolor{keyword}{true});
  pickToolbar\_->addAction(action);

  \textcolor{comment}{// Connect to a local slot. The embedding is transparent, so you can connect all your actions and
       toolbars as usual.}
  connect(pickToolBarActions, SIGNAL(triggered(QAction*)), \textcolor{keyword}{this}, SLOT(slotPickToolbarAction(QAction*)) );

  emit setPickModeToolbar (\textcolor{stringliteral}{"ExamplePlugin Pick Mode"}, pickToolbar\_);
\}
\end{DoxyCode}
\hypertarget{a00160_pickingInterface_usage}{}\paragraph{Usage}\label{a00160_pickingInterface_usage}
To use the \hyperlink{a00957}{Picking\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02449}{Picking\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00957}{Picking\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Picking\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{keyInterfacePage}{}\subsection{Key Interface}\label{keyInterfacePage}
 ~\newline
 Using this interface you can react on key events. You first have to register a key (or key combination) with \hyperlink{a00756_afe64bc70902fb2c08169c16e6f825466}{Key\+Interface\+::register\+Key()}. Note that the log widget will contain a warning if you register a key twice or it is occupied by another plugin.

For each registered key your \hyperlink{a00756_a66e0b9cdc50addcbf20ac78b58e9bff7}{Key\+Interface\+::slot\+Key\+Event()} will be triggered when the key was pressed and the slot \hyperlink{a00756_a94d9819293643c5abe9550f9dae8ba6a}{Key\+Interface\+::slot\+Key\+Release\+Event()} when the key was released. Both slots get the Q\+Key\+Event and will contain all the modifiers that were active when the event occurred.

In Open\+Flippers options tab you can view all registered keys and reassign them. The events will be mapped, such that the plugins still receive the right combination. Therefore the mapping will be completely invisible to them.

See our tutorial \hyperlink{ex3}{Implementing mouse and keyboard interaction} for an example of how to use mouse and keyboard events within a plugin.

To use the \hyperlink{a00756}{Key\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02442}{Key\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00756}{Key\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Key\+Interface) to your plugin class 
\item Implement the required functions. 
\end{DoxyItemize}


\begin{DoxyCode}
\textcolor{comment}{// In your plugin initialization register the keys you want to get.}
\textcolor{keywordtype}{void} ExamplePlugin::initializePlugin() \{

  \textcolor{comment}{// Register keys}
  emit registerKey(Qt::Key\_W,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object down"});
  emit registerKey(Qt::Key\_A,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object left"});
  emit registerKey(Qt::Key\_D,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object right"});
  emit registerKey(Qt::Key\_S,     Qt::NoModifier, \textcolor{stringliteral}{"Rotate object up"});

\}

\textcolor{comment}{// Called when one of the registered Keys is pressed.}
\textcolor{keywordtype}{void} MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* \_event ) \{

  \textcolor{comment}{// Check if it's really the right key}
  \textcolor{keywordflow}{if} ( \_event->modifiers() == Qt::NoModifier ) \{

    \textcolor{comment}{// Switch pressed keys}
    \textcolor{keywordflow}{switch} (\_event->key()) \{
      \textcolor{keywordflow}{case} Qt::Key\_W:
        \textcolor{comment}{// Move forward}
        \textcolor{keywordflow}{break};
      \textcolor{keywordflow}{case} Qt::Key\_A:
        \textcolor{comment}{// Move left}
        \textcolor{keywordflow}{break};
      \textcolor{keywordflow}{case} Qt::Key\_D:
        \textcolor{comment}{// Move right}
        \textcolor{keywordflow}{break};
      \textcolor{keywordflow}{case} Qt::Key\_S:
        \textcolor{comment}{// Move backward}
        \textcolor{keywordflow}{break};
      \textcolor{keywordflow}{default}:
        \textcolor{keywordflow}{break};
    \}

  \}
\}
\end{DoxyCode}
 \hypertarget{pluginInterfacesRendering}{}\subsection{Rendering Interface}\label{pluginInterfacesRendering}
This page shows interfaces which could be used to modify Open\+Flippers rendering system

\hyperlink{renderInterfacePage}{Render Interface} ~\newline
 ~\newline
The \hyperlink{a01107}{Render\+Interface} can be used to replace Open\+Flippers default renderer. Therefore special rendering capabilities can be added as a plugin.( \hyperlink{renderInterfacePage}{Render Interface} ) ~\newline
 \hyperlink{postProcessorInterfacePage}{Post Processor Interface} ~\newline
 ~\newline
The \hyperlink{a01005}{Post\+Processor\+Interface} can be used to add a post processing step to Open\+Flipper. After an image is rendered, it is passed to the post processor which can add additional image processing steps like edge detection.( \hyperlink{postProcessorInterfacePage}{Post Processor Interface} ) ~\newline
\hypertarget{renderInterfacePage}{}\subsection{Render Interface}\label{renderInterfacePage}
 ~\newline
 The \hyperlink{a01107}{Render\+Interface} can be used by plugins to add special rendering functions to Open\+Flipper. You can create a dedicated rendering function for a drawmode. E.\+g. when you need to render 4 passes with different shaders you can do that in your rendering function.

Example Code for functions\+: 
\begin{DoxyCode}
TODO
\end{DoxyCode}


To use the \hyperlink{a01107}{Render\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02460}{Render\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01107}{Render\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Render\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{postProcessorInterfacePage}{}\subsection{Post Processor Interface}\label{postProcessorInterfacePage}
 ~\newline
 The Post\+Processor Interface can be used to add additional image post processing functions to Open\+Flipper. For example you get the rendered image in the usual buffers. Afterwards you can add a post processor doing for example edge detection or taking the depth image from the buffer and render it to the main image.

Example Code for functions\+: 
\begin{DoxyCode}
\textcolor{comment}{// fetch shader from cache:}
\textcolor{comment}{//  default screenquad vertex shader}
\textcolor{comment}{//  custom postprocessor fragment shader stored in "Shaders/MyPostProcessor/shader.glsl"}
\hyperlink{a01020}{GLSL::Program}* shader = \hyperlink{a01156_a25db1fcdf5081ab345e27732e0d07d56}{ACG::ShaderCache::getInstance}()->
      \hyperlink{a01156_af7e74e2c97dcea1fb3c482ea5d8560d0}{getProgram}(\textcolor{stringliteral}{"ScreenQuad/screenquad.glsl"}, \textcolor{stringliteral}{"MyPostProcessor/shader.glsl"});


\textcolor{comment}{// bind color texture input to texture-unit 0}
\_input[0]->bindColorTex(0);


\textcolor{comment}{// bind output FBO}
\_output.bind();


\textcolor{comment}{// setup shader uniforms}
shader->\hyperlink{a01020_ad6b634a00820f63f072e9d380d4dfb5a}{use}();
shader->\hyperlink{a01020_ae78ccf1ed98160af603fdaa72cabbe99}{setUniform}(\textcolor{stringliteral}{"param0"}, someValue);
shader->\hyperlink{a01020_ae78ccf1ed98160af603fdaa72cabbe99}{setUniform}(\textcolor{stringliteral}{"texInput"}, 0); \textcolor{comment}{// color texture was bound to unit 0}

\textcolor{comment}{// execute by drawing a screen quad covering the full viewport}
\hyperlink{a01135_a2deea2d329efedb39a3972721564bf20}{ACG::ScreenQuad::draw}(shader);
\end{DoxyCode}


To use the \hyperlink{a01005}{Post\+Processor\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02458}{Post\+Processor\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01005}{Post\+Processor\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Post\+Processor\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{pluginInterfacesOtherInterfaces}{}\subsection{Other Interfaces}\label{pluginInterfacesOtherInterfaces}
This page shows interfaces for other operations.

\hyperlink{RPCInterfacePage}{R\+P\+C Interface} ~\newline
 ~\newline
Interface to call functions across plugins ( \hyperlink{RPCInterfacePage}{R\+P\+C Interface} ) ~\newline
 \hyperlink{scriptInterfacePage}{Scripting Interface} ~\newline
 ~\newline
For plugins which provide scriptable functions ( \hyperlink{scriptInterfacePage}{Scripting Interface} ) ~\newline
 \hyperlink{pluginConnectionInterfacePage}{Plugin Connection Interface} ~\newline
 ~\newline
Enables the developer to connect signals and slots across plugins. ( \hyperlink{pluginConnectionInterfacePage}{Plugin Connection Interface} ) ~\newline
 \hyperlink{processInterfacePage}{Process Interface} ~\newline
 ~\newline
The \hyperlink{a01017}{Process\+Interface} can be used to start arbitrary functions within threads. ( \hyperlink{processInterfacePage}{Process Interface} ) ~\newline
 \hyperlink{securityInterfacePage}{Security/\+License Interface} ~\newline
 ~\newline
The security Interface can be used to add a license management to your plugin. When it is used, plugins will only start, if a valid license is available. The license is bound to a machine (Processor,network,...) and expires after a specified date. ( \hyperlink{securityInterfacePage}{Security/\+License Interface} ) ~\newline
\hypertarget{RPCInterfacePage}{}\subsection{R\+P\+C Interface}\label{RPCInterfacePage}
 ~\newline
The \hyperlink{a01123}{R\+P\+C\+Interface} can be used by plugins to call functions from other Open\+Flipper plugins. The calls are internally transformed into scripting calls and passed to the other plugins.

You can directly connect signals and slots via the \hyperlink{pluginConnectionInterfacePage}{Plugin Connection Interface} .

The interface itself contains two basic functions which can be used to check if another plugin exists (\hyperlink{a01123_a5db569e86875af8d34f4270476f091f3}{R\+P\+C\+Interface\+::plugin\+Exists()}) or if a specific function exists in another plugin (\hyperlink{a01123_a622cd36167ca99bf7f96b7fe407410a0}{R\+P\+C\+Interface\+::function\+Exists()}). Both functions get the clean name of the plugin to check. To get that name, just open the script editor in Open\+Flipper which lists all plugins and their available functions.

Example Code for plugins\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{bool} isPluginAvailable;
emit pluginExists (\textcolor{stringliteral}{"scripting"}, isPluginAvailable);
\end{DoxyCode}


Example Code for functions\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{bool} isFunctionAvailable;
emit functionExists (\textcolor{stringliteral}{"scripting"}, \textcolor{stringliteral}{"showScriptInEditor(QString)"}, isFunctionAvailable);
\end{DoxyCode}


In addition to these basic functions there is a set of template functions in \hyperlink{a02463}{R\+P\+C\+Wrappers.\+hh} which can be used to directly call a function from another plugin via the scripting system. This requires the parameters to be registered to the Q\+T Meta\+Object system which is already done for the most common types of variables.

For calling a function you can use \hyperlink{a03396_a738f9f8746ac261ad6f5c656e2790cd0}{R\+P\+C\+::call\+Function()} or \hyperlink{a03396_aa259c2dd994e39a983163e93ac441c9f}{R\+P\+C\+::call\+Function\+Value()} if the called function returns a value. These functions get the plugin\+Name and the function name and call the requested function via scripting. It is possible to supply additional parameters to these functions that will be passed to the called function.

Example code\+: 
\begin{DoxyCode}
\textcolor{comment}{// call without getting return value}
\hyperlink{a03396_a738f9f8746ac261ad6f5c656e2790cd0}{RPC::callFunction} (\textcolor{stringliteral}{"pluginName"}, \textcolor{stringliteral}{"FunctionName"});

\textcolor{comment}{// call without getting return value and suplying a parameter}
\textcolor{keywordtype}{int} parameter1
\hyperlink{a03396_a738f9f8746ac261ad6f5c656e2790cd0}{RPC::callFunction} (\textcolor{stringliteral}{"pluginName"}, \textcolor{stringliteral}{"FunctionName"}, parameter1);

\textcolor{comment}{// call with getting return value which is defined as the template parameter}
QString parameter2
\textcolor{keywordtype}{bool} value = RPC::callFunctionValue<bool> (\textcolor{stringliteral}{"pluginName"}, \textcolor{stringliteral}{"FunctionName"}, parameter1, parameter2);
\end{DoxyCode}


To use the \hyperlink{a01123}{R\+P\+C\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02461}{R\+P\+C\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01123}{R\+P\+C\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+R\+P\+C\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

\begin{DoxyNote}{Note}
Multithreading\+: You can call any script function from any thread, but the script will be executed on the main thread. 
\end{DoxyNote}
\hypertarget{scriptInterfacePage}{}\subsection{Scripting Interface}\label{scriptInterfacePage}
~\newline
 ~\newline
 Open\+Flipper uses Q\+Ts scripting system to provide scripting functions to the user and to the plugins. It also includes a batch mode where Open\+Flipper is started without an user interface. All plugins which support this mode can than be controlled by command line supplied batch scripts without any user interaction.

The Scripting\+Interface has several functions to support scripting.


\begin{DoxyItemize}
\item Execute scripts which are provided in a simple Q\+String (\hyperlink{a01138_a70522aa5df14916fa00e3747021d27bd}{Script\+Interface\+::execute\+Script()}). 
\begin{DoxyCode}
emit executeScript( \textcolor{stringliteral}{"translate( 5 , Vector(1 , 0 , 0 ) )"} );
\end{DoxyCode}
 This will translate The object with id 6 by the given vector. 
\item Execute scripts which are provided in a file (\hyperlink{a01138_a41b04efbfba5d46592132995fc3729b7}{Script\+Interface\+::execute\+File\+Script()}). 
\begin{DoxyCode}
emit executeFileScript( \textcolor{stringliteral}{"/home/user/script.ofs"} );
\end{DoxyCode}
 
\item If a scriptable slot is executed, it can add an entry to Open\+Flippers script history. This history can later be used to rerun a process in batch mode ( \hyperlink{a01138_a5065fad145b05c6c1e50fe8c4cf150f0}{Script\+Interface\+::script\+Info()} ).

The following example code shows a function called translate in a plugin, that gets an Object\+Id as a parameter. The plugin which emits this function will automatically be added in the history ( e.\+g. {\ttfamily  move.\+translate( Object\+Id , Vector(1 , 0 , 0 ) ) } )


\begin{DoxyCode}
emit scriptInfo( \textcolor{stringliteral}{"translate( ObjectId , Vector(1 , 0 , 0 ) )"} );
\end{DoxyCode}
 
\item Get Information about scriptable functions ( \hyperlink{a01138_a356df2d1b6bcd96b588c475d7d2d27bf}{Script\+Interface\+::get\+Available\+Functions()},\hyperlink{a01138_a1678873a18e5cfb2b79cd8f1a16a01c3}{Script\+Interface\+::get\+Description()} ).

The first function ( \hyperlink{a01138_a356df2d1b6bcd96b588c475d7d2d27bf}{Script\+Interface\+::get\+Available\+Functions()} ) can be used to get a Q\+Stringlist of all available functions. Each string is of the form {\ttfamily pluginname.\+functionname} 
\begin{DoxyCode}
\textcolor{comment}{// Update list of available functions}
QStringList completeList;
emit getAvailableFunctions( completeList  );
\end{DoxyCode}


The second function ( \hyperlink{a01138_a1678873a18e5cfb2b79cd8f1a16a01c3}{Script\+Interface\+::get\+Description()} ) can be used to get information about a function, if it was provided by the developer. 
\end{DoxyItemize}

To use the \hyperlink{a01138}{Script\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02466}{Script\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01138}{Script\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Script\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

An easier interface to call functions is available by the \hyperlink{RPCInterfacePage}{R\+P\+C Interface}. Additionally it is possible to connect signals and slots across plugins via the \hyperlink{pluginConnectionInterfacePage}{Plugin Connection Interface} \hypertarget{pluginConnectionInterfacePage}{}\subsection{Plugin Connection Interface}\label{pluginConnectionInterfacePage}
~\newline
 ~\newline
 The \hyperlink{a00968}{Plugin\+Connection\+Interface} allows to connect signals and slots across different Open\+Flipper plugins.

Usually you should implement the \hyperlink{a00322_a5f240478907447bf172618bd4205df65}{Base\+Interface\+::plugins\+Initialized()} function from \hyperlink{a00322}{Base\+Interface}. In this function you can setup your connections. Don't try to setup your connections earlier as the plugins you try to connect may not exist yet.

~\newline
 {\bfseries  W\+A\+R\+N\+I\+N\+G! Never connect S\+I\+G\+N\+A\+L\+S and S\+L\+O\+T\+S which are already defined in other Interfaces!! W\+A\+R\+N\+I\+N\+G! } ~\newline
This might result in endless loops and breaks Open\+Flippers control loops. You have to keep track of your connections yourself. If you call slots which call updated\+Oject which in turn call your original slot you get a loop and Open\+Flipper is not responsible for your endless loops! Be careful!

The following code shows a simple example to connect signals and slots. For the signal and slot definition you have to use the common Q\+T macros S\+I\+G\+N\+A\+L and S\+L\+O\+T. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} ExamplePlugin::pluginsInitialized()
\{
 \textcolor{comment}{// Use the QT macros to generate the signatures}
 emit crossPluginConnect(pluginA,SIGNAL(signalA(QString)),pluginB,SLOT(slotB(QString)));
\}
\end{DoxyCode}


To use the \hyperlink{a01138}{Script\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02450}{Plugin\+Connection\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a00968}{Plugin\+Connection\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Plugin\+Connection\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}\hypertarget{processInterfacePage}{}\subsection{Process Interface}\label{processInterfacePage}
~\newline
 ~\newline
 The Process interface can be used to run arbitrary slots of your plugin within a separate thread of Open\+Flipper. Open\+Flipper supports a process manager, visualizing currently running operations to the user. Process dialogs and user information can be provided via special signals.

As in qt user interface operations are only allowed from within the main thread, you can not interact with the ui in your threads. Feedback like the progress or other messages need to be passed through the \hyperlink{a01017}{Process\+Interface}. Additionally you have to make sure, that your operations can actually run in parallel to others. If not, you have to mark your thread as blocking, which would prevent the user from starting additional operations until your job gets finished.

Using threads in Open\+Flipper is quite simple. All necessary class definitions are already available to plugins. A tutorial for the thread interface is available\+: \hyperlink{tutorial_thread}{Using threads from within a plugin}\hypertarget{a00166_processInterface_setup}{}\paragraph{Process Setup}\label{a00166_processInterface_setup}
So the first thing we have to do is instantiate an \hyperlink{a00920}{Open\+Flipper\+Thread} object and tell the core that we just created a thread via \hyperlink{a01017_a58c8f90b997edb9c380c53d8f590c2ab}{Process\+Interface\+::start\+Job()}.


\begin{DoxyCode}
\textcolor{comment}{// Create job named "My Thread" .. Name will e visible in OpenFlippers process manager.}
\hyperlink{a00920}{OpenFlipperThread}* thread = \textcolor{keyword}{new} \hyperlink{a00920}{OpenFlipperThread}(name() + \textcolor{stringliteral}{"My thread"});

\textcolor{comment}{// Tell OpenFlipper about the newly created job. In this case, it gets a description and}
\textcolor{comment}{// a span for its steps. This job has 100 steps from 0 to 100. These values are used}
\textcolor{comment}{// to display a progress bar.}
\textcolor{comment}{// The last parameter means that the job will be non-blocking, so the ui will still be available.}
emit startJob( name() + \textcolor{stringliteral}{"My thread"}, \textcolor{stringliteral}{"My thread's description"} , 0 , 100 , \textcolor{keyword}{false});
\end{DoxyCode}


Next thing to do is connecting the thread's signal to local signals/slots in order to keep track of updates concerning the processing of our thread.


\begin{DoxyCode}
\textcolor{comment}{// Slot connection required to tell the core, that the thread has finished}
connect(thread, SIGNAL(finished(QString)),   \textcolor{keyword}{this}, SIGNAL(finishJob(QString)));

\textcolor{comment}{// Slot connection required setting the function in your plugin that should run inside the thread.}
\textcolor{comment}{// It will get the job name which can be used to control the ui elements like progress.}
\textcolor{comment}{// If you don't want to show progress you can skip the jobId QString.}
connect(thread, SIGNAL(\textcolor{keyword}{function}(QString)),   \textcolor{keyword}{this}, SLOT(testFunctionThread(QString)), Qt::DirectConnection)
      ;
\end{DoxyCode}
\hypertarget{a00166_processInterface_start}{}\paragraph{Process Startup}\label{a00166_processInterface_start}
The function() signal needs to be connected to the function that will actually be processed in the thread. Once having connected these signals, we're about to start our thread\+:


\begin{DoxyCode}
\textcolor{comment}{// Launch the thread}
thread->start();

\textcolor{comment}{// Start processing of the function code (connected via signal OpenFlipperThread::function() )}
\textcolor{comment}{// This function is non-blocking and will return immediately.}
thread->\hyperlink{a00920_a007c870b15292d058ac2faf4975f14f5}{startProcessing}();
\end{DoxyCode}
\hypertarget{a00166_processInterface_status}{}\paragraph{Status Reports}\label{a00166_processInterface_status}
There are two signals that you can use to inform the user about your threads state. The first is \hyperlink{a01017_a79f38ef5bc77806e540a4b81b7bdd9e5}{Process\+Interface\+::set\+Job\+State()}. It gets the job\+Id and an int. The int is the process status. It has to be in the values that have been given with \hyperlink{a01017_a58c8f90b997edb9c380c53d8f590c2ab}{Process\+Interface\+::start\+Job()} before. Open\+Flipper will calculate the percentage on its own and display a progress bar at the specific position.

The second function is \hyperlink{a01017_ad62db4825e2d7bd5ec7892381fce7482}{Process\+Interface\+::set\+Job\+Description()} getting a description, that can be changed wile the thread is running. The following example shows a simple thread slot,using these signals. 
\begin{DoxyCode}
\textcolor{comment}{// Useless example function which runs in a thread and updates the ui state.}
\textcolor{comment}{// The QString parameter is only necessary if you want to provide feedback.}
\textcolor{keywordtype}{void} testFunctionThread(QString \_jobId) \{

    \textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0 ; i < 1000000; ++i) \{

        \textcolor{comment}{// Emit new progress state}
        \textcolor{keywordflow}{if}(i % 10000 == 0)
            emit setJobState(\_jobId, (\textcolor{keywordtype}{int})(i / 10000));

        \textcolor{keywordflow}{if}(i == 500000) \{
            \textcolor{comment}{// When half of the processing is finished}
            \textcolor{comment}{// change the job's description}
            emit setJobDescription(\_jobId, \textcolor{stringliteral}{"Half way done"});
        \}
    \}
\}
\end{DoxyCode}
\hypertarget{a00166_processInterface_usage}{}\paragraph{Usage}\label{a00166_processInterface_usage}
To use the \hyperlink{a01017}{Process\+Interface}\+: 
\begin{DoxyItemize}
\item include \hyperlink{a02459}{Process\+Interface.\+hh} in your plugins header file 
\item derive your plugin from the class \hyperlink{a01017}{Process\+Interface} 
\item add Q\+\_\+\+I\+N\+T\+E\+R\+F\+A\+C\+E\+S(\+Process\+Interface) to your plugin class 
\item And add the signals or slots you want to use to your plugin class (You don't need to implement all of them) 
\end{DoxyItemize}

\begin{DoxyNote}{Note}
In general, Open\+Flipper signals should not be emitted from other threads than the main thread. However, there are some signals, which are save to call outside of another thread. Some will block, until the main thread executed the function, some run asnyc. If a function is guaranteed to be threadsafe, you will find a note in the documentation e.\+g. {\ttfamily \hyperlink{a00784_a7c755e4f595b6c64aa1c33910ff0cc6f}{Logging\+Interface\+::log()}} 
\end{DoxyNote}
\hypertarget{a00166_processInterface_quickstart}{}\paragraph{Quick example}\label{a00166_processInterface_quickstart}
A quick example for stating a thread\+:


\begin{DoxyCode}
\hyperlink{a00920}{OpenFlipperThread}* thread = \textcolor{keyword}{new} \hyperlink{a00920}{OpenFlipperThread}(name() + \textcolor{stringliteral}{"unique id"}); 
                                        \textcolor{comment}{// Create your thread containing a unique id}
connect(thread,SIGNAL( finished(QString)), \textcolor{keyword}{this},SIGNAL(finishJob(QString)));                               \textcolor{comment}{
      // connect your threads finish info to the global one ( you can do the same for a local one )}
connect(thread,SIGNAL( \textcolor{keyword}{function}(QString)), \textcolor{keyword}{this},SLOT(testFunctionThread(QString)),Qt::DirectConnection);   \textcolor{comment}{
      // You can directly give a slot of your app that gets called}
emit startJob( name() + \textcolor{stringliteral}{"unique id"}, \textcolor{stringliteral}{"Description"} , 0 , 100 , \textcolor{keyword}{false});                                     \textcolor{comment}{
      // Tell the core about your thread}
thread->start();                                                                                           \textcolor{comment}{
      // start thread}
thread->\hyperlink{a00920_a007c870b15292d058ac2faf4975f14f5}{startProcessing}();                                                                  
                     \textcolor{comment}{// start processing}
\end{DoxyCode}


Note\+: If your class is derived from \hyperlink{a00920}{Open\+Flipper\+Thread}, do not reimplement the {\itshape run()} function. Instead, use the {\itshape function(\+Q\+String)} to connect the your running function with {\itshape Qt\+::\+Direct\+Connection}. Short example\+: Be {\itshape My\+Thread} the derived thread class 
\begin{DoxyCode}
\textcolor{keyword}{class }MyThread : \textcolor{keyword}{public} \hyperlink{a00920}{OpenFlipperThread}
\end{DoxyCode}


and {\itshape parallel\+Function(\+Q\+String)} the function which should run by different threads. 
\begin{DoxyCode}
\textcolor{keywordtype}{void} MyThread::parallelFunction(QString) \textcolor{comment}{// function which will run in parallel}
\{
  std::cout << \textcolor{stringliteral}{"I am running in another thread."} << currentThreadId() << std::endl;
\}
\end{DoxyCode}


Instead of reimplementing the run function, connect the {\itshape parallel\+Function(\+Q\+String)} with the {\itshape function(\+Q\+String)} signal in e.\+g. the constructor\+: 
\begin{DoxyCode}
MyThread::MyThread(QString \_jobId):\hyperlink{a00920}{OpenFlipperThread}(\_jobId)
\{
  \textcolor{comment}{// connect signal function(QString) with the self defined slot function}
  connect(\textcolor{keyword}{this},SIGNAL(\textcolor{keyword}{function}(QString)),\textcolor{keyword}{this},SLOT(parallelFunction(QString)), Qt::DirectConnection);
\}
\end{DoxyCode}


Note\+: The \hyperlink{a00920}{Open\+Flipper\+Thread} will not be notified about job cancelling. You plugin has to be aware of it.

Note\+: You might also want to connect the signal \hyperlink{a00920_aab4287c49391f9b54554f646538f4f8b}{Open\+Flipper\+Thread\+::state()} to the plugin's signal set\+Job\+State()\+:


\begin{DoxyCode}
connect(thread, SIGNAL(state(QString, \textcolor{keywordtype}{int})), \textcolor{keyword}{this}, SIGNAL(setJobState(QString, \textcolor{keywordtype}{int})));
\end{DoxyCode}


Use signal \hyperlink{a00920_aab4287c49391f9b54554f646538f4f8b}{Open\+Flipper\+Thread\+::state()} within your run() function in order to correctly update the job's state. \hypertarget{securityInterfacePage}{}\subsection{Security/\+License Interface}\label{securityInterfacePage}
 ~\newline
 \hypertarget{a00174_Functionality}{}\paragraph{Functionality}\label{a00174_Functionality}
The security Interface can be used to add a license management to your plugin. When it is used, plugins will only start, if a valid license is available. The license is bound to a machine (Processor,network,...) and expires after a specified date.\hypertarget{a00174_security_interface_usage}{}\paragraph{Usage}\label{a00174_security_interface_usage}
To use this interface do the following steps\+:\hypertarget{a00174_license_includes}{}\subparagraph{Includes}\label{a00174_license_includes}
Add the \hyperlink{a00763}{License\+Manager} include to your plugin header file.


\begin{DoxyCode}
\textcolor{preprocessor}{#include <\hyperlink{a02577}{OpenFlipper/LicenseManager/LicenseManager.hh}>}
\end{DoxyCode}
\hypertarget{a00174_license_licensemanager_integration}{}\subparagraph{Q\+Object Replacement}\label{a00174_license_licensemanager_integration}
Don't derive your Plugin from Q\+Object anymore but from \hyperlink{a00763}{License\+Manager} which has to be the first one in your class definition.


\begin{DoxyCode}
\textcolor{comment}{// Before:}
\textcolor{keyword}{class }ExamplePlugin : \textcolor{keyword}{public} QObject, \hyperlink{a00322}{BaseInterface}, \hyperlink{a00804}{MenuInterface}, 
      \hyperlink{a01138}{ScriptInterface}, \hyperlink{a01309}{ToolbarInterface}, 
      \hyperlink{a01237}{StatusbarInterface}

\textcolor{comment}{// After:}
class ExamplePlugin : \textcolor{keyword}{public} \hyperlink{a00763}{LicenseManager}, \hyperlink{a00322}{BaseInterface}, 
      \hyperlink{a00804}{MenuInterface}, \hyperlink{a01138}{ScriptInterface}, \hyperlink{a01309}{ToolbarInterface}, 
      \hyperlink{a01237}{StatusbarInterface}
\end{DoxyCode}
\hypertarget{a00174_cmake_license_changes}{}\subparagraph{Cmake Change}\label{a00174_cmake_license_changes}
Additionally add the option L\+I\+C\+E\+N\+S\+E\+M\+A\+N\+A\+G\+E\+R to your C\+Make\+Lists generator e.\+g.\+:


\begin{DoxyCode}
openflipper\_plugin (LICENSEMANAGER ) )
\end{DoxyCode}
\hypertarget{a00174_salt_file_setup}{}\subparagraph{Salt File}\label{a00174_salt_file_setup}
Copy the example sat file from Open\+Flipper/\+License\+Manager/salt.\+hh.\+example to your plugin directory and rename it to salt.\+hh ( e.\+g. Plugin-\/\+Example/salt.\+hh ). Modify the contents of your salt file to match your plugin\+:

The contact line will be presented to the user when a license has to be retrieved. The user gets the option to start the mail program with this destination address and the license request. 
\begin{DoxyCode}
\textcolor{preprocessor}{#define CONTACTMAIL QString("contact@openflipper.org")}
\end{DoxyCode}


Afterwards modify the A\+D\+D\+\_\+\+S\+A\+L\+T\+\_\+\+P\+R\+E and A\+D\+D\+\_\+\+S\+A\+L\+T\+\_\+\+P\+O\+S\+T macros. Set the characters to some numbers you want. These salts will basically define a password that will be added to the hashes. It has to be kept !!secret!! as everybody who knows these salts, can generate licenses for your plugin. So don't give away your salt file. It is only used when compiling your plugin and the corresponding license manager.

The last thing to change is the A\+D\+D\+\_\+\+P\+L\+U\+G\+I\+N\+\_\+\+F\+I\+L\+E\+N\+A\+M\+E macro. Specify the filename of your plugin here, omitting the ending as this will be added platform dependent by Open\+Flipper.\hypertarget{a00174_license_genration}{}\paragraph{License generation}\label{a00174_license_genration}
When the plugin is now build, an additional \hyperlink{a00763}{License\+Manager} is generated which shows a widget on execution. It will be in your build directory in the subdirectory License\+Management.

To generate a license, copy the license request you received into the widget. Remove all text lines. The manager will split the request into its separate strings. Enter a date, until the license should be valid and generate it.

The generated license has to be copied into Open\+Flippers License subdirectory. \hypertarget{objectDataStructure}{}\section{Object Data Structures}\label{objectDataStructure}
\hypertarget{a00202_object_data_structure_overview}{}\subsection{Overview}\label{a00202_object_data_structure_overview}


All Objects in Ope\+Flipper have to be derived from the \hyperlink{a00329}{Base\+Object}. For the predefined objects this is already the case. In \hyperlink{a00329}{Base\+Object} a tree structure is implemented. You can use the functions in \hyperlink{a00329}{Base\+Object} to search for items and access them. A root Object is created by Open\+Flipper which is the root of the object tree. You can get it via \hyperlink{a03393_a7db0b763935fa0d5933fac6f605b5cba}{Plugin\+Functions\+::object\+Root()}. There is also a \hyperlink{a00663}{Group\+Object} which holds no data and is used for grouping different objects like in the figure above.

All objects in Open\+Flipper are handled by the core. To create and delete objects use the functions provided by the \hyperlink{loadSaveInterfacePage}{Load/\+Save Interface}. Additionally there is a small example on how to add empty objects to the scene which can be filled by the programmer\+: \hyperlink{adding_empty_objects}{Adding empty Objects in a plugin}\hypertarget{a00202_basicObjectTypes}{}\subsection{Basic object types}\label{a00202_basicObjectTypes}
The object hierarchy of Open\+Flipper is shown in the following diagram\+:



In most cases, you do not have to access the data or scenegraph nodes described in the following sections, as the predefined types already handle this for you. You can directly work on the meshes and tell Open\+Flipper about the changes and the core does the relevant updates. If you want to create your own data types, you should definitely read the following information.\hypertarget{a00202_baseObjectDescription}{}\subsubsection{The Base\+Object class}\label{a00202_baseObjectDescription}
All objects are derived from \hyperlink{a00329}{Base\+Object}. This object implements the basic object functions. It creates a tree structure of all available objects, includes object selection, name and type information. It does not contain any code to visualize objects. Each object derived from \hyperlink{a00329}{Base\+Object} has a \hyperlink{a00477}{Data\+Type} function \hyperlink{a00329_a5e279596d614339c689605a875f7d5a8}{Base\+Object\+::data\+Type()} which can be used to identify which is the actual \hyperlink{a00477}{Data\+Type}, as the class \hyperlink{a00329}{Base\+Object} is never used directly but only via derived classes.

Additionally the \hyperlink{a00329}{Base\+Object} class implements the \hyperlink{a00953}{Per\+Object\+Data} system. You can append additional data to each object in the scene via \hyperlink{a00329_a011e6fd32423693f783231046db4c680}{Base\+Object\+::set\+Object\+Data()} ( see \hyperlink{perObjectDataPage}{Per Object Data} ). This data will be handled by the core. You always have a container for the specific object, which also gets destroyed, when the object itself gets destroyed.\hypertarget{a00202_GroupObjectDescription}{}\subsubsection{The Group\+Object class}\label{a00202_GroupObjectDescription}
The \hyperlink{a00663}{Group\+Object} does not have a visible representation in the scene. It is only used to group several objects in the object tree. This grouping is also visible in the Data\+Control plugin.\hypertarget{a00202_baseObjectDataDescription}{}\subsubsection{The Base\+Object\+Data class}\label{a00202_baseObjectDataDescription}
This class is derived from \hyperlink{a00329}{Base\+Object} and includes basic visualization functions. It creates the basic scenegraph nodes for the object.

For every object, the top scenegraph node is a Separator\+Node which you could get via \hyperlink{a00330_a8317cce9d65624082fc3d3b3f0c0b3fd}{Base\+Object\+Data\+::base\+Node()} . All other nodes ( including per object custom nodes ) have to be added below this node. Additionally a Manipulator\+Node is added below the separator node. This manipulator is used to move or transform the object. Normally this node is managed by the move plugin. There are also additional nodes below, which are described in the following figure.



Usually you should append your own nodes below the last created node which is\+: \hyperlink{a00330_aabc3f13376927eadadb4614629b95a4d}{Base\+Object\+Data\+::material\+Node()}.

If you want to create your own object types which should be visible in the scene, you have to derive from this class! In the image above, you see that the available rendered object types (e.\+g. \hyperlink{a00965}{Plane\+Object}, \hyperlink{a00831}{Mesh\+Object}) are already derived from that class.\hypertarget{a00202_MeshObjectDescription}{}\subsubsection{The Mesh\+Object class}\label{a00202_MeshObjectDescription}
\hyperlink{a00831}{Mesh\+Object} is the class representing triangle or polygonal meshes. It is special due to the fact, that there is a general \hyperlink{a00831}{Mesh\+Object} class, which is basically a template object class. The usable classes are derived from it(\+Tri\+Mesh\+Object,\+Poly\+Mesh\+Object). All of them use \hyperlink{a03368}{Open\+Mesh} as their mesh representation. It is based on \hyperlink{a00330}{Base\+Object\+Data} and adds some additional scenegraph nodes.

See \hyperlink{triMeshType}{Triangular Mesh (D\+A\+T\+A\+\_\+\+T\+R\+I\+A\+N\+G\+L\+E\+\_\+\+M\+E\+S\+H)} and \hyperlink{polyMeshType}{Polygonal Mesh (D\+A\+T\+A\+\_\+\+P\+O\+L\+Y\+\_\+\+M\+E\+S\+H)} for the detailed documentation.\hypertarget{a00202_DataAccess}{}\subsection{Access to data from within the Plugins}\label{a00202_DataAccess}
From each plugin you have to get access to the data. Functions to get the right data are provided by the build-\/in Object\+Iterators(\hyperlink{OpenFlipperIterators}{Iterators and their usage} ). If you need consistent data access during the plugin lifetime (e.\+g. you have to track one mesh during the plugin lifetime) you should use the identifiers made available by the objects which never change( \hyperlink{a00202_identifying_objects}{Identifying Objects}).~\newline
 \begin{DoxyNote}{Note}
The only reliable way of uniquely identifying objects in the scene during the whole runtime, is to use the object Id!
\end{DoxyNote}
It is possible that the vector containing the objects changes during the plugin lifetime (added or deleted objects). Only the identifiers will stay constant. If changes occur, the plugins will get notified. More information about the update Notification system is described in the \hyperlink{a00322}{Base\+Interface} documentation (\hyperlink{a00138_baseInterfacegeneralObjectUpdates}{General update notifications} )\hypertarget{a00202_identifying_objects}{}\subsection{Identifying Objects}\label{a00202_identifying_objects}
Objects in Open\+Flipper get a unique id when they are created. This id will not change during runtime. It is possible, that pointers change so you should only use the id to reference objects in your plugins. To get this id, just call the \hyperlink{a00329_a043f52f3105d646af193d4974482869d}{Base\+Object\+::id()} function. To get an object with a specific id, you can use the \hyperlink{a03393}{Plugin\+Functions} provided by the data type (e.\+g. \hyperlink{a03393_ab0afe158eb7c541de3f14d688d922b4e}{Plugin\+Functions\+::tri\+Mesh\+Object(int)} ). This way, you will always be sure to get the right object. \hypertarget{OpenFlipperSceneGraph}{}\section{Open\+Flipper Scene\+Graph}\label{OpenFlipperSceneGraph}
\hypertarget{a00224_OFSceneGraph_Overview}{}\subsection{Overview}\label{a00224_OFSceneGraph_Overview}
Open\+Flipper has an integrated scenegraph which is used to render the scene. There are various nodes available, which are used to transform the scene, set Open\+G\+L status flags, render objects or react on user interaction. When Open\+Flipper is started, it generates a predefined scenegraph structure, that can be extended by the programmer. The following figure shows the basic setup\+:

\hypertarget{a00224_OFSceneGraph_adding}{}\subsection{Adding additional scenegraph nodes}\label{a00224_OFSceneGraph_adding}
Most of the time, you do not have to deal with scenegraph nodes directly. The Objects (e.\+g. \hyperlink{a00831}{Mesh\+Object},\hyperlink{a00965}{Plane\+Object}) automatically handle and update their nodes as required. Each of the objects has a top level Separator\+Node which is attached to the data root node(\+Plugin\+Functions\+::get\+Root\+Node()). Below the Separator\+Node the objects generate their own node structure. This structure consists of the structure of \hyperlink{a00330}{Base\+Object\+Data} (which is the base class for all visible objects \hyperlink{a00202_baseObjectDataDescription}{The Base\+Object\+Data class}). Visibility of each object is than managed in the Data\+Control plugin by hiding the subtree below the objects Separator\+Node.\hypertarget{a00224_OFSceneGraph_adding_global_status_nodes}{}\subsubsection{Adding global status nodes}\label{a00224_OFSceneGraph_adding_global_status_nodes}
It is also possible to add several status nodes to the scenegraph. The top level status nodes (typically the light sources) are added via \hyperlink{a03393_ab47a89c85888c24e51697cc4dbe0ddce}{Plugin\+Functions\+::add\+Global\+Status\+Node()}. The light sources are managed by the light plugin and should not be modified directly. Please keep in mind, that all objects below your node will be influenced. This includes also core nodes like the coordinate system. \begin{DoxyNote}{Note}
Do not add nodes here, which render objects (triangles,...)
\end{DoxyNote}
\hypertarget{a00224_OFSceneGraph_adding_data_status_nodes}{}\subsubsection{Adding data status nodes}\label{a00224_OFSceneGraph_adding_data_status_nodes}
There is a second possibility to add special status nodes which will be only applied to data objects. These are added via \hyperlink{a03393_a205689202437118e51dc0f47ef07887b}{Plugin\+Functions\+::add\+Object\+Rendering\+Node()}. \begin{DoxyNote}{Note}
You should also avoid nodes that render primitives here.
\end{DoxyNote}
\hypertarget{a00224_OFSceneGraph_adding_global_render_nodes}{}\subsubsection{Adding global rendering nodes}\label{a00224_OFSceneGraph_adding_global_render_nodes}
If you need global nodes that do not correspond to objects, you can add them as global nodes (\hyperlink{a03393_a2458aef543b14b2ac0b06c50d168414e}{Plugin\+Functions\+::add\+Global\+Node()}. These nodes should be completely independent of any other objects in the scene. If you have nodes, that visualize properties of an object or have a different association with it, please read (\hyperlink{a00224_OFSceneGraph_adding_nodes_to_objects}{Adding nodes to objects})\hypertarget{a00224_OFSceneGraph_adding_nodes_to_objects}{}\subsection{Adding nodes to objects}\label{a00224_OFSceneGraph_adding_nodes_to_objects}
All nodes that refer to a specific object have to be attached to it. This way, the core can hide them, when the object gets hidden and if it gets deleted, the attached nodes will also be cleaned up. The functions for attaching nodes are specified in \hyperlink{a00330}{Base\+Object\+Data} (\hyperlink{a00330_BaseObjectData_AdditionalNodes_header}{Functions to attach additional Nodes to objects}). \hypertarget{OpenFlipperIterators}{}\section{Iterators and their usage}\label{OpenFlipperIterators}
\hypertarget{a00218_OpenFlipperIterators_Overview}{}\subsection{Overview}\label{a00218_OpenFlipperIterators_Overview}
Open\+Flipper comes with some build in iterators which are defined in \hyperlink{a02452}{Plugin\+Functions.\+hh} .These iterators can be used to iterate over the objects in the current scene. They are described in the following sections.\hypertarget{a00218_OpenFlipperIterators_ObjectIterator}{}\subsection{Object\+Iterator}\label{a00218_OpenFlipperIterators_ObjectIterator}
The \hyperlink{a00895}{Plugin\+Functions\+::\+Object\+Iterator} iterates over all objects that have a visible representation in the scene (Meshes, Points, Lights, Skeletons, ...). If you also want to iterate over invisible objects (like groups) use the \hyperlink{a00218_OpenFlipperIterators_BaseObjectIterator}{Base\+Object\+Iterator}. You can restrict it to source(\+Plugin\+Functions\+::\+S\+O\+U\+R\+C\+E\+\_\+\+O\+B\+J\+E\+C\+T\+S) and target(\+Plugin\+Functions\+::\+T\+A\+R\+G\+E\+T\+\_\+\+O\+B\+J\+E\+C\+T\+S) objects or iterate over all objects (\hyperlink{a03393_aff89407cfc7a2f18a059f6cff7d4edbb}{Plugin\+Functions\+::\+A\+L\+L\+\_\+\+O\+B\+J\+E\+C\+T\+S}).

Additionally you can specify the \hyperlink{a00477}{Data\+Type} that will be returned by the iterator ( e.\+g. D\+A\+T\+A\+\_\+\+T\+R\+I\+A\+N\+G\+L\+E\+\_\+\+M\+E\+S\+H, D\+A\+T\+A\+\_\+\+P\+O\+L\+Y\+\_\+\+M\+E\+S\+H ). The \hyperlink{a00477}{Data\+Type} can also be combined such that all specified types will be returned\+: 
\begin{DoxyCode}
\hyperlink{a00477}{DataType}(\hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH}|\hyperlink{a02346_ad13fb4faf33db21327d9f9ff9ca58120}{DATA\_POLY\_MESH})
\end{DoxyCode}
 The type for iterating over all objects is\+: D\+A\+T\+A\+\_\+\+A\+L\+L.

Here is a simple example how you can use the iterator to get all target triangle meshes. 
\begin{DoxyCode}
\textcolor{keywordflow}{for} ( \hyperlink{a00895}{PluginFunctions::ObjectIterator} o\_it(
      \hyperlink{a03393_ae60d693ef9114d80221eea2454195526}{PluginFunctions::TARGET\_OBJECTS},
      \hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH}) ;
       o\_it != \hyperlink{a03393_a25c8015c612b1aaf3a840ca072ce68ca}{PluginFunctions::objectsEnd}(); ++o\_it)  \{

  \textcolor{comment}{// Get the corresponding mesh object.}
  \hyperlink{a01339}{TriMeshObject}* \textcolor{keywordtype}{object} = \hyperlink{a03393_a1f03569cd9ea2c79069f362b84c42661}{PluginFunctions::triMeshObject}(*o\_it);

  \textcolor{comment}{// Get the corresponding mesh.}
  TriMesh* mesh = \hyperlink{a03393_a11d22dc1c64537f87c014241cacc4340}{PluginFunctions::triMesh}(*o\_it);

\}
\end{DoxyCode}


Second example how you can use the iterator to get all source skeletons. 
\begin{DoxyCode}
\textcolor{keywordflow}{for} ( \hyperlink{a00895}{PluginFunctions::ObjectIterator} o\_it(
      \hyperlink{a03393_a997c364a51707ba883ee346bc38bcea4}{PluginFunctions::SOURCE\_OBJECTS},\hyperlink{a02384_a2212d910967b02f9b8710b04b1c58a12}{DATA\_SKELETON}) ;
       o\_it != \hyperlink{a03393_a25c8015c612b1aaf3a840ca072ce68ca}{PluginFunctions::objectsEnd}(); ++o\_it)  \{

  \textcolor{comment}{// Get the corresponding mesh object.}
  \hyperlink{a01188}{SkeletonObject}* \textcolor{keywordtype}{object} = \hyperlink{a03393_a8300609f45e97a00d60d23217a25ff9d}{PluginFunctions::skeletonObject}(*
      o\_it);

  \textcolor{comment}{// Get the corresponding mesh.}
  \hyperlink{a01190}{Skeleton}* skeleton = \hyperlink{a03393_aee0be07b858d2cd3abe529e1284f8cb4}{PluginFunctions::skeleton}(*o\_it);

\}
\end{DoxyCode}


If you combine data types or iterate over all objects you need to check the \hyperlink{a00477}{Data\+Type} 
\begin{DoxyCode}
\textcolor{keywordflow}{for} ( \hyperlink{a00895}{PluginFunctions::ObjectIterator} o\_it(
      \hyperlink{a03393_aff89407cfc7a2f18a059f6cff7d4edbb}{PluginFunctions::ALL\_OBJECTS},\hyperlink{a02488_a87446416192751e622bd4693a4339419}{DATA\_ALL}) ;
       o\_it != \hyperlink{a03393_a25c8015c612b1aaf3a840ca072ce68ca}{PluginFunctions::objectsEnd}(); ++o\_it)  \{

  \textcolor{comment}{// Check if this is a skeleton}
  \textcolor{keywordflow}{if} ( o\_it->dataType(\hyperlink{a02384_a2212d910967b02f9b8710b04b1c58a12}{DATA\_SKELETON}) ) \{

    \textcolor{comment}{// Get the corresponding mesh object.}
    \hyperlink{a01188}{SkeletonObject}* \textcolor{keywordtype}{object} = \hyperlink{a03393_a8300609f45e97a00d60d23217a25ff9d}{PluginFunctions::skeletonObject}(*
      o\_it);

    \textcolor{comment}{// Get the corresponding mesh.}
    \hyperlink{a01190}{Skeleton}* skeleton = \hyperlink{a03393_aee0be07b858d2cd3abe529e1284f8cb4}{PluginFunctions::skeleton}(*o\_it);

  \} \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} ( o\_it->dataType(\hyperlink{a02424_a899767380abdeb71a7d93f1764e4c746}{DATA\_TRIANGLE\_MESH}) ) \{

    \textcolor{comment}{// Get the corresponding mesh object.}
    \hyperlink{a01339}{TriMeshObject}* \textcolor{keywordtype}{object} = \hyperlink{a03393_a1f03569cd9ea2c79069f362b84c42661}{PluginFunctions::triMeshObject}(*o\_it
      );

    \textcolor{comment}{// Get the corresponding mesh.}
    TriMesh* mesh = \hyperlink{a03393_a11d22dc1c64537f87c014241cacc4340}{PluginFunctions::triMesh}(*o\_it);

  \}

\}
\end{DoxyCode}
\hypertarget{a00218_OpenFlipperIterators_BaseObjectIterator}{}\subsection{Base\+Object\+Iterator}\label{a00218_OpenFlipperIterators_BaseObjectIterator}
The \hyperlink{a00331}{Plugin\+Functions\+::\+Base\+Object\+Iterator} works like the Object\+Iterator, but also returns objects that do not have a visible representation in the scene. A simple example is given in the following code\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} count = 0;

\textcolor{comment}{// Iterate over all objects of type DATA\_GROUP and count them}
\textcolor{keywordflow}{for} ( \hyperlink{a00331}{PluginFunctions::BaseObjectIterator} o\_it(
      \hyperlink{a03393_aff89407cfc7a2f18a059f6cff7d4edbb}{PluginFunctions::ALL\_OBJECTS},\hyperlink{a02488_aa404cecc33a95757fc7f8220d7d0eb79}{DATA\_GROUP});
                                          o\_it != \hyperlink{a03393_a25c8015c612b1aaf3a840ca072ce68ca}{PluginFunctions::objectsEnd}();
       ++o\_it)
  ++count;
\end{DoxyCode}
 \hypertarget{perObjectDataPage}{}\section{Per Object Data}\label{perObjectDataPage}
\hypertarget{a00228_perObjectDataPage_Overview}{}\subsection{Overview}\label{a00228_perObjectDataPage_Overview}
To help developers organizing their data which belongs to specific objects, Open\+Flipper provides the \hyperlink{a00953}{Per\+Object\+Data} class. When you derive your classes from the \hyperlink{a00953}{Per\+Object\+Data} base class, you can attach it to every object in the scene. This way Open\+Flipper takes care of destructing the object, when the corresponding object gets removed and the developer has a permanent storage associated with the object.\hypertarget{a00228_perObjectDataPage_CreatingPerObjectDatas}{}\subsection{Creating your own class}\label{a00228_perObjectDataPage_CreatingPerObjectDatas}
To use the system, just derive your class from the \hyperlink{a00953}{Per\+Object\+Data} base class\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <\hyperlink{a02505}{OpenFlipper/common/perObjectData.hh}>}

\textcolor{keyword}{class }DataClass : \textcolor{keyword}{public} \hyperlink{a00953}{PerObjectData}
\{
 \textcolor{keyword}{public} :

   \textcolor{comment}{// Constructor}
   DataClass();

   \textcolor{comment}{// Destructor}
   ~DataClass();

   \textcolor{comment}{// Copy function (Implement this copy function to create a hard copy of your class)}
   \hyperlink{a00953}{PerObjectData}* \hyperlink{a00953_a0ff13ad2e3fc9df25f6de96a1cd384e0}{copyPerObjectData}();

   \textcolor{comment}{// Your data/functions}

 \};
\end{DoxyCode}


One important virtual function is the virtual \hyperlink{a00953_a0ff13ad2e3fc9df25f6de96a1cd384e0}{Per\+Object\+Data\+::copy\+Per\+Object\+Data()} function. In this function you have to create a hard copy of your class. This hard copy is used by Open\+Flippers backup system to take a full snapshot of all Objects and their associated data. This way you can easily store your plugin state for a specific object in an \hyperlink{a00953}{Per\+Object\+Data}. If the used than performs undo or redo operations, the attached data will also be switched and your states will be kept persistent with the current state of the object.\hypertarget{a00228_perObjectDataPage_AttachingPerObjectDatas}{}\subsection{Attaching the per object data to objects in the scene.}\label{a00228_perObjectDataPage_AttachingPerObjectDatas}
The corresponding functions are implemented in the \hyperlink{a00329}{Base\+Object} (\hyperlink{a00329_baseObjectPerObjectDataFunctions}{here}). The function to attach it is called \hyperlink{a00329_a011e6fd32423693f783231046db4c680}{Base\+Object\+::set\+Object\+Data()}. It gets a name(\+Q\+String) which should start with the plugin name that generated the data and a reasonable description of the data. To get a pointer to a specific Per\+Object\+D\+Ata attached to the object, call \hyperlink{a00329_a64c9fbbfa9225b718474667da04b7dba}{Base\+Object\+::object\+Data()}. \hypertarget{adding_empty_objects}{}\section{Adding empty Objects in a plugin}\label{adding_empty_objects}
\hypertarget{a00188_adding_empty_objects_overview}{}\subsection{Overview}\label{a00188_adding_empty_objects_overview}
Open\+Flipper provides a set of datatypes (\hyperlink{a00204_datatypes_integrated}{Integrated data types} ). While the load and save functions automatically generate objects for the loaded data, it is also useful to generate objects of a specific datatype and fill them with custom data. This page describes how a plugin can create a new object.\hypertarget{a00188_adding_empty_objects_creating}{}\subsection{Creating a new object}\label{a00188_adding_empty_objects_creating}
Your plugin has to implement a part of the \hyperlink{loadSaveInterfacePage}{Load/\+Save Interface}. So you have to derive from that interface and add the \hyperlink{a00778_a088846b57b3ed0ec478afcda31b64596}{Load\+Save\+Interface\+::add\+Empty\+Object} signal to your plugin\+:


\begin{DoxyCode}
\textcolor{comment}{//includes}
\textcolor{preprocessor}{#include <\hyperlink{a02443}{OpenFlipper/BasePlugin/LoadSaveInterface.hh}>}
...


class ExamplePlugin::QObject, ... , \hyperlink{a00778}{LoadSaveInterface}, ...
\{
  Q\_OBJECT
  Q\_INTERFACES(\hyperlink{a00322}{BaseInterface})
  ...
  Q\_INTERFACES(\hyperlink{a00778}{LoadSaveInterface})

signals:
  \textcolor{comment}{// LoadSaveInterface}
  \textcolor{keywordtype}{void} addEmptyObject( \hyperlink{a00477}{DataType} \_type, \textcolor{keywordtype}{int}& \_id);

...
\end{DoxyCode}


To generate the object you can implement the following in one of your functions\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <\hyperlink{a02452}{OpenFlipper/BasePlugin/PluginFunctions.hh}>}

\textcolor{keywordtype}{void} ExamplePlugin::exampleFunction() \{
  \textcolor{comment}{// Variable which will store the id of the newly created object.}
  \textcolor{keywordtype}{int} newObjectId = -1;

  \textcolor{comment}{// Emit the signal, that we want to create a new object of the specified type plane}
  emit addEmptyObject(\hyperlink{a02311_a1a8ecfca78927f65cd66a2ee37fb052a}{DATA\_PLANE}, newObjectId);

  \textcolor{comment}{// Get the newly created object}
  \hyperlink{a00965}{PlaneObject}* \textcolor{keywordtype}{object} = 0;
  \hyperlink{a03393_ac20ce4f5c004657788cc10f4ad465de0}{PluginFunctions::getObject}(newObjectId,\textcolor{keywordtype}{object});

  \textcolor{keywordflow}{if}(\textcolor{keywordtype}{object}) \{

      \textcolor{comment}{// Now you can use the object as usual, e.g. Get the node}
      \hyperlink{a00964}{PlaneNode}* planeNode = \textcolor{keywordtype}{object}->planeNode();

      \textcolor{comment}{// change it}
      planeNode->setPosition(origin,normal);
      planeNode->setSize(kinectinfo\_->getMaxDepth() / 2, kinectinfo\_->getMaxDepth() / 2);

      \textcolor{comment}{// ...}

  \} \textcolor{keywordflow}{else} \{
    \textcolor{comment}{// Something went wrong when creating the object.}
  \}

\}
\end{DoxyCode}
 Of course you have to add the includes for the Object\+Types you want to use to your list of includes. A list of available Object\+Types can be found here\+: \hyperlink{datatypes}{Open\+Flipper Datatypes} 