CustusX  2023.01.05-dev+develop.0da12
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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 
14 #include <sstream>
15 #include <QVBoxLayout>
16 #include <QPushButton>
17 #include <QTableWidget>
18 #include <QTableWidgetItem>
19 #include <QHeaderView>
20 #include <QLabel>
21 #include <QSlider>
22 #include <vtkDoubleArray.h>
23 #include <vtkImageData.h>
24 #include "cxLogger.h"
25 #include "cxPickerRep.h"
27 #include "cxSettings.h"
28 #include "cxLandmarkRep.h"
29 #include "cxView.h"
30 #include "cxTypeConversions.h"
32 #include "cxRegistrationService.h"
33 #include "cxPatientModelService.h"
34 #include "cxViewService.h"
35 #include "cxRepContainer.h"
36 #include "cxTrackingService.h"
37 #include "cxLandmarkListener.h"
38 #include "cxActiveData.h"
39 #include "cxMesh.h"
40 #include "cxTime.h"
41 
42 namespace cx
43 {
44 CenterlinePointsWidget::CenterlinePointsWidget(RegServicesPtr services, QWidget* parent,
45  QString objectName, QString windowTitle, bool useRegistrationFixedPropertyInsteadOfActiveImage) :
46  LandmarkRegistrationWidget(services, parent, objectName, windowTitle, false),
47  mUseRegistrationFixedPropertyInsteadOfActiveImage(useRegistrationFixedPropertyInsteadOfActiveImage)
48 {
49  if(mUseRegistrationFixedPropertyInsteadOfActiveImage)
50  mCurrentProperty.reset(new StringPropertyRegistrationFixedImage(services->registration(), services->patient()));
51  else
54 
55  mLandmarkListener->useOnlyOneSourceUpdatedFromOutside();
56 
57  mActiveToolProxy = ActiveToolProxy::New(services->tracking());
58  connect(mActiveToolProxy.get(), SIGNAL(toolVisible(bool)), this, SLOT(enableButtons()));
59  connect(mActiveToolProxy.get(), SIGNAL(activeToolChanged(const QString&)), this, SLOT(enableButtons()));
60 
61  //pushbuttons
62  mAddLandmarkButton = new QPushButton("New Landmark", this);
63  mAddLandmarkButton->setToolTip("Add landmark");
64  mAddLandmarkButton->setDisabled(true);
65  connect(mAddLandmarkButton, SIGNAL(clicked()), this, SLOT(addLandmarkButtonClickedSlot()));
66 
67  mEditLandmarkButton = new QPushButton("Resample", this);
68  mEditLandmarkButton->setToolTip("Resample existing landmark");
69  mEditLandmarkButton->setDisabled(true);
70  connect(mEditLandmarkButton, SIGNAL(clicked()), this, SLOT(editLandmarkButtonClickedSlot()));
71 
72  mRemoveLandmarkButton = new QPushButton("Clear", this);
73  mRemoveLandmarkButton->setToolTip("Clear selected landmark");
74  mRemoveLandmarkButton->setDisabled(true);
75  connect(mRemoveLandmarkButton, SIGNAL(clicked()), this, SLOT(removeLandmarkButtonClickedSlot()));
76 
77  mCreateCenterlineButton = new QPushButton("Create centerline", this);
78  mCreateCenterlineButton->setToolTip("Create centerline from landmarks");
79  mCreateCenterlineButton->setDisabled(true);
80  connect(mCreateCenterlineButton, SIGNAL(clicked()), this, SLOT(createCenterlineButtonClickedSlot()));
81 
82  //layout
86 
87  QHBoxLayout* landmarkButtonsLayout = new QHBoxLayout;
88  landmarkButtonsLayout->addWidget(mAddLandmarkButton);
89  landmarkButtonsLayout->addWidget(mEditLandmarkButton);
90  landmarkButtonsLayout->addWidget(mRemoveLandmarkButton);
91  landmarkButtonsLayout->addWidget(mCreateCenterlineButton);
92  mVerticalLayout->addLayout(landmarkButtonsLayout);
93 }
94 
96 {
97 }
98 
100 {
101  DataPtr data = mCurrentProperty->getData();
102 
103  mLandmarkListener->setLandmarkSource(data);
104  this->enableButtons();
105 
106  if (data && !mServices->registration()->getFixedData())
107  mServices->registration()->setFixedData(data);
108 
109  this->setModified();
110 }
111 
113 {
114  return mServices->view()->get3DReps(0, 0)->findFirst<PickerRep>();
115 }
116 
117 DataPtr CenterlinePointsWidget::getCurrentData() const
118 {
119  return mLandmarkListener->getLandmarkSource();
120 }
121 
123 {
125  if (!PickerRep)
126  {
127  reportError("Need a 3D view to set landmarks.");
128  return;
129  }
130 
131  DataPtr image = this->getCurrentData();
132  if (!image)
133  return;
134 
135  QString uid = mServices->patient()->addLandmark();
136  Vector3D pos_r = PickerRep->getPosition();
137  Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
138  image->getLandmarks()->setLandmark(Landmark(uid, pos_d));
139 
140  this->activateLandmark(uid);
141 }
142 
143 
145 {
147  if (!PickerRep)
148  {
149  reportError("Need a 3D view to edit landmarks.");
150  return;
151  }
152 
153  DataPtr image = this->getCurrentData();
154  if (!image)
155  return;
156 
157  QString uid = mActiveLandmark;
158  Vector3D pos_r = PickerRep->getPosition();
159  Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
160  image->getLandmarks()->setLandmark(Landmark(uid, pos_d));
161 
162  this->activateLandmark(this->getNextLandmark());
163 }
164 
166 {
167  DataPtr image = this->getCurrentData();
168  if (!image)
169  return;
170 
171  QString next = this->getNextLandmark();
172  image->getLandmarks()->removeLandmark(mActiveLandmark);
173  this->activateLandmark(next);
174 }
175 
177 {
178  DataPtr image = this->getCurrentData();
179  if (!image)
180  return;
181 
182  Transform3D rMd = image->get_rMd();
183 
184  std::vector<Landmark> landmarkVector = this-> getAllLandmarks();
185 
186  vtkPolyDataPtr outputPositions = vtkPolyDataPtr::New();
187  vtkPointsPtr points = vtkPointsPtr::New();
188  vtkCellArrayPtr lines = vtkCellArrayPtr::New();
189 
190  for(int i=0; i<landmarkVector.size(); i++)
191  {
192  LandmarkProperty prop = mServices->patient()->getLandmarkProperties()[landmarkVector[i].getUid()];
193  if (prop.getActive())
194  {
195  Vector3D pos = landmarkVector[i].getCoord();
196  pos = rMd.coord(pos);
197  points->InsertNextPoint(pos(0),pos(1),pos(2));
198  }
199  }
200  for(int i=0; i<points->GetNumberOfPoints()-1; i++)
201  {
202  vtkIdType connection[2] = {i, i+1};
203  lines->InsertNextCell(2, connection);
204  }
205 
206  outputPositions->SetPoints(points);
207  outputPositions->SetLines(lines);
208 
209  QString filename;
210  QString format = timestampSecondsFormatNice();
211  filename = "CenterlineFromPoints " + QDateTime::currentDateTime().toString(format);
212 
213  MeshPtr mesh = mServices->patient()->createSpecificData<Mesh>(filename, filename);
214  mesh->setVtkPolyData(outputPositions);
215  mesh->setColor(QColor(0, 0, 255, 255));
216  mServices->patient()->insertData(mesh);
217  mServices->view()->autoShowData(mesh);
218 }
219 
221 {
223  this->enableButtons();
224 }
225 
227 {
228  bool selected = !mLandmarkTableWidget->selectedItems().isEmpty();
229  bool loaded = this->getCurrentData() != 0;
230 
231  mEditLandmarkButton->setEnabled(selected);
232  mRemoveLandmarkButton->setEnabled(selected);
233  mCreateCenterlineButton->setEnabled(selected);
234  mAddLandmarkButton->setEnabled(loaded);
235 
236  DataPtr image = this->getCurrentData();
237  if (image)
238  {
239  mAddLandmarkButton->setToolTip(QString("Add landmark to image %1").arg(image->getName()));
240  mEditLandmarkButton->setToolTip(QString("Resample landmark in image %1").arg(image->getName()));
241  }
242 // this->setModified();
243 }
244 
245 void CenterlinePointsWidget::showEvent(QShowEvent* event)
246 {
247  mServices->view()->setRegistrationMode(rsIMAGE_REGISTRATED);
249 
250  if(!mUseRegistrationFixedPropertyInsteadOfActiveImage)
251  {
252  ActiveDataPtr activeData = mServices->patient()->getActiveData();
253  ImagePtr image = activeData->getActive<Image>();
254  if (image)
255  mCurrentProperty->setValue(image->getUid());
256  }
257 }
258 
259 void CenterlinePointsWidget::hideEvent(QHideEvent* event)
260 {
261  mServices->view()->setRegistrationMode(rsNOT_REGISTRATED);
263 
264 }
265 
267 {
269 
270  std::vector<Landmark> landmarks = this->getAllLandmarks();
271 
272  //update buttons
273  mCreateCenterlineButton->setEnabled(!landmarks.empty() && !mActiveLandmark.isEmpty());
274  mEditLandmarkButton->setEnabled(!landmarks.empty() && !mActiveLandmark.isEmpty());
275 }
276 
278 {
279  DataPtr image = this->getCurrentData();
280  if (!image)
281  return LandmarkMap();
282 
283  return image->getLandmarks()->getLandmarks();
284 }
285 
290 {
291  DataPtr image = this->getCurrentData();
292  if (!image)
293  return Transform3D::Identity();
294  return image->get_rMd();
295 }
296 
298 {
299  DataPtr image = this->getCurrentData();
300  if (!image)
301  return;
302  image->getLandmarks()->setLandmark(Landmark(uid, p_target));
303 }
304 
306 {
307  DataPtr image = this->getCurrentData();
308  if (!image)
309  return "None";
310  return image->getName();
311 }
312 
313 
314 }//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:71
A mesh data set.
Definition: cxMesh.h:45
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:40
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:27
void createCenterlineButtonClickedSlot()
reacts when the Create centerline button is clicked
QString timestampSecondsFormatNice()
Definition: cxTime.cpp:26
vtkSmartPointer< vtkPoints > vtkPointsPtr
boost::shared_ptr< class ActiveData > ActiveDataPtr
Definition: cxColorWidget.h:21
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:49
virtual void prePaintEvent()
populates the table widget
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:92
QPushButton * mAddLandmarkButton
the Add Landmark button
A volumetric data set.
Definition: cxImage.h:45
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:20
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:42
std::map< QString, class Landmark > LandmarkMap
QString mActiveLandmark
uid of currently 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:179
rsIMAGE_REGISTRATED
QTableWidget * mLandmarkTableWidget
the table widget presenting the landmarks
Namespace for all CustusX production code.