fw4spl
RepresentationEditor.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "uiReconstructionQt/RepresentationEditor.hpp"
8 
9 #include <fwCom/Signal.hxx>
10 
11 #include <fwData/Material.hpp>
12 #include <fwData/Mesh.hpp>
13 #include <fwData/Reconstruction.hpp>
14 
15 #include <fwGuiQt/container/QtContainer.hpp>
16 
17 #include <fwRuntime/operations.hpp>
18 
19 #include <fwServices/macros.hpp>
20 #include <fwServices/op/Get.hpp>
21 
22 #include <QAbstractButton>
23 #include <QButtonGroup>
24 #include <QGroupBox>
25 #include <QRadioButton>
26 #include <QVBoxLayout>
27 
28 namespace uiReconstructionQt
29 {
30 
33 
34 //------------------------------------------------------------------------------
35 
36 static const ::fwServices::IService::KeyType s_RECONSTRUCTION_INOUT = "reconstruction";
37 
38 //------------------------------------------------------------------------------
39 
41 {
42 }
43 
44 //------------------------------------------------------------------------------
45 
47 {
48 }
49 
50 //------------------------------------------------------------------------------
51 
53 {
55  this->create();
56  ::fwGuiQt::container::QtContainer::sptr qtContainer = ::fwGuiQt::container::QtContainer::dynamicCast(
57  this->getContainer() );
58 
59  QVBoxLayout* layout = new QVBoxLayout();
60 
61  QGroupBox* groupBox = new QGroupBox(tr("Representation"));
62  QVBoxLayout* layoutGroupBox = new QVBoxLayout();
63  groupBox->setLayout(layoutGroupBox);
64 
65  m_buttonGroup = new QButtonGroup(groupBox);
66 
67  QRadioButton* buttonSurface = new QRadioButton( tr("Surface"), groupBox );
68  buttonSurface->setMinimumSize(buttonSurface->sizeHint());
69  m_buttonGroup->addButton(buttonSurface, 0);
70  layoutGroupBox->addWidget(buttonSurface);
71  buttonSurface->setChecked(true);
72 
73  QRadioButton* buttonPoint = new QRadioButton( tr("Point"), groupBox );
74  buttonPoint->setMinimumSize(buttonPoint->sizeHint());
75  m_buttonGroup->addButton(buttonPoint, 1);
76  layoutGroupBox->addWidget(buttonPoint);
77 
78  QRadioButton* buttonWireframe = new QRadioButton( tr("Wireframe"), groupBox );
79  buttonWireframe->setMinimumSize(buttonWireframe->sizeHint());
80  m_buttonGroup->addButton(buttonWireframe, 2);
81  layoutGroupBox->addWidget(buttonWireframe);
82 
83  QRadioButton* buttonEdge = new QRadioButton( tr("Edge"), groupBox );
84  buttonEdge->setMinimumSize(buttonEdge->sizeHint());
85  m_buttonGroup->addButton(buttonEdge, 3);
86  layoutGroupBox->addWidget(buttonEdge);
87 
88  // Shading group box
89  QGroupBox* groupBoxShading = new QGroupBox(tr("Shading"));
90  QVBoxLayout* layoutGroupBoxShading = new QVBoxLayout();
91  groupBoxShading->setLayout(layoutGroupBoxShading);
92  m_buttonGroupShading = new QButtonGroup(groupBoxShading);
93 
94  QRadioButton* buttonAmbient = new QRadioButton( tr("Ambient"), groupBoxShading );
95  buttonAmbient->setMinimumSize(buttonAmbient->sizeHint());
96  m_buttonGroupShading->addButton(buttonAmbient, 0);
97  layoutGroupBoxShading->addWidget(buttonAmbient);
98  buttonAmbient->setChecked(true);
99 
100  QRadioButton* buttonFlat = new QRadioButton( tr("Flat"), groupBoxShading );
101  buttonFlat->setMinimumSize(buttonFlat->sizeHint());
102  m_buttonGroupShading->addButton(buttonFlat, 1);
103  layoutGroupBoxShading->addWidget(buttonFlat);
104  buttonFlat->setChecked(true);
105 
106  QRadioButton* buttonGouraud = new QRadioButton( tr("Gouraud"), groupBoxShading );
107  buttonGouraud->setMinimumSize(buttonGouraud->sizeHint());
108  m_buttonGroupShading->addButton(buttonGouraud, 2);
109  layoutGroupBoxShading->addWidget(buttonGouraud);
110 
111  QRadioButton* buttonPhong = new QRadioButton( tr("Phong"), groupBoxShading );
112  buttonPhong->setMinimumSize(buttonPhong->sizeHint());
113  m_buttonGroupShading->addButton(buttonPhong, 3);
114  layoutGroupBoxShading->addWidget(buttonPhong);
115 
116  layout->addWidget( groupBox);
117  layout->addWidget( groupBoxShading);
118 
119  QGroupBox* groupBoxNormals = new QGroupBox(tr("Normals"));
120  QVBoxLayout* layoutGroupBoxNormals = new QVBoxLayout(groupBoxNormals);
121  m_normalsRadioBox = new QButtonGroup();
122  QRadioButton* pointNormalsButton = new QRadioButton(tr("Show point normals"));
123  QRadioButton* cellNormalsButton = new QRadioButton(tr("Show cell normals"));
124  QRadioButton* hideNormalsButton = new QRadioButton(tr("Hide normals"));
125 
126  m_normalsRadioBox->addButton(pointNormalsButton, 1);
127  m_normalsRadioBox->addButton(cellNormalsButton, 2);
128  m_normalsRadioBox->addButton(hideNormalsButton, 0);
129 
130  layoutGroupBoxNormals->addWidget( pointNormalsButton);
131  layoutGroupBoxNormals->addWidget( cellNormalsButton);
132  layoutGroupBoxNormals->addWidget( hideNormalsButton);
133 
134  layout->addWidget(groupBoxNormals);
135 
136  QObject::connect(m_normalsRadioBox, SIGNAL(buttonClicked(int)), this, SLOT(onShowNormals(int)));
137 
138  qtContainer->setLayout( layout );
139  qtContainer->setEnabled(false);
140 
141  QObject::connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onChangeRepresentation(int)));
142  QObject::connect(m_buttonGroupShading, SIGNAL(buttonClicked(int)), this, SLOT(onChangeShading(int)));
143 
144  this->updating();
145 }
146 
147 //------------------------------------------------------------------------------
148 
150 {
151  SLM_TRACE_FUNC();
152 
153  QObject::disconnect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onChangeRepresentation(int)));
154  QObject::disconnect(m_buttonGroupShading, SIGNAL(buttonClicked(int)), this, SLOT(onChangeShading(int)));
155 
156  QObject::connect(m_normalsRadioBox, SIGNAL(buttonClicked(int)), this, SLOT(onShowNormals(int)));
157 
158  this->destroy();
159 }
160 
161 //------------------------------------------------------------------------------
162 
164 {
165  SLM_TRACE_FUNC();
166  this->initialize();
167 }
168 
169 //------------------------------------------------------------------------------
170 
172 {
173  ::fwData::Reconstruction::sptr reconstruction = this->getInOut< ::fwData::Reconstruction >(s_RECONSTRUCTION_INOUT);
174  if (!reconstruction)
175  {
176  FW_DEPRECATED_KEY(s_RECONSTRUCTION_INOUT, "inout", "18.0");
177  reconstruction = this->getObject< ::fwData::Reconstruction >();
178  }
179  SLM_ASSERT("No Reconstruction!", reconstruction);
180  ::fwGuiQt::container::QtContainer::sptr qtContainer = ::fwGuiQt::container::QtContainer::dynamicCast(
181  this->getContainer() );
182  QWidget* const container = qtContainer->getQtContainer();
183  SLM_ASSERT("container not instanced", container);
184 
185  m_material = reconstruction->getMaterial();
186  container->setEnabled(!reconstruction->getOrganName().empty());
187 
188  this->refreshRepresentation();
189  this->refreshNormals();
190  this->refreshShading();
191 }
192 
193 //------------------------------------------------------------------------------
194 
195 void RepresentationEditor::onChangeRepresentation( int id )
196 {
197 
198  ::fwData::Material::RepresentationType selectedMode = ::fwData::Material::SURFACE;
199 
200  switch(id)
201  {
202  case 0:
203  {
204  selectedMode = ::fwData::Material::SURFACE;
205  break;
206  }
207  case 1:
208  {
209  selectedMode = ::fwData::Material::POINT;
210  break;
211  }
212  case 2:
213  {
214  selectedMode = ::fwData::Material::WIREFRAME;
215  break;
216  }
217  case 3:
218  {
219  selectedMode = ::fwData::Material::EDGE;
220  break;
221  }
222  }
223 
224  m_material->setRepresentationMode( selectedMode );
225  this->notifyMaterial();
226 }
227 
228 //------------------------------------------------------------------------------
229 
230 void RepresentationEditor::onChangeShading( int id )
231 {
232  ::fwData::Material::ShadingType selectedMode = ::fwData::Material::PHONG;
233 
234  switch(id)
235  {
236  case 0:
237  {
238  selectedMode = ::fwData::Material::AMBIENT;
239  break;
240  }
241  case 1:
242  {
243  selectedMode = ::fwData::Material::FLAT;
244  break;
245  }
246  case 2:
247  {
248  selectedMode = ::fwData::Material::GOURAUD;
249  break;
250  }
251  case 3:
252  {
253  selectedMode = ::fwData::Material::PHONG;
254  break;
255  }
256  }
257 
258  m_material->setShadingMode( selectedMode );
259  this->notifyMaterial();
260 }
261 
262 //------------------------------------------------------------------------------
263 
264 void RepresentationEditor::refreshRepresentation()
265 {
266  int representationMode = m_material->getRepresentationMode();
267  QAbstractButton* button;
268 
269  switch(representationMode)
270  {
271  case ::fwData::Material::SURFACE:
272  {
273  button = m_buttonGroup->button(0);
274  button->setChecked(true);
275  break;
276  }
277  case ::fwData::Material::POINT:
278  {
279  button = m_buttonGroup->button(1);
280  button->setChecked(true);
281  break;
282  }
283  case ::fwData::Material::WIREFRAME:
284  {
285  button = m_buttonGroup->button(2);
286  button->setChecked(true);
287  break;
288  }
289  case ::fwData::Material::EDGE:
290  {
291  button = m_buttonGroup->button(3);
292  button->setChecked(true);
293  break;
294  }
295  default:
296  button = m_buttonGroup->button(0);
297  button->setChecked(true);
298  }
299 }
300 
301 //------------------------------------------------------------------------------
302 
303 void RepresentationEditor::refreshShading()
304 {
305  int shadingMode = m_material->getShadingMode();
306  QAbstractButton* button;
307 
308  switch(shadingMode)
309  {
310  case ::fwData::Material::AMBIENT:
311  {
312  button = m_buttonGroupShading->button(0);
313  button->setChecked(true);
314  break;
315  }
316  case ::fwData::Material::FLAT:
317  {
318  button = m_buttonGroupShading->button(1);
319  button->setChecked(true);
320  break;
321  }
322  case ::fwData::Material::GOURAUD:
323  {
324  button = m_buttonGroupShading->button(2);
325  button->setChecked(true);
326  break;
327  }
328  case ::fwData::Material::PHONG:
329  {
330  button = m_buttonGroupShading->button(3);
331  button->setChecked(true);
332  break;
333  }
334  default:
335  button = m_buttonGroupShading->button(2);
336  button->setChecked(true);
337  }
338 }
339 
340 //------------------------------------------------------------------------------
341 
342 void RepresentationEditor::refreshNormals()
343 {
344  QAbstractButton* buttonHide = m_normalsRadioBox->button(0);
345  buttonHide->setChecked(m_material->getOptionsMode() == ::fwData::Material::STANDARD);
346  QAbstractButton* buttonNormals = m_normalsRadioBox->button(1);
347  buttonNormals->setChecked(m_material->getOptionsMode() == ::fwData::Material::NORMALS);
348 }
349 
350 //------------------------------------------------------------------------------
351 
352 void RepresentationEditor::onShowNormals(int state )
353 {
354  ::fwData::Reconstruction::sptr reconstruction = this->getInOut< ::fwData::Reconstruction >(s_RECONSTRUCTION_INOUT);
355  if (!reconstruction)
356  {
357  FW_DEPRECATED_KEY(s_RECONSTRUCTION_INOUT, "inout", "18.0");
358  reconstruction = this->getObject< ::fwData::Reconstruction >();
359  }
360  SLM_ASSERT("No Reconstruction!", reconstruction);
361 
362  switch(state)
363  {
364  case 0:
365  m_material->setOptionsMode( ::fwData::Material::STANDARD );
366  break;
367  case 1:
368  m_material->setOptionsMode( ::fwData::Material::NORMALS );
369  break;
370  case 2:
371  m_material->setOptionsMode( ::fwData::Material::CELLS_NORMALS );
372  break;
373  }
374 
375  this->notifyMaterial();
376 
377  // In VTK backend the normals is handled by the mesh and not by the material
378  auto sig = reconstruction->signal< ::fwData::Reconstruction::MeshChangedSignalType >(
380  sig->asyncEmit(reconstruction->getMesh());
381 }
382 
383 //------------------------------------------------------------------------------
384 
386 {
387  ::fwData::Reconstruction::sptr reconstruction = this->getInOut< ::fwData::Reconstruction >(s_RECONSTRUCTION_INOUT);
388  if (!reconstruction)
389  {
390  FW_DEPRECATED_KEY(s_RECONSTRUCTION_INOUT, "inout", "18.0");
391  reconstruction = this->getObject< ::fwData::Reconstruction >();
392  }
393  SLM_ASSERT("No Reconstruction!", reconstruction);
394 
395  ::fwData::Object::ModifiedSignalType::sptr sig;
396  sig = reconstruction->getMaterial()->signal< ::fwData::Object::ModifiedSignalType >(
398  sig->asyncEmit();
399 }
400 
401 //------------------------------------------------------------------------------
402 
404 {
405  KeyConnectionsMap connections;
406 
407  //FIXME hack to support deprecated getObject()
408  if (this->getInOut< ::fwData::Reconstruction >(s_RECONSTRUCTION_INOUT))
409  {
410  connections.push(s_RECONSTRUCTION_INOUT, ::fwData::Object::s_MODIFIED_SIG, s_UPDATE_SLOT);
411  }
412 
413  return connections;
414 }
415 
416 //------------------------------------------------------------------------------
417 
418 }
virtual void updating() override
Update the UI according to the reconstruction.
#define FW_DEPRECATED_KEY(newKey, access, version)
Use this macro when deprecating a service key to warn the developer.
Definition: spyLog.hpp:366
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
The namespace uiReconstructionQt contains several editors using Qt related on reconstruction.
This class defines a reconstruction object.
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
Defines the service interface managing the editor service for object.
Definition: IEditor.hpp:25
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
UIRECONSTRUCTIONQT_API RepresentationEditor() noexcept
Constructor. Do nothing.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MESH_CHANGED_SIG
Key in m_signals map of signal m_sigMeshModified.
virtual void configuring() override
Do nothing.
virtual void stopping() override
Clean the UI.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
Display a widget to change the reconstruction representation (surface, point, edge, ...).
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
virtual void starting() override
Initialize the UI.
virtual KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
RepresentationType
Representation models.
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
Definition: IService.hpp:177
virtual UIRECONSTRUCTIONQT_API ~RepresentationEditor() noexcept
Destructor. Do nothing.
FWGUI_API void initialize()
Initialize managers.