[vtkusers] Actor not visible when virtual camera is accessed in multi-renderer pipeline
Rhys Thomas
eep22f at bangor.ac.uk
Thu Jul 24 10:49:16 EDT 2008
Hello,
I am having issues with accessing an instance of vtkCamera in a vtk
pipeline containing layered renderers. The program should display the
view from a webcam in the background, and an assembly of volume data and
polydata in the foreground. If I attempt to access the instance of
vtkCamera associated with the renderer connected to the foreground
assembly during initialisation, the assembly is not displayed on screen.
Whilst this may seem unimportant in the example (a small program for
experimentation) below, it is much more of an issue for my main project.
Is there a simple fix for this?
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataReader.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
#include <vtkVolume.h>
#include <vtkAssembly.h>
#include <vtkVolumeTextureMapper3D.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkProperty.h>
#include <vtkCommand.h>
#include <vtkArrowSource.h>
#include <vtkTextActor3D.h>
#include <vtkTextProperty.h>
#include <vtkSphereSource.h>
#include <vtkWin32VideoSource.h>
#include <vtkImageMapper.h>
#include <vtkActor2D.h>
#include <vtkProperty2D.h>
#include <vtkCamera.h>
#include <vtkImageResample.h>
#include <vtkOutputWindow.h>
#include <vtkVectorText.h>
#include <vtkFollower.h>
#define OPACITY_DELTA 0.00125
#define _VIDEO_
vtkRenderWindowInteractor *iren;
vtkPiecewiseFunction *transparency;
vtkAssembly *assembly;
vtkVolumeProperty *volProperty;
vtkRenderWindow *renWin;
vtkProp3D *textPointer;
vtkProp3D *textPointer2;
vtkAssembly *aqueduct;
double opacityLevel;
double opacityDelta;
bool changeTransparency;
vtkWin32VideoSource *webcam;
vtkImageMapper *camMapper;
vtkActor2D *camActor;
vtkRenderer *renderer;
vtkFollower *vTextActor;
/**
Time dependant operations. Was initially used to change transparency
with
time (hence the name). Now rotates the assembly and grabs a camera
frame.
*/
class TransparencyChanger : public vtkCommand
{
public:
static TransparencyChanger *New()
{return new TransparencyChanger;}
virtual void Execute(vtkObject *caller, unsigned long, void *)
{
if(changeTransparency)
{
webcam->Grab();
/**
Reverse the direction of change of opacity if either
zero or one
have been reached.
*/
/* if((opacityLevel <= 0) || (opacityLevel >= 0.125))
{
opacityDelta *= -1;
}
opacityLevel += opacityDelta;*/
transparency->RemovePoint(3);
transparency->RemovePoint(255);
//transparency->AddSegment(2, opacityLevel, 255, opacityLevel);
transparency->AddPoint(3, opacityLevel);
transparency->AddPoint(255, opacityLevel);
// assembly->RotateX(0.1);
// cout << ".";
// cout << opacityLevel << "\r";
// assembly->Modified();
assembly->RotateY(1);
// textPointer->RotateY(1);
// textPointer2->RotateY(1);
aqueduct->RotateY(-1);
renWin->Render();
iren->CreateTimer(VTKI_TIMER_UPDATE);
cout << assembly->GetVisibility();
}
}
};
/**
Attempts to reset the vtk timer. Also gives feedback to the user about
what events have been generated.
*/
class TimerResetter : public vtkCommand
{
public:
static TimerResetter *New()
{return new TimerResetter;}
virtual void Execute(vtkObject *caller, unsigned long eventId, void *)
{
cout << "Event" << eventId << endl;
if(eventId == vtkCommand::ModifiedEvent)
{
cout << "Modified Event" << endl;
}
if(eventId == vtkCommand::StartEvent)
{
cout << "Start Event" << endl;
}
if(eventId == vtkCommand::DeleteEvent)
{
cout << "Delete Event" << endl;
}
if(eventId == vtkCommand::LeftButtonPressEvent)
{
cout << "Left Mouse Button Pressed" << endl;
}
iren->CreateTimer(VTKI_TIMER_UPDATE);
}
};
/**
Catches key events and processes them appropriately.
*/
class myVTKKeyboardCallback : public vtkCommand
{
public:
static myVTKKeyboardCallback *New()
{return new myVTKKeyboardCallback;}
virtual void Execute(vtkObject *caller, unsigned long, void *)
{
char keyPressed =
vtkRenderWindowInteractor::SafeDownCast(caller)->GetKeyCode();
/**
The escape key. Exit the program if this is pressed.
*/
//cout << keyPressed << endl;
if(keyPressed == 27)
{
iren->Disable();
iren->TerminateApp();
// cout << "Exit Event";
}
/**
Toggle whether or not the transparency changes with time.
*/
//if(keyPressed == 97)//The 'T' key
//{
// changeTransparency = !changeTransparency;
// iren->ReInitialize();
//}
/**
Change the opacity of the volume data making the polydata
more or
less visible.
*/
if(keyPressed == ']')
{
if(opacityLevel > 0)
{
opacityLevel += OPACITY_DELTA;
cout << "Up" << endl;
renWin->Render();
}
}
if(keyPressed == '[')
{
if(opacityLevel < 0.25)
{
opacityLevel -= OPACITY_DELTA;
renWin->Render();
}
}
if(keyPressed == 'c')
{
vtkCamera *cam = renderer->GetActiveCamera();
vTextActor->SetCamera(cam);
vTextActor->Modified();
}
}
};
void main(int argc, char **argv)
{
vtkOutputWindow::GetInstance()->PromptUserOn();
/**
Set up pipeline for polydata.
*/
vtkPolyDataReader *polyReader = vtkPolyDataReader::New();
polyReader->SetFileName("C:\\JDHead\\VentriclesPoly.vtk");
//polyReader->SetFileName("VentriclesPoly.vtk");
polyReader->Update();
vtkPolyData *ventricles = polyReader->GetOutput();
vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
mapper->SetInput(ventricles);
vtkActor *actor = vtkActor::New();
actor->SetMapper(mapper);
vtkProperty *ventProperty = vtkProperty::New();
ventProperty->SetColor(1.0, 0, 0);
ventProperty->SetDiffuseColor(1.0, 0.0, 0.0);
ventProperty->SetSpecular(0);
// ventProperty->SetSpecularPower(20);
ventProperty->SetSpecularColor(0.75, 0.75, 0.75);
ventProperty->SetOpacity(1.0);
actor->SetProperty(ventProperty);
/**
Set up pipeline for volume data.
*/
vtkStructuredPointsReader *structReader =
vtkStructuredPointsReader::New();
structReader->SetFileName("C:\\JDHead\\JDHead_8.vtk");
//structReader->SetFileName("JDHead_8.vtk");
structReader->Update();
vtkStructuredPoints *points = structReader->GetOutput();
vtkVolumeTextureMapper3D *volMap = vtkVolumeTextureMapper3D::New();
volMap->SetInput(points);
vtkVolume *volume = vtkVolume::New();
volume->SetMapper(volMap);
opacityLevel = 0.01;
opacityDelta = OPACITY_DELTA;
transparency = vtkPiecewiseFunction::New();
transparency->AddSegment(0, 0, 2, 0);
// transparency->AddSegment(2, 0.01, 255, 0.01);
transparency->AddPoint(3, opacityLevel);
transparency->AddPoint(255, opacityLevel);
/**
We want a transparent volume so that we can see the polydata
located
within.
*/
volProperty = vtkVolumeProperty::New();
volProperty->SetScalarOpacity(transparency);
volume->SetProperty(volProperty);
vtkColorTransferFunction *rescaleGrey = vtkColorTransferFunction::New();
rescaleGrey->AddRGBSegment(0.0, 0.0, 0.0, 0.0, 255.0, 1.0, 1.0, 1.0);
volProperty->SetColor(rescaleGrey);
/**
Set up pipeline for arrow. Use only one arrow, supplied to three
different
actors, each with a different position, orientation and scale.
*/
vtkArrowSource *arrow = vtkArrowSource::New();
arrow->SetTipResolution(20);
arrow->SetShaftResolution(20);
vtkPolyData *arrowData = arrow->GetOutput();
vtkPolyDataMapper *arrowMapper = vtkPolyDataMapper::New();
arrowMapper->SetInput(arrowData);
vtkActor *arrowActor = vtkActor::New();
arrowActor->SetMapper(arrowMapper);
vtkProperty *arrowProperty = vtkProperty::New();
arrowProperty->SetDiffuseColor(0.0, 1.0, 0.0);
arrowActor->SetProperty(arrowProperty);
arrowActor->SetScale(150);
arrowActor->SetPosition(30, 192, 110);
vtkActor *arrow2Actor = vtkActor::New();
arrow2Actor->SetMapper(arrowMapper);
arrow2Actor->SetScale(150);
arrow2Actor->SetProperty(arrowProperty);
arrow2Actor->SetPosition(430, 230, 110);
arrow2Actor->RotateY(180);
vtkActor *arrow3Actor = vtkActor::New();
arrow3Actor->SetMapper(arrowMapper);
arrow3Actor->SetScale(300, 50, 50);
arrow3Actor->SetPosition(92, 410, 260);
arrow3Actor->SetProperty(arrowProperty);
arrow3Actor->RotateY(45);
arrow3Actor->RotateZ(-45);
/**
Set up pipeline for 3D text. All text components here have the same
properties.
*/
vtkVectorText *vText = vtkVectorText::New();
vText->SetText("Third Ventricle");
vtkPolyDataMapper *vTextMapper = vtkPolyDataMapper::New();
vTextMapper->SetInput(vText->GetOutput());
vtkProperty *vTextProperty = vtkProperty::New();
vTextProperty->SetColor(0.0, 1.0, 0.0);
vTextActor = vtkFollower::New();
//vtkActor *vTextActor = vtkActor::New();
vTextActor->SetMapper(vTextMapper);
vTextActor->SetProperty(vTextProperty);
vTextActor->SetPosition(30, 180, 110);
vTextActor->RotateY(180);
vTextActor->RotateZ(180);
vTextActor->SetScale(20);
vtkVectorText *vText2 = vtkVectorText::New();
vText2->SetText("Fourth Ventricle");
vtkPolyDataMapper *vTextMapper2 = vtkPolyDataMapper::New();
vTextMapper2->SetInput(vText2->GetOutput());
//vtkFollower *vTextActor2 = vtkFollower::New();
vtkActor *vTextActor2 = vtkActor::New();
vTextActor2->SetMapper(vTextMapper2);
vTextActor2->SetProperty(vTextProperty);
vTextActor2->SetPosition(430, 218, 110);
vTextActor2->RotateZ(180);
vTextActor2->RotateY(180);
vTextActor2->SetScale(20);
vtkVectorText *vText3 = vtkVectorText::New();
vText3->SetText("Cerebral Aqueduct");
vtkPolyDataMapper *vTextMapper3 = vtkPolyDataMapper::New();
vTextMapper3->SetInput(vText3->GetOutput());
//vtkFollower *vTextActor3 = vtkFollower::New();
vtkActor *vTextActor3 = vtkActor::New();
vTextActor3->SetMapper(vTextMapper3);
vTextActor3->SetProperty(vTextProperty);
vTextActor3->SetPosition(92, 410, 260);
vTextActor3->RotateX(180);
vTextActor3->RotateY(180);
vTextActor3->SetScale(20);
/**
Set up combined part of the vtk pipeline.
*/
assembly = vtkAssembly::New();
assembly->AddPart(actor);
assembly->AddPart(volume);
assembly->AddPart(arrowActor);
assembly->AddPart(arrow2Actor);
assembly->RotateX(180);
assembly->SetOrigin(192, 192, 110);
assembly->SetPosition(192, 192, 110);
aqueduct = vtkAssembly::New();
aqueduct->AddPart(arrow3Actor);
aqueduct->SetOrigin(240, 200, 110);
assembly->AddPart(aqueduct);
aqueduct->RotateY(180);
assembly->AddPart(vTextActor);
assembly->AddPart(vTextActor2);
aqueduct->AddPart(vTextActor3);
cout << assembly->GetEstimatedRenderTime() << endl;
/**
Setup pipeline to capture video from our webcam.
*/
webcam = vtkWin32VideoSource::New();
webcam->SetFrameSize(640, 480, 1);
webcam->SetOutputFormat(VTK_RGB);
webcam->SetFrameRate(15.0);
//webcam->VideoFormatDialog();
camMapper = vtkImageMapper::New();
vtkImageResample *resample = vtkImageResample::New();
resample->SetInput(webcam->GetOutput());
resample->SetAxisOutputSpacing(0, 0.5);
resample->SetAxisOutputSpacing(1, 0.46875);
camMapper->SetInput(resample->GetOutput());
//camMapper->SetInput(webcam->GetOutput());
camMapper->SetColorLevel(127.5);
camMapper->SetColorWindow(255);
camMapper->SetZSlice(0);
camActor = vtkActor2D::New();
camActor->SetMapper(camMapper);
vtkRenderer *camRenderer = vtkRenderer::New();
camRenderer->AddActor(camActor);
renderer = vtkRenderer::New();
// vtkCamera *virtualCamera = renderer->GetActiveCamera();
// vtkCamera *virtualCamera = vtkCamera::New();
// renderer->SetActiveCamera(virtualCamera);
renderer->AddActor(assembly);
//renderer->AddActor(aqueduct);
// renderer->EraseOff();
camRenderer->EraseOff();
renderer->SetBackground(1.0, 1.0, 1.0);
renWin = vtkRenderWindow::New();
renWin->SetNumberOfLayers(2);
#ifdef _VIDEO_
renWin->AddRenderer(camRenderer);
#endif
renWin->AddRenderer(renderer);
renderer->SetLayer(1);
camRenderer->SetLayer(0);
renderer->SetViewport(0, 0, 1, 1);
camRenderer->SetViewport(0, 0, 1, 1);
// camRenderer->InteractiveOff();
renWin->SetSize(1280, 1024);
renWin->FullScreenOn();
renWin->SetStereoTypeToCrystalEyes();
// camActor->SetWidth(1);
// camActor->SetHeight(1);
// renderer->SetAllocatedRenderTime(0.25);
// camRenderer->SetAllocatedRenderTime(0.25);
vtkCamera *virtualCamera = renderer->GetActiveCamera(); //
<--------------------------------------------- This line causes the
assembly to not be displayed.
// vTextActor->SetCamera(camRenderer->GetActiveCamera());
// vTextActor2->SetCamera(camRenderer->GetActiveCamera());
// camRenderer->SetActiveCamera(virtualCamera);
// renderer->SetActiveCamera(virtualCamera);
// renderer->SetLayer(1);
/**
Set up interaction. The timer controls frame grabbing and
rotation of
the assembly.
*/
iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
myVTKKeyboardCallback *keyed = myVTKKeyboardCallback::New();
iren->AddObserver(vtkCommand::KeyPressEvent, keyed, 1);
TransparencyChanger *changer = TransparencyChanger::New();
iren->AddObserver(vtkCommand::TimerEvent, changer, 1);
TimerResetter *resetter = TimerResetter::New();
iren->AddObserver(vtkCommand::LeftButtonPressEvent, resetter, 0);
changeTransparency = true;
iren->Initialize();
iren->CreateTimer(VTKI_TIMER_FIRST);
iren->Start();
polyReader->Delete();
mapper->Delete();
actor->Delete();
structReader->Delete();
ventricles->Delete();
points->Delete();
renderer->Delete();
renWin->Delete();
iren->Delete();
}
Thanks
Rhys Thomas
--
Mr. Rhys Thomas
School of Computer Science
Bangor University
http://www.cs.bangor.ac.uk/
--
Gall y neges e-bost hon, ac unrhyw atodiadau a anfonwyd gyda hi,
gynnwys deunydd cyfrinachol ac wedi eu bwriadu i'w defnyddio'n unig
gan y sawl y cawsant eu cyfeirio ato (atynt). Os ydych wedi derbyn y
neges e-bost hon trwy gamgymeriad, rhowch wybod i'r anfonwr ar
unwaith a dilëwch y neges. Os na fwriadwyd anfon y neges atoch chi,
rhaid i chi beidio â defnyddio, cadw neu ddatgelu unrhyw wybodaeth a
gynhwysir ynddi. Mae unrhyw farn neu safbwynt yn eiddo i'r sawl a'i
hanfonodd yn unig ac nid yw o anghenraid yn cynrychioli barn
Prifysgol Bangor. Nid yw Prifysgol Bangor yn gwarantu
bod y neges e-bost hon neu unrhyw atodiadau yn rhydd rhag firysau neu
100% yn ddiogel. Oni bai fod hyn wedi ei ddatgan yn uniongyrchol yn
nhestun yr e-bost, nid bwriad y neges e-bost hon yw ffurfio contract
rhwymol - mae rhestr o lofnodwyr awdurdodedig ar gael o Swyddfa
Cyllid Prifysgol Bangor. www.bangor.ac.uk
This email and any attachments may contain confidential material and
is solely for the use of the intended recipient(s). If you have
received this email in error, please notify the sender immediately
and delete this email. If you are not the intended recipient(s), you
must not use, retain or disclose any information contained in this
email. Any views or opinions are solely those of the sender and do
not necessarily represent those of the Bangor University.
Bangor University does not guarantee that this email or
any attachments are free from viruses or 100% secure. Unless
expressly stated in the body of the text of the email, this email is
not intended to form a binding contract - a list of authorised
signatories is available from the Bangor University Finance
Office. www.bangor.ac.uk
More information about the vtkusers
mailing list