pluginProgramming.docu 8.92 KB
Newer Older
1
/** \page pluginProgramming Plugin Programming
Mike Kremer's avatar
Mike Kremer committed
2
 *
Jan Möbius's avatar
Jan Möbius committed
3
 * 
Mike Kremer's avatar
Mike Kremer committed
4
5
 * \section quickref Quick references:
 * - \ref plugin_sec
6
 * - \ref plugin_startup
Mike Kremer's avatar
Mike Kremer committed
7
8
9
10
 * - \ref plugin_prog_sec
 * - \ref geometryData
 * \section tuts Tutorials
 * - \ref ex1
11
 * - \ref ex1c
Mike Kremer's avatar
Mike Kremer committed
12
13
 * - \ref ex2
 * - \ref ex3
14
 * - \ref tutorial_thread 
Mike Kremer's avatar
Mike Kremer committed
15
16
17
 *
 * \section plugin_sec Plugin Basics
 * 
Jan Möbius's avatar
Jan Möbius committed
18
 * As mentioned above OpenFlipper is a plugin based system. It uses the QT plugin implementation to
Mike Kremer's avatar
Mike Kremer committed
19
20
21
 * 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 
Jan Möbius's avatar
Jan Möbius committed
22
23
24
 * 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).
25
26
27
28
29
30
31
32
33
34
 *
 * \section plugin_startup OpenFlipper Startup and Plugin Initialization
 * The plugins are initialized as shown in the following flow diagram:
 *
 * \image html OpenFlipperStartup.png 
 * 
 * OpenFlipper first starts its core system. Therefore it loads the settings, parses command line options and initializes
 * the QT 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:
 * -# All the plugins are loaded into memory.
Jan Möbius's avatar
Jan Möbius committed
35
 * -# For each plugin, the interfaces get connected and afterwards the BaseInterface::initializePlugin() function is called.
36
 *    (Here you can setup your internal variables). After execution of this slot your plugin should be fully functional. Only gui
Jan Möbius's avatar
Jan Möbius committed
37
 *    elements may be uninitialized and should be created in BaseInterface::pluginsInitialized().
38
39
40
41
42
43
44
45
46
 * -# For each plugin the BaseInterface::pluginsInitialized() function is called. Here you can setup your gui elements and start
 *    sending signals to the core.
 * -# For each plugin the INIInterface::loadIniFileOptions() slot is called (if the interface is implemented). This slot can be used to load
 *    additional options from INI files. (DEPRECATED! Use the OpenFlipperSettings() class instead)
 *
 *\note - Do not create objects via addEmpty or load objects during OpenFlipper startup, as the rendering system is not ready yet!
 *\note - The ini interface is deprecated for loading or storing plugin options. Please use OpenFlipperSettings() instead.
 *
 * Afterwards the plugin initialization is complete and the core sets up the final gui.
Mike Kremer's avatar
Mike Kremer committed
47
 * 
Jan Möbius's avatar
Jan Möbius committed
48
 * \section plugin_prog_sec Plugin Programming
Mike Kremer's avatar
Mike Kremer committed
49
 * The interface between the core and the plugins is managed via simple interfaces based on the signal/slot
Jan Möbius's avatar
Jan Möbius committed
50
51
52
 * metaphor of QT. Your plugins have to be derived from these interfaces. You don't have to implement
 * all functions or signals of the interfaces you include. The BaseInterface has to be included in every
 * plugin. See the \ref baseInterfacePage "BaseInterface Documentation" for details.
Mike Kremer's avatar
Mike Kremer committed
53
 * 
Jan Möbius's avatar
Jan Möbius committed
54
 * Unimplemented functions will be left unconnected from the core and won't have any impact on the applications
Mike Kremer's avatar
Mike Kremer committed
55
 * speed or stability. As stated above, every plugin has to be derived from the BaseInterface. This is the
Jan Möbius's avatar
Jan Möbius committed
56
57
58
59
 * basic factory which makes the core aware of the plugin. The BaseInterface::name() and the
 * BaseInterface::description() of the plugin is exported via the BaseInterface. The initialization of each
 * plugin is done via this interface too.
 * See \ref baseInterfacePluginInitialization for an overview of OpenFlipper's startup and initialization calls.
Mike Kremer's avatar
Mike Kremer committed
60
 * 
Jan Möbius's avatar
Jan Möbius committed
61
 * After this interface of the plugin is successfully processed all other interfaces will be initialized
62
63
 * and connected to the core. For details about the individual interfaces see the
 * \ref interfaces "Plugin Interfaces Documentation".
Mike Kremer's avatar
Mike Kremer committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 *
 * \section geometryData Handling geometry data within a plugin
 *
 * \subsection addingAndRemovingGeometry Adding and removing mesh objects in OpenFlipper
 *
 * If you want to load geometry data from a file or simply add objects to the scene
 * from within a plugin, it has to implement the \ref LoadSavePlugin.
 *
 * LoadSaveInterface::load(	QString _file, DataType _type, int&	_id) tries to
 * load file with file name _file of type _type, _id contains the new created
 * object's id or -1 if loading failed. OpenFlipper will then create all
 * the necessary scene graph nodes such that the developer generally does
 * not need to know in detail how to create and add the required nodes to the scene.
 *
 * Otherwise if a file has been loaded externally, slot
 *
 * LoadSaveInterface::openedFile (int _id) is called.
 *
 * When removing objects from the scene, the plugin simply has to emit signal
 *
 * LoadSaveInterface::deleteObject(int _id)
 *
 * or
 *
 * LoadSaveInterface::deleteAllObjects() in order to clear the scene.
 *
 * \subsection pluginFunctions OpenFlipper's plugin functions
 *
 * As a plugin in most cases operates on geometry data, developers might want to know how to gain access to mesh data
 * from within a plugin. In our tutorial \ref ex2 we roughly mentioned that the communication between OpenFlipper
 * and it's plugins is accomplished through either one of the provided \ref interfaces or the \ref PluginFunctions.
 *
96
97
 * For example iterating over all objects is managed via the ObjectIterator.
 *
Mike Kremer's avatar
Mike Kremer committed
98
99
100
101
 * <code>
 * for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::SOURCE_OBJECTS);<br />
 * o_it != PluginFunctions::objectsEnd(); ++o_it) { ... }
 * </code>
102
103
 * 
 * See \ref OpenFlipperIterators for details.
Mike Kremer's avatar
Mike Kremer committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
 *
 * Possible restrictions are \c ALL_OBJECTS (to iterate over all objects in the scene), \c TARGET_OBJECTS (objects
 * that were marked as target) and \c SOURCE_OBJECTS.
 *
 * Another way to get handles to scene objects is to use the functions \c PluginFunctions::getObject() or
 * PluginFunctions::getPickedObject(). These functions provide a pointer to either a \ref BaseObjectData
 * or \ref BaseObject object. As in \ref ex2 one can easily test the type of an object by calling
 *
 * \c o_it->dataType(DATA_TYPE)
 *
 * where \c o_it is an object iterator and \c DATA_TYPE is one of the data types specified in \ref OpenFlipper/common/Types.hh.
 * \c o_it->dataType(DATA_TRIANGLE_MESH) for example will return true if the object is a triangle mesh.
 *
 * The mesh data itself can be obtained by calling the appropriate handle plugin function. For example if we consider
 * a triangle mesh, we get a handle to the mesh itself by calling
 *
 * <code>TriMesh* mesh = PluginFunctions::triMesh(*o_it);</code>
 *
 * where \c o_it once again is our object iterator. See \ref PluginFunctions for a complete overview.
 *
 * \subsection updatingObjects Updating objects
 *
 * Once your plugin has manipulated object data we have to inform OpenFlipper's core about the changes.
127
 * When doing this, OpenFlipper distinguishes between five basic types of changes:
Mike Kremer's avatar
Mike Kremer committed
128
 *
129
130
131
132
133
 * - Object selections
 * - Visibility
 * - Geometry
 * - Topology
 * - Selections (Vertices, Edges, Faces)
Mike Kremer's avatar
Mike Kremer committed
134
135
136
137
 *
 * When changing geometry, OpenFlipper's core will be forced to redraw the object that has been
 * changed by emitting signal
 *
138
 * \ref BaseInterface::updatedObject(int _id, UpdateType _type)
Mike Kremer's avatar
Mike Kremer committed
139
 *
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
 * where \c _id is the object's id and _type is the type of changes that have been made.
 * Note: UpdateType offers the following values
 *
 * - UPDATE_ALL
 * - UPDATE_OBJECT_SELECTION
 * - UPDATE_VISIBILITY
 * - UPDATE_GEOMETRY
 * - UPDATE_TOPOLOGY
 * - UPDATE_SELECTION (ALL THREE KINDS)
 * - UPDATE_SELECTION_VERTICES
 * - UPDATE_SELECTION_EDGES
 * - UPDATE_SELECTION_FACES
 * - UPDATE_UNUSED
 *
 * If the second parameter of this signal is not specified, it will fall back
 * to the default value UPDATE_ALL 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.
 *
159
160
161
162
 * Additionally, when overriding the slot BaseInterface::slotObjectUpdated(int, const UpdateType),
 * a plugin receives the updated object's id (first parameter) and the type
 * of changes (second parameter).
 *
163
 * See \ref BaseInterface for more information.
Mike Kremer's avatar
Mike Kremer committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
 *
 * When changing object properties it won't be necessary to redraw the scene
 * since it can be expensive in computation power. In this case, one should emit
 *
 * \ref BaseInterface::objectPropertiesChanged(int _id)
 *
 * where \c _id once again is the object's id.
 *
 * If a plugin changed an object's visibility (hide, show), it should emit
 *
 * \ref BaseInterface::visibilityChanged(int _id)
 *
 * for the core to update the visibility state of object with identifier \c _id.
 *
 * Last, when changing an object's selection, it
 * will be updated by emitting
 *
 * \ref BaseInterface::objectSelectionChanged(int _id)
 *
 * where \c _id as in the examples above is the object's identifier.
 *
 * Also see \ref BaseInterface.
Jan Möbius's avatar
Jan Möbius committed
186
 *
187
188
189
190
191
 * \section pluginProgramming_related_pages Related pages
 * - \subpage pluginExamples
 * - \subpage OpenFlipperIterators
 * - \subpage interfaces
 * - \subpage adding_empty_objects
Mike Kremer's avatar
Mike Kremer committed
192
 */