[vtkusers] Multi-threaded VTK

Chris Volpe ARA/SED cvolpe at ara.com
Mon Jun 27 10:21:26 EDT 2011


>  So to answer to your question, No VTK does not provide a mechanism to
> transfer data / information between threads in a thread safe way

I don't need that -- I can transfer data in a "non-VTK way" safely. It's just event generation that I'm interested in at this point. It seems to me it should be possible to tell the interactive renderer to respond to a "user event" in a particular way, and have my main thread have a vtkObject that generates that event when new data is available. But if that's not possible, then I'll stick with the timer.

> For our application we required something similar and since it is Qt
> based we used Qt signals slots which allowed us to invoke render
> thread with new data as soon as we get it.

My understanding is that when one Qt object emits a signal, the signal dispatching mechanism invokes the recipient's slot directly, i.e. in the same thread. (Since it's possible to use signals and slots outside a GUI framework in Qt, there's no reason for signal-emission code to assume that there's some other thread somewhere hanging out waiting for button clicks or other signal sources.) It's not clear to me if I could solve my problem using Qt then. Is it possible?

Thanks againk
-Chris


> -----Original Message-----
> From: Aashish Chaudhary [mailto:aashish.chaudhary at kitware.com]
> Sent: Monday, June 27, 2011 10:03 AM
> To: Chris Volpe ARA/SED
> Cc: Shashwath T.R.; vtkusers
> Subject: Re: [vtkusers] Multi-threaded VTK
>
> On Mon, Jun 27, 2011 at 8:36 AM, Chris Volpe ARA/SED <cvolpe at ara.com>
> wrote:
> > Thanks, Aashish, I believe I understand the situation now. Please see
> my reply to T.R. from a few minutes ago, and let me know if I have
> misunderstood the situation, or if you have a suggestion on the latency
> problem I mention there.
> >
> > As for what I am trying to achieve, here's the situation: I am
> supplying a library to a co-worker for use in his application. His
> application is not built with CMake and does not know about VTK in any
> way -- I am hiding those details behind an API via a pure-virtual
> abstract base class and a factory function that instantiates the
> concrete subclass that does all the VTK stuff. The client application
> needs to instantiate the class, set some parameters, call an
> initialization routine (which should pop up an interactive VTK window
> and return), and then periodically call routines which supply new data
> and camera positions and render the result, thereby producing an
> animation computed on the fly. In the midst of all this, the user has
> to be able to click in the window and do trackball-style interactions,
> pausing the application's animation during the user interaction. My
> initial approach was to use a mutex (actually, a vtkCriticalSection
> object), along with callbacks for StartInteraction and EndInteraction,
> to ensure that only *one* thread was accessing the graphics pipeline at
> a time. But now I see that that is not enough, since the OpenGL context
> is apparently thread-specific, so I need to get all the graphics out of
> the main application thread.
> >
>
> That explains it. I think you understand the situation.
>
>  So to answer to your question, No VTK does not provide a mechanism to
> transfer data / information between threads in a thread safe way (or
> any mechanism to invoke other thread in a safe way)
>
> For our application we required something similar and since it is Qt
> based we used Qt signals slots which allowed us to invoke render
> thread with new data as soon as we get it. You may encounter issues if
> you have multiple receivers. Also do not use vtkSmartPointer as means
> to pass data (no atomic ref count increments / decrements).  We have a
> class that provides atomic increments / decrements. We will see if
> that code could be released.
>
> Let me know if you have any other questions.
>
> > -Chris
> >
> >
> >> -----Original Message-----
> >> From: Aashish Chaudhary [mailto:aashish.chaudhary at kitware.com]
> >> Sent: Friday, June 24, 2011 4:45 PM
> >> To: Shashwath T.R.
> >> Cc: Chris Volpe ARA/SED; vtkusers
> >> Subject: Re: [vtkusers] Multi-threaded VTK
> >>
> >> Chris,
> >>
> >> If I understood your design then it won't work. Since the context is
> >> not shared and is not made active by the thread then you will have a
> >> crash eventually.
> >>
> >> What exactly you are trying to achieve with two threads?
> >>
> >> Regards,
> >> Aashish
> >>
> >> On Fri, Jun 24, 2011 at 2:57 AM, Shashwath T.R. <trshash at gmail.com>
> >> wrote:
> >> > Right, there are obviously good reasons to want multi-threading,
> but
> >> the
> >> > tradeoffs have to be analyzed.
> >> >
> >> > Like I said earlier, in any case, the interactive thread should be
> >> the
> >> > primary thread of the application. In Windows, cross-thread GUI
> calls
> >> > (rendering, for example), are undefined.
> >> >
> >> > Regards,
> >> > Shash
> >> >
> >> > On Thu, Jun 23, 2011 at 5:43 PM, Chris Volpe ARA/SED
> <cvolpe at ara.com>
> >> wrote:
> >> >>
> >> >> I misspoke: I said "non-rendering thread" when I meant "non-
> >> interactive
> >> >> thread"
> >> >>
> >> >>
> >> >>
> >> >> -Chris
> >> >>
> >> >>
> >> >>
> >> >> From: Chris Volpe ARA/SED
> >> >> Sent: Thursday, June 23, 2011 7:41 AM
> >> >> To: 'Shashwath T.R.'
> >> >> Subject: RE: [vtkusers] Multi-threaded VTK
> >> >>
> >> >>
> >> >>
> >> >> Using a timer was my fallback approach. I wanted to avoid it
> because
> >> data
> >> >> changes are going to be driven asynchronously by the non-
> rendering
> >> thread.
> >> >>
> >> >>
> >> >>
> >> >> Thanks,
> >> >>
> >> >>
> >> >>
> >> >> -Chris
> >> >>
> >> >>
> >> >>
> >> >> From: Shashwath T.R. [mailto:trshash at gmail.com]
> >> >>
> >> >> Sent: Thursday, June 23, 2011 1:54 AM
> >> >> To: Chris Volpe ARA/SED
> >> >> Subject: Re: [vtkusers] Multi-threaded VTK
> >> >>
> >> >>
> >> >>
> >> >> If you're doing this in Windows, I'd definitely suggest doing it
> the
> >> other
> >> >> way around; that is, run the interactor in the main thread and
> the
> >> updation
> >> >> in the worker thread.
> >> >>
> >> >> Generally, in Windows, the UI cannot be touched on a cross-thread
> >> call;
> >> >> the thread that created the UI should handle it. It's always
> better
> >> to run
> >> >> the interactor in the main thread.
> >> >>
> >> >> In any case, for a simple azimuth change once a second, it should
> be
> >> >> possible to create a timer on the interactor and do your camera
> >> management
> >> >> inside the timer callback.
> >> >>
> >> >> Regards,
> >> >> Shash
> >> >>
> >> >> On Thu, Jun 23, 2011 at 2:11 AM, Chris Volpe ARA/SED
> >> <cvolpe at ara.com>
> >> >> wrote:
> >> >>
> >> >> 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
> >> >>
> >> >> _______________________________________________
> >> >> 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
> >> >>
> >> >>
> >> >
> >> > _______________________________________________
> >> > 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
> >
>
>
>
> --
> | Aashish Chaudhary
> | R&D Engineer
> | Kitware Inc.
> | www.kitware.com



More information about the vtkusers mailing list