fw4spl
SOrganTransformation.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 "uiMedDataQt/editor/SOrganTransformation.hpp"
8 
9 #include <fwData/Composite.hpp>
10 #include <fwData/Material.hpp>
11 #include <fwData/Mesh.hpp>
12 #include <fwData/Reconstruction.hpp>
13 
14 #include <fwDataTools/helper/Composite.hpp>
15 #include <fwDataTools/helper/Field.hpp>
16 #include <fwDataTools/TransformationMatrix3D.hpp>
17 
18 #include <fwGuiQt/container/QtContainer.hpp>
19 
20 #include <fwMedData/ModelSeries.hpp>
21 
22 #include <fwServices/macros.hpp>
23 
24 #include <fwTools/fwID.hpp>
25 
26 #include <QCheckBox>
27 #include <QComboBox>
28 #include <QGroupBox>
29 #include <QListWidget>
30 #include <QListWidgetItem>
31 #include <QPushButton>
32 #include <QString>
33 #include <QStringList>
34 #include <QVBoxLayout>
35 
36 #include <map>
37 
38 namespace uiMedDataQt
39 {
40 namespace editor
41 {
42 
44 
45 static const ::fwServices::IService::KeyType s_MODEL_SERIES_INOUT = "modelSeries";
46 static const ::fwServices::IService::KeyType s_COMPOSITE_INOUT = "composite";
47 
48 static const std::string s_MATRIX_FIELD_NAME = "TransformMatrix";
49 
51  m_saveButton( 0 ),
52  m_loadButton( 0 ),
53  m_resetButton( 0 ),
54  m_reconstructionListBox( 0 ),
55  m_saveCount( 0 )
56 {
57 }
58 
59 //------------------------------------------------------------------------------
60 
62 {
63 }
64 
65 //------------------------------------------------------------------------------
66 
68 {
69  this->initialize();
70 }
71 
72 //------------------------------------------------------------------------------
73 
75 {
76  this->create();
77  ::fwGuiQt::container::QtContainer::sptr qtContainer =
78  ::fwGuiQt::container::QtContainer::dynamicCast( this->getContainer() );
79 
80  QVBoxLayout* layout = new QVBoxLayout();
81 
82  QGroupBox* groupBox = new QGroupBox(tr("Organs") );
83  layout->addWidget( groupBox);
84 
85  QVBoxLayout* layoutGroupBox = new QVBoxLayout();
86  groupBox->setLayout(layoutGroupBox);
87 
88  m_selectAllCheckBox = new QCheckBox(tr("Select All") );
89  m_reconstructionListBox = new QListWidget( groupBox);
90  m_resetButton = new QPushButton(tr("Reset") );
91  m_saveButton = new QPushButton(tr("Save") );
92  m_loadButton = new QPushButton(tr("Load") );
93  m_saveSelectionComboBox = new QComboBox();
94 
95  QObject::connect(m_reconstructionListBox,
96  SIGNAL(itemClicked(QListWidgetItem*)),
97  this,
98  SLOT(onReconstructionCheck(QListWidgetItem*)));
99  QObject::connect(m_resetButton, SIGNAL(clicked()), this, SLOT(onResetClick()));
100  QObject::connect(m_saveButton, SIGNAL(clicked()), this, SLOT(onSaveClick()));
101  QObject::connect(m_loadButton, SIGNAL(clicked()), this, SLOT(onLoadClick()));
102  QObject::connect(m_selectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAllChanged(int)));
103 
104  layoutGroupBox->addWidget( m_selectAllCheckBox, 0);
105  layoutGroupBox->addWidget( m_reconstructionListBox, 1);
106  layoutGroupBox->addWidget( m_resetButton, 0);
107  layoutGroupBox->addWidget( m_saveButton, 0);
108  layoutGroupBox->addWidget( m_saveSelectionComboBox, 0);
109  layoutGroupBox->addWidget( m_loadButton, 0);
110 
111  qtContainer->setLayout( layout );
112 
113  this->updating();
114 }
115 
116 //------------------------------------------------------------------------------
117 
119 {
120  QObject::disconnect(m_reconstructionListBox,
121  SIGNAL(itemClicked(QListWidgetItem*)),
122  this,
123  SLOT(onReconstructionCheck(QListWidgetItem*)));
124  QObject::disconnect(m_resetButton, SIGNAL(clicked()), this, SLOT(onResetClick()));
125  QObject::disconnect(m_saveButton, SIGNAL(clicked()), this, SLOT(onSaveClick()));
126  QObject::disconnect(m_loadButton, SIGNAL(clicked()), this, SLOT(onLoadClick()));
127  QObject::disconnect(m_selectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAllChanged(int)));
128 
129  this->destroy();
130 }
131 
132 //------------------------------------------------------------------------------
133 
135 {
136  this->updating();
137 }
138 
139 //------------------------------------------------------------------------------
140 
142 {
143  this->addMeshTransform();
144  this->refresh();
145 }
146 
147 //------------------------------------------------------------------------------
148 
149 void SOrganTransformation::info( ::std::ostream& sstream )
150 {
151 }
152 
153 //------------------------------------------------------------------------------
154 
155 void SOrganTransformation::refresh()
156 {
157  m_reconstructionMap.clear();
158  m_reconstructionListBox->clear();
159 
160  ::fwMedData::ModelSeries::sptr series = this->getInOut< ::fwMedData::ModelSeries >(s_MODEL_SERIES_INOUT);
161 
162  ::fwGuiQt::container::QtContainer::sptr qtContainer =
163  ::fwGuiQt::container::QtContainer::dynamicCast( this->getContainer() );
164  QWidget* const container = qtContainer->getQtContainer();
165  SLM_ASSERT("container not instanced", container);
166 
167  bool hasReconstructions = !series->getReconstructionDB().empty();
168  container->setEnabled( hasReconstructions );
169 
170  if(hasReconstructions)
171  {
172  ::fwData::Composite::sptr pComposite = this->getInOut< ::fwData::Composite>(s_COMPOSITE_INOUT);
173 
174  for(::fwData::Reconstruction::sptr rec : series->getReconstructionDB())
175  {
176  m_reconstructionMap[ rec->getOrganName() ] = rec;
177  }
178 
179  for( ReconstructionMapType::iterator it = m_reconstructionMap.begin(); it != m_reconstructionMap.end(); ++it )
180  {
181  std::string organName = it->first;
182  QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(organName), m_reconstructionListBox);
183  if( pComposite && pComposite->find(organName) != pComposite->end())
184  {
185  item->setCheckState(Qt::Checked);
186  }
187  else
188  {
189  item->setCheckState(Qt::Unchecked);
190  }
191  m_reconstructionListBox->addItem(item);
192  }
193  }
194 }
195 
196 //------------------------------------------------------------------------------
197 
198 void SOrganTransformation::notitfyTransformationMatrix(::fwData::TransformationMatrix3D::sptr aTransMat)
199 {
201  sig->asyncEmit();
202 }
203 
204 //------------------------------------------------------------------------------
205 
206 void SOrganTransformation::onReconstructionCheck(QListWidgetItem* currentItem)
207 {
208  ::fwData::Composite::sptr pComposite = this->getInOut< ::fwData::Composite>(s_COMPOSITE_INOUT);
209  if (pComposite != nullptr)
210  {
211  ::std::string item_name = currentItem->text().toStdString();
212  ::fwData::Reconstruction::sptr pReconstruction = m_reconstructionMap[item_name];
213  ::fwData::Mesh::sptr pMesh = pReconstruction->getMesh();
214 
215  ::fwDataTools::helper::Composite aCompositeHelper(pComposite);
216  if ((currentItem->checkState()) == Qt::Checked)
217  {
218  if (pComposite->find(item_name) == pComposite->end())
219  {
220  aCompositeHelper.add(item_name, pMesh);
221  }
222  else
223  {
224  aCompositeHelper.swap(item_name, pMesh);
225  }
226  }
227  else
228  {
229  if (pComposite->find(item_name) != pComposite->end())
230  {
231  aCompositeHelper.remove(item_name);
232  }
233  }
234  aCompositeHelper.notify();
235  }
236 }
237 
238 //------------------------------------------------------------------------------
239 
240 void SOrganTransformation::onResetClick()
241 {
242  ::fwMedData::ModelSeries::sptr series = this->getInOut< ::fwMedData::ModelSeries >(s_MODEL_SERIES_INOUT);
243 
244  //search the corresponding triangular mesh
245  for(::fwData::Reconstruction::sptr rec : series->getReconstructionDB())
246  {
247  ::fwData::Mesh::sptr pTmpTrMesh = rec->getMesh();
248 
249  ::fwData::TransformationMatrix3D::sptr pTmpMat =
250  pTmpTrMesh->getField< ::fwData::TransformationMatrix3D>( s_MATRIX_FIELD_NAME );
251  if (pTmpMat)
252  {
254  this->notitfyTransformationMatrix(pTmpMat);
255  }
256  }
257 }
258 
259 //------------------------------------------------------------------------------
260 
261 void SOrganTransformation::onSaveClick()
262 {
263  InnerMatMappingType matMap;
264 
265  ::fwMedData::ModelSeries::sptr series = this->getInOut< ::fwMedData::ModelSeries >(s_MODEL_SERIES_INOUT);
266 
267  if(!series->getReconstructionDB().empty())
268  {
269  for(::fwData::Reconstruction::sptr rec : series->getReconstructionDB())
270  {
271  ::fwData::Mesh::sptr pTmpTrMesh = rec->getMesh();
272  ::fwData::TransformationMatrix3D::sptr pTmpMat =
273  pTmpTrMesh->getField< ::fwData::TransformationMatrix3D>( s_MATRIX_FIELD_NAME );
274  if (pTmpMat)
275  {
276  ::fwData::TransformationMatrix3D::sptr pCpyTmpMat;
277  pCpyTmpMat = ::fwData::Object::copy(pTmpMat);
278  matMap[pTmpTrMesh->getID()] = pCpyTmpMat;
279  }
280  }
281 
282  ::std::stringstream tmpSaveName;
283  tmpSaveName << "save_" << m_saveCount;
284  m_saveListing[tmpSaveName.str()] = matMap;
285  m_saveSelectionComboBox->addItem(QString::fromStdString(tmpSaveName.str()));
286  m_saveCount++;
287  }
288 }
289 
290 //------------------------------------------------------------------------------
291 
292 void SOrganTransformation::onLoadClick()
293 {
294  if (m_saveSelectionComboBox->count() != 0)
295  {
296  InnerMatMappingType matMap = m_saveListing[m_saveSelectionComboBox->currentText().toStdString()];
297 
298  ::fwMedData::ModelSeries::sptr series = this->getInOut< ::fwMedData::ModelSeries >(s_MODEL_SERIES_INOUT);
299 
300  //search the corresponding triangular mesh
301  for(::fwData::Reconstruction::sptr rec : series->getReconstructionDB())
302  {
303  ::fwData::Mesh::sptr pTmpTrMesh = rec->getMesh();
304  if (matMap.find(pTmpTrMesh->getID()) != matMap.end())
305  {
306  ::fwData::TransformationMatrix3D::sptr pTmpMat =
307  pTmpTrMesh->getField< ::fwData::TransformationMatrix3D>( s_MATRIX_FIELD_NAME );
308  if (pTmpMat)
309  {
310  pTmpMat->shallowCopy(matMap[pTmpTrMesh->getID()]);
311  this->notitfyTransformationMatrix(pTmpMat);
312  }
313  }
314  }
315  }
316 }
317 
318 //------------------------------------------------------------------------------
319 
320 void SOrganTransformation::onSelectAllChanged(int state)
321 {
322 
323  ::fwData::Composite::sptr composite = this->getInOut< ::fwData::Composite>(s_COMPOSITE_INOUT);
324  ::fwDataTools::helper::Composite compositeHelper(composite);
325 
326  if(state == Qt::Checked)
327  {
328  m_reconstructionListBox->setEnabled(false);
329 
330  ::fwMedData::ModelSeries::sptr series = this->getInOut< ::fwMedData::ModelSeries >(s_MODEL_SERIES_INOUT);
331 
332  for(::fwData::Reconstruction::sptr rec : series->getReconstructionDB())
333  {
334  if(composite->find(rec->getOrganName()) == composite->end())
335  {
336  compositeHelper.add(rec->getOrganName(), rec->getMesh());
337  }
338  }
339 
340  }
341  else if(state == Qt::Unchecked)
342  {
343  m_reconstructionListBox->setEnabled(true);
344 
345  QList<QListWidgetItem*> itemList = m_reconstructionListBox->findItems("", Qt::MatchContains);
346  for(QListWidgetItem* item : itemList)
347  {
348  if(item->checkState() == Qt::Unchecked)
349  {
350  compositeHelper.remove(item->text().toStdString());
351  }
352  }
353 
354  this->refresh();
355  }
356  compositeHelper.notify();
357 
358 }
359 
360 //------------------------------------------------------------------------------
361 
362 void SOrganTransformation::addMeshTransform()
363 {
364  ::fwMedData::ModelSeries::sptr series = this->getInOut< ::fwMedData::ModelSeries >(s_MODEL_SERIES_INOUT);
365 
366  for(const ::fwData::Reconstruction::sptr& rec : series->getReconstructionDB())
367  {
368  ::fwData::Mesh::sptr mesh = rec->getMesh();
369 
370  if (!mesh->getField( s_MATRIX_FIELD_NAME ))
371  {
372  ::fwDataTools::helper::Field fieldHelper(mesh);
373  fieldHelper.setField(s_MATRIX_FIELD_NAME, ::fwData::TransformationMatrix3D::New());
374  fieldHelper.notify();
375  }
376  }
377 }
378 
379 //------------------------------------------------------------------------------
380 
382 {
383  KeyConnectionsMap connections;
384  connections.push(s_MODEL_SERIES_INOUT, ::fwMedData::ModelSeries::s_MODIFIED_SIG, s_UPDATE_SLOT);
385  connections.push(s_MODEL_SERIES_INOUT, ::fwMedData::ModelSeries::s_RECONSTRUCTIONS_ADDED_SIG, s_UPDATE_SLOT);
386  connections.push(s_MODEL_SERIES_INOUT, ::fwMedData::ModelSeries::s_RECONSTRUCTIONS_REMOVED_SIG, s_UPDATE_SLOT);
387  connections.push(s_COMPOSITE_INOUT, ::fwData::Composite::s_MODIFIED_SIG, s_UPDATE_SLOT);
388  connections.push(s_COMPOSITE_INOUT, ::fwData::Composite::s_ADDED_OBJECTS_SIG, s_UPDATE_SLOT);
389  connections.push(s_COMPOSITE_INOUT, ::fwData::Composite::s_CHANGED_OBJECTS_SIG, s_UPDATE_SLOT);
390  connections.push(s_COMPOSITE_INOUT, ::fwData::Composite::s_REMOVED_OBJECTS_SIG, s_UPDATE_SLOT);
391 
392  return connections;
393 }
394 
395 //------------------------------------------------------------------------------
396 
397 } // namespace editor
398 } // namespace uiMedDataQt
Display the organs list and allow an interactive selection to set the corresponding meshes in a compo...
virtual UIMEDDATAQT_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
FWDATATOOLS_API void remove(std::string _compositeKey)
Remove an object in the composite.
virtual UIMEDDATAQT_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
The namespace uiMedDataQt contains editors for medical data.
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
Defines a helper to modify field on a fwData::Object and create a message notifying this modification...
Definition: Field.hpp:22
FWDATATOOLS_API void notify()
Send the message of modification.
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.
FWDATATOOLS_API void add(std::string _compositeKey,::fwData::Object::sptr _newObject)
Add an object in the composite.
FWDATATOOLS_API void swap(std::string _compositeKey,::fwData::Object::sptr _newObject)
Replace an object in the composite.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CHANGED_OBJECTS_SIG
Type of signal when objects are added.
Defines an helper to modify an fwData::Composite and create in parallel the message to announce this ...
UIMEDDATAQT_API SOrganTransformation() noexcept
constructor
virtual UIMEDDATAQT_API void swapping() override
Swap the service from associated object to another object.
FWDATATOOLS_API void notify()
Send the built message and clear the internal maps.
Definition: Field.cpp:148
static FWMEDDATA_APIconst::fwCom::Signals::SignalKeyType s_RECONSTRUCTIONS_ADDED_SIG
Key in m_signals map of signal m_sigReconstructionsAdded.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_REMOVED_OBJECTS_SIG
Type of signal when objects are added.
#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
virtual UIMEDDATAQT_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
static FWDATA_API::fwData::Object::sptr copy(const ::fwData::Object::csptr &source)
return a copy of the source. if source is a null pointer, return a null pointer.
This class represents a 3D transformation matrix (4x4).
FWDATATOOLS_API void setField(const ::fwData::Object::FieldNameType &name,::fwData::Object::sptr obj)
Register field with specified name. If the name does already exist, the matching field will be replac...
Definition: Field.cpp:41
virtual UIMEDDATAQT_API void starting() override
Initialize the service activity.
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_ADDED_OBJECTS_SIG
Type of signal when objects are added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
virtual UIMEDDATAQT_API void configuring() override
Configure the service before starting. Apply the configuration to service.
static FWDATATOOLS_API void identity(::fwData::TransformationMatrix3D::sptr &_trf)
Set the matrix to identity.
virtual UIMEDDATAQT_API ~SOrganTransformation() noexcept
destructor
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
Definition: IService.hpp:177
static FWMEDDATA_APIconst::fwCom::Signals::SignalKeyType s_RECONSTRUCTIONS_REMOVED_SIG
Key in m_signals map of signal m_sigReconstructionsRemoved.
FWGUI_API void initialize()
Initialize managers.
FWDATA_API void shallowCopy(const Object::csptr &_source) override
Defines shallow copy.