Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
67 objectType_(0) {
68 }
69 
70 //==============================================================================================
71 
73 }
74 
75 //==============================================================================================
76 
77 void ObjectSelectionPlugin::initializePlugin() {
78 
79  // Tell core about all scriptable slots
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 
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 
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 
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 
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 
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 
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
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 #if QT_VERSION < 0x050000
355  Q_EXPORT_PLUGIN2(objectselectionplugin, ObjectSelectionPlugin);
356 #endif
357 
358 
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:639
void deleteSelectedObjects()
Delete selected objects.
void selectObjects(IdList _list)
Select specified objects.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(1)<< 4)
Selection updated.
ACG::GLState & glState()
Get the glState of the Viewer.
bool target()
Definition: BaseObject.cc:284
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:439
Class for the handling of simple configuration files.
Definition: INIFile.hh:105
void add_entry(const QString &_section, const QString &_key, const QString &_value)
Addition / modification of a string entry.
Definition: INIFile.cc:263
int id() const
Definition: BaseObject.cc:201
~ObjectSelectionPlugin()
Default destructor.
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
void slotToggleSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a toggle selection.
PrimitiveType objectType_
Primitive type handles:
void slotLoadSelection(const INIFile &_file)
Load selection for specific objects in the scene.
ObjectSelectionPlugin()
Default constructor.
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
QString environmentHandle_
Handle to selection environment.
void updateSlotDescriptions()
Set slot descriptions for scripting functions.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
void slotSelectionOperation(QString _operation)
A specific operation is requested.
IdList getObjectSelection()
Get selected objects.
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void deselectAllObjects()
Deselect all objects.
void invertObjectSelection()
Invert object selection.
void selectAllObjects()
Select all objects.
void slotKeyShortcutEvent(int _key, Qt::KeyboardModifiers _modifiers)
One of the previously registered keys has been pressed.
Predefined datatypes.
Definition: DataTypes.hh:96
int viewport_height() const
get viewport height
Definition: GLState.hh:827
QVector< QPoint > volumeLassoPoints_
Keep volume lasso points.
bool section_exists(const QString &_section) const
Check if given section exists in the current INI file.
Definition: INIFile.cc:233
const QStringList ALL_OBJECTS
Iterable object range.
void slotSaveSelection(INIFile &_file)
Save selection for all objects in the scene.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:76
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void slotVolumeLassoSelection(QMouseEvent *_event, SelectionInterface::PrimitiveType _currentType, bool _deselect)
Called whenever the user performs a volume lasso selection.