Fraxinus  16.5.0-fx-rc8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxLandmarkRep.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 "cxLandmarkRep.h"
34 
35 #include <sstream>
36 #include <vtkMath.h>
37 #include <vtkImageData.h>
38 #include <vtkDoubleArray.h>
39 #include <vtkVectorText.h>
40 #include <vtkFollower.h>
41 #include <vtkSphereSource.h>
42 #include <vtkPolyDataMapper.h>
43 #include <vtkProperty.h>
44 #include <vtkRenderer.h>
45 #include <vtkRenderWindow.h>
46 #include "cxView.h"
47 #include "cxLandmark.h"
48 
49 #include "cxPatientModelService.h"
50 #include "cxTypeConversions.h"
51 #include "boost/bind.hpp"
52 #include "cxVtkHelperClasses.h"
53 
54 namespace cx
55 {
56 
58 {
59  connect(mDataManager->getPatientLandmarks().get(), SIGNAL(landmarkAdded(QString)), this, SIGNAL(changed()));
60  connect(mDataManager->getPatientLandmarks().get(), SIGNAL(landmarkRemoved(QString)), this, SIGNAL(changed()));
61  connect(mDataManager.get(), SIGNAL(rMprChanged()), this, SIGNAL(changed()));
62 }
64 {
65  return mDataManager->getPatientLandmarks()->getLandmarks();
66 }
68 {
69  return mDataManager->get_rMpr();
70 }
71 // --------------------------------------------------------
73 {
74  return p_l;
75 }
76 // --------------------------------------------------------
77 
78 // --------------------------------------------------------
79 // --------------------------------------------------------
80 // --------------------------------------------------------
81 
83 {
84 }
85 
87 {
88  return mData;
89 }
90 
92 {
93  if (image == mData)
94  return;
95 
96  if (mData)
97  {
98  disconnect(mData->getLandmarks().get(), SIGNAL(landmarkAdded(QString)), this, SIGNAL(changed()));
99  disconnect(mData->getLandmarks().get(), SIGNAL(landmarkRemoved(QString)), this, SIGNAL(changed()));
100  disconnect(mData.get(), SIGNAL(transformChanged()), this, SIGNAL(changed()));
101  }
102 
103  mData = image;
104 
105  if (mData)
106  {
107  connect(mData->getLandmarks().get(), SIGNAL(landmarkAdded(QString)), this, SIGNAL(changed()));
108  connect(mData->getLandmarks().get(), SIGNAL(landmarkRemoved(QString)), this, SIGNAL(changed()));
109  connect(mData.get(), SIGNAL(transformChanged()), this, SIGNAL(changed()));
110  }
111 
112  emit changed();
113 }
114 
116 {
117  if (!mData)
118  return LandmarkMap();
119  return mData->getLandmarks()->getLandmarks();
120 }
121 
123 {
124  if (!mData)
125  return Transform3D::Identity();
126  return mData->get_rMd();
127 }
128 
130 {
131  Vector3D imageCenter = mData->boundingBox().center();
132  Vector3D centerToSkinVector = (p_l - imageCenter).normal();
133  Vector3D numberPosition = p_l + 10.0 * centerToSkinVector;
134  return numberPosition;
135 }
136 
137 // --------------------------------------------------------
138 // --------------------------------------------------------
139 // --------------------------------------------------------
140 
142 {
143  return wrap_new(new LandmarkRep(dataManager), uid);
144 }
145 
146 LandmarkRep::LandmarkRep(PatientModelServicePtr dataManager) :
147  RepImpl(),
148  mDataManager(dataManager),
149  mInactiveColor(QColor::fromRgbF(0.5,0.5,0.5)),
150  mColor(QColor(Qt::green)),
151  // mSecondaryColor(0,0.6,0.8),
152  mSecondaryColor(QColor::fromRgbF(0, 0.9, 0.5)),
153  mShowLandmarks(true),
154  mGraphicsSize(1),
155  mLabelSize(2.5)
156 {
157  connect(mDataManager.get(), SIGNAL(landmarkPropertiesChanged()), this, SLOT(internalUpdate()));
158 
160  mViewportListener->setCallback(boost::bind(&LandmarkRep::rescale, this));
161 }
162 
164 {
165 }
166 
168 {
169 // std::cout << this << " LandmarkRep::setPrimarySource " << primary.get() << std::endl;
170 
171  if (mPrimary)
172  disconnect(mPrimary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
173  mPrimary = primary;
174  if (mPrimary)
175  connect(mPrimary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
176 
177  this->internalUpdate();
178 }
179 
181 {
182  if (mSecondary)
183  disconnect(mSecondary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
184  mSecondary = secondary;
185  if (mSecondary)
186  connect(mSecondary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
187 
188  this->internalUpdate();
189 }
190 
191 void LandmarkRep::setColor(QColor color)
192 {
193  mColor = color;
194  this->internalUpdate();
195 }
196 
198 {
199  mSecondaryColor = color;
200  this->internalUpdate();
201 }
202 
204 {
205  mGraphicsSize = size;
206  this->internalUpdate();
207 }
208 
209 void LandmarkRep::setLabelSize(double size)
210 {
211  mLabelSize = size;
212  this->internalUpdate();
213 }
214 
216 {
217  if (on == mShowLandmarks)
218  return;
219 
220  for (LandmarkGraphicsMapType::iterator iter = mGraphics.begin(); iter != mGraphics.end(); ++iter)
221  {
222  if (iter->second.mPrimaryPoint)
223  iter->second.mPrimaryPoint->getActor()->SetVisibility(on);
224  if (iter->second.mSecondaryPoint)
225  iter->second.mSecondaryPoint->getActor()->SetVisibility(on);
226  if (iter->second.mText)
227  iter->second.mText->getActor()->SetVisibility(on);
228  if (iter->second.mLine)
229  iter->second.mLine->getActor()->SetVisibility(on);
230  }
231  mShowLandmarks = on;
232 }
233 
235 {
236 // std::cout << this << " LandmarkRep::addLandmark ADD ALL" << std::endl;
237 
238  LandmarkPropertyMap props = mDataManager->getLandmarkProperties();
239 
240  for (LandmarkPropertyMap::iterator it = props.begin(); it != props.end(); ++it)
241  {
242  this->addLandmark(it->first);
243  }
244 }
245 
247 {
248 // std::cout << this << " LandmarkRep::internalUpdate()" << std::endl;
249 
250  this->clearAll();
251  this->addAll();
252 }
253 
255 {
256 // std::cout << this << " LandmarkRep::addLandmark CLEAR ALL" << std::endl;
257  mGraphics.clear();
258 }
259 
261 {
262  if (!view || !view->getRenderer())
263  return;
264 
265  this->addAll();
266  mViewportListener->startListen(view->getRenderer());
267 }
268 
270 {
271  this->clearAll();
272  mViewportListener->stopListen();
273 }
274 
278 void LandmarkRep::addLandmark(QString uid)
279 {
280 // std::cout << this << " LandmarkRep::addLandmark init" << uid << std::endl;
281  vtkRendererPtr renderer = this->getRenderer();
282 
283  LandmarkProperty property = mDataManager->getLandmarkProperties()[uid];
284  if (property.getUid().isEmpty())
285  {
286 // std::cout << "LandmarkRep::addLandmark CLEAR" << uid << std::endl;
287  mGraphics.erase(uid);
288  return;
289  }
290 
291  double radius = 2;
292  QColor color = mColor;
293  QColor secondaryColor = mSecondaryColor;
294 
295  if (!property.getActive())
296  {
297  radius = 1;
298  color = mInactiveColor;
299  secondaryColor = mInactiveColor;
300  }
301 
302  LandmarkGraphics current;
303 
304  // primary point
305  Landmark primary;
306  Vector3D primary_r(0, 0, 0);
307  if (mPrimary)
308  {
309 // std::cout << this << " LandmarkRep::addLandmark found mPrimary" << uid << std::endl;
310  primary = mPrimary->getLandmarks()[uid];
311  if (!primary.getUid().isEmpty())
312  {
313 // std::cout << this << " LandmarkRep::addLandmark" << uid << std::endl;
314 
315  primary_r = mPrimary->get_rMl().coord(primary.getCoord());
316 
317  current.mPrimaryPoint.reset(new GraphicalPoint3D(renderer));
318  current.mPrimaryPoint->setColor(color);
319  current.mPrimaryPoint->setRadius(radius);
320 
321  current.mText.reset(new FollowerText3D(renderer));
322  current.mText->setText(property.getName());
323  current.mText->setSizeInNormalizedViewport(true, 0.025);
324  current.mText->setColor(color);
325 
326  Vector3D text_r = mPrimary->get_rMl().coord(mPrimary->getTextPos(primary.getCoord()));
327 
328  current.mPrimaryPoint->setValue(primary_r);
329  current.mText->setPosition(text_r);
330  }
331  }
332 
333  // secondary point
334  Vector3D secondary_r(0, 0, 0);
335  Landmark secondary;
336  if (mSecondary)
337  {
338  secondary = mSecondary->getLandmarks()[uid];
339  if (!secondary.getUid().isEmpty())
340  {
341  secondary_r = mSecondary->get_rMl().coord(secondary.getCoord());
342 
343  current.mSecondaryPoint.reset(new GraphicalPoint3D(renderer));
344  current.mSecondaryPoint->setColor(secondaryColor);
345  current.mSecondaryPoint->setRadius(radius);
346  current.mSecondaryPoint->setValue(secondary_r);
347  }
348  }
349 
350  // connecting line
351  if (!secondary.getUid().isEmpty() && !secondary.getUid().isEmpty())
352  {
353  current.mLine.reset(new GraphicalLine3D(renderer));
354  current.mLine->setColor(secondaryColor);
355  current.mLine->setStipple(0x0F0F);
356 
357  current.mLine->setValue(primary_r, secondary_r);
358  }
359 
360  mGraphics[uid] = current;
361  this->rescale();
362 }
363 
365 {
366  if (!mViewportListener->isListening())
367  return;
368  double size = mViewportListener->getVpnZoom();
369  double sphereSize = mGraphicsSize / 100 / size;
370 
371  for (LandmarkGraphicsMapType::iterator iter = mGraphics.begin(); iter != mGraphics.end(); ++iter)
372  {
373  if (iter->second.mSecondaryPoint)
374  iter->second.mSecondaryPoint->setRadius(sphereSize);
375  if (iter->second.mPrimaryPoint)
376  iter->second.mPrimaryPoint->setRadius(sphereSize);
377  }
378 }
379 
380 } //namespace cx
virtual void addRepActorsToViewRenderer(ViewPtr view)
QString getUid() const
Definition: cxLandmark.cpp:54
static LandmarkRepPtr New(PatientModelServicePtr dataManager, const QString &uid="")
bool mShowLandmarks
whether or not the actors should be showed in (all) views
virtual Vector3D getTextPos(Vector3D p_l) const
vtkRendererPtr getRenderer()
Definition: cxRepImpl.cpp:109
void internalUpdate()
updates the text, color, scale etc
PatientLandmarksSource(PatientModelServicePtr dataManager)
PlainObject normal() const
One landmark, or fiducial, coordinate.
Definition: cxLandmark.h:61
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual Vector3D getTextPos(Vector3D p_l) const
LandmarksSourcePtr mSecondary
virtual ~LandmarkRep()
static boost::shared_ptr< REP > wrap_new(REP *object, QString uid)
Definition: cxRepImpl.h:83
void setGraphicsSize(double size)
Helper for rendering a point in 3D.
boost::shared_ptr< class View > ViewPtr
void showLandmarks(bool on)
turn on or off showing landmarks
void addLandmark(QString uid)
Listens to changes in viewport and camera matrix.
ViewportListenerPtr mViewportListener
boost::shared_ptr< class Data > DataPtr
QColor mSecondaryColor
color used on the secondary coordinate
virtual Transform3D get_rMl() const
QColor mInactiveColor
color given to inactive landmarks
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
LandmarksSourcePtr mPrimary
void setSecondarySource(LandmarksSourcePtr secondary)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
Helper for rendering a line in 3D.
void setPrimarySource(LandmarksSourcePtr primary)
void setColor(QColor color)
sets the reps color
GraphicalLine3DPtr mLine
line between primary and secondary point
virtual LandmarkMap getLandmarks() const
Default implementation of Rep.
Definition: cxRepImpl.h:63
Vector3D getCoord() const
Definition: cxLandmark.cpp:59
GraphicalPoint3DPtr mPrimaryPoint
the primary coordinate of the landmark
void setData(DataPtr image)
Helper for rendering 3D text that faces the camera and has a constant viewed size.
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
FollowerText3DPtr mText
name of landmark, attached to primary point
boost::shared_ptr< LandmarksSource > LandmarksSourcePtr
Definition: cxLandmarkRep.h:72
std::map< QString, class Landmark > LandmarkMap
QColor mColor
the color of the landmark actors
void setLabelSize(double size)
void setSecondaryColor(QColor color)
sets the reps color
LandmarkGraphicsMapType mGraphics
std::map< QString, LandmarkProperty > LandmarkPropertyMap
Definition: cxLandmark.h:129
virtual Transform3D get_rMl() const
GraphicalPoint3DPtr mSecondaryPoint
secondary landmark coordinate, accosiated with the primary point
PatientModelServicePtr mDataManager
boost::shared_ptr< class LandmarkRep > LandmarkRepPtr
virtual LandmarkMap getLandmarks() const
virtual void removeRepActorsFromViewRenderer(ViewPtr view)