Developer Documentation
Loading...
Searching...
No Matches
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
69
70//==============================================================================================
71
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
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()
int id() const
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.
ObjectSelectionPlugin()
Default constructor.
PrimitiveType objectType_
Primitive type handles:
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
void slotSaveSelection(INIFile &_file) override
Save selection for all objects in the scene.
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a volume lasso selection.
void selectAllObjects()
Select all objects.
QString environmentHandle_
Handle to selection environment.
void deselectAllObjects()
Deselect all objects.
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers) override
One of the previously registered keys has been pressed.
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect) override
Called whenever the user performs a toggle selection.
void invertObjectSelection()
Invert object selection.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
void slotLoadSelection(const INIFile &_file) override
Load selection for specific objects in the scene.
IdList getObjectSelection()
Get selected objects.
void deleteSelectedObjects()
Delete selected objects.
void slotSelectionOperation(QString _operation) override
A specific operation is requested.
~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.