[vtkusers] Multi-threaded VTK
Aashish Chaudhary
aashish.chaudhary at kitware.com
Mon Jun 27 12:15:05 EDT 2011
On Mon, Jun 27, 2011 at 10:21 AM, Chris Volpe ARA/SED <cvolpe at ara.com> wrote:
>> 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?
I see. I think that probably makes it easier. Have a look at this:
http://doc.qt.nokia.com/latest/threads-qobject.html#signals-and-slots-across-threads
Hope it helps.
>
> 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
>
--
| Aashish Chaudhary
| R&D Engineer
| Kitware Inc.
| www.kitware.com
More information about the vtkusers
mailing list