Hi guys,
I follow this(https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/Core/Testing/Cxx/TestPolygonSelection.cxx#L122) to select a polygonal area, but the data I get is incomplete and some cells are missing(The white dots in the figure below). Does anyone know what caused it?
Hello Claude!
vtkHardwareSelector is using rendering techniques to perform selections. Due to the density of the mesh that you are trying to visualize at that particular depth, some very small triangles that occupy the same space as others (at that particular depth) don’t get a unique pixel therefore they can’t be selected.
Rendering-based selections are fast but are not super accurate for dense meshes.
If you want software-based selections which perform geometric tests, and are slower, check vtkCellPicker and vtkPointPicker. By the way, vtkHardwarePicker is a wrapper of vtkHardwareSelector that satisfies the picker infrastructure.
Hi Spiros,
Thanks for your response!
I am aware of vtkCellPicker and vtkPointPicker,but it seems they cannot achieve selection fast of polygonal regions.If hardwareselector’s accuracy is not sufficient for dense meshes, do I have any other options to achieve polygonal selection?
Nope you have fast but not super accurate for sense meshes, or slow but accurate. Your pick.
@dcthomp This issue reminds me about what we talked about yesterday - hardware based selection misses some cells when many cells are rendered in one pixel.
One solution would be to identify such pixels with the hardware selector, and if selected, perform software based selection.
I’m aware of a method to continue benefiting from the hardware selector. At present, the hardware selector utilizes a process where cell indices are written into a texture (in simpler terms, a 2D array accessible on the GPU) that matches the dimensions of the render window. This setup confines the information that a shader can encode to just one cell per pixel.
An alternative approach exists: VTK can instruct the hardware selector to populate a Shader Storage Buffer Object (SSBO, a term understood in simple terms as a 1D array accessible on the GPU) with 1s or 0s. The size of this array would be equal to the number of cells. Zeroing this ssbo is so easy and fast. Readback of selected cells can be done with glMapBuffer
. Each value of 1 would signify that a cell was selected, while a value of 0 would indicate that the cell wasn’t selected.
@dcthomp, @sankhesh, @cory.quammen what do you think?
Either that or a two-pass approach that counts selected cells then writes to a buffer allocated after the first pass.
Either that or a two-pass approach that counts selected cells then writes to a buffer allocated after the first pass.
Can you elaborate more on the two-pass approach? What does the first pass look like and what does the second pass look like?
Sorry, it would require more than that:
- Increment a counter for each fragment produced
- Sum the counters for all fragments (this is a reduction pass and I don’t think there’s a really efficient way to do this in a GL shader). The closest you might get is computing a cumulative sum per fragment using 2*log(N) passes, with each pass halvng the output framebuffer size. Bleh
- Allocate an output buffer for all the primitive IDs.
- Final pass that writes to the buffer for each fragment processed.
This would only be useful if the size of the mesh was truly gigantic and selections were small compared to the mesh size.
Nevermind.
Hi ,
I have been struggling with this issue for a long time. I need to implement polygon picking. Can you please guide me on how to achieve this goal?
Hello Claude,
As I’ve pointed out before in another reply, it is possible to implement fast and accurate cell picker with an ssbo. Depending upon your level of comfortability with VTK source code, I suggest studying the existing implementation in vtkHardwareSelector and modifying it to use an ssbo. Please do not hesitate to ask any questions here.
Thanks! I haven’t learned ssbo related knowledge yet, but according to your suggestion, I realized the fast editing function by converting the world coordinates of the model to display coordinates and sacrifice some space in exchange for reduced computing time (although I know this is not the best way). But I encountered a problem. After the vtkUnstructuredGrid obtained using vtkExtractSelection is converted into vtkpolydata by vtkGeometryFilter, the number of vertices converted for the first time will drop significantly. What is the reason for this?
The geometry filter extracts cell faces on the outer surface. All the interior geometry is discarded.