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