1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkInteractorObserver.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkInteractorObserver.h"
16 
17 #include "vtkAbstractPropPicker.h"
18 #include "vtkCallbackCommand.h"
19 #include "vtkObjectFactory.h"
20 #include "vtkRenderer.h"
21 #include "vtkRenderWindow.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkObserverMediator.h"
24 #include "vtkPickingManager.h"
25 
26 
27 vtkCxxSetObjectMacro(vtkInteractorObserver,DefaultRenderer,vtkRenderer);
28 
29 //----------------------------------------------------------------------------
vtkInteractorObserver()30 vtkInteractorObserver::vtkInteractorObserver()
31 {
32   this->Enabled = 0;
33 
34   this->Interactor = NULL;
35 
36   this->EventCallbackCommand = vtkCallbackCommand::New();
37   this->EventCallbackCommand->SetClientData(this);
38 
39   //subclass has to invoke SetCallback()
40 
41   this->KeyPressCallbackCommand = vtkCallbackCommand::New();
42   this->KeyPressCallbackCommand->SetClientData(this);
43   this->KeyPressCallbackCommand->SetCallback(vtkInteractorObserver::ProcessEvents);
44 
45   this->CurrentRenderer = NULL;
46   this->DefaultRenderer = NULL;
47 
48   this->Priority = 0.0f;
49   this->PickingManaged = true;
50 
51   this->KeyPressActivation = 1;
52   this->KeyPressActivationValue = 'i';
53 
54   this->CharObserverTag = 0;
55   this->DeleteObserverTag = 0;
56 
57   this->ObserverMediator = 0;
58 }
59 
60 //----------------------------------------------------------------------------
~vtkInteractorObserver()61 vtkInteractorObserver::~vtkInteractorObserver()
62 {
63   this->UnRegisterPickers();
64 
65   this->SetEnabled(0);
66   this->SetCurrentRenderer(NULL);
67   this->SetDefaultRenderer(NULL);
68   this->EventCallbackCommand->Delete();
69   this->KeyPressCallbackCommand->Delete();
70   this->SetInteractor(0);
71 }
72 
73 //----------------------------------------------------------------------------
SetCurrentRenderer(vtkRenderer * _arg)74 void vtkInteractorObserver::SetCurrentRenderer(vtkRenderer *_arg)
75 {
76   if (this->CurrentRenderer == _arg)
77     {
78     return;
79     }
80 
81   if (this->CurrentRenderer != NULL)
82     {
83     this->CurrentRenderer->UnRegister(this);
84     }
85 
86   // WARNING: see .h, if the DefaultRenderer is set, whatever the value
87   // of _arg (except NULL), we are going to use DefaultRenderer
88   // Normally when the widget is activated (SetEnabled(1) or when
89   // keypress activation takes place), the renderer over which the mouse
90   // pointer is positioned is used to call SetCurrentRenderer().
91   // Alternatively, we may want to specify a user-defined renderer to bind the
92   // interactor to when the interactor observer is activated.
93   // The problem is that in many 3D widgets, when SetEnabled(0) is called,
94   // the CurrentRender is set to NULL. In that case, the next time
95   // SetEnabled(1) is called, the widget will try to set CurrentRenderer
96   // to the renderer over which the mouse pointer is positioned, and we
97   // will use our user-defined renderer. To solve that, we introduced the
98   // DefaultRenderer ivar, which will be used to force the value of
99   // CurrentRenderer each time SetCurrentRenderer is called (i.e., no matter
100   // if SetCurrentRenderer is called with the renderer that was poked at
101   // the mouse coords, the DefaultRenderer will be used).
102 
103   if (_arg && this->DefaultRenderer)
104     {
105     _arg = this->DefaultRenderer;
106     }
107 
108   this->CurrentRenderer = _arg;
109 
110   if (this->CurrentRenderer != NULL)
111     {
112     this->CurrentRenderer->Register(this);
113     }
114 
115   this->Modified();
116 }
117 
118 //----------------------------------------------------------------------------
119 // This adds the keypress event observer and the delete event observer
SetInteractor(vtkRenderWindowInteractor * i)120 void vtkInteractorObserver::SetInteractor(vtkRenderWindowInteractor* i)
121 {
122   if (i == this->Interactor)
123     {
124     return;
125     }
126 
127   // Since the observer mediator is bound to the interactor, reset it to
128   // 0 so that the next time it is requested, it is queried from the
129   // new interactor.
130   // Furthermore, remove ourself from the mediator queue.
131 
132   if (this->ObserverMediator)
133     {
134     this->ObserverMediator->RemoveAllCursorShapeRequests(this);
135     this->ObserverMediator = 0;
136     }
137 
138   // if we already have an Interactor then stop observing it
139   if (this->Interactor)
140     {
141     this->SetEnabled(0); //disable the old interactor
142     this->Interactor->RemoveObserver(this->CharObserverTag);
143     this->CharObserverTag = 0;
144     this->Interactor->RemoveObserver(this->DeleteObserverTag);
145     this->DeleteObserverTag = 0;
146     }
147 
148   this->Interactor = i;
149 
150   // add observers for each of the events handled in ProcessEvents
151   if (i)
152     {
153     this->CharObserverTag = i->AddObserver(vtkCommand::CharEvent,
154                                            this->KeyPressCallbackCommand,
155                                            this->Priority);
156     this->DeleteObserverTag = i->AddObserver(vtkCommand::DeleteEvent,
157                                              this->KeyPressCallbackCommand,
158                                              this->Priority);
159 
160     this->RegisterPickers();
161     }
162 
163   this->Modified();
164 }
165 
166 //----------------------------------------------------------------------------
RegisterPickers()167 void vtkInteractorObserver::RegisterPickers()
168 {
169 }
170 
171 //----------------------------------------------------------------------------
UnRegisterPickers()172 void vtkInteractorObserver::UnRegisterPickers()
173 {
174   vtkPickingManager* pm = this->GetPickingManager();
175   if (!pm)
176     {
177     return;
178     }
179 
180   pm->RemoveObject(this);
181 }
182 
183 //----------------------------------------------------------------------------
PickersModified()184 void vtkInteractorObserver::PickersModified()
185 {
186   if (!this->GetPickingManager())
187     {
188     return;
189     }
190 
191   this->UnRegisterPickers();
192   this->RegisterPickers();
193 }
194 
195 //----------------------------------------------------------------------------
GetPickingManager()196 vtkPickingManager* vtkInteractorObserver::GetPickingManager()
197 {
198   return this->Interactor ? this->Interactor->GetPickingManager() : 0;
199 }
200 
201 //------------------------------------------------------------------------------
202 vtkAssemblyPath* vtkInteractorObserver::
GetAssemblyPath(double X,double Y,double Z,vtkAbstractPropPicker * picker)203 GetAssemblyPath(double X, double Y, double Z, vtkAbstractPropPicker* picker)
204 {
205   if (!this->GetPickingManager())
206     {
207     picker->Pick(X, Y, Z, this->CurrentRenderer);
208     return picker->GetPath();
209     }
210 
211   return this->GetPickingManager()->GetAssemblyPath(
212     X, Y, Z, picker, this->CurrentRenderer, this);
213 }
214 
215 //----------------------------------------------------------------------------
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))216 void vtkInteractorObserver::ProcessEvents(vtkObject* vtkNotUsed(object),
217                                           unsigned long event,
218                                           void* clientdata,
219                                           void* vtkNotUsed(calldata))
220 {
221   if (event == vtkCommand::CharEvent ||
222       event == vtkCommand::DeleteEvent)
223     {
224     vtkObject *vobj = reinterpret_cast<vtkObject *>( clientdata );
225     vtkInteractorObserver* self
226       = vtkInteractorObserver::SafeDownCast(vobj);
227     if (self)
228       {
229       if (event == vtkCommand::CharEvent)
230         {
231         self->OnChar();
232         }
233       else // delete event
234         {
235         self->SetInteractor(0);
236         }
237       }
238     else
239       {
240       vtkGenericWarningMacro("Process Events received a bad client data. The client data class name was " << vobj->GetClassName());
241       }
242     }
243 }
244 
245 //----------------------------------------------------------------------------
StartInteraction()246 void vtkInteractorObserver::StartInteraction()
247 {
248   this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate());
249 }
250 
251 //----------------------------------------------------------------------------
EndInteraction()252 void vtkInteractorObserver::EndInteraction()
253 {
254   this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetStillUpdateRate());
255 }
256 
257 //----------------------------------------------------------------------------
258 // Description:
259 // Transform from display to world coordinates.
260 // WorldPt has to be allocated as 4 vector
ComputeDisplayToWorld(vtkRenderer * ren,double x,double y,double z,double worldPt[4])261 void vtkInteractorObserver::ComputeDisplayToWorld(vtkRenderer *ren,
262                                                   double x,
263                                                   double y,
264                                                   double z,
265                                                   double worldPt[4])
266 {
267   ren->SetDisplayPoint(x, y, z);
268   ren->DisplayToWorld();
269   ren->GetWorldPoint(worldPt);
270   if (worldPt[3])
271     {
272     worldPt[0] /= worldPt[3];
273     worldPt[1] /= worldPt[3];
274     worldPt[2] /= worldPt[3];
275     worldPt[3] = 1.0;
276     }
277 }
278 
279 
280 //----------------------------------------------------------------------------
281 // Description:
282 // Transform from world to display coordinates.
283 // displayPt has to be allocated as 3 vector
ComputeWorldToDisplay(vtkRenderer * ren,double x,double y,double z,double displayPt[3])284 void vtkInteractorObserver::ComputeWorldToDisplay(vtkRenderer *ren,
285                                                   double x,
286                                                   double y,
287                                                   double z,
288                                                   double displayPt[3])
289 {
290   ren->SetWorldPoint(x, y, z, 1.0);
291   ren->WorldToDisplay();
292   ren->GetDisplayPoint(displayPt);
293 }
294 
295 //----------------------------------------------------------------------------
296 // Description:
297 // Transform from display to world coordinates.
298 // WorldPt has to be allocated as 4 vector
ComputeDisplayToWorld(double x,double y,double z,double worldPt[4])299 void vtkInteractorObserver::ComputeDisplayToWorld(double x,
300                                                   double y,
301                                                   double z,
302                                                   double worldPt[4])
303 {
304   if ( !this->CurrentRenderer )
305     {
306     return;
307     }
308 
309   this->ComputeDisplayToWorld(this->CurrentRenderer, x, y, z, worldPt);
310 }
311 
312 
313 //----------------------------------------------------------------------------
314 // Description:
315 // Transform from world to display coordinates.
316 // displayPt has to be allocated as 3 vector
ComputeWorldToDisplay(double x,double y,double z,double displayPt[3])317 void vtkInteractorObserver::ComputeWorldToDisplay(double x,
318                                                   double y,
319                                                   double z,
320                                                   double displayPt[3])
321 {
322   if ( !this->CurrentRenderer )
323     {
324     return;
325     }
326 
327   this->ComputeWorldToDisplay(this->CurrentRenderer, x, y, z, displayPt);
328 }
329 
330 //----------------------------------------------------------------------------
OnChar()331 void vtkInteractorObserver::OnChar()
332 {
333   // catch additional keycodes otherwise
334   if ( this->KeyPressActivation )
335     {
336     if (this->Interactor->GetKeyCode() == this->KeyPressActivationValue )
337       {
338       if ( !this->Enabled )
339         {
340         this->On();
341         }
342       else
343         {
344         this->Off();
345         }
346       this->KeyPressCallbackCommand->SetAbortFlag(1);
347       }
348     }//if activation enabled
349 }
350 
351 //----------------------------------------------------------------------------
GrabFocus(vtkCommand * mouseEvents,vtkCommand * keypressEvents)352 void vtkInteractorObserver::GrabFocus(vtkCommand *mouseEvents, vtkCommand *keypressEvents)
353 {
354   if ( this->Interactor )
355     {
356     this->Interactor->GrabFocus(mouseEvents,keypressEvents);
357     }
358 }
359 
360 
361 //----------------------------------------------------------------------------
ReleaseFocus()362 void vtkInteractorObserver::ReleaseFocus()
363 {
364   if ( this->Interactor )
365     {
366     this->Interactor->ReleaseFocus();
367     }
368 }
369 
370 //----------------------------------------------------------------------------
RequestCursorShape(int requestedShape)371 int vtkInteractorObserver::RequestCursorShape(int requestedShape)
372 {
373   if ( !this->Interactor )
374     {
375     return 0;
376     }
377 
378   if ( ! this->ObserverMediator )
379     {
380     this->ObserverMediator = this->Interactor->GetObserverMediator();
381     }
382   int status = this->ObserverMediator->RequestCursorShape(this,requestedShape);
383   if ( status )
384     {
385     this->InvokeEvent(vtkCommand::CursorChangedEvent,NULL);
386     }
387   return status;
388 }
389 
390 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)391 void vtkInteractorObserver::PrintSelf(ostream& os, vtkIndent indent)
392 {
393   this->Superclass::PrintSelf(os,indent);
394 
395   os << indent << "Current Renderer: " << this->CurrentRenderer << "\n";
396   os << indent << "Default Renderer: " << this->DefaultRenderer << "\n";
397   os << indent << "Enabled: " << this->Enabled << "\n";
398   os << indent << "Priority: " << this->Priority << "\n";
399   os << indent << "Interactor: " << this->Interactor << "\n";
400   os << indent << "Key Press Activation: "
401      << (this->KeyPressActivation ? "On" : "Off") << "\n";
402   os << indent << "Key Press Activation Value: "
403      << this->KeyPressActivationValue << "\n";
404 }
405 
406 
407