fw4spl
fwHandleRepresentation3D.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwRenderVTK/vtk/fwHandleRepresentation3D.hpp"
8 
9 #include <vtkCamera.h>
10 #include <vtkCleanPolyData.h>
11 #include <vtkCubeSource.h>
12 #include <vtkCylinderSource.h>
13 #include <vtkFollower.h>
14 #include <vtkInteractorObserver.h>
15 #include <vtkMath.h>
16 #include <vtkObjectFactory.h>
17 #include <vtkPolyDataMapper.h>
18 #include <vtkPolyDataNormals.h>
19 #include <vtkProperty.h>
20 #include <vtkRenderer.h>
21 #include <vtkSphereSource.h>
22 #include <vtkTransform.h>
23 #include <vtkTransformPolyDataFilter.h>
24 
25 namespace fwRenderVTK
26 {
27 
28 namespace vtk
29 {
30 
31 vtkStandardNewMacro(fwHandleRepresentation3D);
32 
33 //----------------------------------------------------------------------
34 fwHandleRepresentation3D::fwHandleRepresentation3D()
35 {
36  // Instantiate a handle template shape as a cube
37  this->CubeSource = vtkSmartPointer<vtkCubeSource>::New();
38 
39  // Instantiate a handle template shape as a sphere
40  this->SphereSource = vtkSmartPointer<vtkSphereSource>::New();
41  this->SphereSource->SetThetaResolution(20);
42  this->SphereSource->SetPhiResolution(20);
43  this->SphereSource->Update();
44  this->SetHandle(this->SphereSource->GetOutput());
45 
46  this->GetSelectedProperty()->SetColor(0., 1., 0.);
47 
48  this->ShapeRepresentation = SPHERE;
49 
50  auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
51  cylinderSource->SetCenter(0., -1., 0.);
52  cylinderSource->SetResolution(64);
53  cylinderSource->SetHeight(0.);
54  this->Marker = cylinderSource;
55 
56  this->CleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
57  this->CleanPolyData->PointMergingOn();
58  this->CleanPolyData->CreateDefaultLocator();
59  this->CleanPolyData->SetInputConnection(0, this->Marker->GetOutputPort(0));
60 
61  auto MarkerNormals = vtkSmartPointer<vtkPolyDataNormals>::New();
62  MarkerNormals->SetInputConnection( 0, this->CleanPolyData->GetOutputPort(0) );
63 
64  this->MarkerMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
65  this->MarkerMapper->SetInputConnection( MarkerNormals->GetOutputPort() );
66 
67  this->Follower = vtkSmartPointer<vtkFollower>::New();
68  this->Follower->SetMapper(this->MarkerMapper);
69  this->Follower->RotateX(90);
70 
71  // Set up the initial properties, parent's one is called in parent's constructor
72  this->CreateDefaultProperties();
73 
74  this->MarkerRadiusFactor = 1.2;
75  this->SetMarkerProperty(this->MarkerProperty);
76  cylinderSource->SetRadius(this->MarkerRadiusFactor * this->SphereSource->GetRadius());
77 }
78 
79 //----------------------------------------------------------------------
80 
81 fwHandleRepresentation3D::~fwHandleRepresentation3D()
82 {
83 
84 }
85 
86 //-----------------------------------------------------------------------------
87 
88 void fwHandleRepresentation3D::PrintSelf(ostream& os, vtkIndent indent)
89 {
90  this->Superclass::PrintSelf(os, indent);
91 
92  os << indent << "HandleSize: " << this->HandleSize << endl;
93  os << indent << "ShapeRepresentation: " << (this->ShapeRepresentation == SPHERE ? "SPHERE" : "CUBE") << endl;
94  if (this->SphereSource)
95  {
96  this->SphereSource->PrintSelf(os, indent.GetNextIndent());
97  }
98  if (this->CubeSource)
99  {
100  this->CubeSource->PrintSelf(os, indent.GetNextIndent());
101  }
102 }
103 
104 //-------------------------------------------------------------------------
105 
106 void fwHandleRepresentation3D::SetWorldPosition(double p[3])
107 {
108  this->vtkPolygonalHandleRepresentation3D::SetWorldPosition(p);
109  this->Follower->SetPosition(this->GetWorldPosition());// p may have been clamped
110 
111  this->UpdateLabel();
112 }
113 
114 //----------------------------------------------------------------------
115 
116 void fwHandleRepresentation3D::CreateDefaultProperties()
117 {
118  this->MarkerProperty = vtkProperty::New();
119  this->MarkerProperty->SetColor(1., 1., 0.);
120  this->MarkerProperty->SetOpacity(1.);
121 }
122 
123 //---------------------------------------------------------------------------
124 
125 void fwHandleRepresentation3D::SetShapeRepresentation( Shape shape)
126 {
127  this->ShapeRepresentation = shape;
128  if (this->ShapeRepresentation == SPHERE)
129  {
130  vtkSmartPointer<vtkCylinderSource> cynlinderSource = vtkCylinderSource::SafeDownCast(this->Marker);
131  if (!cynlinderSource)
132  {
133  cynlinderSource = vtkCylinderSource::New();
134  cynlinderSource->SetCenter(0., -1., 0.);
135  cynlinderSource->SetResolution(64);
136  cynlinderSource->SetHeight(0.);
137  cynlinderSource->SetRadius(this->MarkerRadiusFactor * this->SphereSource->GetRadius() );
138  this->Marker = cynlinderSource;
139  this->CleanPolyData->SetInputConnection(0, this->Marker->GetOutputPort(0));
140  }
141 
142  this->SetHandle(this->SphereSource->GetOutput());
143  }
144  else
145  {
146  vtkSmartPointer<vtkCubeSource> cubeSource = vtkCubeSource::SafeDownCast(this->Marker);
147  if (!cubeSource)
148  {
149  cubeSource = vtkCubeSource::New();
150  cubeSource->SetCenter(0., -1., 0.);
151  cubeSource->SetXLength(this->MarkerRadiusFactor * this->CubeSource->GetXLength() );
152  cubeSource->SetYLength(0.);
153  cubeSource->SetZLength(this->MarkerRadiusFactor * this->CubeSource->GetXLength() );
154  this->Marker = cubeSource;
155  this->CleanPolyData->SetInputConnection(0, this->Marker->GetOutputPort(0));
156  }
157 
158  this->SetHandle(this->CubeSource->GetOutput());
159  }
160 }
161 
162 //---------------------------------------------------------------------------
163 void fwHandleRepresentation3D::BuildRepresentation()
164 {
165  if (!this->GetRenderer() ||
166  !this->GetRenderer()->GetActiveCamera())
167  {
168  return;
169  }
170 
171  double currLength;
172  if (this->ShapeRepresentation == SPHERE)
173  {
174  currLength = this->SphereSource->GetRadius()*2;
175  }
176  else
177  {
178  currLength = this->CubeSource->GetXLength();
179  }
180 
181  if (currLength != this->HandleSize)
182  {
183  // Generate a handle with a radius of w_r in physical units
184  if (this->ShapeRepresentation == SPHERE)
185  {
186  this->SphereSource->SetRadius(this->HandleSize / 2.);
187  this->SphereSource->Update();
188 
189  vtkSmartPointer<vtkCylinderSource> cynlinderSource = vtkCylinderSource::SafeDownCast(this->Marker);
190  if (cynlinderSource)
191  {
192  cynlinderSource->SetRadius(this->MarkerRadiusFactor * this->HandleSize / 2. );
193  }
194 
195  this->SetHandle(this->SphereSource->GetOutput());
196  }
197  else
198  {
199  this->CubeSource->SetXLength(this->HandleSize);
200  this->CubeSource->SetYLength(this->HandleSize);
201  this->CubeSource->SetZLength(this->HandleSize);
202  this->CubeSource->Update();
203 
204  vtkSmartPointer<vtkCubeSource> cubeSource = vtkCubeSource::SafeDownCast(this->Marker);
205  if (cubeSource)
206  {
207  cubeSource->SetXLength(this->MarkerRadiusFactor * this->HandleSize );
208  cubeSource->SetYLength(0.);
209  cubeSource->SetZLength(this->MarkerRadiusFactor * this->HandleSize );
210  }
211 
212  this->SetHandle(this->CubeSource->GetOutput());
213  }
214 
215  this->Follower->SetCamera( this->GetRenderer()->GetActiveCamera() );
216  this->Marker->Update();
217 
218  const double textScale = 10;
219  this->SetLabelTextScale(textScale, textScale, textScale);
220 
221  // Update the label,
222  this->UpdateLabel();
223 
224  this->BuildTime.Modified();
225  }
226 }
227 
228 //----------------------------------------------------------------------
229 
230 void fwHandleRepresentation3D::GetActors(vtkPropCollection* pc)
231 {
232  this->Actor->GetActors(pc);
233  this->LabelTextActor->GetActors(pc);
234  this->Follower->GetActors(pc);
235 }
236 
237 //----------------------------------------------------------------------
238 
239 void fwHandleRepresentation3D::ReleaseGraphicsResources(vtkWindow* win)
240 {
241  this->Actor->ReleaseGraphicsResources(win);
242  this->LabelTextActor->ReleaseGraphicsResources(win);
243  this->Follower->ReleaseGraphicsResources(win);
244 }
245 
246 //----------------------------------------------------------------------
247 
248 int fwHandleRepresentation3D::RenderOpaqueGeometry(vtkViewport* viewport)
249 {
250  this->BuildRepresentation();
251  int ret = 0;
252  if (this->GetRenderer()->GetActiveCamera()->GetParallelProjection())
253  {
254  ret = this->Follower->RenderOpaqueGeometry(viewport);
255  }
256  if (this->HandleVisibility)
257  {
258  ret += this->Actor->RenderOpaqueGeometry(viewport);
259  }
260  if (this->LabelVisibility)
261  {
262  ret += this->LabelTextActor->RenderOpaqueGeometry(viewport);
263  }
264 
265  return ret;
266 }
267 
268 //----------------------------------------------------------------------
269 
270 int fwHandleRepresentation3D::RenderTranslucentPolygonalGeometry(vtkViewport* viewport)
271 {
272  this->BuildRepresentation();
273  int ret = 0;
274  if (this->GetRenderer()->GetActiveCamera()->GetParallelProjection())
275  {
276  ret = this->Follower->RenderTranslucentPolygonalGeometry(viewport);
277  }
278  if (this->HandleVisibility)
279  {
280  ret += this->Actor->RenderTranslucentPolygonalGeometry(viewport);
281  }
282  if (this->LabelVisibility)
283  {
284  ret += this->LabelTextActor->RenderTranslucentPolygonalGeometry(viewport);
285  }
286  return this->Actor->RenderTranslucentPolygonalGeometry(viewport) + ret;
287 }
288 
289 //----------------------------------------------------------------------
290 
291 int fwHandleRepresentation3D::HasTranslucentPolygonalGeometry()
292 {
293  return 1;
294 }
295 
296 //----------------------------------------------------------------------
297 
298 void fwHandleRepresentation3D::SetMarkerProperty(vtkProperty* p)
299 {
300  vtkSetObjectBodyMacro(MarkerProperty, vtkProperty, p);
301  if (p)
302  {
303  this->Follower->SetProperty( p );
304  }
305 }
306 
307 } // namespace vtk
308 
309 } // namespace fwRenderVTK
The namespace fwRenderVTK contains classes for rendering with VTK.