[vtkusers] customizing the event loop
Andrew J. Dolgert
ajd27 at cornell.edu
Fri Dec 3 14:12:14 EST 2004
You can force a redraw with renderWindowInteractor->Render() or
renderWindow->Render().
The challenge to updating the pipeline asynchronously is that user
interaction could invoke Update() on the pipeline while you are changing
values, maybe even while you are inserting or removing filters. I've
always handled this by writing my own loop to do the update and call
Render(), but you want to stick to the
vtkRenderWindowInteractor::Start() so that it works cross-platform, so
let's think of another way.
If you want to modify a pipeline asynchronously while the user interacts
with it, you have to disconnect the pipeline's update mechanism from the
actor which the user sees. Using a shallow copy can help do this.
Starting with:
bFilter->SetInput( aFilter->GetOutput() );
mapper->SetInput( bFilter->GetOutput() );
Change it to:
bFilter->SetInput( aFilter->GetOutput() );
bFilter->Update();
vtkPolyData* pdCopy = vtkPolyData::New();
pdCopy->ShallowCopy( bFilter->GetOutput() );
mapper->SetInput( pdCopy );
pdCopy->Delete();
Now you can change aFilter without worrying about asynchronous actor
updates. The down side is that, every time you want to change what is
shown on the screen, you have to do a shallow copy again, and you don't
want to do the copy during an Update(). There was just some traffic on
this group about creating a filter which does this shallow copy, and it
sounded like a good idea. I think they even showed how to write the
code. Somewhere in there you need a critical section so that
bFilter->Update() doesn't get called during modifications to the
pipeline or during the shallow copy. I think VTK has a cross-platform
vtkSimpleCriticalSection for this.
You might think that the TimerEvent in the vtkInteractorStyle would let
you add an observer to the interactor style which would receive a
message at specified intervals, but you would be wrong. The Joystick
and Trackball interactor styles hijack this event so that it won't
function for your intentions. If you start the timer, it will work for
a while, until you manipulate the scene with the mouse. When you
release the mouse, the interactor calls EndRotate() or EndDolly() or
whatever, which destroys the timer. I don't know a good way around that
without changing library code. The good news is that, if you implement
a filter that does a guarded shallow copy, you could make your own
external loop that modifies the pipeline any time you want and won't
need to wait for VTK to tell you when it's okay to update.
Maybe someone else knows an easier way?
Drew Dolgert
Cornell Theory Center
More information about the vtkusers
mailing list