[vtkusers] Dealing with QTBUG-40889

Elvis Stansvik elvis.stansvik at orexplore.com
Sat Jul 2 06:41:08 EDT 2016


2016-07-02 12:12 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:

> Thanks to both of you for your answers.
>
> 2016-07-02 1:13 GMT+02:00 David Gobbi <david.gobbi at gmail.com>:
>
>> On Fri, Jul 1, 2016 at 4:08 PM, <clinton at elemtech.com> wrote:
>>
>>>
>>>
>>> ----- On Jul 1, 2016, at 7:07 AM, Elvis Stansvik <
>>> elvis.stansvik at orexplore.com> wrote:
>>>
>>> I'm in the unfortunate situation of having to support Qt 5.5.1, and I'm
>>> hit by
>>>
>>> https://bugreports.qt.io/browse/QTBUG-40889
>>>
>>> which was fixed in 5.6 with
>>>
>>> https://codereview.qt-project.org/#/c/126136/
>>>
>>> I've been trying to find a way to work around this bug using a
>>> combination of native and non-native event filters in Qt, but haven't
>>> really found a good solution.
>>>
>>> The problem is I want to use the built-in interactor styles in VTK, such
>>> as vtkInteractorStyleTrackballCamera, and these makes calls to Render() as
>>> fast as the mouse events arrive.
>>>
>>> I have to ask: Is this really a good idea, shoudn't the rendering be
>>> governed by a timer during the interaction (say dolly), to be more robust
>>> against a flood of mouse events? The reason Qt has even buffered events
>>> (and hence opened up for compression, barring that bug) is that the main
>>> thread is overworked. And this is due to VTK rendering at every mouse move
>>> event.
>>>
>>> If I make my own completely custom interactor style, I of course have
>>> full control and can let a timer govern the rendering, but I was hoping to
>>> leverage the built-in ones. And it's not possible to subclass them and
>>> disable just the Render calls unfortunately.
>>>
>>> At the moment I don't quite know what to do. Moving the camera around in
>>> a VTK window is like syrup, and our product is to run using the Qt 5.5.1
>>> that is packaged in *buntu Xenial :(
>>>
>>> Thanks for any advice, especially if you've worked around this problem
>>> yourself somehow.
>>>
>>> Elvis
>>>
>>>
>>> I think this problem is related to not following the Qt recommended way
>>> of doing rendering with mouse events.
>>> What Qt 5.5 would like to do is give you 2 or maybe 3 mouse events per
>>> render.
>>>
>>> To do that with VTK, you can implement a render callback for the
>>> interactor, which calls QVTKWidget::update(), then overload
>>> QVTKWidget::paintEvent() to call vtkRenderWindow::Render() instead of
>>> vtkRenderWindowInteractor::Render().
>>>
>>> This is what I have done to gain back the responsiveness.
>>> I've had thoughts in the past about proposing
>>> a vtkRenderWindowInteractor::RequestRender() function which the interactor
>>> style classes can use, which might help solve this problem.  But then with
>>> Qt 5.6, the problem goes away.
>>>
>>
> This worked great and is a much simpler workaround than I had in mind.
> Thanks!
>
> For reference to others, what I did in the QVTKWidget subclass I was
> experimenting with was:
>
> SampleWidget::SampleWidget(QWidget *parent, Qt::WindowFlags f) :
> QVTKWidget(parent, f)
> {
>     // Set up some stuff (cylinder, polymapper, renderer)
>
>     GetInteractor()->AddObserver(vtkCommand::RenderEvent, this,
> &SampleWidget::onInteractorRender);
>

In fact, I could use update() as the callback directly:

    GetInteractor()->AddObserver(vtkCommand::RenderEvent, this,
&SampleWidget::update);

Elvis


>     GetInteractor()->SetEnableRender(false);
> }
>
> void SampleWidget::paintEvent(QPaintEvent *event)
> {
>     Q_UNUSED(event);
>
>     if (updatesEnabled()) {
>         GetRenderWindow()->Render();
>     }
> }
>
> void SampleWidget::onInteractorRender(vtkObject* caller, long unsigned int
> eventId, void* callData)
> {
>     Q_UNUSED(caller);
>     Q_UNUSED(eventId);
>     Q_UNUSED(callData);
>
>     update();
> }
>
> The GetInteractor()->SetEnableRender(false) was one important part,
> otherwise the interactor would still issue direct calls to Render on the
> render window.
>
>
>>
>> I don't use the interactors, but apart from that my Qt widget does what
>> Clint describes:
>>
>> void cbQtWidget::paintEvent(QPaintEvent *)
>> {
>>   if (updatesEnabled()) {
>>     m_ViewFrame->Render();  // calls vtkRenderWindow::Render()
>>   }
>> }
>>
>> This is the only place where I allow a render to occur. Qt is 100% in
>> charge.
>>
>
> Yep, this worked fine. And with Clint's maneuver I could also make use of
> the interactor/interactor styles.
>
>
>>
>> However, since VTK no longer renders for every input event, I have to be
>> careful when I use the VTK picker.  I wrote a method called
>> UpdatePropsForPick() that I call for every input event, and it ensures that
>> the picking works correctly regardless of whether the Render()s are
>> actually happening.
>>
>
> Ah, this is good advice. Would you mind sharing how it ensures this? Not
> necessarily in code, but just in a few words? I'm quite new to VTK and
> haven't done any picking yet.
>
> Elvis
>
>
>>
>>  - David
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160702/9b09bf38/attachment.html>


More information about the vtkusers mailing list