I’m using a thin slab volume actor (using clipping planes) along with multiple polydata actors (each with unique color and the same clipping planes applied) to render a DICOM RT, and it works fine, but not performance wise.
Basically, I’m rendering the polyData with the following code
const points = vtkPoints.newInstance();
const lines = vtkCellArray.newInstance();
const polygon = vtkPolyData.newInstance();
const mapper = vtkMapper.newInstance();
const actor = vtkActor.newInstance();
actor.getProperty().setColor(colorToUse, colorToUse, colorToUse);
overall I have 1 volume Actor and 31 polyData actors (each contourSet has a unique color and spans multiple slices).
I did a performance profiling and it seems like it is dropping a lot of frames, and something that caught my attention was
I guess the problem is for each render it needs to draw each of the 31 polydata and clipping planes doesn’t help there.
My questions are basically
- Is it possible to have ONE polydata actor for all my polyData? In other words, is there a way to use one actor to render two “cones” with unique color that are not touching each other for instance?
- Is there a filter that I can use for my polyData to limit the region for the GPU to traverse? I know there is one clipClosedSurface, but I don’t have a closedSurface…
A movie of performance stats for reference
I appreciate your help
Thanks for the reply Julien.
Basically my second question is that is there any alternative to
vtkClipClosedSurface which is a filter for clipping closed surfaces BUT for polyData? Is there such filter to clip polyData in CPU via a filter? (I guess it accepts two planes and just remove the vertices that the polyData has outside those planes)
vtkClipClosedSurface with 2 planes and from which you discard the “closed surface” (set
Btw, did you see VolumeOutline ?
They are 3D contours and not volumes, since they are overlapping and they span whole image (often +100 slices), I guess the cost of having 31 volumes in the cache would be huge, unless I’m missing something
indeed, VolumeOutline does not fit your need.
I tried the
vtkCutter and it was not great re performance. So I used the
AppendPolyData and it works like a charm for the performance, I can reach 58 fps which is awesome
(video below if you are intereseted)
before I move to figuring out the coloring for each contour, I had a question about using
- is it possible to have separate thickness assigned for each polyData?
- can I hide/show each polyData separately?
separate thickness: no, it’s not possible without rewritting the shader
show/hide: yes if you play with the opacity parameter of the transfer function.
I appreciate your help along the way Julien. I was able to fully implement the appendPolyData. Something interesting that I encountered was that the lineWidth had a direct impact on the rendering performance (fps). Is this a known fact? See below comparison of lineWidth 10 (achieving 20 fps) vs lineWidth of 1 (58 fps)
@Alireza Yes, line width is tricky. Most of the graphics drivers support very small widths, so the mapper simulates wide lines by instancing the original line. If you want, you can query the maximum supported line width via
openglRenderWindow.getHardwareMaximumLineWidth() and stick to a width under that number. However, the lines will look different on different systems.
Hey @sankhesh thanks for the answer. Keeping the width below the maximum supported with seems to be very narrow (for me width 1).
Also I set the width to be like 1.4 or 1.5 but doesn’t seem to have any effect. Is it taking integer width only? Any other trick to make it be best of both worlds (fast as width 1 and thick as width 2)
Thanks in advance
Hi @Alireza, are you on a mac? I agree that a maximum supported width of 1 is really small.
Yes, line widths have to be integer values. The custom line width code uses an instanced pass which should be faster but I haven’t run performance benchmarks on a two-triangle approach.