I have 10000+ objects to draw, everyone can be shown/hided individually, and everyone has its own color, draw each one object using one actor, one mapper, but the performance is bad, how to do?
Maybe you need to give more details of what you want to achive. A well specified problem is more likely to get an efficient solution from the community, 10000+ objects can mean anything from 10000+ points to 10000+ galaxies.
I am working on developing CAE software, I have 10000+ surface to draw, each surface have its own color, and each one can be show/hide. One surface is treated as one actor, one mapper? or you have some other suggest to improve the performance?
For example, I will draw a car, the car is assembled by 10000+ parts, each part can show/hide individually, each part has its own color. one mapper, 10000+ actors to render?
1000+ actor is a bad idea. Partitioned/multiblock should work well enough.
I work in petroleum industry, and I’ve seen similar applications to render oil rigs and refineries with millions of parts. Do you need to render all the millions of actors? Short answer: no. Long answer: if you do need a large number of actors, one approach to such problem is to use an hierarchical one. I mean, no one can actually view the entirety of such complex objects. One either views the whole model in low detail or views a smaller part in more detail. Either way, you never actually need more than a hundred actors. Your software must be smart. It must discard, load and display actors as they are needed.
For your example: when one views the entire car, you don’t need to render its innards. If the user wants to view the engine, you don’t need to render the other parts of the car and so on. Does it make sense? This can be done on demand or handled automatically.
A scene-graph-based API naturally handles that like charm, but VTK is pipeline-based, so you need to be smart to achive that kind of functionality (e.g. with stacks or using a tree data structure). For example, you can keep all the 10000+ actor objects in memory only, but send to VTK for rendering only the few ones that will be actually viewed as you move about. The pre-selection of actors is mainly affected by: viewing frustum and object occlusions. So, first discard actors whose bounding boxes are outside the viewing frustum volume. This can be relatively easily done with optimized spatial queries on an octree, for example. Discarding actors that would be hidden by foreground ones is a bit more challenging but it’s not rocket science. In the figure below, some of the column actors do not need to be sent to VTK because they are completely hidden by the Pantheon.
One way to perform this pre-selection efficiently is with a “shadow frustum”, which is presented here: https://dspace5.zcu.cz/bitstream/11025/6658/1/Papaioannou.pdf .
I hope this helps you get started.
You can render a model with even millions of parts, change visibility (and color, opacity) of each part separately in near-zero time, using a single actor. You need to set a unique scalar value to each cell or point and use a lookup table to specify color and opacity.
Using multiple actors, multi-block data sets, etc. may be necessary if you want to edit selected parts (apply transform, filters,…).
Dear Andras, your solution is using single actor, set the opacity 0 or 1 to change the visibility?
Dear Paulo, I have got your idea, it will be a smart program to create and delete actors to display what user would like to see, thanks.
Yes, to hide/show a part set the corresponding opacity (alpha) value in the lookup table to 0/1.
Dear Andras, If I would like to render some parts using wireframe, the other parts using edge surface, can it does?
You may be able to hide cells using cell data while keeping lines visible. However, in general if you want to use different display styles then probably the simplest is to use a separate actor for each major display style. Alternatively, you can write a custom shader, a short GLSL code snippet that can alter appearance of a mesh any way you want, based on some custom point/cell scalars.
Hello, andras, that is go back to the initial question, to render 10000+ car parts, using one actor, it seems it is impossible to draw some parts with wireframe, some parts with surface shading.
You can easily do it with two actors for all the 10k parts. One actor renders the solid, the other one renders the wireframe parts.
You can probably do it with one actor and custom shader. This still does not require any changes in VTK, just deeper knowledge of how VTK and GLSL shaders work.
Visualization with VTK is easy and efficient. You can surely manage display of even the most complex CAD models. However, if you want to do CAD modelling (parametric creation and editing of CAD models from geometric shapes) then you may consider building your application by extending and customizing an open-source CAD modelling tool, such as FreeCAD (at the cost of much higher complexity and computational needs than just VTK visualization).
Complementing Andras’ answer, here’s an oil reservoir model partly rendered solid and partly rendered as wireframe. I used two actors for that:
BTW, I used a
vtkUnstructuredGrid that allows arbitrarily shaped cells (not only cubes). Likewise, maybe you can model the car as a single
vtkUnstructuredGrid and mark each of the 10000+ parts with a scalar containing values that are part IDs. You can then, for example, make use of some class of the
vtkPolyDataAlgorithm (https://vtk.org/doc/nightly/html/classvtkPolyDataAlgorithm.html) family to extract and transform (rotation, etc.) an specific part (e.g. door, with ID=42) or render it with a different mapper/actor.
Thanks very much for Paulo and Andras, methods are always more than difficulties, I have got it, VTK is a powerful rendering tool
Dear Andras and Paulo,
I still met two questions for render parts.
I set the lookup table to set the visible, but if the surface edge is visible, the hidden surfaces will be shown.
Another，in lookup table, some alpha value are 1.0, some are 0.0, it will shown with transparent.
Hello, Andras, set the opacity one part 0, the other parts 1, the opacity 0 part will be hidden, but why the shown parts will be transparent? the opacity value is 1.
You can specify colors for points (vertices) and cells (faces). There are also several mapper options. If something does not work as you expect then please provide a self-contained example (e.g., a python code snippet and a .vtp file) that reproduces that behavior.