Developer Documentation
PropertyVisPlugin.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 //=============================================================================
45 //
46 // CLASS PropertyVisPlugin - IMPLEMENTATION
47 //
48 //=============================================================================
49 
50 //== INCLUDES =================================================================
51 
52 #include "PropertyVisPlugin.hh"
53 
54 #include "Models/PropertyModelFactory.hh"
55 #include "Models/SingleObjectPropertyModel.hh"
56 
57 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
59 #endif
60 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
62 #endif
63 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
65 #endif
66 
67 //== IMPLEMENTATION ==========================================================
68 
69 #define PROP_VIS "PropertyVisualization"
70 
71 PropertyVisPlugin::PropertyVisPlugin() :
72 tool_(0),
73 propertyModel_(0)
74 {
75 }
76 
77 void PropertyVisPlugin::initializePlugin()
78 {
79  if ( OpenFlipper::Options::gui() ) {
80  tool_ = new PropertyVisToolbar();
81 
82  QSize size(300,300);
83  tool_->resize(size);
84 
85  tool_->meshNames->setModel(&objectListItemModel_);
86 
87  emit addHiddenPickMode( PROP_VIS );
88 
89  QIcon* toolIcon = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"PropertyVisIcon.png");
90 
91  emit addToolbox( tr("Property Visualization") , tool_, toolIcon );
92  }
93 }
94 
95 //-----------------------------------------------------------------------------
96 
97 void PropertyVisPlugin::pluginsInitialized()
98 {
99  if ( OpenFlipper::Options::gui() ) {
100 
101  // connect toolbox elements
102  connect(tool_->meshNames, SIGNAL( currentIndexChanged(int) ), this, SLOT( slotMeshChanged(int) ) );
103 
104  connect(tool_->visualizeButton, SIGNAL( clicked() ), this, SLOT( slotVisualize() ) );
105  connect(tool_->clearButton, SIGNAL( clicked() ), this, SLOT( slotAllCleared() ) );
106 
107  connect(tool_->refresh_property_names_tb, SIGNAL( clicked() ), this, SLOT( slotMeshChanged() ) );
108  connect(tool_->duplicate_property_tb, SIGNAL( clicked() ), this, SLOT( slotDuplicateProperty() ) );
109  connect(tool_->remove_property_tb, SIGNAL( clicked() ), this, SLOT( slotRemoveProperty() ) );
110 
111  connect(tool_, SIGNAL( widgetShown() ), this, SLOT( updateGUI() ) );
112 
113  setNewPropertyModel(-1);
114  }
115 }
116 
117 //-----------------------------------------------------------------------------
118 
119 void PropertyVisPlugin::slotVisualizeProperty( int _id, const QString& _propname )
120 {
121  PropertyModel* model = PropertyModelFactory::Instance().getModel(_id);
122 
123  if (model != 0)
124  {
125  model->gatherProperties();
126  QModelIndex idx = model->indexFromPlainPropName(_propname);
127 
128  if (idx.isValid())
129  {
130  QModelIndexList list;
131  list.append(idx);
132 
133  model->visualize(list);
134 
135 
136  emit updateView();
137  emit updatedObject( _id, UPDATE_COLOR );
138  }
139  }
140 }
141 
142 void PropertyVisPlugin::slotClear(int _id, const QString &_propname)
143 {
144  PropertyModel* model = PropertyModelFactory::Instance().getModel(_id);
145 
146  if (model != 0)
147  {
148  model->gatherProperties();
149  QModelIndex idx = model->indexFromPlainPropName(_propname);
150 
151  if (idx.isValid())
152  {
153  QModelIndexList list;
154  list.append(idx);
155 
156  model->clear(list);
157 
158  emit updateView();
159  emit updatedObject( _id, UPDATE_COLOR );
160  }
161  }
162 }
163 
164 QScriptValue PropertyVisPlugin::getPropertyVisualizer(int _id, const QString &_propname)
165 {
166  PropertyModel* model = PropertyModelFactory::Instance().getModel(_id);
167 
168  if (model == nullptr) { return QScriptValue::SpecialValue::NullValue; }
169 
170  model->gatherProperties();
171  QModelIndex idx = model->indexFromPlainPropName(_propname);
172  if (!idx.isValid()) { return QScriptValue::SpecialValue::NullValue; }
173 
174  QScriptEngine *engine;
175  emit getScriptingEngine (engine);
176  if (engine == nullptr) { return QScriptValue::SpecialValue::NullValue; }
177 
178  QScriptContext *ctx = engine->currentContext();
179  if (ctx == nullptr) { return QScriptValue::SpecialValue::NullValue; }
180 
181  auto sopm = dynamic_cast<SingleObjectPropertyModel*>(model);
182  if (!sopm) { return QScriptValue::SpecialValue::NullValue; }
183 
184  return sopm->getScriptObject(idx, ctx);
185 }
186 
187 //-----------------------------------------------------------------------------
188 
189 void PropertyVisPlugin::slotPickModeChanged( const std::string& _mode)
190 {
191  if (propertyModel_ != 0)
192  propertyModel_->pickModeChanged(_mode);
193 }
194 
195 //-----------------------------------------------------------------------------
196 
197 void PropertyVisPlugin::slotAllCleared()
198 {
199  using namespace PluginFunctions;
200 
201  if (propertyModel_ != 0)
202  {
203  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
204  propertyModel_->clear(selectedIndices);
205  propertyModel_->objectUpdated();
206  emit updateView();
207  }
208 }
209 
210 //-----------------------------------------------------------------------------
211 
212 void PropertyVisPlugin::objectDeleted(int _id)
213 {
214  if( OpenFlipper::Options::gui() )
215  objectListItemModel_.removeObject(_id);
216  PropertyModelFactory::Instance().deleteModel(_id);
217 }
218 
219 //-----------------------------------------------------------------------------
220 
221 void PropertyVisPlugin::slotObjectUpdated( int _identifier, const UpdateType& _type )
222 {
223  if( OpenFlipper::Options::gui() )
224  {
225  if ( tool_->isVisible() )
226  updateGUI();
227  PropertyModel* propertyModel = PropertyModelFactory::Instance().getModel(_identifier);
228  if (propertyModel)
229  {
230  if (_type == UPDATE_ALL)
231  propertyModel->gatherProperties();
232  if (_type == (UPDATE_ALL | UPDATE_GEOMETRY))
233  propertyModel->objectUpdated();
234  }
235  }
236 }
237 
238 void PropertyVisPlugin::slotObjectPropertiesChanged(int _identifier)
239 {
240  // We get this signal when properties are renamed
241  if( OpenFlipper::Options::gui() && tool_->isVisible() )
242  {
243  updateGUI();
244  }
245 }
246 
247 void PropertyVisPlugin::updateGUI()
248 {
250 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
251  datatype |= DataType(DATA_POLYHEDRAL_MESH);
252 #endif
253 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
254  datatype |= DataType(DATA_HEXAHEDRAL_MESH);
255 #endif
256 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
257  datatype |= DataType(DATA_TETRAHEDRAL_MESH);
258 #endif
259  objectListItemModel_.refresh(datatype);
260 }
261 
262 //-----------------------------------------------------------------------------
263 
265 {
266  if (propertyModel_ != 0)
267  {
268  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
269  propertyModel_->updateWidget(selectedIndices);
270  }
271 }
272 
273 //-----------------------------------------------------------------------------
274 
275 
285 {
286  if (propertyModel_)
287  {
288  propertyModel_->hideWidget();
289  disconnect(propertyModel_, SIGNAL(log(Logtype,QString)), this, SLOT(slotLog(Logtype,QString)));
290  disconnect(propertyModel_, SIGNAL(log(QString)), this, SLOT(slotLog(QString)));
291  }
292  propertyModel_ = PropertyModelFactory::Instance().getModel(id);
293  if (propertyModel_ != 0)
294  {
295 
296  tool_->propertyName_lv->setModel(propertyModel_);
297  connect(propertyModel_, SIGNAL( modelReset() ), this, SLOT( propertySelectionChanged() ));
298  connect(tool_->propertyName_lv->selectionModel(),
299  SIGNAL( selectionChanged(const QItemSelection &, const QItemSelection &) ),
300  this,
301  SLOT( propertySelectionChanged() ));
302  QWidget* widget = propertyModel_->getWidget();
303  tool_->propertyWidgets->addWidget(widget);
304  widget->show();
305  propertyModel_->gatherProperties();
306  connect(propertyModel_, SIGNAL(log(Logtype,QString)), this, SLOT(slotLog(Logtype,QString)));
307  connect(propertyModel_, SIGNAL(log(QString)), this, SLOT(slotLog(QString)));
308  }
309  else
310  {
311  tool_->propertyName_lv->setModel(0);
312  }
313 }
314 
315 //-----------------------------------------------------------------------------
316 
317 void PropertyVisPlugin::slotMeshChanged(int /*_index*/)
318 {
319  int id = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
320  setNewPropertyModel(id);
321 }
322 
323 //-----------------------------------------------------------------------------
324 
325 void PropertyVisPlugin::slotVisualize()
326 {
327  using namespace PluginFunctions;
328 
329  // return if nothing is selected
330  if (propertyModel_ == 0) return;
331 
332  int selectedId = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
333  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
334 
335  // visualize property
336  propertyModel_->visualize(selectedIndices);
337 
338  // emit updates
339  emit updateView();
340 
341  if (selectedId >= 0)
342  {
343  emit updatedObject( selectedId, UPDATE_COLOR );
344  }
345  else
346  {
347  ObjectIterator o_it(ALL_OBJECTS, supportedDataTypes());
348  while (o_it != objectsEnd())
349  {
350  emit updatedObject( o_it->id(), UPDATE_COLOR );
351  ++o_it;
352  }
353  }
354 }
355 
356 //-----------------------------------------------------------------------------
357 
358 void PropertyVisPlugin::slotMouseEvent( QMouseEvent* _event ) {
359  if (propertyModel_ != 0)
360  propertyModel_->mouseEvent(_event);
361 }
362 
363 //-----------------------------------------------------------------------------
364 
366 {
367  using namespace PluginFunctions;
368 
369  if (propertyModel_ != 0)
370  {
371  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
372  propertyModel_->duplicateProperty(selectedIndices);
373 
374  emit updateView();
375  int id = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
376  slotMeshChanged();
377 
378  if (id >= 0)
379  {
380  emit updatedObject( id, UPDATE_ALL );
381  }
382  else
383  {
384  ObjectIterator o_it(ALL_OBJECTS, supportedDataTypes());
385  while (o_it != objectsEnd())
386  {
387  emit updatedObject( o_it->id(), UPDATE_ALL );
388  ++o_it;
389  }
390  }
391  }
392 }
393 
395 {
396  using namespace PluginFunctions;
397 
398  if (propertyModel_ != 0)
399  {
400  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
401  propertyModel_->removeProperty(selectedIndices);
402 
403  emit updateView();
404  int id = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
405 
406  if (id >= 0)
407  {
408  emit updatedObject( id, UPDATE_ALL );
409  }
410  else
411  {
412  ObjectIterator o_it(ALL_OBJECTS, supportedDataTypes());
413  while (o_it != objectsEnd())
414  {
415  emit updatedObject( o_it->id(), UPDATE_ALL );
416  ++o_it;
417  }
418  }
419  }
420 }
421 
422 
void slotClear(int _id, const QString &_propname)
This class manages the visualizers for a single object.
#define DATA_POLYHEDRAL_MESH
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void propertySelectionChanged()
Called when user selects a property.
#define DATA_TETRAHEDRAL_MESH
#define DATA_HEXAHEDRAL_MESH
Logtype
Log types for Message Window.
const QStringList ALL_OBJECTS
Iterable object range.
void slotVisualizeProperty(int _id, const QString &_propname)
Predefined datatypes.
Definition: DataTypes.hh:83
int id() const
Definition: BaseObject.cc:190
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
virtual void clear(QModelIndexList selectedIndices)=0
Clears the selected property visualization.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
virtual void visualize(QModelIndexList selectedIndices, QWidgetList widgets=QWidgetList())=0
Visualizes the selected properties.
virtual void objectUpdated()=0
Revisualizes visualized properties.
QModelIndex indexFromPlainPropName(const QString &propName) const
Returns the index of the property with the given name.
void setNewPropertyModel(int id)
Exchanges the PropertyModel after the user selected a different object.
Update type class.
Definition: UpdateType.hh:59
void slotRemoveProperty()
Removes the selected properties.
virtual QScriptValue getScriptObject(const QModelIndex index, QScriptContext *ctx)
Returns a qscript object that can be used to access visualisation parameters.
void slotDuplicateProperty()
Duplicates the selected properties.
const UpdateType UPDATE_COLOR(UpdateTypeSet(1024))
Colors have changed.
static T & Instance()
Definition: SingletonT.hh:86
virtual void gatherProperties()=0
Searches for properties and creates PropertyVisualizers.