We have a VTK based Qt6 application that we are building and we would like to add the feature that would allow the user to hover their mouse over a point/cell in the VTK scene and have a pop up that gives information about that point. There is similar functionality in ParaView. We tried a few different implementations but they are all very slow and laggy (when compared to ParaView). We tried researching better algorithms or even digging into ParaView (daunting at best) but didn’t really find anything.
What would be the “modern VTK” way of doing this? If anyone has an example that uses QtVtkRendering (or what ever that class is) that would be awesome.
This feature is seriously awesome! Previously, I used to subclass vtkInteractorStyleTrackballCamera to “pick” the props or cells under the mouse using vtkHardwarePicker in the mouse move handler. See HoverPickStyle::OnMouseMove. Have you tried this approach?
Feel free to give it a shot and replicate what I did in the screen recording, live at jspanchu.dev/vtkWasmBenchmark. This is all just VTK. Just to let you know, in my situation, I re-render the scene where the stuff under the mouse gets bigger. It seems to make things a bit slower. Since you’re just looking to log or display the cells in the user interface, I’d expect it to be much quicker!
Just keep in mind that because this is a fresh interactor style customized for your app, the application should have the capability to switch to this interactor style on the fly when you enter hover mode.
Please let us know if you run into other issues. Happy to help.
I have been trying to figure out how to integrate it into our application. Coming up a bit short. I think I have all the bits in place. I am getting a whole lot of:
2023-09-05 15:09:14.836 ( 174.907s) [ 300DAC] vtkHardwarePicker.cxx:315 ERR| vtkHardwarePicker (0x7fbfa75fc1b0): The intersection was not properly found
I had to adjust a few bits like adding in our DataSets one at a time (but that should be working correctly).
Which is a Q_SLOT that gets called when you click a button. I also note that you are highlighting an entire “geometry” where I just want to highlight a point or cell. I will look into the vtkHardwarePicker and see what I can figure out from that.
It’s been a while, and I am getting rustier by the day, but I believe the ParaView implementation uses AreaSelection (or more precisely the infrastructure behind that) to do its thing. Ie when the mode is on, after every camera motion ParaView causes the renderer to render (offscreen) additional passes that assign one or more IDs to each pixel in one or more auxilliary buffers.
On a hover the “colors” aka ids are read back, mapped back to the originating cell/point, and displayed. The GLOBAL_IDS concept in VTK’s DataSetAttributes are there to help out with the mapping back process.
At @cory.quammen please correct me if/as I may be off.
Dave has it right AFAIK at a high level. How that translates into VTK object interactions - I’ll admit I don’t know the architecture all that well. @mwestphal might have a better idea.
Thank you everyone for the feedback. I was able to get the vtkHardwarePicker implemented but something is still ‘off’ in my implementation as when I print out the various data for the hovered point or cell, the data is in correct. I’m probably not doing the mapping back and forth correctly.
Ahh. Figured out the issue. I am trying to render a Quad surface but somewhere in our code (I would assume) we are telling VTK to convert the quads to triangles. This is what is messing up the displayed values. We just use the vtkDataSetMapper class for our rendering. We use a vtkUnstructuredGrid as the “go between” of our own custom internal data structures. Maybe I should be using vtkPolyData instead?
Does vtkHardwarePicker work with vtkImageData? I’m having conceptual trouble trying to figure out how to map the cellId that is returned from
vtkIdType cellId = picker->GetCellId();
to the actual underlying cellId from the vtkImageData. We are using the vtkImageToStructuredGrid filter through a vtkDataSetMapper to display the data on screen. Maybe that setup is not correct?