fw4spl
InteractorStyle3DForNegato.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-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/InteractorStyle3DForNegato.hpp"
8 
9 #include "vtkCellPicker.h"
10 
11 #include <fwCore/base.hpp>
12 
13 #include <vtkCallbackCommand.h>
14 #include <vtkCamera.h>
15 #include <vtkCommand.h>
16 #include <vtkMath.h>
17 #include <vtkObjectFactory.h>
18 #include <vtkRenderer.h>
19 #include <vtkRenderWindow.h>
20 #include <vtkRenderWindowInteractor.h>
21 
22 vtkStandardNewMacro(InteractorStyle3DForNegato);
23 
24 //------------------------------------------------------------------------------
25 
26 InteractorStyle3DForNegato::InteractorStyle3DForNegato() :
27  vtkInteractorStyleTrackballCamera()
28 {
29 }
30 
31 //------------------------------------------------------------------------------
32 
33 InteractorStyle3DForNegato::~InteractorStyle3DForNegato()
34 {
35 }
36 
37 //------------------------------------------------------------------------------
38 
39 void InteractorStyle3DForNegato::OnChar()
40 {
41  if(this->CurrentRenderer == nullptr)
42  {
43  return;
44  }
45 
46  vtkRenderWindowInteractor* rwi = this->Interactor;
47 
48  switch (rwi->GetKeyCode())
49  {
50  case 'r':
51  this->FindPokedRenderer(rwi->GetEventPosition()[0],
52  rwi->GetEventPosition()[1]);
53 
54  this->CurrentRenderer->ResetCamera();
55  if (this->getAutoRender())
56  {
57  rwi->Render();
58  }
59  break;
60  case 'f':
61  case 'F':
62  {
63  this->AnimState = VTKIS_ANIM_ON;
64  vtkAssemblyPath* path = NULL;
65  this->FindPokedRenderer(rwi->GetEventPosition()[0],
66  rwi->GetEventPosition()[1]);
67  rwi->GetPicker()->Pick(rwi->GetEventPosition()[0],
68  rwi->GetEventPosition()[1],
69  0.0,
70  this->CurrentRenderer);
71  vtkAbstractPropPicker* picker;
72  if ((picker = vtkAbstractPropPicker::SafeDownCast(rwi->GetPicker())))
73  {
74  path = picker->GetPath();
75  }
76  if (path != NULL)
77  {
78  rwi->FlyTo(this->CurrentRenderer, picker->GetPickPosition());
79  }
80  this->AnimState = VTKIS_ANIM_OFF;
81  }
82  break;
83 
84  }
85 }
86 
87 //------------------------------------------------------------------------------
88 
89 void InteractorStyle3DForNegato::OnKeyUp()
90 {
91  vtkRenderWindowInteractor* rwi = this->Interactor;
92 
93  switch (rwi->GetKeyCode())
94  {
95  case 'q':
96  OnLeftButtonUp();
97  break;
98  }
99 }
100 
101 //------------------------------------------------------------------------------
102 
103 void InteractorStyle3DForNegato::OnKeyDown()
104 {
105  vtkRenderWindowInteractor* rwi = this->Interactor;
106 
107  switch (rwi->GetKeyCode())
108  {
109  case 'q':
110  OnLeftButtonDown();
111  break;
112  }
113 }
114 
115 //------------------------------------------------------------------------------
116 
117 void InteractorStyle3DForNegato::OnLeftButtonDown()
118 {
119  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
120  this->Interactor->GetEventPosition()[1]);
121  if (this->CurrentRenderer == NULL)
122  {
123  return;
124  }
125 
126  this->GrabFocus(this->EventCallbackCommand);
127  m_oldPickPoint[0] = this->Interactor->GetEventPosition()[0];
128  m_oldPickPoint[1] = this->Interactor->GetEventPosition()[1];
129 
130  if (this->Interactor->GetShiftKey())
131  {
132  this->StartRotate();
133  }
134  else
135  {
136  if (this->Interactor->GetControlKey())
137  {
138  // press Ctrl key
139  this->StartSpin();
140  }
141  else
142  {
143  this->StartRotate();
144  }
145  }
146 }
147 
148 //------------------------------------------------------------------------------
149 
150 void InteractorStyle3DForNegato::OnRightButtonDown()
151 {
152  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
153  this->Interactor->GetEventPosition()[1]);
154  if (this->CurrentRenderer == NULL)
155  {
156  return;
157  }
158 
159  this->GrabFocus(this->EventCallbackCommand);
160 
161  m_oldPickPoint[0] = this->Interactor->GetEventPosition()[0];
162  m_oldPickPoint[1] = this->Interactor->GetEventPosition()[1];
163  this->StartDolly();
164 }
165 
166 //------------------------------------------------------------------------------
167 
168 void InteractorStyle3DForNegato::OnMiddleButtonDown()
169 {
170  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
171 
172  if (this->CurrentRenderer != NULL)
173  {
174  m_oldPickPoint[0] = this->Interactor->GetEventPosition()[0];
175  m_oldPickPoint[1] = this->Interactor->GetEventPosition()[1];
176  this->StartPan();
177  }
178 }
179 
180 //------------------------------------------------------------------------------
181 
182 void InteractorStyle3DForNegato::OnMouseMove()
183 {
184  int x = this->Interactor->GetEventPosition()[0];
185  int y = this->Interactor->GetEventPosition()[1];
186 
187  m_newPickPoint[0] = this->Interactor->GetEventPosition()[0];
188  m_newPickPoint[1] = this->Interactor->GetEventPosition()[1];
189 
190  switch (this->State)
191  {
192  case VTKIS_ROTATE:
193  this->FindPokedRenderer(x, y);
194  this->Rotate();
195  this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
196  break;
197 
198  case VTKIS_PAN:
199  this->FindPokedRenderer(x, y);
200  this->Pan();
201  this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
202  break;
203 
204  case VTKIS_DOLLY:
205  this->FindPokedRenderer(x, y);
206  this->Dolly();
207  this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
208  break;
209 
210  case VTKIS_SPIN:
211  this->FindPokedRenderer(x, y);
212  this->Spin();
213  this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
214  break;
215  }
216  m_oldPickPoint[0] = m_newPickPoint[0];
217  m_oldPickPoint[1] = m_newPickPoint[1];
218 }
219 
220 //----------------------------------------------------------------------------
221 
222 void InteractorStyle3DForNegato::OnMouseWheelBackward()
223 {
224  if (!this->Interactor->GetShiftKey())
225  {
226  this->GrabFocus(this->EventCallbackCommand);
227  this->StartDolly();
228  double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
229  this->Dolly(pow(1.1, factor));
230  this->EndDolly();
231  this->ReleaseFocus();
232  }
233 }
234 
235 //----------------------------------------------------------------------------
236 
237 void InteractorStyle3DForNegato::OnMouseWheelForward()
238 {
239  if (!this->Interactor->GetShiftKey())
240  {
241  this->GrabFocus(this->EventCallbackCommand);
242  this->StartDolly();
243  double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
244  this->Dolly(pow(1.1, factor));
245  this->EndDolly();
246  this->ReleaseFocus();
247  }
248 }
249 
250 //----------------------------------------------------------------------------
251 
252 void InteractorStyle3DForNegato::Pan()
253 {
254  if (this->CurrentRenderer == NULL)
255  {
256  return;
257  }
258 
259  // do nothing if mouse is still on the same pos
260  if( (m_newPickPoint[0] == m_oldPickPoint[0]) &&
261  (m_newPickPoint[1] == m_oldPickPoint[1]) )
262  {
263  return;
264  }
265 
266  vtkRenderWindowInteractor* rwi = this->Interactor;
267  double viewFocus[4], focalDepth, viewPoint[3];
268  double newPickPoint[4], oldPickPoint[4];
269  double motionVector[3];
270 
271  // Calculate the focal depth since we'll be using it a lot
272  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
273  camera->GetFocalPoint(viewFocus);
274  this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
275  viewFocus);
276  focalDepth = viewFocus[2];
277 
278  this->ComputeDisplayToWorld( m_newPickPoint[0],
279  m_newPickPoint[1],
280  focalDepth,
281  newPickPoint);
282 
283  // Has to recalc old mouse point since the viewport has moved,
284  // so can't move it outside the loop
285  this->ComputeDisplayToWorld(m_oldPickPoint[0],
286  m_oldPickPoint[1],
287  focalDepth,
288  oldPickPoint);
289 
290  // Camera motion is reversed
291  motionVector[0] = oldPickPoint[0] - newPickPoint[0];
292  motionVector[1] = oldPickPoint[1] - newPickPoint[1];
293  motionVector[2] = oldPickPoint[2] - newPickPoint[2];
294 
295  camera->GetFocalPoint(viewFocus);
296  camera->GetPosition(viewPoint);
297 
298  camera->SetFocalPoint(motionVector[0] + viewFocus[0],
299  motionVector[1] + viewFocus[1],
300  motionVector[2] + viewFocus[2]);
301 
302  camera->SetPosition(motionVector[0] + viewPoint[0],
303  motionVector[1] + viewPoint[1],
304  motionVector[2] + viewPoint[2]);
305 
306  if (rwi->GetLightFollowCamera())
307  {
308  this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
309  }
310 
311  if (this->getAutoRender())
312  {
313  rwi->Render();
314  }
315 }
316 
317 //----------------------------------------------------------------------------
318 
319 void InteractorStyle3DForNegato::Dolly()
320 {
321  if (this->CurrentRenderer == NULL)
322  {
323  return;
324  }
325  if( (m_newPickPoint[0] == m_oldPickPoint[0]) &&
326  (m_newPickPoint[1] == m_oldPickPoint[1]) )
327  {
328  return;
329  }
330  double* center = this->CurrentRenderer->GetCenter();
331  int dy = static_cast<int>(m_newPickPoint[1] - m_oldPickPoint[1]);
332  double dyf = this->MotionFactor * dy / center[1];
333  this->Dolly(pow(1.1, dyf));
334 }
335 
336 //----------------------------------------------------------------------------
337 
338 void InteractorStyle3DForNegato::Dolly(double factor)
339 {
340  if (this->CurrentRenderer == NULL)
341  {
342  return;
343  }
344 
345  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
346  if (camera->GetParallelProjection())
347  {
348  camera->SetParallelScale(camera->GetParallelScale() / factor);
349  }
350  else
351  {
352  camera->Dolly(factor);
353  if (this->AutoAdjustCameraClippingRange)
354  {
355  this->CurrentRenderer->ResetCameraClippingRange();
356  }
357  }
358 
359  if (this->Interactor->GetLightFollowCamera())
360  {
361  this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
362  }
363 
364  if (this->getAutoRender())
365  {
366  this->Interactor->Render();
367  }
368 }
369 
370 //----------------------------------------------------------------------------
371 
372 void InteractorStyle3DForNegato::Rotate()
373 {
374  if (this->CurrentRenderer == NULL)
375  {
376  return;
377  }
378  vtkRenderWindowInteractor* rwi = this->Interactor;
379  int dx = static_cast<int>(m_newPickPoint[0] - m_oldPickPoint[0]);
380  int dy = static_cast<int>(m_newPickPoint[1] - m_oldPickPoint[1]);
381  int* size = this->CurrentRenderer->GetRenderWindow()->GetSize();
382  double delta_elevation = -20.0 / size[1];
383  double delta_azimuth = -20.0 / size[0];
384  double rxf = dx * delta_azimuth * this->MotionFactor;
385  double ryf = dy * delta_elevation * this->MotionFactor;
386 
387  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
388  camera->Azimuth(rxf);
389  camera->Elevation(ryf);
390  camera->OrthogonalizeViewUp();
391  if (this->AutoAdjustCameraClippingRange)
392  {
393  this->CurrentRenderer->ResetCameraClippingRange();
394  }
395  if (rwi->GetLightFollowCamera())
396  {
397  this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
398  }
399 
400  if (this->getAutoRender())
401  {
402  rwi->Render();
403  }
404 }
405 
406 //----------------------------------------------------------------------------
407 
408 void InteractorStyle3DForNegato::Spin()
409 {
410  if ( this->CurrentRenderer == NULL )
411  {
412  return;
413  }
414  vtkRenderWindowInteractor* rwi = this->Interactor;
415  double* center = this->CurrentRenderer->GetCenter();
416  double newAngle =
417  vtkMath::DegreesFromRadians( atan2( m_newPickPoint[1] - center[1],
418  m_newPickPoint[0] - center[0] ) );
419  double oldAngle =
420  vtkMath::DegreesFromRadians( atan2( m_oldPickPoint[1] - center[1],
421  m_oldPickPoint[0] - center[0] ) );
422  vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
423  camera->Roll( newAngle - oldAngle );
424  camera->OrthogonalizeViewUp();
425 
426  if (this->getAutoRender())
427  {
428  rwi->Render();
429  }
430 }
bool getAutoRender() const
Get the autorender flag.