Fraxinus  17.12
An IGT application
cxCenterlinePointsWidget.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 
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 #include "cxMesh.h"
61 #include "cxTime.h"
62 
63 namespace cx
64 {
65 CenterlinePointsWidget::CenterlinePointsWidget(RegServicesPtr services, QWidget* parent,
66  QString objectName, QString windowTitle, bool useRegistrationFixedPropertyInsteadOfActiveImage) :
67  LandmarkRegistrationWidget(services, parent, objectName, windowTitle, false),
68  mUseRegistrationFixedPropertyInsteadOfActiveImage(useRegistrationFixedPropertyInsteadOfActiveImage)
69 {
70  if(mUseRegistrationFixedPropertyInsteadOfActiveImage)
71  mCurrentProperty.reset(new StringPropertyRegistrationFixedImage(services->registration(), services->patient()));
72  else
75 
76  mLandmarkListener->useOnlyOneSourceUpdatedFromOutside();
77 
78  mActiveToolProxy = ActiveToolProxy::New(services->tracking());
79  connect(mActiveToolProxy.get(), SIGNAL(toolVisible(bool)), this, SLOT(enableButtons()));
80  connect(mActiveToolProxy.get(), SIGNAL(activeToolChanged(const QString&)), this, SLOT(enableButtons()));
81 
82  //pushbuttons
83  mAddLandmarkButton = new QPushButton("New Landmark", this);
84  mAddLandmarkButton->setToolTip("Add landmark");
85  mAddLandmarkButton->setDisabled(true);
86  connect(mAddLandmarkButton, SIGNAL(clicked()), this, SLOT(addLandmarkButtonClickedSlot()));
87 
88  mEditLandmarkButton = new QPushButton("Resample", this);
89  mEditLandmarkButton->setToolTip("Resample existing landmark");
90  mEditLandmarkButton->setDisabled(true);
91  connect(mEditLandmarkButton, SIGNAL(clicked()), this, SLOT(editLandmarkButtonClickedSlot()));
92 
93  mRemoveLandmarkButton = new QPushButton("Clear", this);
94  mRemoveLandmarkButton->setToolTip("Clear selected landmark");
95  mRemoveLandmarkButton->setDisabled(true);
96  connect(mRemoveLandmarkButton, SIGNAL(clicked()), this, SLOT(removeLandmarkButtonClickedSlot()));
97 
98  mCreateCenterlineButton = new QPushButton("Create centerline", this);
99  mCreateCenterlineButton->setToolTip("Create centerline from landmarks");
100  mCreateCenterlineButton->setDisabled(true);
101  connect(mCreateCenterlineButton, SIGNAL(clicked()), this, SLOT(createCenterlineButtonClickedSlot()));
102 
103  //layout
107 
108  QHBoxLayout* landmarkButtonsLayout = new QHBoxLayout;
109  landmarkButtonsLayout->addWidget(mAddLandmarkButton);
110  landmarkButtonsLayout->addWidget(mEditLandmarkButton);
111  landmarkButtonsLayout->addWidget(mRemoveLandmarkButton);
112  landmarkButtonsLayout->addWidget(mCreateCenterlineButton);
113  mVerticalLayout->addLayout(landmarkButtonsLayout);
114 }
115 
117 {
118 }
119 
121 {
122  DataPtr data = mCurrentProperty->getData();
123 
124  mLandmarkListener->setLandmarkSource(data);
125  this->enableButtons();
126 
127  if (data && !mServices->registration()->getFixedData())
128  mServices->registration()->setFixedData(data);
129 
130  this->setModified();
131 }
132 
134 {
135  return mServices->view()->get3DReps(0, 0)->findFirst<PickerRep>();
136 }
137 
138 DataPtr CenterlinePointsWidget::getCurrentData() const
139 {
140  return mLandmarkListener->getLandmarkSource();
141 }
142 
144 {
146  if (!PickerRep)
147  {
148  reportError("Need a 3D view to set landmarks.");
149  return;
150  }
151 
152  DataPtr image = this->getCurrentData();
153  if (!image)
154  return;
155 
156  QString uid = mServices->patient()->addLandmark();
157  Vector3D pos_r = PickerRep->getPosition();
158  Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
159  image->getLandmarks()->setLandmark(Landmark(uid, pos_d));
160 
161  this->activateLandmark(uid);
162 }
163 
164 
166 {
168  if (!PickerRep)
169  {
170  reportError("Need a 3D view to edit landmarks.");
171  return;
172  }
173 
174  DataPtr image = this->getCurrentData();
175  if (!image)
176  return;
177 
178  QString uid = mActiveLandmark;
179  Vector3D pos_r = PickerRep->getPosition();
180  Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
181  image->getLandmarks()->setLandmark(Landmark(uid, pos_d));
182 
183  this->activateLandmark(this->getNextLandmark());
184 }
185 
187 {
188  DataPtr image = this->getCurrentData();
189  if (!image)
190  return;
191 
192  QString next = this->getNextLandmark();
193  image->getLandmarks()->removeLandmark(mActiveLandmark);
194  this->activateLandmark(next);
195 }
196 
198 {
199  DataPtr image = this->getCurrentData();
200  if (!image)
201  return;
202 
203  Transform3D rMd = image->get_rMd();
204 
205  std::vector<Landmark> landmarkVector = this-> getAllLandmarks();
206 
207  vtkPolyDataPtr outputPositions = vtkPolyDataPtr::New();
208  vtkPointsPtr points = vtkPointsPtr::New();
209  vtkCellArrayPtr lines = vtkCellArrayPtr::New();
210 
211  for(int i=0; i<landmarkVector.size(); i++)
212  {
213  LandmarkProperty prop = mServices->patient()->getLandmarkProperties()[landmarkVector[i].getUid()];
214  if (prop.getActive())
215  {
216  Vector3D pos = landmarkVector[i].getCoord();
217  pos = rMd.coord(pos);
218  points->InsertNextPoint(pos(0),pos(1),pos(2));
219  }
220  }
221  for(int i=0; i<points->GetNumberOfPoints()-1; i++)
222  {
223  vtkIdType connection[2] = {i, i+1};
224  lines->InsertNextCell(2, connection);
225  }
226 
227  outputPositions->SetPoints(points);
228  outputPositions->SetLines(lines);
229 
230  QString filename;
231  QString format = timestampSecondsFormatNice();
232  filename = "CenterlineFromPoints " + QDateTime::currentDateTime().toString(format);
233 
234  MeshPtr mesh = mServices->patient()->createSpecificData<Mesh>(filename, filename);
235  mesh->setVtkPolyData(outputPositions);
236  mesh->setColor(QColor(0, 0, 255, 255));
237  mServices->patient()->insertData(mesh);
238  mServices->view()->autoShowData(mesh);
239 }
240 
242 {
244  this->enableButtons();
245 }
246 
248 {
249  bool selected = !mLandmarkTableWidget->selectedItems().isEmpty();
250  bool loaded = this->getCurrentData() != 0;
251 
252  mEditLandmarkButton->setEnabled(selected);
253  mRemoveLandmarkButton->setEnabled(selected);
254  mCreateCenterlineButton->setEnabled(selected);
255  mAddLandmarkButton->setEnabled(loaded);
256 
257  DataPtr image = this->getCurrentData();
258  if (image)
259  {
260  mAddLandmarkButton->setToolTip(QString("Add landmark to image %1").arg(image->getName()));
261  mEditLandmarkButton->setToolTip(QString("Resample landmark in image %1").arg(image->getName()));
262  }
263 // this->setModified();
264 }
265 
266 void CenterlinePointsWidget::showEvent(QShowEvent* event)
267 {
268  mServices->view()->setRegistrationMode(rsIMAGE_REGISTRATED);
270 
271  if(!mUseRegistrationFixedPropertyInsteadOfActiveImage)
272  {
273  ActiveDataPtr activeData = mServices->patient()->getActiveData();
274  ImagePtr image = activeData->getActive<Image>();
275  if (image)
276  mCurrentProperty->setValue(image->getUid());
277  }
278 }
279 
280 void CenterlinePointsWidget::hideEvent(QHideEvent* event)
281 {
282  mServices->view()->setRegistrationMode(rsNOT_REGISTRATED);
284 
285 }
286 
288 {
290 
291  std::vector<Landmark> landmarks = this->getAllLandmarks();
292 
293  //update buttons
294  mCreateCenterlineButton->setEnabled(!landmarks.empty() && !mActiveLandmark.isEmpty());
295  mEditLandmarkButton->setEnabled(!landmarks.empty() && !mActiveLandmark.isEmpty());
296 }
297 
299 {
300  DataPtr image = this->getCurrentData();
301  if (!image)
302  return LandmarkMap();
303 
304  return image->getLandmarks()->getLandmarks();
305 }
306 
311 {
312  DataPtr image = this->getCurrentData();
313  if (!image)
314  return Transform3D::Identity();
315  return image->get_rMd();
316 }
317 
319 {
320  DataPtr image = this->getCurrentData();
321  if (!image)
322  return;
323  image->getLandmarks()->setLandmark(Landmark(uid, p_target));
324 }
325 
327 {
328  DataPtr image = this->getCurrentData();
329  if (!image)
330  return "None";
331  return image->getName();
332 }
333 
334 
335 }//namespace cx
void addLandmarkButtonClickedSlot()
reacts when the Add Landmark button is clicked
virtual Transform3D getTargetTransform() const
virtual void showEvent(QShowEvent *event)
updates internal info before showing the widget
QPushButton * mEditLandmarkButton
the Edit Landmark button
void reportError(QString msg)
Definition: cxLogger.cpp:92
A mesh data set.
Definition: cxMesh.h:66
virtual QString getTargetName() const
virtual void setTargetLandmark(QString uid, Vector3D p_target)
QPushButton * mRemoveLandmarkButton
the Remove Landmark button
QLabel * mAvarageAccuracyLabel
label showing the average accuracy
One landmark, or fiducial, coordinate.
Definition: cxLandmark.h:61
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual void hideEvent(QHideEvent *event)
vtkSmartPointer< class vtkCellArray > vtkCellArrayPtr
static StringPropertySelectDataPtr New(PatientModelServicePtr patientModelService, QString typeRegexp=".*")
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
void createCenterlineButtonClickedSlot()
reacts when the Create centerline button is clicked
QString timestampSecondsFormatNice()
Definition: cxTime.cpp:47
vtkSmartPointer< vtkPoints > vtkPointsPtr
boost::shared_ptr< class ActiveData > ActiveDataPtr
Definition: cxColorWidget.h:42
Composite widget for string selection.
QVBoxLayout * mVerticalLayout
vertical layout is used
virtual void cellClickedSlot(int row, int column)
when a landmark is selected from the table
void removeLandmarkButtonClickedSlot()
reacts when the Remove Landmark button is clicked
virtual void hideEvent(QHideEvent *event)
static ActiveToolProxyPtr New(TrackingServicePtr trackingService)
SelectDataStringPropertyBasePtr mCurrentProperty
boost::shared_ptr< class Data > DataPtr
boost::shared_ptr< class PickerRep > PickerRepPtr
Picking of points in an image.
Definition: cxPickerRep.h:70
virtual void prePaintEvent()
populates the table widget
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:112
QPushButton * mAddLandmarkButton
the Add Landmark button
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 showEvent(QShowEvent *event)
updates internal info before showing the widget
boost::shared_ptr< class RegServices > RegServicesPtr
Definition: cxRegServices.h:41
virtual void prePaintEvent()
populates the table widget
rsNOT_REGISTRATED
virtual LandmarkMap getTargetLandmarks() const
void changed()
emit when the underlying data value is changed: The user interface will be updated.
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
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
QPushButton * mCreateCenterlineButton
the Create centerline button
virtual void editLandmarkButtonClickedSlot()
reacts when the Edit Landmark button is clicked
boost::shared_ptr< class Mesh > MeshPtr
bool getActive() const
Definition: cxLandmark.cpp:200
rsIMAGE_REGISTRATED
QTableWidget * mLandmarkTableWidget
the table widget presenting the landmarks
Namespace for all CustusX production code.