Developer Documentation

ObjectSelectionPlugin.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Author$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50 #include "ObjectSelectionPlugin.hh"
51
52 #include <OpenFlipper/common/GlobalOptions.hh>
53
54 // Primitive type icons
55 #define OBJECT_TYPE "selection_object.png"
56 // =======================================
57 // Define operations
58 // =======================================
59 // Vertices:
60 #define O_SELECT_ALL "Select All Objects"
61 #define O_DESELECT_ALL "Deselect All Objects"
62 #define O_INVERT "Invert Object Selection"
63 #define O_DELETE "Delete Selected Objects"
64
66 ObjectSelectionPlugin::ObjectSelectionPlugin() :
67 objectType_(0) {
68 }
69
70 //==============================================================================================
71
72 ObjectSelectionPlugin::~ObjectSelectionPlugin() {
73 }
74
75 //==============================================================================================
76
77 void ObjectSelectionPlugin::initializePlugin() {
78
79 // Tell core about all scriptable slots
80 updateSlotDescriptions();
81 }
82
83 //==============================================================================================
84
85 void ObjectSelectionPlugin::pluginsInitialized() {
86 // Create new selection environment for polylines
87 // and register polyline data type for the environment.
88
89 QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
90
91 emit addSelectionEnvironment("Object Selections", "Select objects.",
92 iconPath + OBJECT_TYPE, environmentHandle_);
93
94 // Register mesh object types
95 emit registerType(environmentHandle_, DATA_ALL);
96
97 emit addPrimitiveType(environmentHandle_, "Select Objects", iconPath + OBJECT_TYPE, objectType_);
98
99 // Determine, which selection modes are requested
100 emit showToggleSelectionMode(environmentHandle_, true, objectType_);
101 emit showVolumeLassoSelectionMode(environmentHandle_, true, objectType_);
102
103 // Define object operations
104 QStringList objectOperations;
105 objectOperations.append(O_SELECT_ALL);
106 objectOperations.append(O_DESELECT_ALL);
107 objectOperations.append(O_INVERT);
108 objectOperations.append(O_DELETE);
109
110 emit addSelectionOperations(environmentHandle_, objectOperations, "Object Operations", objectType_);
111
112 // Register key shortcuts:
113
114 // Select (a)ll
115 emit registerKeyShortcut(Qt::Key_A, Qt::ControlModifier);
116 // (C)lear selection
117 emit registerKeyShortcut(Qt::Key_C, Qt::NoModifier);
118 // (I)nvert selection
119 emit registerKeyShortcut(Qt::Key_I, Qt::NoModifier);
120 // Delete selected entities
121 emit registerKeyShortcut(Qt::Key_Delete, Qt::NoModifier);
122 }
123
124 //==============================================================================================
125
126 void ObjectSelectionPlugin::updateSlotDescriptions() {
127
128 emit setSlotDescription("selectAllObjects(int)", tr("Select all objects"),
129 QStringList("objectId"), QStringList("Id of object"));
130 emit setSlotDescription("deselectAllObjects(int)", tr("Deselect all objects"),
131 QStringList("objectId"), QStringList("Id of object"));
132 emit setSlotDescription("invertObjectSelection(int)", tr("Invert object selection"),
133 QStringList("objectId"), QStringList("Id of object"));
134 emit setSlotDescription("deleteSelectedObjects(int)", tr("Delete selected objects"),
135 QStringList("objectId"), QStringList("Id of object"));
136 emit setSlotDescription("selectObjects(int,IdList)", tr("Select the specified objects"),
137 QString("objectId,objectList").split(","), QString("Id of object,List of objects").split(","));
138
139 emit setSlotDescription("loadSelection(int,QString)", tr("Load selection from selection file"),
140 QString("objectId,filename").split(","), QString("Id of an object,Selection file").split(","));
141 }
142
143 //==============================================================================================
144
145 void ObjectSelectionPlugin::slotSelectionOperation(QString _operation) {
146
147 SelectionInterface::PrimitiveType type = 0u;
148 emit getActivePrimitiveType(type);
149
150 if((type & objectType_) == 0)
151 return;
152
153 if(_operation == O_SELECT_ALL) {
154 // Select all objects
155 selectAllObjects();
156 } else if (_operation == O_DESELECT_ALL) {
157 // Deselect all objects
158 deselectAllObjects();
159 } else if (_operation == O_INVERT) {
160 // Invert object selection
161 invertObjectSelection();
162 } else if (_operation == O_DELETE) {
163 // Delete selected objects
164 deleteSelectedObjects();
165 }
166 }
167
168 //==============================================================================================
169
170 void ObjectSelectionPlugin::slotToggleSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
171
172 // Return if none of the currently active types is handled by this plugin
173 if((_currentType & objectType_) == 0) return;
174
175 // Return if mouse event is not a left-button click
176 if(_event->button() != Qt::LeftButton) return;
177
178 size_t node_idx = 0;
179 size_t target_idx = 0;
180 ACG::Vec3d hit_point;
181
182 BaseObjectData* object = 0;
183
184 bool successfullyPicked = PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx,
185 target_idx, &hit_point) && PluginFunctions::getPickedObject(node_idx, object);
186
187 if(successfullyPicked) {
188
189 if(object->target() || _deselect)
190 object->target(false);
191 else
192 object->target(true);
193
194 emit updatedObject(object->id(), UPDATE_SELECTION);
195 }
196 }
197
198 //==============================================================================================
199
200 void ObjectSelectionPlugin::slotVolumeLassoSelection(QMouseEvent* _event, SelectionInterface::PrimitiveType _currentType, bool _deselect) {
201
202 // Return if none of the currently active types is handled by this plugin
203 if((_currentType & objectType_) == 0) return;
204
205 ACG::Vec3d hit_point;
206
207 if(_event->type() == QEvent::MouseButtonPress) {
208
209 ACG::GLState &state = PluginFunctions::viewerProperties().glState();
210 QPoint p(_event->pos().x(), state.viewport_height() - _event->pos().y());
211
212 volumeLassoPoints_.append(p);
213
214 return;
215
216 } else if(_event->type() == QEvent::MouseButtonDblClick) {
217
218 ACG::GLState &state = PluginFunctions::viewerProperties().glState();
219
220 QPolygon polygon(volumeLassoPoints_);
221
222 // Select all vertices that lie in this region
223 for(PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_ALL));
224 o_it != PluginFunctions::objectsEnd(); ++o_it) {
225
226 if (o_it->visible()) {
227
228 // Look if COG of object lies within polygon
229 ACG::Vec3d bbmin(0.0);
230 ACG::Vec3d bbmax(0.0);
231 o_it->getBoundingBox(bbmin, bbmax);
232 ACG::Vec3d c = (bbmin + bbmax)/2.0;
233
234 ACG::Vec3d pc = state.project(c);
235 QPoint p((int)pc[0], (int)pc[1]);
236
237 if(polygon.containsPoint(p, Qt::OddEvenFill)) {
238 o_it->target(!_deselect);
239 }
240 }
241
242 emit updatedObject(o_it->id(), UPDATE_SELECTION);
243 }
244
245
246 // Clear lasso points
247 volumeLassoPoints_.clear();
248 }
249 }
250
251 //==============================================================================================
252
253 void ObjectSelectionPlugin::loadSelection(int _objId, const QString& _filename) {
254
255 // Load ini file
256 INIFile file;
257
258 if(!file.connect(_filename, false)) {
259 emit log(LOGERR, QString("Could not read file '%1'!").arg(_filename));
260 return;
261 }
262
263 // Load selection from file
264 loadIniFile(file, _objId);
265 }
266
267 //==============================================================================================
268
269 void ObjectSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
270 // From INI Interface
271 // Load plugin specific settings
272 }
273
274 //==============================================================================================
275
276 void ObjectSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
277 // From INI Interface
278 // Save plugin specific settings
279 }
280
281 //==============================================================================================
282
283 void ObjectSelectionPlugin::slotLoadSelection(const INIFile& _file) {
284
285 // Iterate over all polyline objects in the scene and save
286 // the selections for all supported entity types
287 for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_ALL));
288 o_it != PluginFunctions::objectsEnd(); ++o_it) {
289
290 // Read section for each object
291 // Append object name to section identifier
292 QString section = QString("ObjectSelection") + "//" + o_it->name();
293 if(!_file.section_exists(section)) {
294 continue;
295 }
296
297 std::vector<int> ids;
298 // Load vertex selection:
299 _file.get_entry(ids, section, "Target");
300 selectObjects(ids);
301 ids.clear();
302
303 emit updatedObject(o_it->id(), UPDATE_SELECTION);
304 }
305 }
306
307 //==============================================================================================
308
309 void ObjectSelectionPlugin::slotSaveSelection(INIFile& _file) {
310
311 // Iterate over all polyline objects in the scene and save
312 // the selections for all vertices
313 for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_ALL));
314 o_it != PluginFunctions::objectsEnd(); ++o_it) {
315
316 // Create section for each object
317 // Append object name to section identifier
318 QString section = QString("ObjectSelection") + "//" + o_it->name();
319
320 // Store vertex selection:
321 _file.add_entry(section, "Target", getObjectSelection());
322 }
323 }
324
325 //==============================================================================================
326
327 void ObjectSelectionPlugin::slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) {
328
329 SelectionInterface::PrimitiveType type = 0u;
330 emit getActivePrimitiveType(type);
331
332 if((type & objectType_) == 0) {
333 // No supported type is active
334 return;
335 }
336
337 if(_key == Qt::Key_A && _modifiers == Qt::ControlModifier) {
338 // Select all objects
339 selectAllObjects();
340 } else if(_key == Qt::Key_C && _modifiers == Qt::NoModifier) {
341 // Deselect all vertices
342 deselectAllObjects();
343 } else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
344 // Invert object selection
345 invertObjectSelection();
346 } else if(_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
347 // Delete selected objects
348 deleteSelectedObjects();
349 }
350 }
351
352 //==============================================================================================
353
354
355
ObjectSelectionPlugin::slotLoadSelection
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
Definition: ObjectSelectionPlugin.cc:283
ObjectSelectionPlugin::objectType_
PrimitiveType objectType_
Primitive type handles:
Definition: ObjectSelectionPlugin.hh:215
PluginFunctions::scenegraphPick
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
Definition: PluginFunctions.cc:478
ACG::SceneGraph::PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
ObjectSelectionPlugin::slotToggleSelection
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
Definition: ObjectSelectionPlugin.cc:170
ObjectSelectionPlugin::deselectAllObjects
void deselectAllObjects()
Deselect all objects.
Definition: ObjectSelectionFunctions.cc:76
ObjectSelectionPlugin::~ObjectSelectionPlugin
~ObjectSelectionPlugin()
Default destructor.
Definition: ObjectSelectionPlugin.cc:72
BaseObject::id
int id() const
Definition: BaseObject.cc:190
PluginFunctions::getPickedObject
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
Definition: PluginFunctions.cc:259
ObjectSelectionPlugin::ObjectSelectionPlugin
ObjectSelectionPlugin()
Default constructor.
Definition: ObjectSelectionPlugin.cc:66
UPDATE_SELECTION
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
INIFile::section_exists
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
ObjectSelectionPlugin::environmentHandle_
QString environmentHandle_
Handle to selection environment.
Definition: ObjectSelectionPlugin.hh:212
ObjectSelectionPlugin::slotVolumeLassoSelection
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.
Definition: ObjectSelectionPlugin.cc:200
ObjectSelectionPlugin::deleteSelectedObjects
void deleteSelectedObjects()
Delete selected objects.
Definition: ObjectSelectionFunctions.cc:100
INIFile::connect
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
PluginFunctions::ALL_OBJECTS
const QStringList ALL_OBJECTS
Iterable object range.
Definition: PluginFunctions.hh:430
LOGERR
Definition: LoggingInterface.hh:96
BaseObject::target
bool target()
Definition: BaseObject.cc:273
GlobalOptions.hh
ObjectSelectionPlugin::slotSaveSelection
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
Definition: ObjectSelectionPlugin.cc:309
ACG::GLState
Definition: GLState.hh:213
ObjectSelectionPlugin::updateSlotDescriptions
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
Definition: ObjectSelectionPlugin.cc:126
PluginFunctions::viewerProperties
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
Definition: PluginFunctions.cc:609
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
ObjectSelectionPlugin::slotKeyShortcutEvent
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
Definition: ObjectSelectionPlugin.cc:327
ACG::GLState::viewport_height
int viewport_height() const
get viewport height
Definition: GLState.hh:824
ObjectSelectionPlugin::selectObjects
void selectObjects(IdList _list)
Select specified objects.
Definition: ObjectSelectionFunctions.cc:62
ObjectSelectionPlugin::selectAllObjects
void selectAllObjects()
Select all objects.
Definition: ObjectSelectionFunctions.cc:50
ObjectSelectionPlugin::slotSelectionOperation
void slotSelectionOperation(QString _operation)
A specific operation is requested.
Definition: ObjectSelectionPlugin.cc:145
INIFile::add_entry
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
DataType
Predefined datatypes.
Definition: DataTypes.hh:83
PluginFunctions::ObjectIterator
Core Data Iterator.
Definition: PluginFunctions.hh:441
ObjectSelectionPlugin::invertObjectSelection
void invertObjectSelection()
Invert object selection.
Definition: ObjectSelectionFunctions.cc:88
PluginFunctions::objectsEnd
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Definition: PluginFunctionsIterator.cc:177
OpenMesh::VectorT
Definition: Vector11T.hh:83
Viewer::ViewerProperties::glState
ACG::GLState & glState()
Get the glState of the Viewer.
Definition: ViewerProperties.cc:318
ObjectSelectionPlugin::getObjectSelection
IdList getObjectSelection()
Get selected objects.
Definition: ObjectSelectionFunctions.cc:127
BaseObjectData
Definition: BaseObjectData.hh:102
DATA_ALL
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
ObjectSelectionPlugin::volumeLassoPoints_
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
Definition: ObjectSelectionPlugin.hh:218
INIFile
Class for the handling of simple configuration files.
Definition: INIFile.hh:99
INIFile::get_entry
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433