Rendering pipeline for RGG entities
For now the rendering pipeline for rgg entities is as follows:
-
Pin - Ex. made of two cylinders and two materials. As in smtk if the geometric representation type of an entity is a vtkMultiBlockDataset, there is no way to specify color for each block and render it properly. The current solution is to make the pin a composite auxiliary geometry and make cylinder0, annulus cylinder0, cylinder1 and annulus cylinder1 to be child auxgeom and assign color to each one. So the pin has 2*2 children.
numChildren = numPieces * numMaterials
Note: The upgrade from Qt 5.9 to Qt 5.12 breaks the size of the combobox. Anyway it should be a trivial fix.
- Duct - Ex. made of two 3D hexagon as first hexagon has three materials and second has one material. The description of Pin also holds true here. The duct has 3+1 children.
where n is the number of hexagons and materials[i] is ith hexagon's number of materials.
-
Assembly - made of pins and ducts. The prototypes for glyphing are children in each pin and each duct.
where n is the number of pins and m is the number of ducts in the assembly
-
Core - made of pins and ducts.
where n is the number of pins and m is the number of ducts in the core.
Let's take a look at the abtr reactor model. Each assembly uses about 32 prototypes(27 children in duct and ~5 in pins). 8 assemblies needs 32*8 = 256 prototypes. The core uses about 230 prototypes(27*8 in 8 ducts and ~10 pins). As I'm hiding the glyphing for all assemblies, there are about 450 prototypes passing into the vtkGlyph3DMapper.
Now let's talk about how vtkGlyph3DMapper works under the hood. First it looks charming that it uses one mapper to do the glyphing. However it's not the case. It's the subclass - vtkOpenGLGlyph3DMapper who is doing all the heavy lifting on the GPU. It creates one subclass of vtkOpenGLPolyDataMapper per instance. In the abtr example, there are 450 mappers connected to one actor. No wonder why it's slow in CMB. Meanwhile since we are using two vtkGlyphMappers for normal rendering and selection rendering, the scenario is worsen by a factor of two.
Possible solutions:
-
The reason why old rgg application has smooth interaction experience is because how it treats its prototypes for glyphing. It does not need to fit into any existing framework or go through any adapter classes. The basic idea is that it has unit prototypes(plain simple geometry) as unit cylinder, unit annulus cylinders, unit hexagon and unit annulus hexagons. When doing glyphing, it can apply transform, scale, coloring at each glyphing point. Moreover instead of hiding the glyphing for assemblies, representation for pins and ducts, it just clear up the pipeline and start a vanilla rendering. So when glyphing the abtr reactor, it only has 6 prototypes.
-
What we can improve in SMTK&&CMB:
- For now the control of transformation, scale, color and orientation in smtk instance is missing. Expose them and hook it up with vtkModelMutiBlockSource and vtkSMTKRresourceRepresentation class. That means a big change to smtk rendering pipeline.
- Rework the rendering logic for assembly&&core. Define prototype as unit geometries instead of subpins and subducts. It should be easy because the logic is almost the same in rggAuxliaryGeometryExtension.
- Questions:
- In rgg workflow, it does not make sense to render pin/duct/assembly/core at the same time. Should we use glyph to render pin and duct as well?
- Visibility control looks redundant here. If a user selects an rgg entity in the resource panel, it should just render the entity while hide the previous one.
- To do glyphing, we need at lease one prototype(things we want to glyph) and one instance(a data structure which holds info about how we want to glyph it). Let's say we have a unit cylinder. Should it be shared by all assemblies and core? If so, then anytime we make a change to the layout, we need to rebuild the instance for this cylinder as vtkAOSDataArray uses a contiguous memory model. To put it in a simpler way, if we remove/insert an element in the middle of
std::vector
, it will triggers a relocation since the vector needs to support O(1) random access.
I'm happily to make the previous changes/improvements, but I want to hear what smtk developers agree/disagree first.