CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxGraphicalPrimitives.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 "cxGraphicalPrimitives.h"
13 
14 #include "boost/bind.hpp"
15 #include <vtkSphereSource.h>
16 #include <vtkLineSource.h>
17 #include <vtkArcSource.h>
18 #include <vtkPolyDataMapper.h>
19 #include <vtkActor.h>
20 #include <vtkCellArray.h>
21 #include <vtkProperty.h>
22 #include <vtkRenderer.h>
23 #include <vtkCommand.h>
24 #include <vtkFollower.h>
25 #include <vtkVectorText.h>
26 #include <vtkCamera.h>
27 #include "cxTypeConversions.h"
28 #include "cxBoundingBox3D.h"
29 #include "vtkArrowSource.h"
30 #include "vtkMatrix4x4.h"
31 #include "vtkCaptionActor2D.h"
32 #include "vtkTextProperty.h"
33 #include "cxVtkHelperClasses.h"
34 #include "vtkPolyDataNormals.h"
35 
36 namespace cx
37 {
38 
39 
41 {
42  mProperty = vtkPropertyPtr::New();
43  mActor = vtkActorPtr::New();
44  mActor->SetProperty(mProperty);
45 }
46 
48 {
49  this->setRenderer(NULL);
50 }
51 
53 {
55  mSource = source;
56 
57  if (mSource)
58  getMapper()->SetInputConnection(mSource->GetOutputPort());
59  else
60  getMapper()->SetInputConnection(NULL);
61 }
62 
64 {
65  if (mRenderer)
66  mRenderer->RemoveActor(mActor);
67 
68  mRenderer = renderer;
69 
70  if (mRenderer)
71  mRenderer->AddActor(mActor);
72 }
73 
75 {
76  mActor->SetVisibility(visible);
77 }
78 
79 
81 {
82  mActor->GetProperty()->SetBackfaceCulling(val);
83 }
84 
86 {
87  mActor->GetProperty()->SetFrontfaceCulling(val);
88 }
89 
90 void GraphicalGeometricBase::setColor(double red, double green, double blue)
91 {
92  mActor->GetProperty()->SetColor(red, green, blue);
93 }
94 
96 {
97  mActor->GetProperty()->SetColor(color.begin());
98 }
99 
101 {
102  mActor->SetPosition(point.begin());
103 }
104 
106 {
107  mActor->GetProperty()->SetOpacity(val);
108 }
109 
110 void GraphicalGeometricBase::setUserMatrix(vtkMatrix4x4 *matrix)
111 {
112  mActor->SetUserMatrix(matrix);
113 }
114 
116 {
117  if(pointSize<=0)
118  return;
119  mProperty->SetPointSize(pointSize);
120 }
121 
123 {
124  getMapper()->SetScalarVisibility(show);
125 }
126 
128 {
129  getMapper()->SetScalarModeToUseCellData();
130 }
131 
133 {
134  return Vector3D(mActor->GetPosition());
135 }
136 
138 {
139  return mActor;
140 }
141 
143 {
144  return mProperty;
145 }
146 
148 {
149  if (mSource)
150  return mSource->GetOutput();
151  else
152  return mData;
153 }
154 
156 {
157  return mSource;
158 }
159 
160 //--------------------------------------------------------
161 //--------------------------------------------------------
162 //-------------------------------------------------------
163 
165  GraphicalGeometricBase(source,renderer)
166 {
167  mMapper = vtkPolyDataMapperPtr::New();
168 
169  mActor->SetMapper(mMapper);
170  setSource(source);
171  setRenderer(renderer);
172 }
173 
175 {
176  mActor->GetProperty()->SetRepresentationToWireframe();
177 }
178 
180 {
182  mData = data;
183 
184  mMapper->SetInputData(mData);
185 }
186 
188 {
189  mActor->SetTexture(texture);
190 }
191 
192 
194 {
195  return mMapper;
196 }
197 
198 //--------------------------------------------------------
199 //--------------------------------------------------------
200 //-------------------------------------------------------
201 
203  GraphicalGeometricBase(source,renderer)
204 {
205  mMapper = vtkSmartPointer<vtkGlyph3DMapper>::New();
206  vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();
207  mMapper->SetSourceConnection(arrowSource->GetOutputPort());
208  mMapper->ScalarVisibilityOn();
209  mMapper->SetUseLookupTableScalarRange(1);
210  mMapper->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_FIELD_DATA);
211  mActor->SetMapper(mMapper);
212  setSource(source);
213  setRenderer(renderer);
214 }
215 
216 
218 {
219  mData = data;
220  if (data)
221  mMapper->SetInputData(mData);
222 }
223 
224 void GraphicalGlyph3DData::setOrientationArray(const char* orientationArray)
225 {
226  mMapper->SetOrientationArray(orientationArray);
227 }
228 
229 void GraphicalGlyph3DData::setColorArray(const char* colorArray)
230 {
231  if(strlen(colorArray)>0)
232  {
233  setScalarVisibility(true);
234  }else
235  {
236  setScalarVisibility(false);
237  }
238  mMapper->SelectColorArray(colorArray);
239 }
240 
241 
242 void GraphicalGlyph3DData::setLUT(const char* lut)
243 {
244  vtkSmartPointer<vtkColorSeries> colorSeries = vtkSmartPointer<vtkColorSeries>::New();
245  vtkSmartPointer<vtkLookupTable> table = vtkLookupTable::New();
246  colorSeries->SetColorSchemeByName(lut);
247  colorSeries->BuildLookupTable(table , vtkColorSeries::ORDINAL);
248  mMapper->SetLookupTable(table);
249 }
250 
251 
252 void GraphicalGlyph3DData::setScaleFactor(double scaleFactor)
253 {
254  if(scaleFactor<=0) return;
255  mMapper->SetScaleFactor(scaleFactor);
256 }
257 
259 {
260  return mMapper;
261 }
262 
263 //--------------------------------------------------------
264 //--------------------------------------------------------
265 //--------------------------------------------------------
266 
268 {
269  // mRenderer = renderer;
270  source = vtkSphereSourcePtr::New();
271  source->SetRadius(4);
272  // default:
273  // source->SetThetaResolution(8);
274  // source->SetPhiResolution(8);
275  // 24*16 = 384, 8*8=64, 16*12=192
276  source->SetThetaResolution(16);
277  source->SetPhiResolution(12);
278  source->LatLongTessellationOn();
279 
280  vtkPolyDataNormalsPtr normals = vtkPolyDataNormalsPtr::New();
281  normals->SetInputConnection(source->GetOutputPort());
282  normals->Update();
283 
284  mapper = vtkPolyDataMapperPtr::New();
285  mapper->SetInputConnection(normals->GetOutputPort());
286 
287  actor = vtkActorPtr::New();
288  actor->SetMapper(mapper);
289 
290  this->setRenderer(renderer);
291 }
292 
294 {
295  this->setRenderer(NULL);
296 }
297 
299 {
300  if (mRenderer)
301  {
302  mRenderer->RemoveActor(actor);
303  }
304 
305  mRenderer = renderer;
306 
307  if (mRenderer)
308  {
309  mRenderer->AddActor(actor);
310  }
311 }
312 
313 void GraphicalPoint3D::setRadius(double radius)
314 {
315  source->SetRadius(radius);
316 }
317 
318 void GraphicalPoint3D::setColor(QColor color)
319 {
320  setColorAndOpacity(actor->GetProperty(), color);
321 }
322 
324 {
325  actor->SetPosition(point.begin());
326 }
327 
329 {
330  return Vector3D(actor->GetPosition());
331 }
332 
334 {
335  return actor;
336 }
337 
339 {
340  return source->GetOutput();
341 }
342 
343 //--------------------------------------------------------
344 //--------------------------------------------------------
345 //--------------------------------------------------------
346 
348 {
349  mRenderer = renderer;
350  source = vtkLineSourcePtr::New();
351  mapper = vtkPolyDataMapperPtr::New() ;
352  actor = vtkActorPtr::New() ;
353 
354  mapper->SetInputConnection( source->GetOutputPort() );
355  actor->SetMapper (mapper );
356  this->setRenderer(renderer);
357 }
358 
360 {
361  this->setRenderer(NULL);
362 }
363 
365 {
366  if (mRenderer)
367  {
368  mRenderer->RemoveActor(actor);
369  }
370 
371  mRenderer = renderer;
372 
373  if (mRenderer)
374  {
375  mRenderer->AddActor(actor);
376  }
377 }
378 
379 void GraphicalLine3D::setColor(QColor color)
380 {
381  setColorAndOpacity(actor->GetProperty(), color);
382 }
383 
385 {
386  source->SetPoint1(point1.begin());
387  source->SetPoint2(point2.begin());
388 }
389 
391 {
392  actor->GetProperty()->SetLineStipplePattern(stipple);
393 }
394 
396 {
397  return actor;
398 }
399 
400 //--------------------------------------------------------
401 //--------------------------------------------------------
402 //--------------------------------------------------------
403 
405 {
406  mRenderer = renderer;
407  source = vtkArcSourcePtr::New();
408  source->SetResolution(20);
409  mapper = vtkPolyDataMapperPtr::New() ;
410  actor = vtkActorPtr::New() ;
411 
412  mapper->SetInputConnection( source->GetOutputPort() );
413  actor->SetMapper (mapper );
414  if (mRenderer)
415  mRenderer->AddActor(actor);
416 }
417 
419 {
420  if (mRenderer)
421  mRenderer->RemoveActor(actor);
422 }
423 
424 void GraphicalArc3D::setColor(QColor color)
425 {
426  setColorAndOpacity(actor->GetProperty(), color);
427 }
428 
430 {
431  source->SetPoint1(point1.begin());
432  source->SetPoint2(point2.begin());
433  source->SetCenter(center.begin());
434 }
435 
436 void GraphicalArc3D::setStipple(int stipple)
437 {
438  actor->GetProperty()->SetLineStipplePattern(stipple);
439 }
440 
442 {
443  return actor;
444 }
445 
446 //--------------------------------------------------------
447 //--------------------------------------------------------
448 //--------------------------------------------------------
449 
451 {
452  mRenderer = renderer;
453  source = vtkArrowSourcePtr::New();
454  source->SetTipResolution(24);
455  source->SetShaftResolution(24);
456  mapper = vtkPolyDataMapperPtr::New() ;
457  actor = vtkActorPtr::New() ;
458 
459  mapper->SetInputConnection( source->GetOutputPort() );
460  actor->SetMapper (mapper );
461  if (mRenderer)
462  mRenderer->AddActor(actor);
463 }
464 
466 {
467  if (mRenderer)
468  mRenderer->RemoveActor(actor);
469 }
470 
471 void GraphicalArrow3D::setColor(QColor color)
472 {
473  setColorAndOpacity(actor->GetProperty(), color);
474 }
475 
477 {
478  // find an arbitrary vector k perpendicular to normal:
479  Vector3D k = cross(Vector3D(1,0,0), normal);
480  if (similar(k, Vector3D(0,0,0)))
481  k = cross(Vector3D(0,1,0), normal);
482  k = k.normalized();
483  Transform3D M = createTransformIJC(normal, k, base);
484 
485  // std::cout << "GraphicalArrow3D::setValue " << base << " - " << normal << std::endl;
486  Transform3D S = createTransformScale(Vector3D(length,1,1));
487  M = M * S;
488  // let arrow shape increase slowly with length:
489  // source->SetTipLength(0.35/sqrt(length));
490  // source->SetTipRadius(0.1*sqrt(length));
491  // source->SetShaftRadius(0.03*sqrt(length));
492  source->SetTipLength(0.35);
493  source->SetTipRadius(0.1*(length));
494  source->SetShaftRadius(0.03*(length));
495  actor->SetUserMatrix(M.getVtkMatrix());
496 }
497 
498 //--------------------------------------------------------
499 //--------------------------------------------------------
500 //--------------------------------------------------------
501 
502 Rect3D::Rect3D(vtkRendererPtr renderer, QColor color)
503 {
504  mRenderer = renderer;
505  mapper = vtkPolyDataMapperPtr::New();
506  actor = vtkActorPtr::New();
507  setColorAndOpacity(actor->GetProperty(), color);
508  actor->SetMapper(mapper);
509  if (mRenderer)
510  mRenderer->AddActor(actor);
511 
512  mPolyData = vtkPolyDataPtr::New();
513  mPoints = vtkPointsPtr::New();
514  mSide = vtkCellArrayPtr::New();
515 
516  vtkIdType cells[5] = { 0,1,2,3,0 };
517  mSide->InsertNextCell(5, cells);
518 
519  mPolyData->SetPoints(mPoints);
520  mapper->SetInputData(mPolyData);
521 }
522 
523 void Rect3D::setLine(bool on, int width)
524 {
525  if (on)
526  {
527  mPolyData->SetLines(mSide);
528  actor->GetProperty()->SetLineWidth(width);
529  }
530  else
531  {
532  mPolyData->SetLines(NULL);
533  }
534 }
535 
536 void Rect3D::setSurface(bool on)
537 {
538  if (on)
539  {
540  mPolyData->SetPolys(mSide);
541  actor->GetProperty()->SetOpacity(1.0); // transparent planes dont work well together with texture volume. Use 1.0
542  }
543  else
544  {
545  mPolyData->SetPolys(NULL);
546  }
547 }
548 
550 {
551  if (mRenderer)
552  mRenderer->RemoveActor(actor);
553 }
554 
555 void Rect3D::setColor(QColor color)
556 {
557  setColorAndOpacity(actor->GetProperty(), color);
558 }
559 
561 {
562  mPoints = vtkPointsPtr::New();
563  mPoints->InsertPoint(0, M.coord(bb.corner(0,0,0)).begin());
564  mPoints->InsertPoint(1, M.coord(bb.corner(0,1,0)).begin());
565  mPoints->InsertPoint(2, M.coord(bb.corner(1,1,0)).begin());
566  mPoints->InsertPoint(3, M.coord(bb.corner(1,0,0)).begin());
567  mPolyData->SetPoints(mPoints);
568 }
569 
570 //--------------------------------------------------------
571 //--------------------------------------------------------
572 //--------------------------------------------------------
573 
575 {
576  mText = vtkVectorTextPtr::New();
577  vtkPolyDataMapperPtr mapper = vtkPolyDataMapperPtr::New();
578  mapper->SetInputConnection(mText->GetOutputPort());
579  mFollower = vtkFollowerPtr::New();
580  mFollower->SetMapper(mapper);
581  Vector3D mTextScale(2,2,2);
582  mFollower->SetScale(mTextScale.begin());
583 
584  this->setSizeInNormalizedViewport(true, 0.025);
585  this->setRenderer(renderer);
586 }
587 
589 {
590  if (mRenderer)
591  {
592  mRenderer->RemoveActor(mFollower);
593  mViewportListener->stopListen();
594  }
595 
596  mRenderer = renderer;
597 
598  if (mRenderer)
599  {
600  mRenderer->AddActor(mFollower);
601  mFollower->SetCamera(mRenderer->GetActiveCamera());
602  if (mViewportListener)
603  mViewportListener->startListen(mRenderer);
604  }
605 }
606 
608 {
609  if (mRenderer)
610  mRenderer->RemoveActor(mFollower);
611 }
612 
613 void FollowerText3D::setSize(double val)
614 {
615  mSize = val;
616  this->scaleText();
617 }
618 
620 {
621  if (on)
622  {
623  if (!mViewportListener)
624  {
625  mViewportListener.reset(new ViewportListener);
626  mViewportListener->setCallback(boost::bind(&FollowerText3D::scaleText, this));
627  }
628  }
629  else
630  {
631  mViewportListener.reset();
632  }
633 
634  this->setSize(size);
635 }
636 
637 void FollowerText3D::setColor(QColor color)
638 {
639  setColorAndOpacity(mFollower->GetProperty(), color);
640 }
641 
642 void FollowerText3D::setText(QString text)
643 {
644  mText->SetText(cstring_cast(text));
645 }
646 
648 {
649  mFollower->SetPosition(pos.begin());
650 }
651 
653 {
654  return mFollower;
655 }
656 
664 {
665  if (!mViewportListener || !mViewportListener->isListening())
666  {
667  mFollower->SetScale(Vector3D(mSize,mSize,mSize).begin());
668  return;
669  }
670 
671  double size = mViewportListener->getVpnZoom(Vector3D(mFollower->GetPosition()));
672 
673  double scale = mSize/size;
674  // std::cout << "s= " << size << " ,scale= " << scale << std::endl;
675  Vector3D mTextScale(scale,scale,scale);
676  if (mFollower)
677  mFollower->SetScale(mTextScale.begin());
678 }
679 
680 //--------------------------------------------------------
681 //--------------------------------------------------------
682 //--------------------------------------------------------
683 
685 {
686  mText = vtkCaptionActor2DPtr::New();
687  mText->BorderOff();
688  mText->LeaderOff();
689 
690  mText->GetCaptionTextProperty()->BoldOff();
691  mText->GetCaptionTextProperty()->ItalicOff();
692  mText->GetCaptionTextProperty()->ShadowOff();
693  mText->SetWidth(10);
694  mText->SetHeight(0.03);
695 
696  this->setRenderer(renderer);
697 }
698 
700 {
701  mText->SetPosition(-15, -30);
702  mText->SetPosition2(15, -10);
703 }
704 
706 {
707  mText->SetPosition(-15, 2);
708 }
709 
711 {
712  mText->SetVisibility(visible);
713 }
714 
716 {
717  if (mRenderer)
718  {
719  mRenderer->RemoveActor(mText);
720  }
721 
722  mRenderer = renderer;
723 
724  if (mRenderer)
725  {
726  mRenderer->AddActor(mText);
727  }
728 }
729 
731 {
732  if (mRenderer)
733  mRenderer->RemoveActor(mText);
734 }
735 
736 void CaptionText3D::setSize(double val)
737 {
738  mText->SetHeight(val);
739 }
740 
741 void CaptionText3D::setColor(QColor color)
742 {
743  mText->GetCaptionTextProperty()->SetColor(getColorAsVector3D(color).begin());
744 }
745 
746 void CaptionText3D::setText(QString text)
747 {
748  mText->SetCaption(cstring_cast(text));
749 }
750 
752 {
753  mPos = pos;
754  mText->SetAttachmentPoint(pos.begin());
755 }
756 
758 {
759  return mPos;
760 }
761 
763 {
764  return mText;
765 }
766 
767 //--------------------------------------------------------
768 //--------------------------------------------------------
769 //--------------------------------------------------------
770 
771 }
void setRenderer(vtkRendererPtr renderer=vtkRendererPtr())
void setScaleFactor(double scaleFactor)
vtkSmartPointer< class vtkTexture > vtkTexturePtr
void setValue(Vector3D point1, Vector3D point2, Vector3D center)
CaptionText3D(vtkRendererPtr renderer=vtkRendererPtr())
GraphicalGlyph3DData(vtkPolyDataAlgorithmPtr source=vtkPolyDataAlgorithmPtr(), vtkRendererPtr renderer=vtkRendererPtr())
vtkSmartPointer< class vtkActor > vtkActorPtr
void setRenderer(vtkRendererPtr renderer=vtkRendererPtr())
Vector3D corner(int x, int y, int z) const
void setRenderer(vtkRendererPtr renderer=vtkRendererPtr())
Vector3D getColorAsVector3D(QColor color)
Scalar * begin()
PlainObject normal() const
void setData(vtkPolyDataPtr data)
vtkSmartPointer< class vtkPolyDataMapper > vtkPolyDataMapperPtr
void setValue(Vector3D point)
Vector3D getPosition() const
GraphicalPoint3D(vtkRendererPtr renderer=vtkRendererPtr())
vtkCaptionActor2DPtr getActor()
Transform3D createTransformScale(const Vector3D &scale_)
vtkSmartPointer< class vtkProperty > vtkPropertyPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
void setOrientationArray(const char *orientationArray)
void setPosition(Vector3D pos)
void setText(QString text)
GraphicalArc3D(vtkRendererPtr renderer=vtkRendererPtr())
void setColor(QColor color)
cstring_cast_Placeholder cstring_cast(const T &val)
virtual vtkMapperPtr getMapper()=0
Rect3D(vtkRendererPtr renderer, QColor color)
void setColorArray(const char *colorArray)
GraphicalLine3D(vtkRendererPtr renderer=vtkRendererPtr())
void setData(vtkPolyDataPtr data)
Listens to changes in viewport and camera matrix.
Vector3D cross(const Vector3D &a, const Vector3D &b)
compute cross product of a and b.
Definition: cxVector3D.cpp:41
void setStipple(int stipple)
GraphicalGeometricBase(vtkPolyDataAlgorithmPtr source=vtkPolyDataAlgorithmPtr(), vtkRendererPtr renderer=vtkRendererPtr())
void setRenderer(vtkRendererPtr renderer=vtkRendererPtr())
void setTexture(vtkTexturePtr texture)
Transform3D createTransformIJC(const Vector3D &ivec, const Vector3D &jvec, const Vector3D &center)
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
vtkSmartPointer< class vtkFollower > vtkFollowerPtr
void setColor(double red, double green, double blue)
void scaleText()
internal method
vtkSmartPointer< class vtkMapper > vtkMapperPtr
void setPosition(Vector3D pos)
void setLine(bool on, int width)
GraphicalPolyData3D(vtkPolyDataAlgorithmPtr source=vtkPolyDataAlgorithmPtr(), vtkRendererPtr renderer=vtkRendererPtr())
vtkSmartPointer< class vtkPolyDataNormals > vtkPolyDataNormalsPtr
FollowerText3D(vtkRendererPtr renderer=vtkRendererPtr())
void setRenderer(vtkRendererPtr renderer=vtkRendererPtr())
void setColor(QColor color)
void setUserMatrix(vtkMatrix4x4 *matrix)
vtkSmartPointer< class vtkCaptionActor2D > vtkCaptionActor2DPtr
void setColor(QColor color)
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.
void setSizeInNormalizedViewport(bool on, double size)
vtkPolyDataAlgorithmPtr getSource()
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
void updatePosition(const DoubleBoundingBox3D bb, const Transform3D &M)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
void setSurface(bool on)
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
vtkSmartPointer< class vtkPolyDataAlgorithm > vtkPolyDataAlgorithmPtr
Definition: cxViewWrapper.h:29
RealScalar length() const
void setVisibility(bool visible)
void setSource(vtkPolyDataAlgorithmPtr source)
void setStipple(int stipple)
void setColor(QColor color)
void setValue(Vector3D base, Vector3D normal, double length)
GraphicalArrow3D(vtkRendererPtr renderer=vtkRendererPtr())
void setRadius(double radius)
void setColor(QColor color)
void setText(QString text)
vtkPolyDataAlgorithmPtr mSource
void setValue(Vector3D point1, Vector3D point2)
void setColorAndOpacity(vtkPropertyOrProperty2DPtr property, QColor color)
Namespace for all CustusX production code.