CustusX  15.3.4-beta
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxPointSamplingWidget.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 #include "cxPointSamplingWidget.h"
33 
34 #include <QTreeWidget>
35 #include <QTreeWidgetItem>
36 #include <QStringList>
37 #include <QVBoxLayout>
38 #include <QHeaderView>
39 
40 
41 #include "cxTypeConversions.h"
43 #include "cxTrackingService.h"
44 #include "cxManualTool.h"
45 #include "cxLogger.h"
46 #include "cxLegacySingletons.h"
47 #include "cxSpaceProvider.h"
48 #include "cxPatientModelService.h"
49 #include "cxViewGroupData.h"
50 #include "cxViewService.h"
51 
52 
53 namespace cx
54 {
55 
57  BaseWidget(parent, "PointSamplingWidget", "Point sampler/3D ruler"),
58  mVerticalLayout(new QVBoxLayout(this)),
59  mTable(new QTableWidget(this)),
60  mActiveLandmark(""),
61  mAddButton(new QPushButton("Add", this)),
62  mEditButton(new QPushButton("Resample", this)),
63  mRemoveButton(new QPushButton("Remove", this)),
64  mLoadReferencePointsButton(new QPushButton("Load reference points", this))
65 {
67 
68  //table widget
69  connect(mTable, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
70 
71  this->setLayout(mVerticalLayout);
72 
73  //pushbuttons
74  connect(mAddButton, SIGNAL(clicked()), this, SLOT(addButtonClickedSlot()));
75  mEditButton->setDisabled(true);
76  connect(mEditButton, SIGNAL(clicked()), this, SLOT(editButtonClickedSlot()));
77  mRemoveButton->setDisabled(true);
78  connect(mRemoveButton, SIGNAL(clicked()), this, SLOT(removeButtonClickedSlot()));
79  connect(mLoadReferencePointsButton, SIGNAL(clicked()), this, SLOT(loadReferencePointsSlot()));
80 
81  //layout
82  mVerticalLayout->addWidget(mTable);
83 
84  QHBoxLayout* buttonLayout = new QHBoxLayout;
85  mVerticalLayout->addLayout(buttonLayout);
86 
87  buttonLayout->addWidget(mAddButton);
88  buttonLayout->addWidget(mEditButton);
89  buttonLayout->addWidget(mRemoveButton);
91 }
92 
94 {}
95 
97 {
98  return "<html>"
99  "<h3>Utility for sampling points in 3D</h3>"
100  "<p>Lets you sample points in 3D and get the distance between sampled points.</p>"
101  "<p><i></i></p>"
102  "</html>";
103 }
104 
106 {
107  //std::cout << "pling" << std::endl;
108 
109  QTableWidgetItem* item = mTable->currentItem();
110 
111  mActiveLandmark = item->data(Qt::UserRole).toString();
112 
113  for (unsigned i=0; i<mSamples.size(); ++i)
114  {
115  if (mSamples[i].getUid()!=mActiveLandmark)
116  continue;
117  setManualTool(mSamples[i].getCoord());
118  break;
119  }
120 
121  enablebuttons();
122 }
123 
124 void PointSamplingWidget::showEvent(QShowEvent* event)
125 {
126  QWidget::showEvent(event);
127 
128  ViewGroupDataPtr data = viewService()->getGroup(0);
129  ViewGroupData::Options options = data->getOptions();
130  options.mShowPointPickerProbe = true;
131  data->setOptions(options);
132 
133  this->updateSlot();
134 }
135 
136 void PointSamplingWidget::hideEvent(QHideEvent* event)
137 {
138  QWidget::hideEvent(event);
139 }
140 
142 {
143  mTable->blockSignals(true);
144  mTable->clear();
145 
146  //ready the table widget
147  mTable->setRowCount(mSamples.size());
148  mTable->setColumnCount(3);
149  QStringList headerItems(QStringList() << "Name" << "Coordinates(r)" << "Delta (mm)");
150  mTable->setHorizontalHeaderLabels(headerItems);
151  mTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
152  mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
153 
154  for (unsigned i = 0; i < mSamples.size(); ++i)
155  {
156  std::vector<QTableWidgetItem*> items(3); // name, coordinates, delta
157 
158  Vector3D coord = mSamples[i].getCoord();
159 
160  items[0] = new QTableWidgetItem(qstring_cast(mSamples[i].getUid()));
161 
162  QString coordText;
163  int width = 5;
164  int prec = 1;
165  coordText = tr("(%1, %2, %3)").arg(coord[0], width, 'f', prec).arg(coord[1], width, 'f', prec).arg(coord[2],
166  width, 'f', prec);
167 
168  items[1] = new QTableWidgetItem(coordText);
169 
170  if (i==0)
171  {
172  items[2] = new QTableWidgetItem;
173  }
174  else
175  {
176  double delta = (mSamples[i].getCoord() - mSamples[0].getCoord()).length();
177  items[2] = new QTableWidgetItem(tr("%1").arg(delta, width, 'f', prec));
178  }
179 
180  for (unsigned j = 0; j < items.size(); ++j)
181  {
182  items[j]->setData(Qt::UserRole, qstring_cast(mSamples[i].getUid()));
183  mTable->setItem(i, j, items[j]);
184  }
185 
186  //highlight selected row
187  if (mSamples[i].getUid() == mActiveLandmark)
188  {
189  mTable->setCurrentItem(items[1]);
190  }
191  }
192 
193  mTable->blockSignals(false);
194 
195  this->enablebuttons();
196 }
197 
199 {
200  mAddButton->setEnabled(true);
201  mEditButton->setEnabled(mActiveLandmark!="");
202  mRemoveButton->setEnabled(mActiveLandmark!="");
203  mLoadReferencePointsButton->setEnabled(trackingService()->getReferenceTool() ? true : false);
204 }
205 
207 {
208  // find unique uid:
209  int max = 0;
210  for (unsigned i=0; i<mSamples.size(); ++i)
211  {
212  max = std::max(max, qstring_cast(mSamples[i].getUid()).toInt());
213  }
214  QString uid = qstring_cast(max+1);
215 
216  mSamples.push_back(Landmark(uid, point));
217  mActiveLandmark = uid;
218 
219  this->updateSlot();
220 }
221 
223 {
224  ToolPtr tool = trackingService()->getManualTool();
225 
226  //Transform3D sMr = mSliceProxy->get_sMr();
227  Transform3D rMpr = patientService()->get_rMpr();
228  Transform3D prMt = tool->get_prMt();
229 
230  // find tool position in r
231  Vector3D tool_t(0,0,tool->getTooltipOffset());
232  Vector3D tool_r = (rMpr*prMt).coord(tool_t);
233 
234  // find click position in s.
235  //Vector3D click_s = get_vpMs().inv().coord(click_vp);
236 
237  // compute the new tool position in slice space as a synthesis of the plane part of click and the z part of original.
238  //Vector3D cross_s(click_s[0], click_s[1], tool_s[2]);
239  // compute the position change and transform to patient.
240  Vector3D delta_r = p_r - tool_r;
241  Vector3D delta_pr = rMpr.inv().vector(delta_r);
242 
243  // MD is the actual tool movement in patient space, matrix form
244  Transform3D MD = createTransformTranslate(delta_pr);
245  // set new tool position to old modified by MD:
246  tool->set_prMt(MD*prMt);
247 }
248 
250 {
251  this->addPoint(this->getSample());
252 }
253 
255 {
256 // CoordinateSystem ref = spaceProvider()->getR();
257  Vector3D P_ref = spaceProvider()->getActiveToolTipPoint(CoordinateSystem::reference(), true);
258 
259  return P_ref;
260 }
261 
263 {
264  for (unsigned i=0; i<mSamples.size(); ++i)
265  {
266  if (mSamples[i].getUid()!=mActiveLandmark)
267  continue;
269  }
270  updateSlot();
271 }
272 
274 {
275  for (unsigned i=0; i<mSamples.size(); ++i)
276  {
277  if (mSamples[i].getUid()!=mActiveLandmark)
278  continue;
279  mSamples.erase(mSamples.begin()+i);
280  mActiveLandmark = "";
281  if (i<mSamples.size())
282  mActiveLandmark = mSamples[i].getUid();
283  break;
284  }
285  updateSlot();
286 }
287 
289 {
290 
291 }
292 
294 {
295  ToolPtr refTool = trackingService()->getReferenceTool();
296  if(!refTool) // we only load reference points from reference tools
297  {
298  reportDebug("No reference tool, cannot load reference points into the pointsampler");
299  return;
300  }
301 
302  std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
303  if(referencePoints_s.empty())
304  {
305  reportWarning("No referenceppoints in reference tool "+refTool->getName());
306  return;
307  }
308 
309  CoordinateSystem ref = spaceProvider()->getR();
310  CoordinateSystem sensor = spaceProvider()->getS(refTool);
311 
312  std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
313  for(; it != referencePoints_s.end(); ++it)
314  {
315  Vector3D P_ref = spaceProvider()->get_toMfrom(sensor, ref).coord(it->second);
316  this->addPoint(P_ref);
317  }
318 }
319 
320 }//end namespace cx
QString qstring_cast(const T &val)
QVBoxLayout * mVerticalLayout
vertical layout is used
boost::shared_ptr< class ViewGroupData > ViewGroupDataPtr
Definition: cxViewGroup.h:50
QPushButton * mEditButton
the Edit Landmark button
One landmark, or fiducial, coordinate.
Definition: cxLandmark.h:61
QTableWidget * mTable
the table widget presenting the landmarks
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual QString defaultWhatsThis() const
Returns a short description of what this widget will do for you.
virtual void hideEvent(QHideEvent *event)
QString mActiveLandmark
uid of surrently selected landmark.
virtual void showEvent(QShowEvent *event)
updates internal info before showing the widget
static CoordinateSystem reference()
QPushButton * mRemoveButton
the Remove Landmark button
PointSamplingWidget(QWidget *parent)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
void setManualTool(const Vector3D &p_r)
Vector3d coord(const Vector3d &v) const
transform a coordinate [x,y,z,1].
Transform3D createTransformTranslate(const Vector3D &translation)
QPushButton * mLoadReferencePointsButton
button for loading a reference tools reference points
Identification of a Coordinate system.
cxLogicManager_EXPORT SpaceProviderPtr spaceProvider()
QPushButton * mAddButton
the Add Landmark button
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:108
cxLogicManager_EXPORT ViewServicePtr viewService()
cxLogicManager_EXPORT PatientModelServicePtr patientService()
RealScalar length() const
cxLogicManager_EXPORT TrackingServicePtr trackingService()
void reportDebug(QString msg)
Definition: cxLogger.cpp:89
boost::shared_ptr< class Tool > ToolPtr