[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