Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

298 lines
9.8 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkInteractorObserver.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkInteractorObserver.h"
#include "vtkCallbackCommand.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
vtkCxxRevisionMacro(vtkInteractorObserver, "$Revision: 1.32 $");
vtkCxxSetObjectMacro(vtkInteractorObserver,DefaultRenderer,vtkRenderer);
//----------------------------------------------------------------------------
vtkInteractorObserver::vtkInteractorObserver()
{
this->Enabled = 0;
this->Interactor = NULL;
this->EventCallbackCommand = vtkCallbackCommand::New();
this->EventCallbackCommand->SetClientData(this);
//subclass has to invoke SetCallback()
this->KeyPressCallbackCommand = vtkCallbackCommand::New();
this->KeyPressCallbackCommand->SetClientData(this);
this->KeyPressCallbackCommand->SetCallback(vtkInteractorObserver::ProcessEvents);
this->CurrentRenderer = NULL;
this->DefaultRenderer = NULL;
this->Priority = 0.0;
this->KeyPressActivation = 1;
this->KeyPressActivationValue = 'i';
this->CharObserverTag = 0;
this->DeleteObserverTag = 0;
}
//----------------------------------------------------------------------------
vtkInteractorObserver::~vtkInteractorObserver()
{
this->SetEnabled(0);
this->SetCurrentRenderer(NULL);
this->SetDefaultRenderer(NULL);
this->EventCallbackCommand->Delete();
this->KeyPressCallbackCommand->Delete();
this->SetInteractor(0);
}
//----------------------------------------------------------------------------
void vtkInteractorObserver::SetCurrentRenderer(vtkRenderer *_arg)
{
if (this->CurrentRenderer == _arg)
{
return;
}
if (this->CurrentRenderer != NULL)
{
this->CurrentRenderer->UnRegister(this);
}
// WARNING: see .h, if the DefaultRenderer is set, whatever the value
// of _arg (except NULL), we are going to use DefaultRenderer
// Normally when the widget is activated (SetEnabled(1) or when
// keypress activation takes place), the renderer over which the mouse
// pointer is positioned is used to call SetCurrentRenderer().
// Alternatively, we may want to specify a user-defined renderer to bind the
// interactor to when the interactor observer is activated.
// The problem is that in many 3D widgets, when SetEnabled(0) is called,
// the CurrentRender is set to NULL. In that case, the next time
// SetEnabled(1) is called, the widget will try to set CurrentRenderer
// to the renderer over which the mouse pointer is positioned, and we
// will use our user-defined renderer. To solve that, we introduced the
// DefaultRenderer ivar, which will be used to force the value of
// CurrentRenderer each time SetCurrentRenderer is called (i.e., no matter
// if SetCurrentRenderer is called with the renderer that was poked at
// the mouse coords, the DefaultRenderer will be used).
if (_arg && this->DefaultRenderer)
{
_arg = this->DefaultRenderer;
}
this->CurrentRenderer = _arg;
if (this->CurrentRenderer != NULL)
{
this->CurrentRenderer->Register(this);
}
this->Modified();
}
//----------------------------------------------------------------------------
// This adds the keypress event observer and the delete event observer
void vtkInteractorObserver::SetInteractor(vtkRenderWindowInteractor* i)
{
if (i == this->Interactor)
{
return;
}
// if we already have an Interactor then stop observing it
if (this->Interactor)
{
this->SetEnabled(0); //disable the old interactor
this->Interactor->RemoveObserver(this->CharObserverTag);
this->CharObserverTag = 0;
this->Interactor->RemoveObserver(this->DeleteObserverTag);
this->DeleteObserverTag = 0;
}
this->Interactor = i;
// add observers for each of the events handled in ProcessEvents
if (i)
{
this->CharObserverTag = i->AddObserver(vtkCommand::CharEvent,
this->KeyPressCallbackCommand,
this->Priority);
this->DeleteObserverTag = i->AddObserver(vtkCommand::DeleteEvent,
this->KeyPressCallbackCommand,
this->Priority);
}
this->Modified();
}
//----------------------------------------------------------------------------
void vtkInteractorObserver::ProcessEvents(vtkObject* vtkNotUsed(object),
unsigned long event,
void* clientdata,
void* vtkNotUsed(calldata))
{
if (event == vtkCommand::CharEvent ||
event == vtkCommand::DeleteEvent)
{
vtkObject *vobj = reinterpret_cast<vtkObject *>( clientdata );
vtkInteractorObserver* self
= vtkInteractorObserver::SafeDownCast(vobj);
if (self)
{
if (event == vtkCommand::CharEvent)
{
self->OnChar();
}
else // delete event
{
self->SetInteractor(0);
}
}
else
{
vtkGenericWarningMacro("Process Events received a bad client data. The client data class name was " << vobj->GetClassName());
}
}
}
//----------------------------------------------------------------------------
void vtkInteractorObserver::StartInteraction()
{
this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetDesiredUpdateRate());
}
//----------------------------------------------------------------------------
void vtkInteractorObserver::EndInteraction()
{
this->Interactor->GetRenderWindow()->SetDesiredUpdateRate(this->Interactor->GetStillUpdateRate());
}
//----------------------------------------------------------------------------
// Description:
// Transform from display to world coordinates.
// WorldPt has to be allocated as 4 vector
void vtkInteractorObserver::ComputeDisplayToWorld(vtkRenderer *ren,
double x,
double y,
double z,
double worldPt[4])
{
ren->SetDisplayPoint(x, y, z);
ren->DisplayToWorld();
ren->GetWorldPoint(worldPt);
if (worldPt[3])
{
worldPt[0] /= worldPt[3];
worldPt[1] /= worldPt[3];
worldPt[2] /= worldPt[3];
worldPt[3] = 1.0;
}
}
//----------------------------------------------------------------------------
// Description:
// Transform from world to display coordinates.
// displayPt has to be allocated as 3 vector
void vtkInteractorObserver::ComputeWorldToDisplay(vtkRenderer *ren,
double x,
double y,
double z,
double displayPt[3])
{
ren->SetWorldPoint(x, y, z, 1.0);
ren->WorldToDisplay();
ren->GetDisplayPoint(displayPt);
}
//----------------------------------------------------------------------------
// Description:
// Transform from display to world coordinates.
// WorldPt has to be allocated as 4 vector
void vtkInteractorObserver::ComputeDisplayToWorld(double x,
double y,
double z,
double worldPt[4])
{
if ( !this->CurrentRenderer )
{
return;
}
this->ComputeDisplayToWorld(this->CurrentRenderer, x, y, z, worldPt);
}
//----------------------------------------------------------------------------
// Description:
// Transform from world to display coordinates.
// displayPt has to be allocated as 3 vector
void vtkInteractorObserver::ComputeWorldToDisplay(double x,
double y,
double z,
double displayPt[3])
{
if ( !this->CurrentRenderer )
{
return;
}
this->ComputeWorldToDisplay(this->CurrentRenderer, x, y, z, displayPt);
}
//----------------------------------------------------------------------------
void vtkInteractorObserver::OnChar()
{
// catch additional keycodes otherwise
if ( this->KeyPressActivation )
{
if (this->Interactor->GetKeyCode() == this->KeyPressActivationValue )
{
if ( !this->Enabled )
{
this->On();
}
else
{
this->Off();
}
this->KeyPressCallbackCommand->SetAbortFlag(1);
}
}//if activation enabled
}
//----------------------------------------------------------------------------
void vtkInteractorObserver::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Current Renderer: " << this->CurrentRenderer << "\n";
os << indent << "Default Renderer: " << this->DefaultRenderer << "\n";
os << indent << "Enabled: " << this->Enabled << "\n";
os << indent << "Priority: " << this->Priority << "\n";
os << indent << "Interactor: " << this->Interactor << "\n";
os << indent << "Key Press Activation: "
<< (this->KeyPressActivation ? "On" : "Off") << "\n";
os << indent << "Key Press Activation Value: "
<< this->KeyPressActivationValue << "\n";
}