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
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
67objectType_(0) {
68}
69
70//==============================================================================================
71
73}
74
75//==============================================================================================
76
77void ObjectSelectionPlugin::initializePlugin() {
78
79 // Tell core about all scriptable slots
81}
82
83//==============================================================================================
84
85void 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
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
145void ObjectSelectionPlugin::slotSelectionOperation(const 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
156 } else if (_operation == O_DESELECT_ALL) {
157 // Deselect all objects
159 } else if (_operation == O_INVERT) {
160 // Invert object selection
162 } else if (_operation == O_DELETE) {
163 // Delete selected objects
165 }
166}
167
168//==============================================================================================
169
170void 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
200void 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
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
219
220 QPolygon polygon(volumeLassoPoints_);
221
222 // Select all vertices that lie in this region
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
253void 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
269void ObjectSelectionPlugin::loadIniFile(INIFile& _ini, int _id) {
270 // From INI Interface
271 // Load plugin specific settings
272}
273
274//==============================================================================================
275
276void ObjectSelectionPlugin::saveIniFile(INIFile& _ini, int _id) {
277 // From INI Interface
278 // Save plugin specific settings
279}
280
281//==============================================================================================
282
284
285 // Iterate over all polyline objects in the scene and save
286 // the selections for all supported entity types
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
310
311 // Iterate over all polyline objects in the scene and save
312 // the selections for all vertices
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
327void 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
340 } else if(_key == Qt::Key_C && _modifiers == Qt::NoModifier) {
341 // Deselect all vertices
343 } else if(_key == Qt::Key_I && _modifiers == Qt::NoModifier) {
344 // Invert object selection
346 } else if(_key == Qt::Key_Delete && _modifiers == Qt::NoModifier) {
347 // Delete selected objects
349 }
350}
351
352//==============================================================================================
353
354
355
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
@ LOGERR
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
int viewport_height() const
get viewport height
Definition: GLState.hh:849
bool target()
Definition: BaseObject.cc:271
int id() const
Definition: BaseObject.cc:188
Predefined datatypes.
Definition: DataTypes.hh:83
Class for the handling of simple configuration files.
Definition: INIFile.hh:100
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:227
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:257
void selectObjects(IdList _list)
Select specified objects.
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
ObjectSelectionPlugin()
Default constructor.
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.
PrimitiveType objectType_
Primitive type handles:
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
void selectAllObjects()
Select all objects.
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
QString environmentHandle_
Handle to selection environment.
void deselectAllObjects()
Deselect all objects.
void invertObjectSelection()
Invert object selection.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
IdList getObjectSelection()
Get selected objects.
void deleteSelectedObjects()
Delete selected objects.
~ObjectSelectionPlugin()
Default destructor.
ACG::GLState & glState()
Get the glState of the Viewer.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(16))
Selection updated.
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
const QStringList ALL_OBJECTS
Iterable object range.