CustusX  16.5.0-rc9
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 {
66  this->setToolTip("Sample and store points");
68 
69  //table widget
70  connect(mTable, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
71 
72  this->setLayout(mVerticalLayout);
73 
74  //pushbuttons
75  connect(mAddButton, SIGNAL(clicked()), this, SLOT(addButtonClickedSlot()));
76  mEditButton->setDisabled(true);
77  connect(mEditButton, SIGNAL(clicked()), this, SLOT(editButtonClickedSlot()));
78  mRemoveButton->setDisabled(true);
79  connect(mRemoveButton, SIGNAL(clicked()), this, SLOT(removeButtonClickedSlot()));
80  connect(mLoadReferencePointsButton, SIGNAL(clicked()), this, SLOT(loadReferencePointsSlot()));
81 
82  //layout
83  mVerticalLayout->addWidget(mTable);
84 
85  QHBoxLayout* buttonLayout = new QHBoxLayout;
86  mVerticalLayout->addLayout(buttonLayout);
87 
88  buttonLayout->addWidget(mAddButton);
89  buttonLayout->addWidget(mEditButton);
90  buttonLayout->addWidget(mRemoveButton);
92 }
93 
95 {}
96 
98 {
99  //std::cout << "pling" << std::endl;
100 
101  QTableWidgetItem* item = mTable->currentItem();
102 
103  mActiveLandmark = item->data(Qt::UserRole).toString();
104 
105  for (unsigned i=0; i<mSamples.size(); ++i)
106  {
107  if (mSamples[i].getUid()!=mActiveLandmark)
108  continue;
109  setManualTool(mSamples[i].getCoord());
110  break;
111  }
112 
113  enablebuttons();
114 }
115 
116 void PointSamplingWidget::showEvent(QShowEvent* event)
117 {
118  QWidget::showEvent(event);
119 
120  ViewGroupDataPtr data = viewService()->getGroup(0);
121  ViewGroupData::Options options = data->getOptions();
122  options.mShowPointPickerProbe = true;
123  data->setOptions(options);
124 
125  this->updateSlot();
126 }
127 
128 void PointSamplingWidget::hideEvent(QHideEvent* event)
129 {
130  QWidget::hideEvent(event);
131 }
132 
134 {
135  mTable->blockSignals(true);
136  mTable->clear();
137 
138  //ready the table widget
139  mTable->setRowCount(mSamples.size());
140  mTable->setColumnCount(3);
141  QStringList headerItems(QStringList() << "Name" << "Coordinates(r)" << "Delta (mm)");
142  mTable->setHorizontalHeaderLabels(headerItems);
143  mTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
144  mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
145 
146  for (unsigned i = 0; i < mSamples.size(); ++i)
147  {
148  std::vector<QTableWidgetItem*> items(3); // name, coordinates, delta
149 
150  Vector3D coord = mSamples[i].getCoord();
151 
152  items[0] = new QTableWidgetItem(qstring_cast(mSamples[i].getUid()));
153 
154  QString coordText;
155  int width = 5;
156  int prec = 1;
157  coordText = tr("(%1, %2, %3)").arg(coord[0], width, 'f', prec).arg(coord[1], width, 'f', prec).arg(coord[2],
158  width, 'f', prec);
159 
160  items[1] = new QTableWidgetItem(coordText);
161 
162  if (i==0)
163  {
164  items[2] = new QTableWidgetItem;
165  }
166  else
167  {
168  double delta = (mSamples[i].getCoord() - mSamples[0].getCoord()).length();
169  items[2] = new QTableWidgetItem(tr("%1").arg(delta, width, 'f', prec));
170  }
171 
172  for (unsigned j = 0; j < items.size(); ++j)
173  {
174  items[j]->setData(Qt::UserRole, qstring_cast(mSamples[i].getUid()));
175  mTable->setItem(i, j, items[j]);
176  }
177 
178  //highlight selected row
179  if (mSamples[i].getUid() == mActiveLandmark)
180  {
181  mTable->setCurrentItem(items[1]);
182  }
183  }
184 
185  mTable->blockSignals(false);
186 
187  this->enablebuttons();
188 }
189 
191 {
192  mAddButton->setEnabled(true);
193  mEditButton->setEnabled(mActiveLandmark!="");
194  mRemoveButton->setEnabled(mActiveLandmark!="");
195  mLoadReferencePointsButton->setEnabled(trackingService()->getReferenceTool() ? true : false);
196 }
197 
199 {
200  // find unique uid:
201  int max = 0;
202  for (unsigned i=0; i<mSamples.size(); ++i)
203  {
204  max = std::max(max, qstring_cast(mSamples[i].getUid()).toInt());
205  }
206  QString uid = qstring_cast(max+1);
207 
208  mSamples.push_back(Landmark(uid, point));
209  mActiveLandmark = uid;
210 
211  this->updateSlot();
212 }
213 
215 {
216  ToolPtr tool = trackingService()->getManualTool();
217 
218  //Transform3D sMr = mSliceProxy->get_sMr();
219  Transform3D rMpr = patientService()->get_rMpr();
220  Transform3D prMt = tool->get_prMt();
221 
222  // find tool position in r
223  Vector3D tool_t(0,0,tool->getTooltipOffset());
224  Vector3D tool_r = (rMpr*prMt).coord(tool_t);
225 
226  // find click position in s.
227  //Vector3D click_s = get_vpMs().inv().coord(click_vp);
228 
229  // compute the new tool position in slice space as a synthesis of the plane part of click and the z part of original.
230  //Vector3D cross_s(click_s[0], click_s[1], tool_s[2]);
231  // compute the position change and transform to patient.
232  Vector3D delta_r = p_r - tool_r;
233  Vector3D delta_pr = rMpr.inv().vector(delta_r);
234 
235  // MD is the actual tool movement in patient space, matrix form
236  Transform3D MD = createTransformTranslate(delta_pr);
237  // set new tool position to old modified by MD:
238  tool->set_prMt(MD*prMt);
239 }
240 
242 {
243  this->addPoint(this->getSample());
244 }
245 
247 {
248 // CoordinateSystem ref = spaceProvider()->getR();
249  Vector3D P_ref = spaceProvider()->getActiveToolTipPoint(CoordinateSystem::reference(), true);
250 
251  return P_ref;
252 }
253 
255 {
256  for (unsigned i=0; i<mSamples.size(); ++i)
257  {
258  if (mSamples[i].getUid()!=mActiveLandmark)
259  continue;
261  }
262  updateSlot();
263 }
264 
266 {
267  for (unsigned i=0; i<mSamples.size(); ++i)
268  {
269  if (mSamples[i].getUid()!=mActiveLandmark)
270  continue;
271  mSamples.erase(mSamples.begin()+i);
272  mActiveLandmark = "";
273  if (i<mSamples.size())
274  mActiveLandmark = mSamples[i].getUid();
275  break;
276  }
277  updateSlot();
278 }
279 
281 {
282 
283 }
284 
286 {
287  ToolPtr refTool = trackingService()->getReferenceTool();
288  if(!refTool) // we only load reference points from reference tools
289  {
290  reportDebug("No reference tool, cannot load reference points into the pointsampler");
291  return;
292  }
293 
294  std::map<int, Vector3D> referencePoints_s = refTool->getReferencePoints();
295  if(referencePoints_s.empty())
296  {
297  reportWarning("No referenceppoints in reference tool "+refTool->getName());
298  return;
299  }
300 
301  CoordinateSystem ref = spaceProvider()->getR();
302  CoordinateSystem sensor = spaceProvider()->getS(refTool);
303 
304  std::map<int, Vector3D>::iterator it = referencePoints_s.begin();
305  for(; it != referencePoints_s.end(); ++it)
306  {
307  Vector3D P_ref = spaceProvider()->get_toMfrom(sensor, ref).coord(it->second);
308  this->addPoint(P_ref);
309  }
310 }
311 
312 }//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 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)
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