CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxGraphicalDisk.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 "cxGraphicalDisk.h"
13 
14 #include <QColor>
15 #include <vtkRenderer.h>
16 #include <vtkActor.h>
17 #include <vtkPolyDataMapper.h>
18 #include <vtkProperty.h>
19 #include <vtkSectorSource.h>
20 #include "cxVtkHelperClasses.h"
21 #include "vtkMatrix4x4.h"
22 #include "vtkLinearExtrusionFilter.h"
23 #include "vtkPolyDataNormals.h"
24 
25 namespace cx
26 {
27 
29  mOutlineWidth(0.1)
30 {
31  mDirection = Vector3D::UnitZ();
32 // std::cout << "GraphicalDisk::create " << mDirection << std::endl;
33 
34  mRadius = 1;
35  mColor = QColor(Qt::blue);
36  mFillVisible = true;
37  mOutlineColor = QColor(Qt::magenta);
38  mUseLighting = false;
39  mHeight = 0;
40 }
41 
43 {
44  this->removeActors();
45 }
46 
47 void GraphicalDisk::setRadius(double radius)
48 {
49  mRadius = radius;
50 }
52 {
53  mOutlineWidth = width;
54 }
56 {
57  mFillVisible = val;
58 }
60 {
61  mOutlineColor = color;
62 }
63 void GraphicalDisk::setColor(QColor color)
64 {
65  mColor = color;
66 }
68 {
69  mPosition = pos;
70 }
72 {
73 // std::cout << "GraphicalDisk::setDirection " << direction << std::endl;
74 
75  mDirection = direction;
76 }
78 {
79  mUseLighting = on;
80 }
81 void GraphicalDisk::setHeight(double height)
82 {
83  mHeight = height;
84 }
85 
87 {
88  this->removeActors();
89  mRenderer = renderer;
90  this->addActors();
91 }
92 
93 void GraphicalDisk::addActors()
94 {
95  if (mRenderer && mCircleActor && mOutlineActor)
96  {
97  mRenderer->AddActor(mCircleActor);
98  mRenderer->AddActor(mOutlineActor);
99  }
100 }
101 
102 void GraphicalDisk::removeActors()
103 {
104  if (mRenderer && mCircleActor && mOutlineActor)
105  {
106  mRenderer->RemoveActor(mCircleActor);
107  mRenderer->RemoveActor(mOutlineActor);
108  }
109 }
110 
112 {
113  if (!mRenderer)
114  return;
115 
116  if (!mCircleActor)
117  {
118  this->createActors();
119  this->addActors();
120  }
121 
122  if (!mCircleActor)
123  return;
124 
125  mCircleActor->GetProperty()->SetColor(getColorAsVector3D(mColor).begin());
126  mOutlineActor->GetProperty()->SetColor(getColorAsVector3D(mOutlineColor).begin());
127 
128  double innerRadius = std::max(0.0, mRadius*(1.0 - mOutlineWidth));
129  mCircleSource->SetOuterRadius(innerRadius);
130  mOutlineSource->SetInnerRadius(innerRadius);
131  mOutlineSource->SetOuterRadius(mRadius);
132 
133  mCircleExtruder->SetScaleFactor(mHeight);
134  mOutlineExtruder->SetScaleFactor(mHeight);
135 
136  mCircleActor->SetVisibility(mFillVisible);
137 
138  this->updateOrientation();
139 }
140 
141 void GraphicalDisk::createActors()
142 {
143  if (mCircleActor)
144  return;
145 
146  int resolution = 40;
147 
148  mCircleSource = vtkSectorSourcePtr::New();
149  mCircleSource->SetOuterRadius(mRadius);
150  mCircleSource->SetInnerRadius(0);
151  mCircleSource->SetStartAngle(0);
152  mCircleSource->SetEndAngle(360);
153  mCircleSource->SetCircumferentialResolution(resolution);
154 
155  mCircleExtruder = vtkLinearExtrusionFilterPtr::New();
156  mCircleExtruder->SetInputConnection(mCircleSource->GetOutputPort());
157  mCircleExtruder->SetScaleFactor(mHeight);
158  mCircleExtruder->SetExtrusionTypeToVectorExtrusion();
159  mCircleExtruder->SetVector(0,0,1);
160 
161  vtkPolyDataMapperPtr mapper = vtkPolyDataMapperPtr::New();
162  mapper->SetInputConnection(mCircleExtruder->GetOutputPort());
163  mapper->ScalarVisibilityOff();
164  mCircleActor = vtkActorPtr::New();
165  mCircleActor->SetMapper(mapper);
166  mCircleActor->GetProperty()->SetLighting(mUseLighting);
167 
168  mOutlineSource = vtkSectorSourcePtr::New();
169  mOutlineSource->SetOuterRadius(mRadius);
170  mOutlineSource->SetInnerRadius(0);
171  mOutlineSource->SetStartAngle(0);
172  mOutlineSource->SetEndAngle(360);
173  mOutlineSource->SetCircumferentialResolution(resolution);
174 
175  mOutlineExtruder = vtkLinearExtrusionFilterPtr::New();
176  mOutlineExtruder->SetInputConnection(mOutlineSource->GetOutputPort());
177  mOutlineExtruder->SetScaleFactor(mHeight);
178  mOutlineExtruder->SetExtrusionTypeToVectorExtrusion();
179  mOutlineExtruder->SetVector(0,0,1);
180 
181  vtkPolyDataNormalsPtr normals = vtkPolyDataNormalsPtr::New();
182  normals->SetInputConnection(mOutlineExtruder->GetOutputPort());
183 
184  vtkPolyDataMapperPtr outlineMapper = vtkPolyDataMapperPtr::New();
185  outlineMapper->SetInputConnection(normals->GetOutputPort());
186  outlineMapper->ScalarVisibilityOff();
187  mOutlineActor = vtkActorPtr::New();
188  mOutlineActor->SetMapper(outlineMapper);
189  mOutlineActor->GetProperty()->SetLighting(mUseLighting);
190 }
191 
192 
193 void GraphicalDisk::updateOrientation()
194 {
195 // Transform3D M = createTransformRotationBetweenVectors(Vector3D::UnitX(), mDirection.normal());
196 
197  Vector3D from = Vector3D::UnitZ();
198  Transform3D M;
199  bool directionAlongYAxis = similar(dot(from, mDirection.normal()), 1.0);
200 
201  if (directionAlongYAxis)
202  {
203  M = Transform3D::Identity();
204  }
205  else
206  {
207  Vector3D newXAxis = cross(from, mDirection).normal();
208  Vector3D newZAxis = mDirection;
209  Vector3D ivec = newXAxis;
210  Vector3D jvec = cross(newZAxis, newXAxis);
211  Vector3D center = Vector3D::Zero();
212  M = createTransformIJC(ivec, jvec, center);
213 
214  }
215 
216  Transform3D T = createTransformTranslate(mPosition);
217  M = T*M;
218 
219  mCircleActor->SetUserMatrix(M.getVtkMatrix());
220  mOutlineActor->SetUserMatrix(M.getVtkMatrix());
221 
222 // mCircleActor->SetPosition(mPosition[0], mPosition[1], mPosition[2]);
223 // mOutlineActor->SetPosition(mPosition[0], mPosition[1], mPosition[2]);
224 
225 }
226 
227 void GraphicalDisk::setRadiusBySlicingSphere(double sphereRadius, double sliceHeight)
228 {
229  double r = this->getRadiusOfCircleSlicedFromSphere(sphereRadius, sliceHeight);
230  this->setRadius(r);
231 }
232 
233 double GraphicalDisk::getRadiusOfCircleSlicedFromSphere(double sphereRadius, double sliceHeight) const
234 {
235  double retval = 0;
236 
237  if (std::abs(sliceHeight) > sphereRadius)
238  {
239  retval = 0;
240  }
241  else
242  {
243  retval = sphereRadius*cos(asin(sliceHeight/sphereRadius));
244  }
245 
246  return retval;
247 }
248 
249 
250 } // namespace cx
251 
252 
void setRadius(double radius)
Vector3D getColorAsVector3D(QColor color)
Scalar * begin()
void setColor(QColor color)
vtkSmartPointer< class vtkPolyDataMapper > vtkPolyDataMapperPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
void setLighting(bool on)
void setPosition(Vector3D pos)
void setRenderer(vtkRendererPtr renderer=vtkRendererPtr())
Vector3D cross(const Vector3D &a, const Vector3D &b)
compute cross product of a and b.
Definition: cxVector3D.cpp:41
void setOutlineWidth(double width)
void setHeight(double height)
Transform3D createTransformIJC(const Vector3D &ivec, const Vector3D &jvec, const Vector3D &center)
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
vtkSmartPointer< class vtkPolyDataNormals > vtkPolyDataNormalsPtr
void setOutlineColor(QColor color)
void setRadiusBySlicingSphere(double sphereRadius, double sliceHeight)
void setDirection(Vector3D direction)
Transform3D createTransformTranslate(const Vector3D &translation)
double dot(const Vector3D &a, const Vector3D &b)
compute inner product (or dot product) of a and b.
Definition: cxVector3D.cpp:46
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
void setFillVisible(bool val)
Namespace for all CustusX production code.