CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxDummyTool.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 <boost/cstdint.hpp>
34 #include "cxDummyTool.h"
35 
36 #include <vtkPolyData.h>
37 #include <vtkAppendPolyData.h>
38 #include <vtkConeSource.h>
39 #include <vtkCylinderSource.h>
40 #include <QTimer>
41 #include <QTime>
42 #include <vtkPlane.h>
43 #include <vtkClipPolyData.h>
44 
45 #include "cxTimeKeeper.h"
46 
47 namespace cx
48 {
49 
50 ProbeDefinition DummyToolTestUtilities::createProbeData(ProbeDefinition::TYPE type, double depth, double width, Eigen::Array2i frameSize)
51 {
52  ProbeDefinition retval;
53  retval.setType(type);
54  Eigen::Array2i extent = frameSize - 1;
55  retval.setSector(0, depth, width, 0);
56 
57  Vector3D imageSpacing(width/extent[0], depth/extent[1], 1.0);
58  retval.setOrigin_p(Vector3D(frameSize[0]/2,0,0));
59  retval.setSpacing(imageSpacing);
60  retval.setClipRect_p(DoubleBoundingBox3D(0, extent[0], 0, extent[1], 0, 0));
61  retval.setSize(QSize(frameSize[0], frameSize[1]));
62 
63  return retval;
64 }
65 
66 ProbeDefinition DummyToolTestUtilities::createProbeDataLinear(double depth, double width, Eigen::Array2i frameSize)
67 {
68  return createProbeData(ProbeDefinition::tLINEAR, depth, width, frameSize);
69 }
70 
72 {
73  DummyToolPtr retval(new DummyTool());
74  retval->setProbeSector(probeData);
75  retval->setVisible(true);
76  retval->startTracking(30);
77  return retval;
78 }
79 
83 
84 int DummyTool::mTransformCount = 0;
85 
86 
87 
88 
89 DummyTool::DummyTool(const QString& uid) :
90  ToolImpl(uid),
91  mVisible(false),
92  mTransformSaveFileName("DummyToolsAreToDumbToSaveThemselves"),
93  mTimer(new QTimer()),
94  mThread(NULL)
95 {
96  qRegisterMetaType<Transform3D>("Transform3D");
97  mUid = uid;
98  mName = uid;
99 
100  DoubleBoundingBox3D bb(Vector3D(0,0,0), Vector3D(512,512,256));
102  mPolyData = this->createPolyData(150, 15, 4, 2);
103 
104  connect(mTimer.get(), SIGNAL(timeout()),this, SLOT(sendTransform()));
105 }
106 
108 {
109  this->stopThread();
110 }
111 
112 std::set<Tool::Type> DummyTool::getTypes() const
113 {
114  return mTypes;
115 }
116 
118 {
119  setToolPositionMovement(createToolPositionMovement(bb));
120 }
121 
122 std::vector<Transform3D> DummyTool::getToolPositionMovement()
123 {
124  return mTransforms;
125 }
126 
131 void DummyTool::setToolPositionMovement(const std::vector<Transform3D>& positions)
132 {
133  mTransforms = positions;
134 }
135 
137 {
138  mTypes.clear();
139  mTypes.insert(type);
140 }
141 
143 {
144  return mPolyData;
145 }
146 void DummyTool::setTransformSaveFile(const QString& filename)
147 {
148  mTransformSaveFileName = filename;
149 }
150 
152 {
153  return mVisible;
154 }
155 QString DummyTool::getUid() const
156 {
157  return mUid;
158 }
159 QString DummyTool::getName() const
160 {
161  return mName;
162 }
163 void DummyTool::startTracking(int interval)
164 {
165  mThread = new DummyToolThread(interval);
166  connect(mThread, SIGNAL(ping()), this, SLOT(sendTransform()));
167  mThread->start();
168 
169 
170 // mTimer->start(interval);
171 //std::cout << "start tracking" << std::endl;
172  mVisible = true;
173 
174  emit toolVisible(mVisible);
175 }
177 {
178  return true;
179 }
180 
181 void DummyTool::stopThread()
182 {
183  if (!mThread)
184  {
185  return;
186  }
187  disconnect(mThread, SIGNAL(ping()), this, SLOT(sendTransform()));
188 
189  mThread->quit();
190  mThread->wait(2000); // forever or until dead thread
191 
192  if (mThread->isRunning())
193  {
194  mThread->terminate();
195  mThread->wait(); // forever or until dead thread
196  }
197  mThread = NULL;
198 }
199 
201 {
202  this->stopThread();
203 
204 // std::cout << "stop tracking" << std::endl;
205 
206  mVisible = false;
207  emit toolVisible(mVisible);
208 }
209 
210 void DummyTool::setVisible(bool val)
211 {
212  mVisible = val;
213  emit toolVisible(mVisible);
214 }
215 void DummyTool::sendTransform()
216 {
217  set_prMt(*getNextTransform());
218 // std::cout << "DummyTool::sendTransform(): " << this->get_prMt().coord(Vector3D(0,0,0)) << std::endl;
219 }
220 
226 vtkPolyDataPtr DummyTool::createPolyData(double h1, double h2, double r1, double r2)
227 {
228 
229 // double r1 = 10;
230 // double r2 = 3;
231 // double h1 = 140;
232 // double h2 = 10;
233 
234  vtkAppendPolyDataPtr assembly = vtkAppendPolyDataPtr::New();
235 
236  vtkPlanePtr plane = vtkPlanePtr::New();
237  plane->SetNormal(0,0,-1);
238  plane->SetOrigin(0,0,-h2);
239 
240  vtkConeSourcePtr cone1 = vtkConeSourcePtr::New();
241  double h1_extension = h1*r2 / (r1-r2);
242  double h1_mod = h1+h1_extension;
243  cone1->SetResolution(50);
244  cone1->SetRadius(r1);
245  cone1->SetHeight(h1_mod);
246  cone1->SetDirection(0,0,1);
247  double center1 = -h1/2-h2+h1_extension/2;
248  cone1->SetCenter(Vector3D(0,0,center1).begin());
249 
250  vtkClipPolyDataPtr clipper1 = vtkClipPolyDataPtr::New();
251  clipper1->SetInputConnection(cone1->GetOutputPort());
252  clipper1->SetClipFunction(plane);
253 
254  vtkConeSourcePtr cone2 = vtkConeSourcePtr::New();
255  cone2->SetResolution(25);
256  cone2->SetRadius(r2);
257  cone2->SetHeight(h2);
258  cone2->SetDirection(0,0,1);
259  double center2 = -h2/2;
260  cone2->SetCenter(Vector3D(0,0,center2).begin());
261 
262  assembly->AddInputConnection(clipper1->GetOutputPort());
263  assembly->AddInputConnection(cone2->GetOutputPort());
264 // mPolyData = assembly->GetOutput();
265  assembly->Update();
266  return assembly->GetOutput();
267 }
268 
269 void DummyTool::createLinearMovement(std::vector<Transform3D>* retval, Transform3D* T_in, const Transform3D& R, const Vector3D& a, const Vector3D& b, double step) const
270 {
271  Vector3D u = (b-a).normal();
272  //No round in Windows
273  //unsigned N = (unsigned)round((b-a).length()/step);
274  unsigned N = (unsigned)floor((b-a).length()/step + 0.5);
275  Transform3D& T = *T_in;
276 
277  for (unsigned i=0; i<N; ++i)
278  {
279  Transform3D T_delta = createTransformTranslate(u*step);
280  T = T_delta * T;
281  retval->push_back(T * R);
282  }
283 }
284 
287 std::vector<Transform3D> DummyTool::createToolPositionMovement(const DoubleBoundingBox3D& bb) const
288 {
289 // std::cout<<"createToolPositionMovement:"<<bb<<std::endl;
290  std::vector<Transform3D> retval;
291 
292  Vector3D range = bb.range();
293  // define four points. Traverse them and then back to the starting point.
294  Vector3D a = bb.center() + Vector3D(range[0]/2, 0, 0);
295  Vector3D b = bb.center();
296  Vector3D c = b + Vector3D(0, -range[0]*0.1, 0);
297  Vector3D d = c + Vector3D(0, 0, range[2]/2);
298 
299 // Vector3D a = bb.corner(0,0,0);
300 // Vector3D b = bb.corner(1,0,0);
301 // Vector3D c = bb.corner(1,1,0);
302 // Vector3D d = bb.corner(1,1,1);
303 
304 // std::cout << "a" << a << std::endl;
305 // std::cout << "b" << b << std::endl;
306 // std::cout << "c" << c << std::endl;
307 // std::cout << "d" << d << std::endl;
308 
309  int steps = 200;
310  double step = *std::max_element(range.begin(), range.end()) / steps;
311 
315 
316  createLinearMovement(&retval, &T, R, a, b, step);
317 
318  for (unsigned i=0; i<50; ++i)
319  {
320  Transform3D r_delta = createTransformRotateZ(-M_PI*0.01);
321  R = r_delta * R;
322  retval.push_back(T * R);
323  }
324 
325  createLinearMovement(&retval, &T, R, b, c, step);
326 
327  for (unsigned i=0; i<50; ++i)
328  {
329  Transform3D r_delta = createTransformRotateZ(-M_PI*0.01);
330  R = r_delta * R;
331  retval.push_back(T * R);
332  }
333 
334  createLinearMovement(&retval, &T, R, c, d, step);
335  createLinearMovement(&retval, &T, R, d, a, step);
336 
337  for (unsigned i=0; i<20; ++i)
338  {
339  Transform3D r_delta = createTransformRotateZ(-M_PI/20);
340  R = r_delta * R;
341  retval.push_back(T * R);
342  }
343 
344  return retval;
345 }
346 
350 {
351  std::vector<Transform3D> retval;
352 
353  Vector3D range = bb.range();
354  // define four points. Traverse them and then back to the starting point.
355 // Vector3D a = bb.center() + Vector3D(range[0]/2, range[0]/10, range[0]/10);
356 // Vector3D b = bb.center();
357 // Vector3D c = b + Vector3D(-range[0]*0.1, -range[0]*0.1, -range[0]*0.1);
358 // Vector3D d = c + Vector3D(range[0]*0.1, range[0]*0.1, range[2]/3);
359  Vector3D a = bb.center() + Vector3D( range[0]*0.4, range[1]*0.4, range[2]*0.4);
360  Vector3D b = bb.center();
361  Vector3D c = bb.center() + Vector3D(-range[0]*0.4, -range[1]*0.1, -range[2]*0.1);
362  Vector3D d = bb.center() + Vector3D( range[0]*0.0, range[1]*0.1, range[2]*0.3);
363 
364  int steps = 200;
365  double step = *std::max_element(range.begin(), range.end()) / steps;
366 
370 
371  createLinearMovement(&retval, &T, R, a, b, step);
372  createLinearMovement(&retval, &T, R, b, c, step);
373  createLinearMovement(&retval, &T, R, c, d, step);
374  createLinearMovement(&retval, &T, R, d, a, step);
375 
376  return retval;
377 }
378 
379 
380 Transform3D* DummyTool::getNextTransform()
381 {
382  if(mTransformCount >= int(mTransforms.size()))
383  mTransformCount = 0;
384 
385  return &mTransforms.at(mTransformCount++);
386 }
387 
389 {
390  double timestamp = this->getTimestamp();
391  ToolImpl::set_prMt(prMt, timestamp);
392 }
393 
395 {
396  return createTransformTranslate(Vector3D(5,5,20));
397 }
398 
399 
400 }//namespace cx
void setToolPositionMovement(const std::vector< Transform3D > &positions)
static ProbeDefinition createProbeDataLinear(double depth=40, double width=50, Eigen::Array2i frameSize=Eigen::Array2i(80, 40))
Definition: cxDummyTool.cpp:66
void setVisible(bool val)
if available for this type, set visibility
void setType(TYPE type)
PlainObject normal() const
Scalar * begin()
void setSpacing(Vector3D spacing)
void setToolPositionMovementBB(const DoubleBoundingBox3D &bb)
std::vector< Transform3D > getToolPositionMovement()
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
void set_prMt(const Transform3D &ptMt)
Common functionality for Tool subclasses.
Definition: cxToolImpl.h:50
virtual Transform3D getCalibration_sMt() const
get the calibration transform from tool space to sensor space (where the spheres or similar live) ...
US beam is emitted straight forward.
Definition: cxProbeData.h:125
vtkSmartPointer< class vtkAppendPolyData > vtkAppendPolyDataPtr
virtual vtkPolyDataPtr getGraphicsPolyData() const
get geometric 3D description
static DummyToolPtr createDummyTool(ProbeDefinition probeData=ProbeDefinition())
Definition: cxDummyTool.cpp:71
void setSector(double depthStart, double depthEnd, double width, double centerOffset=0)
virtual bool isCalibrated() const
a tool may not be calibrated, then no tracking i allowed
vtkSmartPointer< class vtkClipPolyData > vtkClipPolyDataPtr
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
Definition: cxProbeSector.h:47
QString mUid
Definition: cxTool.h:149
boost::shared_ptr< class DummyTool > DummyToolPtr
void toolVisible(bool visible)
void setOrigin_p(Vector3D origin_p)
QString mName
Definition: cxTool.h:150
DummyTool(const QString &uid="dummytool")
Definition: cxDummyTool.cpp:89
virtual double getTimestamp() const
latest valid timestamp for the position matrix. 0 means indeterminate (for f.ex. manual tools) ...
Definition: cxDummyTool.h:203
void setClipRect_p(DoubleBoundingBox3D clipRect_p)
Transform3D createTransformTranslate(const Vector3D &translation)
static ProbeDefinition createProbeData(ProbeDefinition::TYPE, double depth=40, double width=50, Eigen::Array2i frameSize=Eigen::Array2i(80, 40))
Definition: cxDummyTool.cpp:50
virtual QString getName() const
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
Implementation of a Tool used for testing.
Definition: cxDummyTool.h:170
vtkSmartPointer< class vtkConeSource > vtkConeSourcePtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Definition of characteristics for an Ultrasound Probe Sector.
Definition: cxProbeData.h:120
virtual void setTransformSaveFile(const QString &filename)
Vector3D center() const
virtual QString getUid() const
Transform3D createTransformRotateZ(const double angle)
virtual void set_prMt(const Transform3D &prMt, double timestamp)
if available for this type, set pos, ts<0 means use current time
Definition: cxToolImpl.cpp:84
virtual bool getVisible() const
static vtkPolyDataPtr createPolyData(double h1, double h2, double r1, double r2)
Transform3D createTransformRotateX(const double angle)
virtual void setType(Type)
vtkSmartPointer< class vtkPlane > vtkPlanePtr
void setSize(QSize size)
void startTracking(int interval=33)
void stopTracking()
std::vector< Transform3D > createToolPositionMovementTranslationOnly(const DoubleBoundingBox3D &bb) const
#define M_PI
virtual std::set< Type > getTypes() const