CustusX  2023.01.05-dev+develop.0da12
An IGT application
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) 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 
12 #include "cxLandmarkRep.h"
13 
14 #include <sstream>
15 #include <vtkMath.h>
16 #include <vtkImageData.h>
17 #include <vtkDoubleArray.h>
18 #include <vtkVectorText.h>
19 #include <vtkFollower.h>
20 #include <vtkSphereSource.h>
21 #include <vtkPolyDataMapper.h>
22 #include <vtkProperty.h>
23 #include <vtkRenderer.h>
24 #include <vtkRenderWindow.h>
25 #include "cxView.h"
26 #include "cxLandmark.h"
27 
28 #include "cxPatientModelService.h"
29 #include "cxTypeConversions.h"
30 #include "boost/bind.hpp"
31 #include "cxVtkHelperClasses.h"
32 
33 namespace cx
34 {
35 
37 {
38  connect(mDataManager->getPatientLandmarks().get(), SIGNAL(landmarkAdded(QString)), this, SIGNAL(changed()));
39  connect(mDataManager->getPatientLandmarks().get(), SIGNAL(landmarkRemoved(QString)), this, SIGNAL(changed()));
40  connect(mDataManager.get(), SIGNAL(rMprChanged()), this, SIGNAL(changed()));
41 }
43 {
44  return mDataManager->getPatientLandmarks()->getLandmarks();
45 }
47 {
48  return mDataManager->get_rMpr();
49 }
50 // --------------------------------------------------------
52 {
53  return p_l;
54 }
55 // --------------------------------------------------------
56 
57 // --------------------------------------------------------
58 // --------------------------------------------------------
59 // --------------------------------------------------------
60 
62 {
63 }
64 
66 {
67  return mData;
68 }
69 
71 {
72  if (image == mData)
73  return;
74 
75  if (mData)
76  {
77  disconnect(mData->getLandmarks().get(), SIGNAL(landmarkAdded(QString)), this, SIGNAL(changed()));
78  disconnect(mData->getLandmarks().get(), SIGNAL(landmarkRemoved(QString)), this, SIGNAL(changed()));
79  disconnect(mData.get(), SIGNAL(transformChanged()), this, SIGNAL(changed()));
80  }
81 
82  mData = image;
83 
84  if (mData)
85  {
86  connect(mData->getLandmarks().get(), SIGNAL(landmarkAdded(QString)), this, SIGNAL(changed()));
87  connect(mData->getLandmarks().get(), SIGNAL(landmarkRemoved(QString)), this, SIGNAL(changed()));
88  connect(mData.get(), SIGNAL(transformChanged()), this, SIGNAL(changed()));
89  }
90 
91  emit changed();
92 }
93 
95 {
96  if (!mData)
97  return LandmarkMap();
98  return mData->getLandmarks()->getLandmarks();
99 }
100 
102 {
103  if (!mData)
104  return Transform3D::Identity();
105  return mData->get_rMd();
106 }
107 
109 {
110  Vector3D imageCenter = mData->boundingBox().center();
111  Vector3D centerToSkinVector = (p_l - imageCenter).normal();
112  Vector3D numberPosition = p_l + 10.0 * centerToSkinVector;
113  return numberPosition;
114 }
115 
116 // --------------------------------------------------------
117 // --------------------------------------------------------
118 // --------------------------------------------------------
119 
121 {
122  return wrap_new(new LandmarkRep(dataManager), uid);
123 }
124 
125 LandmarkRep::LandmarkRep(PatientModelServicePtr dataManager) :
126  RepImpl(),
127  mDataManager(dataManager),
128  mInactiveColor(QColor::fromRgbF(0.5,0.5,0.5)),
129  mColor(QColor(Qt::green)),
130  // mSecondaryColor(0,0.6,0.8),
131  mSecondaryColor(QColor::fromRgbF(0, 0.9, 0.5)),
132  mShowLandmarks(true),
133  mGraphicsSize(1),
134  mLabelSize(2.5)
135 {
136  connect(mDataManager.get(), SIGNAL(landmarkPropertiesChanged()), this, SLOT(internalUpdate()));
137 
139  mViewportListener->setCallback(boost::bind(&LandmarkRep::rescale, this));
140 }
141 
143 {
144 }
145 
147 {
148 // std::cout << this << " LandmarkRep::setPrimarySource " << primary.get() << std::endl;
149 
150  if (mPrimary)
151  disconnect(mPrimary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
152  mPrimary = primary;
153  if (mPrimary)
154  connect(mPrimary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
155 
156  this->internalUpdate();
157 }
158 
160 {
161  if (mSecondary)
162  disconnect(mSecondary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
163  mSecondary = secondary;
164  if (mSecondary)
165  connect(mSecondary.get(), SIGNAL(changed()), this, SLOT(internalUpdate()));
166 
167  this->internalUpdate();
168 }
169 
170 void LandmarkRep::setColor(QColor color)
171 {
172  mColor = color;
173  this->internalUpdate();
174 }
175 
177 {
178  mSecondaryColor = color;
179  this->internalUpdate();
180 }
181 
183 {
184  mGraphicsSize = size;
185  this->internalUpdate();
186 }
187 
188 void LandmarkRep::setLabelSize(double size)
189 {
190  mLabelSize = size;
191  this->internalUpdate();
192 }
193 
195 {
196  if (on == mShowLandmarks)
197  return;
198 
199  for (LandmarkGraphicsMapType::iterator iter = mGraphics.begin(); iter != mGraphics.end(); ++iter)
200  {
201  if (iter->second.mPrimaryPoint)
202  iter->second.mPrimaryPoint->getActor()->SetVisibility(on);
203  if (iter->second.mSecondaryPoint)
204  iter->second.mSecondaryPoint->getActor()->SetVisibility(on);
205  if (iter->second.mText)
206  iter->second.mText->getActor()->SetVisibility(on);
207  if (iter->second.mLine)
208  iter->second.mLine->getActor()->SetVisibility(on);
209  }
210  mShowLandmarks = on;
211 }
212 
214 {
215 // std::cout << this << " LandmarkRep::addLandmark ADD ALL" << std::endl;
216 
217  LandmarkPropertyMap props = mDataManager->getLandmarkProperties();
218 
219  for (LandmarkPropertyMap::iterator it = props.begin(); it != props.end(); ++it)
220  {
221  this->addLandmark(it->first);
222  }
223 }
224 
226 {
227 // std::cout << this << " LandmarkRep::internalUpdate()" << std::endl;
228 
229  this->clearAll();
230  this->addAll();
231 }
232 
234 {
235 // std::cout << this << " LandmarkRep::addLandmark CLEAR ALL" << std::endl;
236  mGraphics.clear();
237 }
238 
240 {
241  if (!view || !view->getRenderer())
242  return;
243 
244  this->addAll();
245  mViewportListener->startListen(view->getRenderer());
246 }
247 
249 {
250  this->clearAll();
251  mViewportListener->stopListen();
252 }
253 
257 void LandmarkRep::addLandmark(QString uid)
258 {
259 // std::cout << this << " LandmarkRep::addLandmark init" << uid << std::endl;
260  vtkRendererPtr renderer = this->getRenderer();
261 
262  LandmarkProperty property = mDataManager->getLandmarkProperties()[uid];
263  if (property.getUid().isEmpty())
264  {
265 // std::cout << "LandmarkRep::addLandmark CLEAR" << uid << std::endl;
266  mGraphics.erase(uid);
267  return;
268  }
269 
270  double radius = 2;
271  QColor color = mColor;
272  QColor secondaryColor = mSecondaryColor;
273 
274  if (!property.getActive())
275  {
276  radius = 1;
277  color = mInactiveColor;
278  secondaryColor = mInactiveColor;
279  }
280 
281  LandmarkGraphics current;
282 
283  // primary point
284  Landmark primary;
285  Vector3D primary_r(0, 0, 0);
286  if (mPrimary)
287  {
288 // std::cout << this << " LandmarkRep::addLandmark found mPrimary" << uid << std::endl;
289  primary = mPrimary->getLandmarks()[uid];
290  if (!primary.getUid().isEmpty())
291  {
292 // std::cout << this << " LandmarkRep::addLandmark" << uid << std::endl;
293 
294  primary_r = mPrimary->get_rMl().coord(primary.getCoord());
295 
296  current.mPrimaryPoint.reset(new GraphicalPoint3D(renderer));
297  current.mPrimaryPoint->setColor(color);
298  current.mPrimaryPoint->setRadius(radius);
299 
300  current.mText.reset(new FollowerText3D(renderer));
301  current.mText->setText(property.getName());
302  current.mText->setSizeInNormalizedViewport(true, 0.025);
303  current.mText->setColor(color);
304 
305  Vector3D text_r = mPrimary->get_rMl().coord(mPrimary->getTextPos(primary.getCoord()));
306 
307  current.mPrimaryPoint->setValue(primary_r);
308  current.mText->setPosition(text_r);
309  }
310  }
311 
312  // secondary point
313  Vector3D secondary_r(0, 0, 0);
314  Landmark secondary;
315  if (mSecondary)
316  {
317  secondary = mSecondary->getLandmarks()[uid];
318  if (!secondary.getUid().isEmpty())
319  {
320  secondary_r = mSecondary->get_rMl().coord(secondary.getCoord());
321 
322  current.mSecondaryPoint.reset(new GraphicalPoint3D(renderer));
323  current.mSecondaryPoint->setColor(secondaryColor);
324  current.mSecondaryPoint->setRadius(radius);
325  current.mSecondaryPoint->setValue(secondary_r);
326  }
327  }
328 
329  // connecting line
330  if (!secondary.getUid().isEmpty() && !secondary.getUid().isEmpty())
331  {
332  current.mLine.reset(new GraphicalLine3D(renderer));
333  current.mLine->setColor(secondaryColor);
334  current.mLine->setStipple(0x0F0F);
335 
336  current.mLine->setValue(primary_r, secondary_r);
337  }
338 
339  mGraphics[uid] = current;
340  this->rescale();
341 }
342 
344 {
345  if (!mViewportListener->isListening())
346  return;
347 
348  for (LandmarkGraphicsMapType::iterator iter = mGraphics.begin(); iter != mGraphics.end(); ++iter)
349  {
350  GraphicalPoint3DPtr primaryPoint = iter->second.mPrimaryPoint;
351  GraphicalPoint3DPtr secondaryPoint = iter->second.mSecondaryPoint;
352  if (primaryPoint)
353  {
354  double size = mViewportListener->getVpnZoom(primaryPoint->getValue());
355  double sphereSize = mGraphicsSize / 100 / size;
356  primaryPoint->setRadius(sphereSize);
357  }
358  if (secondaryPoint)
359  {
360  double size = mViewportListener->getVpnZoom(secondaryPoint->getValue());
361  double sphereSize = mGraphicsSize / 100 / size;
362  secondaryPoint->setRadius(sphereSize);
363  }
364  }
365 }
366 
367 } //namespace cx
virtual void addRepActorsToViewRenderer(ViewPtr view)
QString getUid() const
Definition: cxLandmark.cpp:33
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:88
void internalUpdate()
updates the text, color, scale etc
PatientLandmarksSource(PatientModelServicePtr dataManager)
boost::shared_ptr< class GraphicalPoint3D > GraphicalPoint3DPtr
PlainObject normal() const
One landmark, or fiducial, coordinate.
Definition: cxLandmark.h:40
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual Vector3D getTextPos(Vector3D p_l) const
LandmarksSourcePtr mSecondary
virtual ~LandmarkRep()
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:42
Vector3D getCoord() const
Definition: cxLandmark.cpp:38
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:42
FollowerText3DPtr mText
name of landmark, attached to primary point
boost::shared_ptr< LandmarksSource > LandmarksSourcePtr
Definition: cxLandmarkRep.h:51
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:108
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)
Namespace for all CustusX production code.