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 QScriptValue PropertyVisPlugin::getPropertyVisualizer(int _id, const QString &_propname)
143 {
144  PropertyModel* model = PropertyModelFactory::Instance().getModel(_id);
145 
146  if (model == nullptr) { return QScriptValue::SpecialValue::NullValue; }
147 
148  model->gatherProperties();
149  QModelIndex idx = model->indexFromPlainPropName(_propname);
150  if (!idx.isValid()) { return QScriptValue::SpecialValue::NullValue; }
151 
152  QScriptEngine *engine;
153  emit getScriptingEngine (engine);
154  if (engine == nullptr) { return QScriptValue::SpecialValue::NullValue; }
155 
156  QScriptContext *ctx = engine->currentContext();
157  if (ctx == nullptr) { return QScriptValue::SpecialValue::NullValue; }
158 
159  auto sopm = dynamic_cast<SingleObjectPropertyModel*>(model);
160  if (!sopm) { return QScriptValue::SpecialValue::NullValue; }
161 
162  return sopm->getScriptObject(idx, ctx);
163 }
164 
165 //-----------------------------------------------------------------------------
166 
167 void PropertyVisPlugin::slotPickModeChanged( const std::string& _mode)
168 {
169  if (propertyModel_ != 0)
170  propertyModel_->pickModeChanged(_mode);
171 }
172 
173 //-----------------------------------------------------------------------------
174 
175 void PropertyVisPlugin::slotAllCleared()
176 {
177  using namespace PluginFunctions;
178 
179  if (propertyModel_ != 0)
180  {
181  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
182  propertyModel_->clear(selectedIndices);
183  propertyModel_->objectUpdated();
184  emit updateView();
185  }
186 }
187 
188 //-----------------------------------------------------------------------------
189 
190 void PropertyVisPlugin::objectDeleted(int _id)
191 {
192  if( OpenFlipper::Options::gui() )
193  objectListItemModel_.removeObject(_id);
194  PropertyModelFactory::Instance().deleteModel(_id);
195 }
196 
197 //-----------------------------------------------------------------------------
198 
199 void PropertyVisPlugin::slotObjectUpdated( int _identifier, const UpdateType& _type )
200 {
201  if( OpenFlipper::Options::gui() )
202  {
203  if ( tool_->isVisible() )
204  updateGUI();
205  PropertyModel* propertyModel = PropertyModelFactory::Instance().getModel(_identifier);
206  if (propertyModel)
207  {
208  if (_type == UPDATE_ALL)
209  propertyModel->gatherProperties();
210  if (_type == (UPDATE_ALL | UPDATE_GEOMETRY))
211  propertyModel->objectUpdated();
212  }
213  }
214 }
215 
216 void PropertyVisPlugin::slotObjectPropertiesChanged(int _identifier)
217 {
218  // We get this signal when properties are renamed
219  if( OpenFlipper::Options::gui() && tool_->isVisible() )
220  {
221  updateGUI();
222  }
223 }
224 
225 void PropertyVisPlugin::updateGUI()
226 {
228 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
229  datatype |= DataType(DATA_POLYHEDRAL_MESH);
230 #endif
231 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
232  datatype |= DataType(DATA_HEXAHEDRAL_MESH);
233 #endif
234 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT
235  datatype |= DataType(DATA_TETRAHEDRAL_MESH);
236 #endif
237  objectListItemModel_.refresh(datatype);
238 }
239 
240 //-----------------------------------------------------------------------------
241 
243 {
244  if (propertyModel_ != 0)
245  {
246  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
247  propertyModel_->updateWidget(selectedIndices);
248  }
249 }
250 
251 //-----------------------------------------------------------------------------
252 
253 
263 {
264  if (propertyModel_)
265  {
266  propertyModel_->hideWidget();
267  disconnect(propertyModel_, SIGNAL(log(Logtype,QString)), this, SLOT(slotLog(Logtype,QString)));
268  disconnect(propertyModel_, SIGNAL(log(QString)), this, SLOT(slotLog(QString)));
269  }
270  propertyModel_ = PropertyModelFactory::Instance().getModel(id);
271  if (propertyModel_ != 0)
272  {
273 
274  tool_->propertyName_lv->setModel(propertyModel_);
275  connect(propertyModel_, SIGNAL( modelReset() ), this, SLOT( propertySelectionChanged() ));
276  connect(tool_->propertyName_lv->selectionModel(),
277  SIGNAL( selectionChanged(const QItemSelection &, const QItemSelection &) ),
278  this,
279  SLOT( propertySelectionChanged() ));
280  QWidget* widget = propertyModel_->getWidget();
281  tool_->propertyWidgets->addWidget(widget);
282  widget->show();
283  propertyModel_->gatherProperties();
284  connect(propertyModel_, SIGNAL(log(Logtype,QString)), this, SLOT(slotLog(Logtype,QString)));
285  connect(propertyModel_, SIGNAL(log(QString)), this, SLOT(slotLog(QString)));
286  }
287  else
288  {
289  tool_->propertyName_lv->setModel(0);
290  }
291 }
292 
293 //-----------------------------------------------------------------------------
294 
295 void PropertyVisPlugin::slotMeshChanged(int /*_index*/)
296 {
297  int id = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
298  setNewPropertyModel(id);
299 }
300 
301 //-----------------------------------------------------------------------------
302 
303 void PropertyVisPlugin::slotVisualize()
304 {
305  using namespace PluginFunctions;
306 
307  // return if nothing is selected
308  if (propertyModel_ == 0) return;
309 
310  int selectedId = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
311  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
312 
313  // visualize property
314  propertyModel_->visualize(selectedIndices);
315 
316  // emit updates
317  emit updateView();
318 
319  if (selectedId >= 0)
320  {
321  emit updatedObject( selectedId, UPDATE_COLOR );
322  }
323  else
324  {
325  ObjectIterator o_it(ALL_OBJECTS, supportedDataTypes());
326  while (o_it != objectsEnd())
327  {
328  emit updatedObject( o_it->id(), UPDATE_COLOR );
329  ++o_it;
330  }
331  }
332 }
333 
334 //-----------------------------------------------------------------------------
335 
336 void PropertyVisPlugin::slotMouseEvent( QMouseEvent* _event ) {
337  if (propertyModel_ != 0)
338  propertyModel_->mouseEvent(_event);
339 }
340 
341 //-----------------------------------------------------------------------------
342 
344 {
345  using namespace PluginFunctions;
346 
347  if (propertyModel_ != 0)
348  {
349  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
350  propertyModel_->duplicateProperty(selectedIndices);
351 
352  emit updateView();
353  int id = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
354  slotMeshChanged();
355 
356  if (id >= 0)
357  {
358  emit updatedObject( id, UPDATE_ALL );
359  }
360  else
361  {
362  ObjectIterator o_it(ALL_OBJECTS, supportedDataTypes());
363  while (o_it != objectsEnd())
364  {
365  emit updatedObject( o_it->id(), UPDATE_ALL );
366  ++o_it;
367  }
368  }
369  }
370 }
371 
373 {
374  using namespace PluginFunctions;
375 
376  if (propertyModel_ != 0)
377  {
378  QModelIndexList selectedIndices = tool_->propertyName_lv->selectionModel()->selectedIndexes();
379  propertyModel_->removeProperty(selectedIndices);
380 
381  emit updateView();
382  int id = tool_->meshNames->itemData( tool_->meshNames->currentIndex() ).toInt();
383 
384  if (id >= 0)
385  {
386  emit updatedObject( id, UPDATE_ALL );
387  }
388  else
389  {
390  ObjectIterator o_it(ALL_OBJECTS, supportedDataTypes());
391  while (o_it != objectsEnd())
392  {
393  emit updatedObject( o_it->id(), UPDATE_ALL );
394  ++o_it;
395  }
396  }
397  }
398 }
399 
400 
Update type class.
Definition: UpdateType.hh:60
void setNewPropertyModel(int id)
Exchanges the PropertyModel after the user selected a different object.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
Logtype
Log types for Message Window.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
void slotDuplicateProperty()
Duplicates the selected properties.
int id() const
Definition: BaseObject.cc:190
void slotRemoveProperty()
Removes the selected properties.
This class manages the visualizers for a single object.
const QStringList ALL_OBJECTS
Iterable object range.
virtual void visualize(QModelIndexList selectedIndices, QWidgetList widgets=QWidgetList())=0
Visualizes the selected properties.
#define DATA_TETRAHEDRAL_MESH
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
void propertySelectionChanged()
Called when user selects a property.
static T & Instance()
Definition: SingletonT.hh:89
QModelIndex indexFromPlainPropName(const QString &propName) const
Returns the index of the property with the given name.
#define DATA_HEXAHEDRAL_MESH
Predefined datatypes.
Definition: DataTypes.hh:83
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
#define DATA_POLYHEDRAL_MESH
virtual QScriptValue getScriptObject(const QModelIndex index, QScriptContext *ctx)
Returns a qscript object that can be used to access visualisation parameters.
virtual void objectUpdated()=0
Revisualizes visualized properties.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
const UpdateType UPDATE_COLOR(UpdateTypeSet(1)<< 10)
Colors have changed.
virtual void gatherProperties()=0
Searches for properties and creates PropertyVisualizers.