NorMIT-nav  2023.01.05-dev+develop.0da12
An IGT application
cxVtkHelperClasses.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 
13 
14 #include "cxVtkHelperClasses.h"
15 
16 #include <vtkSphereSource.h>
17 #include <vtkLineSource.h>
18 #include <vtkPolyDataMapper2D.h>
19 #include <vtkProperty2D.h>
20 #include <vtkTextMapper.h>
21 #include <vtkTextProperty.h>
22 #include <vtkAxesActor.h>
23 #include <vtkCaptionActor2D.h>
24 #include <vtkMatrix4x4.h>
25 #include <vtkRenderer.h>
26 #include <vtkCursor2D.h>
27 #include <vtkLeaderActor2D.h>
28 #include "cxTypeConversions.h"
29 #include <vtkProperty.h>
30 #include "cxBoundingBox3D.h"
31 #include "cxLogger.h"
32 
33 #include "vtkOverrideInformationCollection.h"
34 #include "vtkObjectFactory.h"
35 
36 // --------------------------------------------------------
37 namespace cx
38 {
39 
41 {
42  Vector3D retval(color.redF(), color.greenF(), color.blueF());
43  return retval;
44 }
45 
46 
48 
50 {
51  for (unsigned i=0; i<size(); ++i)
52  elems[i] = t.elems[i];
53 }
54 
56 {
57  if (this!=&t)
58  {
59  for (unsigned i=0; i<size(); ++i)
60  elems[i] = t.elems[i];
61  }
62  return *this;
63 }
64 
65 RGBColor& RGBColor::operator=(const QColor& t)
66 {
67  elems[0] = t.redF();
68  elems[1] = t.greenF();
69  elems[2] = t.blueF();
70  return *this;
71 }
72 
74 {
75  elems[0] = c.redF();
76  elems[1] = c.greenF();
77  elems[2] = c.blueF();
78 }
79 
80 RGBColor::RGBColor(double r, double g, double b)
81 {
82  elems[0] = r;
83  elems[1] = g;
84  elems[2] = b;
85 }
86 
87 RGBColor::RGBColor(const double* rgb)
88 {
89  elems[0] = rgb[0];
90  elems[1] = rgb[1];
91  elems[2] = rgb[2];
92 }
93 
94 
95 // --------------------------------------------------------
96 // OFFSEET POINT CLASS
97 // --------------------------------------------------------
98 
99 
101 {
102  mRenderer = renderer;
103  source = vtkSphereSourcePtr::New() ;
104  source->SetRadius( 4);
105 
106  mapper = vtkPolyDataMapper2DPtr::New() ;
107  mapper->SetInputConnection(source->GetOutputPort() );
108 
109  actor = vtkActor2DPtr::New();
110  actor->SetMapper(mapper);
111  mRenderer->AddActor(actor);
112 }
113 
115 {
116  mRenderer->RemoveActor(actor);
117 }
118 
119 void OffsetPoint::setRadius(int radius)
120 {
121  source->SetRadius(radius);
122 }
123 
125 {
126  actor->GetProperty()->SetColor(color.begin());
127  actor->SetPosition(point.begin());
128 }
129 
131 {
132  actor->GetProperty()->SetColor(color.begin());
133  actor->SetPosition(point.begin());
134 }
135 
136 void OffsetPoint::update( const Vector3D& position )
137 {
138  Vector3D p = position;
139  actor->SetPosition ( p.begin() );
140 }
141 
143 {
144  return actor;
145 }
146 
147 
148 //---------------------------------------------------------//
149 // LINESEGMENT CLASS
150 //---------------------------------------------------------//
151 
152 
154 {
155  mRenderer = renderer;
156  source = vtkLineSourcePtr::New();
157  mapper2d = vtkPolyDataMapper2DPtr::New();
158  actor2d = vtkActor2DPtr::New();
159 }
160 
162 {
163  mRenderer->RemoveActor(actor2d);
164 }
165 
166 void LineSegment::setPoints(Vector3D point1, Vector3D point2, RGBColor color, int stipplePattern)
167 {
168  source->SetPoint1(point1.begin());
169  source->SetPoint2(point2.begin());
170  mapper2d->SetInputConnection(source->GetOutputPort());
171  actor2d->SetMapper(mapper2d);
172  actor2d->GetProperty()->SetColor(color.begin());
173  actor2d->GetProperty()->SetLineStipplePattern(stipplePattern);
174  mRenderer->AddActor(actor2d);
175 }
176 
178 {
179  source->SetResolution(res);
180 }
181 
182 void LineSegment::setWidth(float width)
183 {
184  actor2d->GetProperty()->SetLineWidth(width);
185 }
186 
188 {
189  source->SetPoint1(point1.begin());
190  source->SetPoint2(point2.begin());
191 }
192 
194 {
195  actor2d->GetProperty()->SetColor(color.begin());
196 }
197 
198 void LineSegment::setPattern(int stipplePattern)
199 {
200  actor2d->GetProperty()->SetLineStipplePattern(stipplePattern);
201 }
202 
204 {
205  return actor2d;
206 }
207 
208 // --------------------------------------------------------
209 // CROSS HAIR CLASS
210 // --------------------------------------------------------
211 
213 {
214  mRenderer = renderer;
215  mCursor2D = vtkCursor2DPtr::New();
216  mapper = vtkPolyDataMapper2DPtr::New();
217  mapper->SetInputConnection ( mCursor2D->GetOutputPort() );
218 
219  actor = vtkActor2DPtr::New();
220  actor->SetMapper ( mapper );
221  mRenderer->AddActor ( actor );
222 }
223 
225 {
226  mRenderer->RemoveActor(actor);
227 }
228 
229 void CrossHair2D::setValue(const Vector3D& focalPoint, int width, int height, double bordarOffset, const RGBColor& color )
230 {
231  RGBColor c = color;
232  Vector3D p = focalPoint;
233  bordarOffset = 0.0;
234  mCursor2D->SetModelBounds ( bordarOffset, width - bordarOffset, bordarOffset, height - bordarOffset, 0.0, 0.0 );
235  mCursor2D->SetFocalPoint ( p[0]/2, p[1]/2, 0.0 );
236  mCursor2D->SetRadius ( 5 );
237  mCursor2D->AllOff();
238  mCursor2D->AxesOn();
239  mCursor2D->PointOn();
240  mCursor2D->OutlineOff();
241  actor->GetProperty()-> SetColor ( c.begin() );
242 }
243 
246 void CrossHair2D::updateRegCross( const Vector3D& crossPos )
247 {
248  Vector3D cp = crossPos;
249  if ( mCursor2D )
250  {
251  mCursor2D->SetModelBounds( cp[0]-50, cp[0]+50, cp[1]-50, cp[1]+50, 0.0, 0.0 );
252  mCursor2D->SetFocalPoint ( cp.begin() );
253  mCursor2D->Update();
254  }
255 }
256 void CrossHair2D::update( const Vector3D& crossPos, const DoubleBoundingBox3D& vp)
257 {
258  Vector3D cp = crossPos;
259  cp[2] = 0.0; // make it fit inside the z bounds.
260 
261  DoubleBoundingBox3D bb = vp;
262  if (!bb.contains(cp))
263  {
264  mCursor2D->AllOff();
265  }
266  else
267  {
268  mCursor2D->AllOff();
269  mCursor2D->AxesOn();
270  mCursor2D->PointOn();
271  mCursor2D->OutlineOff();
272  }
273 
274  if ( mCursor2D )
275  {
276  mCursor2D->SetFocalPoint ( cp.begin() );
277  mCursor2D->Update();
278  }
279  if (mapper)
280  {
281  //mapper->Update();
282  }
283 }
284 
286 {
287  return actor;
288 }
289 
290 // --------------------------------------------------------
291 // TEXT DISPLAY CLASS
292 // --------------------------------------------------------
293 TextDisplay::TextDisplay( const QString& text, const QColor &color, int fontsize )
294 {
295  this->text = text;
296 // Vector3D c = color;
297 // this->forceUseVtkTextMapper();
298  mapper = vtkTextMapperPtr::New();
299  mapper->SetInput( cstring_cast(text) );
300  this->setColor(color);
301  mapper->GetTextProperty()->SetFontSize( fontsize );
302 
303  actor= vtkActor2DPtr::New();
304  actor->SetMapper( mapper );
305  maxWidth = 0;
306 }
307 
309 {
310  //Force the use of vtkTextMapper instead of vtkOpenGLFreeTypeTextMapper
311  //Copied from TestFreeTypeTextMapper.cxx
312 
313  // Remove any override to the class to ensure that the actual vtkTextMapper
314  // class is being tested:
315  vtkNew<vtkOverrideInformationCollection> overrides;
316  vtkObjectFactory::GetOverrideInformation("vtkTextMapper",
317  overrides.GetPointer());
318  overrides->InitTraversal();
319  while (vtkOverrideInformation *override = overrides->GetNextItem())
320  {
321  if (vtkObjectFactory *factory = override->GetObjectFactory())
322  {
323  vtkObjectFactory::UnRegisterFactory(factory);
324  }
325  }
326  verifyVtkTextMapper();
327 }
328 
329 void TextDisplay::verifyVtkTextMapper()
330 {
331  vtkNew<vtkTextMapper> nameChecker;
332  if (vtkStdString(nameChecker->GetClassName()) != "vtkTextMapper")
333  {
334  reportError("Needed a vtkTextMapper instance, got " + QString(nameChecker->GetClassName()));
335  }
336 }
337 
338 void TextDisplay::setColor(QColor color)
339 {
340  mapper->GetTextProperty()->SetColor(getColorAsVector3D(color).begin() );
341 }
342 
344 {
345  if (mRenderer)
346  mRenderer->RemoveActor(actor);
347  mRenderer = renderer;
348  if (mRenderer)
349  mRenderer->AddActor(actor);
350 }
351 
353 {
354  this->setRenderer(vtkRendererPtr());
355 }
356 
357 void TextDisplay::setMaxWidth( int width, vtkViewport *vp)
358 {
359  maxWidth = width;
360  QStringList components = text.split("\n");
361  for (QStringList::iterator it = components.begin(); it != components.end(); ++it)
362  {
363  this->verifyVtkTextMapper();
364  vtkTextMapperPtr line = vtkTextMapperPtr::New();
365  bool changed = false;
366  line->SetInput( it->toLatin1().constData() );
367  line->SetTextProperty(mapper->GetTextProperty());
368  while((*it).length() > 0 && line->GetWidth(vp) > maxWidth)
369  {
370  (*it).chop(1);
371  line->SetInput( QString("%1...").arg(*it).toLatin1().constData() );
372  changed = true;
373  }
374  if (changed)
375  {
376  (*it).append("...");
377  }
378  }
379  QString newString = components.join("\n");
380  mapper->SetInput( newString.toLatin1().constData() );
381 }
382 
384 {
385  return maxWidth;
386 }
387 
388 int TextDisplay::getWidth( vtkViewport *vp)
389 {
390  return mapper->GetWidth( vp );
391 }
392 
394 {
395  actor->SetPosition( pos[0], pos[1] );
396 }
397 
398 void TextDisplay::setPosition( float x, float y )
399 {
400  actor->SetPosition( x, y );
401 }
402 
403 void TextDisplay::updateText( const QString& text)
404 {
405  QString input = text;
406  //VTK has a bug which leaves a white square where the text was, if the text is replaced with no text.
407  //E.g. the volume name when removing the last visible voulume. So we add a space instead of an empty text.
408  if(input.isEmpty())
409  input = " ";
410 
411  if (input == QString(mapper->GetInput()))
412  return;
413 
414  mapper->SetInput( cstring_cast(input) );
415  actor->Modified();
416 }
417 
418 vtkTextProperty* TextDisplay::textProperty()
419 {
420  return mapper->GetTextProperty();
421 }
422 
424 {
425  return actor;
426 }
427 
429 {
430  mapper->GetTextProperty()->SetJustificationToCentered() ;
431  mapper->GetTextProperty()->SetVerticalJustificationToCentered() ;
432 }
433 
434 // --------------------------------------------------------
435 // Axes3D CLASS
436 // --------------------------------------------------------
437 
438 Axes3D::Axes3D(vtkRendererPtr renderer) : mRenderer(renderer)
439 {
440  mAxes = vtkSmartPointer<vtkAxesActor>::New();
441 
442  setCaption(mAxes->GetXAxisCaptionActor2D(), "x", RGBColor(1,0,0));
443  setCaption(mAxes->GetYAxisCaptionActor2D(), "y", RGBColor(0,1,0));
444  setCaption(mAxes->GetZAxisCaptionActor2D(), "z", RGBColor(0,0,1));
445 
446  //SW_LOG("total len %s", string_cast(Vector3D(axes->GetTotalLength())).c_str());
447  //SW_LOG("scale %s", string_cast(Vector3D(mAxes->GetScale())).c_str());
448 
449  setPosition(Transform3D::Identity());
450 
451  Vector3D len(mAxes->GetNormalizedShaftLength());
452  //SW_LOG("len %s", string_cast(len).c_str());
453  //len = Vector3D(0.1,0.1,0.1);
454  mAxes->SetNormalizedShaftLength(len.begin());
455 
456  if (mRenderer)
457  mRenderer->AddActor(mAxes);
458 }
459 
463 {
464  double scale = 20;
465  //axes->SetScale(Vector3D(scale,scale,scale).begin());
466  Transform3D S = createTransformScale(Vector3D(scale,scale,scale));
467 
468  mAxes->SetUserMatrix((S*pos).getVtkMatrix());
469 }
470 
472 {
473  if (mRenderer)
474  mRenderer->RemoveActor(mAxes);
475 }
476 
478 {
479  return mAxes;
480 }
481 
482 void Axes3D::setCaption(vtkCaptionActor2D* captionActor, const QString& caption, RGBColor color)
483 {
484  captionActor->SetCaption(cstring_cast(caption));
485  captionActor->GetCaptionTextProperty()->SetColor(color.begin());
486 
487  double fontsize = 0.02;
488  captionActor->SetWidth(fontsize);
489  captionActor->SetHeight(fontsize);
490 }
491 
492 }// namespace vm
493 // --------------------------------------------------------
cx::LineSegment::getActor
vtkActor2DPtr getActor()
Definition: cxVtkHelperClasses.cpp:203
cx::RGBColor::RGBColor
RGBColor()
Definition: cxVtkHelperClasses.cpp:47
cxLogger.h
cx::CrossHair2D::CrossHair2D
CrossHair2D(vtkRendererPtr renderer)
Definition: cxVtkHelperClasses.cpp:212
cx::DoubleBoundingBox3D
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,...
Definition: cxBoundingBox3D.h:63
cx::LineSegment::setColor
void setColor(RGBColor color)
Definition: cxVtkHelperClasses.cpp:193
cx::CrossHair2D::setValue
void setValue(const Vector3D &focalPoint, int width, int height, double bordarOffset, const RGBColor &color)
Definition: cxVtkHelperClasses.cpp:229
cx::TextDisplay::setCentered
void setCentered()
Definition: cxVtkHelperClasses.cpp:428
cx
Namespace for all CustusX production code.
Definition: cx_dev_group_definitions.h:13
cx::createTransformScale
Transform3D createTransformScale(const Vector3D &scale_)
Definition: cxTransform3D.cpp:157
cx::LineSegment::setWidth
void setWidth(float width)
Definition: cxVtkHelperClasses.cpp:182
cx::TextDisplay::setMaxWidth
void setMaxWidth(int width, vtkViewport *vp)
Definition: cxVtkHelperClasses.cpp:357
cx::Axes3D::getProp
vtkProp3DPtr getProp()
Definition: cxVtkHelperClasses.cpp:477
cx::Axes3D::setPosition
void setPosition(const Transform3D &pos)
Definition: cxVtkHelperClasses.cpp:462
begin
Scalar * begin()
Definition: cxPlainObjectEigenAddons.h:22
cx::Axes3D::Axes3D
Axes3D(vtkRendererPtr renderer=vtkRendererPtr())
Definition: cxVtkHelperClasses.cpp:438
cx::TextDisplay::getWidth
int getWidth(vtkViewport *vp)
Definition: cxVtkHelperClasses.cpp:388
cstring_cast
cstring_cast_Placeholder cstring_cast(const T &val)
Definition: cxTypeConversions.h:69
cx::TextDisplay::getActor
vtkActor2DPtr getActor()
Definition: cxVtkHelperClasses.cpp:423
cx::OffsetPoint::~OffsetPoint
~OffsetPoint()
Definition: cxVtkHelperClasses.cpp:114
cxBoundingBox3D.h
cx::CrossHair2D::~CrossHair2D
~CrossHair2D()
Definition: cxVtkHelperClasses.cpp:224
vtkActor2DPtr
vtkSmartPointer< class vtkActor2D > vtkActor2DPtr
Definition: vtkForwardDeclarations.h:30
cx::CrossHair2D::update
void update(const Vector3D &crossPos, const DoubleBoundingBox3D &vp)
Definition: cxVtkHelperClasses.cpp:256
cx::OffsetPoint::setRadius
void setRadius(int radius)
Definition: cxVtkHelperClasses.cpp:119
cx::LineSegment::setPoints
void setPoints(Vector3D point1, Vector3D point2, RGBColor color, int stipplePattern=0xFFFF)
Definition: cxVtkHelperClasses.cpp:166
cx::TextDisplay::getMaxWidth
int getMaxWidth()
Definition: cxVtkHelperClasses.cpp:383
vtkTextMapperPtr
vtkSmartPointer< class vtkTextMapper > vtkTextMapperPtr
Definition: vtkForwardDeclarations.h:135
cx::OffsetPoint::getActor
vtkActor2DPtr getActor()
Definition: cxVtkHelperClasses.cpp:142
cx::OffsetPoint::setValue
void setValue(Vector3D point, RGBColor color)
Definition: cxVtkHelperClasses.cpp:124
cx::Transform3D
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Definition: cxLandmarkPatientRegistrationWidget.h:33
cx::getColorAsVector3D
Vector3D getColorAsVector3D(QColor color)
Definition: cxVtkHelperClasses.cpp:40
cx::Axes3D::~Axes3D
~Axes3D()
Definition: cxVtkHelperClasses.cpp:471
cxTypeConversions.h
cx::TextDisplay::updateText
void updateText(const QString &text)
Definition: cxVtkHelperClasses.cpp:403
cx::DoubleBoundingBox3D::contains
bool contains(const Vector3D &p) const
Definition: cxBoundingBox3D.cpp:220
cx::CrossHair2D::updateRegCross
void updateRegCross(const Vector3D &crossPos)
Definition: cxVtkHelperClasses.cpp:246
cx::TextDisplay::textProperty
vtkTextProperty * textProperty()
Definition: cxVtkHelperClasses.cpp:418
cx::LineSegment::LineSegment
LineSegment(vtkRendererPtr renderer)
Definition: cxVtkHelperClasses.cpp:153
cx::TextDisplay::~TextDisplay
~TextDisplay()
Definition: cxVtkHelperClasses.cpp:352
cx::TextDisplay::setRenderer
void setRenderer(vtkRendererPtr renderer)
Definition: cxVtkHelperClasses.cpp:343
cx::TextDisplay::forceUseVtkTextMapper
static void forceUseVtkTextMapper()
Definition: cxVtkHelperClasses.cpp:308
cx::TextDisplay::setColor
void setColor(QColor color)
Definition: cxVtkHelperClasses.cpp:338
cx::TextDisplay::setPosition
void setPosition(float x, float y)
Definition: cxVtkHelperClasses.cpp:398
cx::LineSegment::setPattern
void setPattern(int stipplePattern)
Definition: cxVtkHelperClasses.cpp:198
cx_transform3D_internal::getVtkMatrix
vtkMatrix4x4Ptr getVtkMatrix(const Eigen::Affine3d *self)
Definition: cxTransform3D.cpp:67
cx::TextDisplay::TextDisplay
TextDisplay(const QString &text, const QColor &color, int fontsize)
Definition: cxVtkHelperClasses.cpp:293
cxVtkHelperClasses.h
cx::RGBColor::operator=
RGBColor & operator=(const RGBColor &t)
Definition: cxVtkHelperClasses.cpp:55
cx::RGBColor
RGB color data.
Definition: cxVtkHelperClasses.h:48
vtkProp3DPtr
vtkSmartPointer< class vtkProp3D > vtkProp3DPtr
Definition: vtkForwardDeclarations.h:119
cx::reportError
void reportError(QString msg)
Definition: cxLogger.cpp:71
cx::LineSegment::updatePosition
void updatePosition(Vector3D point1, Vector3D point2)
Definition: cxVtkHelperClasses.cpp:187
cx::LineSegment::setResolution
void setResolution(int res)
Definition: cxVtkHelperClasses.cpp:177
cx::LineSegment::~LineSegment
~LineSegment()
Definition: cxVtkHelperClasses.cpp:161
cx::Vector3D
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
vtkRendererPtr
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
Definition: vtkForwardDeclarations.h:122
cx::OffsetPoint::OffsetPoint
OffsetPoint(vtkRendererPtr renderer)
Definition: cxVtkHelperClasses.cpp:100
cx::OffsetPoint::update
void update(const Vector3D &point)
Definition: cxVtkHelperClasses.cpp:136
cx::CrossHair2D::getActor
vtkActor2DPtr getActor()
Definition: cxVtkHelperClasses.cpp:285