Discontinuous Galerkin elements and other novel cell-types/function-spaces

Correct, GLES 3.0 does not support them. Although, they can be emulated via 2D textures. All texelFetcheBuffers will be replaced by a texelFetch. The indexing code looks crazy but it works.

Ex: this will be edited at runtime by vtkOpenGLShaderCache


int main() {
  //  ...
  int cellId = texelFetchBuffer(cellIdsBuffer, gl_VertexID);
  //  ...
}

into

ivec2 Get2DIndexFrom1DIndex(int idx, ivec2 texSize)
{
  int w = texSize.x;
  int i = idx % w;
  int j = (idx - i) / texSize.x;
  return ivec2(i, j);
}
#define texelFetchBuffer(a,b) texelFetch(a, Get2DIndexFrom1DIndex(b, textureSize(a, 0)), 0)

int main() {
  int cellId = texelFetchBuffer(cellIdsBuffer, gl_VertexID);
}
1 Like

Very fancy! I like that it gets rewritten from clean to workable only when it is required. Almost like polyfill.js but for OpenGL…

On a side note, I would love to greatly simplify TestArrayRenderer.py and turn it into a tutorial (here’s how to turn an array into triangles, how to add color to them using another array, to use a lookup table for the color, etc.). I think it could help inspire new visualizations by making prototyping easier.

1 Like

Just posting here for closure - the OpenGL classes in Rendering/CellGrid were easily moved into Rendering/OpenGL2 module as part of vtk/vtk@5d835f1. The transition was easier than I imagined it would be!

Selection

As we start working on cell selection for cell-grid data, we need to address how selecting (a.k.a. picking) rendered cells and cell-sides will work.

Issue

The main problem is that, especially for volumetric cells, it is not always possible to discern whether users intended to pick the surface (side) of the cell or the cell itself. Here’s why:

  1. VTK’s existing data model does not represent sides of cells as first-class objects. Instead, there are filters (vtkGeometryFilter, vtkDataSetSurfaceFilter, etc.) that create new cells which represent sides of the original cells (e.g., triangles that represent the sides of a tetrahedron).
  2. Novel function spaces cannot follow this approach; they are not always well-defined on lower-dimensional cells that bound the space over which the original cell was defined. For traditional Lagrangian elements, if you have a function f(r, s, t) defined over a hexahedron, and you wish to render its restriction f(s,t) on the +r quadrilateral face of that hexahedron, you can simply create a quadrilateral cell whose nodal values are identical to the hexahedron from which the face was drawn. But for H-Curl and H-Div spaces, vector functions on volume and surface elements cannot be restricted to an edge or node in this way; you must evaluate f(r, s, t) on the original hexahedron. For example, H-Curl fields are defined by taking the cross-product of edge vectors of a 2- or 3-d element. With a line, there is no other vector to cross with the line’s direction-vector.
  3. So, when we need to render the edge, we render a line in OpenGL whose endpoints are assigned 2- or 3-d parameter-space coordinates to match the original cell and the original cell’s interpolation functions are used. This means the renderer for vtkDGCell objects knows how to render sides of its cells (as well as the cell itself if it is a surface or edge cell).
  4. Finite element codes typically apply boundary conditions on sides of cells that discretize the simulation domain, not on the cells themselves. Users frequently wish to see these boundary-condition surfaces. These must also be rendered by a shader using the cell’s entire state instead of some new cell of lower dimension.
  5. This means when a user picks a cell using hardware selection but we are rendering sides, it could mean that the user wants to pick the entire cell or it could mean the user wants to pick the side (boundary condition surface) of the cell.

Proposed Solution

We intend to modify the vtkCellGridComputeSurface filter so that ParaView (and VTK) representations that use it to produce renderable geometry from volume elements can indicate which output sides were present on its input (and thus selectable as first-class objects) and which output sides were external surfaces of volumetric elements (and thus should result in the selection of the volumetric elements they represent).

This also means that when given a vtkSelectionNode that selects cells from a cell-grid, the filter which extracts the selection must know how to examine the output of vtkCellGridComputeSurface to find this indicator and produce either sides or cells, depending on its value.

For vtkDGCell, we plan to add this indicator as a member of the vtkDGCell::Source structure for each side-specification.