[vtkusers] 3D axis that follows main actor
Steve Boyd
boyd at biomed.ee.ethz.ch
Fri Sep 28 10:15:59 EDT 2001
Hello,
I've made an example C++ program that has a 3D axis that automatically
orients itself relative to the actor in the main renderer. I used
vtkCallbackCommand to do the automatic updates.
I'm posting this little example for two reasons: First, others might
find it useful. Second, because it would be appreciated if others with
more C++ experience could suggest improvements. For example, I wasn't
sure how to update the 3D axis renderer (aAxisRenderer) without
declaring it as a global variable.
Sincerely,
Steve
// An example of a 3D axis inset into the render window that
// illustrates the orientation of the object in the main
// render window.
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkActor.h"
#include "vtkDataSetMapper.h"
#include "vtkAxes.h"
#include "vtkTubeFilter.h"
#include "vtkSphereSource.h"
#include "vtkElevationFilter.h"
#include "vtkCommand.h"
void updateAxis(vtkObject*,unsigned long, void*, void*);
// global variables
vtkRenderWindow *renWin;
vtkRenderer *aAxisRenderer;
int main( int argc, char **argv )
{
// create the renderer stuff
vtkRenderer *aRenderer = vtkRenderer::New();
aRenderer->SetBackground(0,0,204);
aAxisRenderer = vtkRenderer::New();
aAxisRenderer->SetViewport(0.8,0,1,0.2);
aAxisRenderer->SetBackground(0,0,204);
aAxisRenderer->InteractiveOff();
renWin = vtkRenderWindow::New();
renWin->AddRenderer(aRenderer);
renWin->AddRenderer(aAxisRenderer);
renWin->SetSize(600,600);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
// make a sphere actor
vtkSphereSource *sphere = vtkSphereSource::New();
sphere->SetPhiResolution(12);
sphere->SetThetaResolution(12);
vtkElevationFilter *colorIt = vtkElevationFilter::New();
colorIt->SetInput(sphere->GetOutput());
colorIt->SetLowPoint(0,0,-1);
colorIt->SetHighPoint(0,0,1);
vtkDataSetMapper *sphereMapper = vtkDataSetMapper::New();
sphereMapper->SetInput(colorIt->GetOutput());
vtkActor *actor = vtkActor::New();
actor->SetMapper(sphereMapper);
// make the 3D axis
vtkAxes *axisObj = vtkAxes::New();
axisObj->SetScaleFactor(1.0);
vtkTubeFilter *axisTube = vtkTubeFilter::New();
axisTube->SetInput(axisObj->GetOutput());
axisTube->SetRadius(1.0/20.);
axisTube->SetNumberOfSides(6);
vtkPolyDataMapper *axisMapper = vtkPolyDataMapper::New();
axisMapper->SetInput(axisTube->GetOutput());
axisMapper->ScalarVisibilityOff();
vtkActor *axis = vtkActor::New();
axis->SetMapper(axisMapper);
axis->PickableOff();
axis->GetProperty()->SetColor(0,0,0);
// now, tell the main renderer our actors
aRenderer->AddActor(actor);
aAxisRenderer->AddActor(axis);
// callback command is set to watch the main renderer
vtkCallbackCommand *cbc = new vtkCallbackCommand;
cbc->SetCallback(updateAxis);
cbc->SetClientData((void*)aRenderer->GetActiveCamera());
aRenderer->AddObserver(vtkCommand::AnyEvent,cbc);
// start the interaction
iren->Initialize();
iren->Start();
// clean up
aRenderer->Delete();
aAxisRenderer->Delete();
sphere->Delete();
colorIt->Delete();
sphereMapper->Delete();
actor->Delete();
axisObj->Delete();
axisTube->Delete();
axisMapper->Delete();
axis->Delete();
}
void updateAxis(vtkObject* caller,
unsigned long vtkNotUsed(event),
void* arg, void* vtkNotUsed(whatIsThis))
{
double cPos[3], cFoc[3], aFoc[3];
int *size;
// set the axis camera according to the main renderer.
vtkCamera *cam = (vtkCamera *)arg;
cam->GetPosition(cPos);
cam->GetFocalPoint(cFoc);
aAxisRenderer->GetActiveCamera()->GetFocalPoint(aFoc);
aAxisRenderer->GetActiveCamera()->SetViewUp(cam->GetViewUp());
aAxisRenderer->GetActiveCamera()->SetPosition(cPos[0] - cFoc[0] +
aFoc[0],\
cPos[1] - cFoc[1] + aFoc[1],\
cPos[2] - cFoc[2] + aFoc[2]);
aAxisRenderer->ResetCamera();
// keep the axis window size a constant 120 pixels squared (ugly).
size = renWin->GetSize();
aAxisRenderer->SetViewport(\
((float)size[0]-120.)/(float)size[0],\
0.,\
1.,\
(120.)/(float)size[1]);
}
--
Steven Boyd, PhD
Institute for Biomedical Engineering
ETH and University Zuerich
Moussonstrasse 18
8044 Zuerich, Switzerland
tel. +41.1.632.4591 fax. +41.1.632.1214 boyd at biomed.ee.ethz.ch
-------------------------------------------------------------------
More information about the vtkusers
mailing list