GOFIGURE2  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
vtkInteractorStyleImage2D.cxx
Go to the documentation of this file.
1 /*========================================================================
2  Copyright (c) INRIA - ASCLEPIOS Project (http://www-sop.inria.fr/asclepios).
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are met:
7 
8  * Redistributions of source code must retain the above copyright notice,
9  this list of conditions and the following disclaimer.
10 
11  * Redistributions in binary form must reproduce the above copyright notice,
12  this list of conditions and the following disclaimer in the documentation
13  and/or other materials provided with the distribution.
14 
15  * Neither the name of INRIA or ASCLEPIOS, nor the names of any contributors
16  may be used to endorse or promote products derived from this software
17  without specific prior written permission.
18 
19  * Modified source versions must be plainly marked as such, and must not be
20  misrepresented as being the original software.
21 
22  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
23  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
26  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  =========================================================================*/
33 
34 /*=========================================================================
35  Modifications were made by the GoFigure Dev. Team.
36  while at Megason Lab, Systems biology, Harvard Medical school, 2009-11
37 
38  Copyright (c) 2009-11, President and Fellows of Harvard College.
39  All rights reserved.
40 
41  Redistribution and use in source and binary forms, with or without
42  modification, are permitted provided that the following conditions are met:
43 
44  Redistributions of source code must retain the above copyright notice,
45  this list of conditions and the following disclaimer.
46  Redistributions in binary form must reproduce the above copyright notice,
47  this list of conditions and the following disclaimer in the documentation
48  and/or other materials provided with the distribution.
49  Neither the name of the President and Fellows of Harvard College
50  nor the names of its contributors may be used to endorse or promote
51  products derived from this software without specific prior written
52  permission.
53 
54  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
55  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
56  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
58  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
59  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
60  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
61  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
62  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
63  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
64  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65 
66  =========================================================================*/
67 
69 
70 #include "vtkAbstractPropPicker.h"
71 #include "vtkAssemblyPath.h"
72 #include "vtkMath.h"
73 #include "vtkObjectFactory.h"
74 #include "vtkRenderWindowInteractor.h"
75 #include <vtkImageData.h>
76 #include <vtkRenderWindow.h>
77 #include <vtkCamera.h>
78 #include <vtkRenderer.h>
79 #include "vtkProperty.h"
80 
81 #include "vtkViewImage2DCommand.h"
82 
83 
86 
87 //----------------------------------------------------------------------------
89 {
90  this->SliceStep = 0;
91  this->RequestedPosition = new int[2];
92  this->RequestedPosition[0] = this->RequestedPosition[1] = 0;
93 
94  this->m_LeftButtonDown = false;
95 
96  this->m_SynchronizeViews = true;
97 
99 }
100 
101 //----------------------------------------------------------------------------
102 
103 //----------------------------------------------------------------------------
106 {
107  delete[] this->RequestedPosition;
108 }
109 
110 //----------------------------------------------------------------------------
111 
112 //----------------------------------------------------------------------------
113 void
115 {
116  this->DefaultMoveAction();
117 
118  switch ( this->State )
119  {
120  case VTKIS_PAN:
121  this->InvokeEvent(vtkViewImage2DCommand::PanEvent);
122  break;
123  // USEFUL....
124  case VTKIS_SPIN:
125  case VTKIS_ROTATE:
126  case VTKIS_DOLLY:
127  case VTKIS_ZOOM:
128  this->InvokeEvent(vtkViewImage2DCommand::ZoomEvent);
129  break;
130  case VTKIS_FORWARDFLY:
131  case VTKIS_REVERSEFLY:
132  this->InvokeEvent(vtkViewImage2DCommand::CameraMoveEvent, this);
133  break;
134  case VTKIS_PICK:
136  break;
137  default:
138  this->Superclass::OnMouseMove();
139  break;
140  }
141 
142  //Update image information (pixel position and value)
143  this->InvokeEvent(vtkViewImage2DCommand::InteractionEvent, this);
144 }
145 
146 //----------------------------------------------------------------------------
147 void
149 {
150  int x = this->Interactor->GetEventPosition()[0];
151  int y = this->Interactor->GetEventPosition()[1];
152 
153  this->m_LeftButtonDown = true;
154 
155  this->FindPokedRenderer(x, y);
156 
157  if ( this->Interactor->GetRepeatCount() )
158  {
159  this->RequestedPosition[0] = x;
160  this->RequestedPosition[1] = y;
162  return;
163  }
164 
165  switch ( this->m_Mode )
166  {
167  case InteractionTypeZoom:
168  this->InvokeEvent(vtkViewImage2DCommand::ZoomEvent);
169  this->Superclass::OnRightButtonDown();
170  break;
171  case InteractionTypePan:
172  this->InvokeEvent(vtkViewImage2DCommand::PanEvent);
173  this->Superclass::OnMiddleButtonDown();
174  break;
177  break;
178  default:
179  break;
180  }
181 
182  // Call parent to handle all other states and perform additional work
183  this->Superclass::OnLeftButtonDown();
184 }
185 
186 //----------------------------------------------------------------------------
187 void
189 {
190  this->m_LeftButtonDown = false;
191 
192  switch ( this->m_Mode )
193  {
194  case InteractionTypeZoom:
195  this->Superclass::OnRightButtonDown();
196  break;
197  case InteractionTypePan:
198  this->Superclass::OnMiddleButtonDown();
199  break;
200  default:
201  break;
202  }
203 
204  // Call parent to handle all other states and perform additional work
205  this->Superclass::OnLeftButtonUp();
206 }
207 
208 //----------------------------------------------------------------------------
209 void
211 {
212  int x = this->Interactor->GetEventPosition()[0];
213  int y = this->Interactor->GetEventPosition()[1];
214 
215  this->FindPokedRenderer(x, y);
216 
217  switch ( this->m_Mode )
218  {
220  this->Superclass::OnLeftButtonDown();
221  break;
222  case InteractionTypeZoom:
223  this->InvokeEvent(vtkViewImage2DCommand::ZoomEvent);
224  this->Superclass::OnRightButtonDown();
225  break;
227  this->State = VTKIS_NONE;
228  break;
229  default:
230  break;
231  }
232 
233  // Call parent to handle all other states and perform additional work
234  this->Superclass::OnMiddleButtonDown();
235 }
236 
237 //----------------------------------------------------------------------------
238 void
240 {
241  switch ( this->m_Mode )
242  {
243  case InteractionTypeZoom:
244  this->Superclass::OnRightButtonUp();
245  break;
247  this->State = VTKIS_NONE;
248  this->Superclass::StartPick();
249  return;
250  default:
251  break;
252  }
253 
254  // Call parent to handle all other states and perform additional work
255  this->Superclass::OnMiddleButtonUp();
256 }
257 
258 //----------------------------------------------------------------------------
259 void
261 {
262  //change state to zoom
263  switch ( this->m_Mode )
264  {
265  case InteractionTypePan:
266  this->InvokeEvent(vtkViewImage2DCommand::PanEvent);
267  this->Superclass::OnMiddleButtonDown();
268  break;
270  this->Superclass::OnLeftButtonDown();
271  break;
273  this->State = VTKIS_NONE;
274  break;
275  default:
276  break;
277  }
278 
279  // Call parent to handle all other states and perform additional work
280  this->Superclass::OnRightButtonDown();
281 }
282 
283 //----------------------------------------------------------------------------
284 void
286 {
287  switch ( this->m_Mode )
288  {
289  case InteractionTypePan:
290  this->Superclass::OnMiddleButtonUp();
291  break;
293  this->Superclass::OnLeftButtonUp();
294  break;
296  this->State = VTKIS_NONE;
297  this->Superclass::StartPick();
298  return;
299  default:
300  break;
301  }
302 
303  // Call parent to handle all other states and perform additional work
304  this->Superclass::OnRightButtonUp();
305 }
306 
307 //----------------------------------------------------------------------------
308 void
310 {
311  int x = this->Interactor->GetEventPosition()[0];
312  int y = this->Interactor->GetEventPosition()[1];
313 
314  this->FindPokedRenderer(x, y);
315  if ( !this->CurrentRenderer )
316  {
317  return;
318  }
319 
320  switch ( this->m_Mode )
321  {
323  this->StartSliceMove();
324  this->SliceStep = static_cast< int >( this->MouseWheelMotionFactor );
325  this->SliceMove();
326  this->EndSliceMove();
327  break;
329  this->StartSliceMove();
330  this->SliceStep = static_cast< int >( this->MouseWheelMotionFactor );
331  this->SliceMove();
332  this->EndSliceMove();
333  break;
334  default:
335  break;
336  }
337 }
338 
339 //----------------------------------------------------------------------------
340 void
342 {
343  int x = this->Interactor->GetEventPosition()[0];
344  int y = this->Interactor->GetEventPosition()[1];
345 
346  this->FindPokedRenderer(x, y);
347  if ( !this->CurrentRenderer )
348  {
349  return;
350  }
351 
352  switch ( this->m_Mode )
353  {
355  this->StartSliceMove();
356  this->SliceStep = static_cast< int >( -this->MouseWheelMotionFactor );
357  this->SliceMove();
358  this->EndSliceMove();
359  break;
361  this->StartSliceMove();
362  this->SliceStep = static_cast< int >( -this->MouseWheelMotionFactor );
363  this->SliceMove();
364  this->EndSliceMove();
365  break;
366  default:
367  break;
368  }
369 }
370 
371 //----------------------------------------------------------------------------
372 void
374 {
375  vtkRenderWindowInteractor *rwi = this->Interactor;
376 
377  if ( !strcmp (rwi->GetKeySym(), "Up") )
378  {
379  this->SliceStep = 1;
380  this->StartSliceMove();
381  this->SliceStep = static_cast< int >( -this->MouseWheelMotionFactor );
382  this->SliceMove();
383  this->EndSliceMove();
384  }
385  else if ( !strcmp (rwi->GetKeySym(), "Down") )
386  {
387  this->SliceStep = -1;
388  this->StartSliceMove();
389  this->SliceMove();
390  this->EndSliceMove();
391  }
392  else if ( ( rwi->GetKeyCode() == 'r' ) || ( rwi->GetKeyCode() == 'R' ) )
393  {
394  this->InvokeEvent (vtkViewImage2DCommand::ResetWindowLevelEvent, this);
395  }
396  else if ( ( rwi->GetKeyCode() == 'o' ) || ( rwi->GetKeyCode() == 'O' ) )
397  {
398  this->InvokeEvent (vtkViewImage2DCommand::ResetViewerEvent, this);
399  }
400  else if ( ( rwi->GetKeyCode() == 'w' ) || ( rwi->GetKeyCode() == 'W' ) )
401  {
402  vtkActorCollection *ac;
403  vtkActor *anActor, *aPart;
404  vtkAssemblyPath *path;
405  this->FindPokedRenderer(rwi->GetEventPosition()[0],
406  rwi->GetEventPosition()[1]);
407  if(this->CurrentRenderer!=0)
408  {
409  ac = this->CurrentRenderer->GetActors();
410  vtkCollectionSimpleIterator ait;
411  for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); )
412  {
413  for (anActor->InitPathTraversal(); (path=anActor->GetNextPath()); )
414  {
415 
416  // make sure we don't modify the planes actors
417  if ( path != NULL )
418  {
419  std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin();
420  while(it2!=m_PlanesActors.end())
421  {
422  if(path && dynamic_cast<vtkProp*>(*it2) == path->GetLastNode()->GetViewProp())
423  {
424  path = NULL;
425  }
426  ++it2;
427  }
428  }
429 
430  // go on if target is not a plane
431  if(path)
432  {
433  aPart=static_cast<vtkActor *>(path->GetLastNode()->GetViewProp());
434  aPart->GetProperty()->SetRepresentationToWireframe();
435  }
436  }
437  }
438  }
439  else
440  {
441  vtkWarningMacro(<<"no current renderer on the interactor style.");
442  }
443  rwi->Render();
444  return;
445  }
446  else if ( ( rwi->GetKeyCode() == 's' ) || ( rwi->GetKeyCode() == 'S' ) )
447  {
448  vtkActorCollection *ac;
449  vtkActor *anActor, *aPart;
450  vtkAssemblyPath *path;
451  this->FindPokedRenderer(rwi->GetEventPosition()[0],
452  rwi->GetEventPosition()[1]);
453  if(this->CurrentRenderer!=0)
454  {
455  ac = this->CurrentRenderer->GetActors();
456  vtkCollectionSimpleIterator ait;
457  for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); )
458  {
459  for (anActor->InitPathTraversal(); (path=anActor->GetNextPath()); )
460  {
461 
462  // make sure we don't modify the planes actors
463  if ( path != NULL )
464  {
465  std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin();
466  while(it2!=m_PlanesActors.end())
467  {
468  if(path && dynamic_cast<vtkProp*>(*it2) == path->GetLastNode()->GetViewProp())
469  {
470  path = NULL;
471  }
472  ++it2;
473  }
474  }
475 
476  // go on if target is not a plane
477  if(path)
478  {
479  aPart=static_cast<vtkActor *>(path->GetLastNode()->GetViewProp());
480  aPart->GetProperty()->SetRepresentationToSurface();
481  }
482  }
483  }
484  }
485  else
486  {
487  vtkWarningMacro(<<"no current renderer on the interactor style.");
488  }
489  rwi->Render();
490  return;
491  }
492 
493  this->Superclass::OnChar();
494 }
495 
496 //----------------------------------------------------------------------------
497 void
499 {
500  vtkRenderWindowInteractor *rwi = this->Interactor;
501 
502  if ( !strcmp (rwi->GetKeySym(), "Up") )
503  {
504  this->SliceStep = 1;
505  this->StartSliceMove();
506  this->SliceMove();
507  this->EndSliceMove();
508  }
509  else if ( !strcmp (rwi->GetKeySym(), "Down") )
510  {
511  this->SliceStep = -1;
512  this->StartSliceMove();
513  this->SliceMove();
514  this->EndSliceMove();
515  }
516  else if ( !strcmp (rwi->GetKeySym(), "o") )
517  {
518  this->InvokeEvent (vtkViewImage2DCommand::ResetViewerEvent, this);
519  }
520  else if ( !strcmp (rwi->GetKeySym(), "r") )
521  {
522  this->InvokeEvent (vtkViewImage2DCommand::ResetWindowLevelEvent, this);
523  }
524 
525  this->Superclass::OnKeyUp();
526 }
527 
528 //----------------------------------------------------------------------------
529 void
531 {
532  this->Superclass::OnKeyPress();
533 }
534 
535 //----------------------------------------------------------------------------
536 void
538 {
539  this->Superclass::OnKeyRelease();
540 }
541 
542 //----------------------------------------------------------------------------
543 void
545 {
546  if ( ( this->State != VTKIS_NONE ) && ( this->State != VTKIS_PICK ) )
547  {
548  return;
549  }
550  this->StartState(VTKIS_SLICE_MOVE);
551  this->InvokeEvent(vtkViewImage2DCommand::StartSliceMoveEvent, this);
552 }
553 
554 //----------------------------------------------------------------------------
555 void
557 {
558  if ( this->State != VTKIS_SLICE_MOVE )
559  {
560  return;
561  }
562  this->StopState();
563  this->InvokeEvent(vtkViewImage2DCommand::EndSliceMoveEvent, this);
564 
565  // Call one more time to update views...
567  {
568  this->InvokeEvent(vtkViewImage2DCommand::SyncViewsEvent, this);
569  }
570 }
571 
572 //----------------------------------------------------------------------------
573 void
575 {
576  if ( this->State != VTKIS_SLICE_MOVE )
577  {
578  return;
579  }
581  {
582  this->InvokeEvent(vtkViewImage2DCommand::SyncViewsEvent, this);
583  }
584 }
585 
586 //----------------------------------------------------------------------------
587 void
589 {
590  // Apparently there is a problem here.
591  // The event vtkCommand::CharEvent and vtkCommand::KeyPressEvent seem
592  // to mix between each other.
593  // tackled by calling the charevent
594  // (supposed to be called at any keyboard event)
595  this->OnChar();
596  this->Superclass::OnKeyDown();
597 }
598 
599 //----------------------------------------------------------------------------
600 void
602 {
603  this->InvokeEvent (vtkViewImage2DCommand::DefaultMoveEvent, this);
604 }
605 
606 //----------------------------------------------------------------------------
607 vtkProp *
609 {
610  return this->CurrentProp;
611 }
612 
613 //----------------------------------------------------------------------------
614 void
616 {
617  vtkRenderWindowInteractor *rwi = this->Interactor;
618 
619  if ( this->CurrentRenderer != 0 )
620  {
621  vtkAssemblyPath *path = NULL;
622  int * eventPos = rwi->GetEventPosition();
623  this->FindPokedRenderer(eventPos[0], eventPos[1]);
624  rwi->StartPickCallback();
625  vtkAbstractPropPicker *picker =
626  vtkAbstractPropPicker::SafeDownCast( rwi->GetPicker() );
627  if ( picker != NULL )
628  {
629  picker->Pick(eventPos[0], eventPos[1],
630  0.0, this->CurrentRenderer);
631  path = picker->GetPath();
632  }
633 
634  // make sure we don't modify the planes actors
635  if ( path != NULL )
636  {
637  std::vector< vtkProp3D * >::iterator it2 = m_PlanesActors.begin();
638  while(it2!=m_PlanesActors.end())
639  {
640  if(path && dynamic_cast<vtkProp*>(*it2) == path->GetFirstNode()->GetViewProp())
641  {
642  path = NULL;
643  }
644  ++it2;
645  }
646  }
647 
648  if ( path == NULL )
649  {
650  this->HighlightProp(NULL);
651  this->PropPicked = 0;
652  }
653  else
654  {
655  this->HighlightProp( path->GetFirstNode()->GetViewProp() );
656  this->PropPicked = 1;
657  }
658  rwi->EndPickCallback();
659  }
660 }
661 
662 //----------------------------------------------------------------------------
663 void
665 {
666  this->State = VTKIS_NONE;
668 }
669 
670 //----------------------------------------------------------------------------
671 void
673 {
674  this->State = VTKIS_NONE;
675  this->m_Mode = InteractionTypeZoom;
676 }
677 
678 //----------------------------------------------------------------------------
679 void
681 {
682  this->State = VTKIS_NONE;
683  this->m_Mode = InteractionTypePan;
684 }
685 
686 //----------------------------------------------------------------------------
687 void
689 {
690  this->State = VTKIS_NONE;
692  this->Superclass::StartPick();
693 }
694 //----------------------------------------------------------------------------
695 void
697 {
698  m_SynchronizeViews = iSynchronize;
699 }
700 
701 //----------------------------------------------------------------------------
702 void
704 SetPlanesActors( std::vector< vtkProp3D * > iBounds)
705 {
706  this->m_PlanesActors= iBounds;
707 }
708 //----------------------------------------------------------------------------
void HighlightCurrentActor()
Draw a bounding box around the actor which is pointed by the cursor.
#define VTKIS_SLICE_MOVE
void SynchronizeViews(bool iSynchronize)
void SetPlanesActors(std::vector< vtkProp3D * > iBounds)
vtkCxxRevisionMacro(vtkFillImageWithPolyData,"$Revision: 490 $")
vtkProp * GetCurrentProp()
Return the actor which is pointed by the cursor.
Define the interactor behavior withing a vtkImage2D. 4 modes (Default, Zoom, Pan and Pick) ...
std::vector< vtkProp3D * > m_PlanesActors
void SetPanMode()
Start the Pan Mode.
void SetZoomMode()
Start the Zoom Mode.
void SetPickMode()
Start the Pick Mode.
vtkStandardNewMacro(vtkFillImageWithPolyData)
void SetDefaultMode()
Start the Default Mode.