[vtkusers] Multi-threaded VTK

Chris Volpe ARA/SED cvolpe at ara.com
Wed Jun 22 16:41:00 EDT 2011


At the moment, I'm doing a very simplified version (for proof of concept) of my ultimate goal. The simplified version is to azimuth the camera by 10 degrees once a second in the main thread while showing a cone in the render window. So, no, I am not currently creating vtkObjects in the main thread once the background thread (interactor) starts..



Here's an excerpt of code from my "FeatureViewer" class. In my simplified proof of concept, the main program instantiates FeatureViewer and invokes the RunTest method, which sets everything up and spawns the background thread to run the interactor loop. When RunTest returns, the main program enters a loop in which it invokes CameraAzimuth once per second. You'll notice a couple references to a class called "vtkCommandDelegator" -- this is a template subclass of vtkCommand I wrote that allows you to specify and arbitrary method of an arbitrary class instance as the command callback. I wrote it because it seemed silly to have to create a new subclass of vtkCommand every time I want to have a callback for something.



I'll leave out the class def and just include the relevant methods for brevity.



static DWORD WINAPI ThreadCallbackFunction(LPVOID lpParameter)
{
      FeatureViewer *This = static_cast<FeatureViewer *>(lpParameter);

      // Start the render window interactor in the background
      This->InternalRunInteractor();
      return 0;
}

FeatureViewer::FeatureViewer()
{
      CS = vtkCriticalSection::New();
      pCam = NULL;
}


void FeatureViewer::LockCriticalSection(vtkObject *caller, unsigned long eventID, void *callData)
{
      CS->Lock();
      fprintf(stderr,"Interactor about to render\n");
}

void FeatureViewer::UnlockCriticalSection(vtkObject *caller, unsigned long eventID, void *callData)
{
      fprintf(stderr,"Interactor done rendering\n");
      CS->Unlock();

}


void FeatureViewer::RunInteractorInBackground()
{
      // Start up the thread
      LPSECURITY_ATTRIBUTES attr = NULL;
      SIZE_T stackSize = 0; // default = 1 MB
      DWORD dwCreationFlags = 0;
      LPDWORD noThreadID = NULL;

      HANDLE m_hThreadHandle = CreateThread(attr, stackSize, ThreadCallbackFunction,
            this, dwCreationFlags, noThreadID);
}

void FeatureViewer::InternalRunInteractor()
{
      // Called in background thread.
      pIRen->Initialize();
      pIRen->Start();
}



void FeatureViewer::CameraAzimuth(double rot)
{
      // Rotate camera here. Called by main thread
      CS->Lock();
      fprintf(stderr, "About to rotate camera\n");
      pCam->Azimuth(rot);
      pRenWin->Render();
      fprintf(stderr,"Done rotating camera\n");
      CS->Unlock();

}


void FeatureViewer::RunTest()

{
      vtkConeSource *cone = vtkConeSource::New();
      cone->SetHeight( 3.0 );
      cone->SetRadius( 1.0 );
      cone->SetResolution( 10 );
      vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
      coneMapper->SetInputConnection( cone->GetOutputPort() );
      vtkActor *coneActor = vtkActor::New();
      coneActor->SetMapper( coneMapper );

      pRen = vtkRenderer::New();
      pRen->AddActor( coneActor );
      pRen->SetBackground( 0.1, 0.2, 0.4 );
      pRenWin = vtkRenderWindow::New();
      pRenWin->AddRenderer( pRen );
      pRenWin->SetSize( 300, 300 );

      pIRen = vtkRenderWindowInteractor::New();
      pIRen->SetRenderWindow(pRenWin);

      vtkInteractorStyleTrackballCamera *style =
            vtkInteractorStyleTrackballCamera::New();
      pIRen->SetInteractorStyle(style);

pCam = pRen->GetActiveCamera();

      pStartInteractionCommand = vtkCommandDelegator<FeatureViewer>::New();
      pStartInteractionCommand->RegisterCallback(this, &FeatureViewer::LockCriticalSection);
      pEndInteractionCommand = vtkCommandDelegator<FeatureViewer>::New();
      pEndInteractionCommand->RegisterCallback(this, &FeatureViewer::UnlockCriticalSection);
      style->AddObserver(vtkCommand::StartInteractionEvent,pStartInteractionCommand);
      style->AddObserver(vtkCommand::EndInteractionEvent, pEndInteractionCommand);



      RunInteractorInBackground();

}



Thanks,

-Chris





> -----Original Message-----

> From: Aashish Chaudhary [mailto:aashish.chaudhary at kitware.com]

> Sent: Wednesday, June 22, 2011 12:46 PM

> To: Chris Volpe ARA/SED

> Cc: vtkusers at vtk.org

> Subject: Re: [vtkusers] Multi-threaded VTK

>

> On Wed, Jun 22, 2011 at 12:27 PM, Chris Volpe ARA/SED <cvolpe at ara.com>

> wrote:

> > I'm trying to have an application that drives scene content change on

> its

> > own, while still allowing the user to manipulate the scene with

> > vtkRenderWindowInteractor. The approach I'm trying to use is to have

> the

> > vtkRenderWindowInteractor run in a background thread, with some

> concurrency

> > protection to keep it from invoking the rendering pipeline at the

> same time

> > the main thread tries to do so. My application main thread creates

> all the

> > vtk objects (actor, render window, renderer, interactor), registers a

> couple

> > of callbacks for the interactor style's StartInteractionEvent and

> > EndInteractionEvent which lock and unlock a vtkCriticalSection,

> > respectively, and then spawns a background thread in which the

> interactor is

> > started. The main thread then, periodically, locks the critical

> section,

> > makes scene changes, renders, and unlocks the critical section.

> >

> >

> >

> > Although this approach seems sound in principle, I'm encountering

> corruption

> > that leads me to believe that there is some kind of pipeline

> manipulation

> > occurring before processing the StartInteractionEvent that is

> conflicting

> > with what I'm doing in my main thread. Can someone with detailed

> knowledge

> > of pipeline bowels provide some insight as to what might be going on,

> and

> > perhaps provide an alternate course of action?

>

> Do you produce new vtk objects in the background thread? If yes do you

> use vtkSmartPointer? That could be cause of the problem depending on

> how you are passing vtk objects from one thread to another.

>

> Also it might help if you can attach a minimal code to reproduce the

> behavior.

>

> Thanks

>

>

> >

> >

> >

> > Thanks,

> >

> >

> >

> > Chris

> >

> > --

> > Christopher R. Volpe,

> > Ph.D.

> Email:

> > cvolpe at ara.com

> >

> > Senior Scientist, Information Exploitation Systems             Main

> Desk:

> > 919-582-3300

> >

> > Applied Research Associates,

> > Inc                                                     Direct: 919-

> 582-3380

> >

> > 8537 Six Forks Rd., Suite

> > 6000                                                            Fax :

> > 919-582-3301

> >

> > Raleigh, NC 27615                                         Web:

> > http://www.ara.com/offices/NC.htm

> >

> >

> >

> >

> >

> > _______________________________________________

> > Powered by www.kitware.com

> >

> > Visit other Kitware open-source projects at

> > http://www.kitware.com/opensource/opensource.html

> >

> > Please keep messages on-topic and check the VTK FAQ at:

> > http://www.vtk.org/Wiki/VTK_FAQ

> >

> > Follow this link to subscribe/unsubscribe:

> > http://www.vtk.org/mailman/listinfo/vtkusers

> >

> >

>

>

>

> --

> | Aashish Chaudhary

> | R&D Engineer

> | Kitware Inc.

> | www.kitware.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20110622/598943f7/attachment.htm>


More information about the vtkusers mailing list