CustusX  16.5
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxImageLandmarksWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxImageLandmarksWidget.h"
34 
35 #include <sstream>
36 #include <QVBoxLayout>
37 #include <QPushButton>
38 #include <QTableWidget>
39 #include <QTableWidgetItem>
40 #include <QHeaderView>
41 #include <QLabel>
42 #include <QSlider>
43 #include <vtkDoubleArray.h>
44 #include <vtkImageData.h>
45 #include "cxLogger.h"
46 #include "cxPickerRep.h"
48 #include "cxSettings.h"
49 #include "cxLandmarkRep.h"
50 #include "cxView.h"
51 #include "cxTypeConversions.h"
53 #include "cxRegistrationService.h"
54 #include "cxPatientModelService.h"
55 #include "cxViewService.h"
56 #include "cxRepContainer.h"
57 #include "cxTrackingService.h"
58 #include "cxLandmarkListener.h"
59 #include "cxActiveData.h"
60 
61 namespace cx
62 {
63 ImageLandmarksWidget::ImageLandmarksWidget(RegServicesPtr services, QWidget* parent,
64  QString objectName, QString windowTitle, bool useRegistrationFixedPropertyInsteadOfActiveImage) :
65  LandmarkRegistrationWidget(services, parent, objectName, windowTitle),
66  mUseRegistrationFixedPropertyInsteadOfActiveImage(useRegistrationFixedPropertyInsteadOfActiveImage)
67 {
68  if(mUseRegistrationFixedPropertyInsteadOfActiveImage)
69  mCurrentProperty.reset(new StringPropertyRegistrationFixedImage(services->registration(), services->patient()));
70  else
73 
74  mLandmarkListener->useOnlyOneSourceUpdatedFromOutside();
75 
76  mActiveToolProxy = ActiveToolProxy::New(services->tracking());
77  connect(mActiveToolProxy.get(), SIGNAL(toolVisible(bool)), this, SLOT(enableButtons()));
78  connect(mActiveToolProxy.get(), SIGNAL(activeToolChanged(const QString&)), this, SLOT(enableButtons()));
79 
80  //pushbuttons
81  mAddLandmarkButton = new QPushButton("New Landmark", this);
82  mAddLandmarkButton->setToolTip("Add landmark");
83  mAddLandmarkButton->setDisabled(true);
84  connect(mAddLandmarkButton, SIGNAL(clicked()), this, SLOT(addLandmarkButtonClickedSlot()));
85 
86  mEditLandmarkButton = new QPushButton("Resample", this);
87  mEditLandmarkButton->setToolTip("Resample existing landmark");
88  mEditLandmarkButton->setDisabled(true);
89  connect(mEditLandmarkButton, SIGNAL(clicked()), this, SLOT(editLandmarkButtonClickedSlot()));
90 
91  mRemoveLandmarkButton = new QPushButton("Clear", this);
92  mRemoveLandmarkButton->setToolTip("Clear selected landmark");
93  mRemoveLandmarkButton->setDisabled(true);
94  connect(mRemoveLandmarkButton, SIGNAL(clicked()), this, SLOT(removeLandmarkButtonClickedSlot()));
95 
96  //layout
100 
101  QHBoxLayout* landmarkButtonsLayout = new QHBoxLayout;
102  landmarkButtonsLayout->addWidget(mAddLandmarkButton);
103  landmarkButtonsLayout->addWidget(mEditLandmarkButton);
104  landmarkButtonsLayout->addWidget(mRemoveLandmarkButton);
105  mVerticalLayout->addLayout(landmarkButtonsLayout);
106 }
107 
109 {
110 }
111 
113 {
114  DataPtr data = mCurrentProperty->getData();
115 
116  mLandmarkListener->setLandmarkSource(data);
117  this->enableButtons();
118 
119  if (data && !mServices->registration()->getFixedData())
120  mServices->registration()->setFixedData(data);
121 
122  this->setModified();
123 }
124 
126 {
127  return mServices->view()->get3DReps(0, 0)->findFirst<PickerRep>();
128 }
129 
130 DataPtr ImageLandmarksWidget::getCurrentData() const
131 {
132  return mLandmarkListener->getLandmarkSource();
133 }
134 
136 {
138  if (!PickerRep)
139  {
140  reportError("Could not find a rep to add the landmark to.");
141  return;
142  }
143 
144  DataPtr image = this->getCurrentData();
145  if (!image)
146  return;
147 
148  QString uid = mServices->patient()->addLandmark();
149  Vector3D pos_r = PickerRep->getPosition();
150  Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
151  image->getLandmarks()->setLandmark(Landmark(uid, pos_d));
152 
153  this->activateLandmark(uid);
154 }
155 
156 
158 {
160  if (!PickerRep)
161  {
162  reportError("Could not find a rep to edit the landmark for.");
163  return;
164  }
165 
166  DataPtr image = this->getCurrentData();
167  if (!image)
168  return;
169 
170  QString uid = mActiveLandmark;
171  Vector3D pos_r = PickerRep->getPosition();
172  Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
173  image->getLandmarks()->setLandmark(Landmark(uid, pos_d));
174 
175  this->activateLandmark(this->getNextLandmark());
176 }
177 
179 {
180  DataPtr image = this->getCurrentData();
181  if (!image)
182  return;
183 
184  QString next = this->getNextLandmark();
185  image->getLandmarks()->removeLandmark(mActiveLandmark);
186  this->activateLandmark(next);
187 }
188 
189 void ImageLandmarksWidget::cellClickedSlot(int row, int column)
190 {
192  this->enableButtons();
193 }
194 
196 {
197  bool selected = !mLandmarkTableWidget->selectedItems().isEmpty();
198  bool loaded = this->getCurrentData() != 0;
199 
200  mEditLandmarkButton->setEnabled(selected);
201  mRemoveLandmarkButton->setEnabled(selected);
202  mAddLandmarkButton->setEnabled(loaded);
203 
204  DataPtr image = this->getCurrentData();
205  if (image)
206  {
207  mAddLandmarkButton->setToolTip(QString("Add landmark to image %1").arg(image->getName()));
208  mEditLandmarkButton->setToolTip(QString("Resample landmark in image %1").arg(image->getName()));
209  }
210 // this->setModified();
211 }
212 
213 void ImageLandmarksWidget::showEvent(QShowEvent* event)
214 {
215  mServices->view()->setRegistrationMode(rsIMAGE_REGISTRATED);
217 
218  if(!mUseRegistrationFixedPropertyInsteadOfActiveImage)
219  {
220  ActiveDataPtr activeData = mServices->patient()->getActiveData();
221  ImagePtr image = activeData->getActive<Image>();
222  if (image)
223  mCurrentProperty->setValue(image->getUid());
224  }
225 }
226 
227 void ImageLandmarksWidget::hideEvent(QHideEvent* event)
228 {
229  mServices->view()->setRegistrationMode(rsNOT_REGISTRATED);
231 
232 }
233 
235 {
237 
238  std::vector<Landmark> landmarks = this->getAllLandmarks();
239 
240  //update buttons
241  mRemoveLandmarkButton->setEnabled(!landmarks.empty() && !mActiveLandmark.isEmpty());
242  mEditLandmarkButton->setEnabled(!landmarks.empty() && !mActiveLandmark.isEmpty());
243 }
244 
246 {
247  DataPtr image = this->getCurrentData();
248  if (!image)
249  return LandmarkMap();
250 
251  return image->getLandmarks()->getLandmarks();
252 }
253 
258 {
259  DataPtr image = this->getCurrentData();
260  if (!image)
261  return Transform3D::Identity();
262  return image->get_rMd();
263 }
264 
266 {
267  DataPtr image = this->getCurrentData();
268  if (!image)
269  return;
270  image->getLandmarks()->setLandmark(Landmark(uid, p_target));
271 }
272 
274 {
275  DataPtr image = this->getCurrentData();
276  if (!image)
277  return "None";
278  return image->getName();
279 }
280 
281 
282 }//namespace cx
virtual void showEvent(QShowEvent *event)
updates internal info before showing the widget
virtual void editLandmarkButtonClickedSlot()
reacts when the Edit Landmark button is clicked
QPushButton * mRemoveLandmarkButton
the Remove Landmark button
void reportError(QString msg)
Definition: cxLogger.cpp:92
void removeLandmarkButtonClickedSlot()
reacts when the Remove Landmark button is clicked
QPushButton * mEditLandmarkButton
the Edit Landmark button
boost::shared_ptr< class RegServices > RegServicesPtr
Definition: cxRegServices.h:41
QLabel * mAvarageAccuracyLabel
label showing the average accuracy
QPushButton * mAddLandmarkButton
the Add Landmark button
One landmark, or fiducial, coordinate.
Definition: cxLandmark.h:61
virtual Transform3D getTargetTransform() const
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual void showEvent(QShowEvent *event)
updates internal info before showing the widget
static StringPropertySelectDataPtr New(PatientModelServicePtr patientModelService, QString typeRegexp=".*")
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
virtual void hideEvent(QHideEvent *event)
boost::shared_ptr< class ActiveData > ActiveDataPtr
Definition: cxColorWidget.h:42
Composite widget for string selection.
QVBoxLayout * mVerticalLayout
vertical layout is used
virtual void setTargetLandmark(QString uid, Vector3D p_target)
virtual void hideEvent(QHideEvent *event)
static ActiveToolProxyPtr New(TrackingServicePtr trackingService)
boost::shared_ptr< class Data > DataPtr
boost::shared_ptr< class PickerRep > PickerRepPtr
ActiveToolProxyPtr mActiveToolProxy
Picking of points in an image.
Definition: cxPickerRep.h:70
void addLandmarkButtonClickedSlot()
reacts when the Add Landmark button is clicked
A volumetric data set.
Definition: cxImage.h:66
virtual void cellClickedSlot(int row, int column)
when a landmark is selected from the table
virtual void prePaintEvent()
populates the table widget
rsNOT_REGISTRATED
virtual void prePaintEvent()
populates the table widget
void changed()
emit when the underlying data value is changed: The user interface will be updated.
virtual QString getTargetName() const
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
std::map< QString, class Landmark > LandmarkMap
QString mActiveLandmark
uid of surrently selected landmark.
std::vector< Landmark > getAllLandmarks() const
get all the landmarks from the image and the datamanager
SelectDataStringPropertyBasePtr mCurrentProperty
virtual LandmarkMap getTargetLandmarks() const
virtual void cellClickedSlot(int row, int column)
when a landmark is selected from the table
rsIMAGE_REGISTRATED
QTableWidget * mLandmarkTableWidget
the table widget presenting the landmarks