fsleyes.gl.glmesh

This module provides the GLMesh class, a GLObject used to render Mesh overlays.

class fsleyes.gl.glmesh.GLMesh(overlay, overlayList, displayCtx, canvas, threedee)[source]

Bases: fsleyes.gl.globject.GLObject

The GLMesh class is a GLObject which encapsulates the logic required to draw 2D slices, and 3D renderings, of a Mesh overlay. The GLMesh class assumes that the Display instance associated with the Mesh overlay holds a reference to a MeshOpts instance, which contains GLMesh specific display settings.

2D rendering

A GLMesh is rendered in one of two different ways, depending upon the value of the MeshOpts.outline and MeshOpts.vertexData properties.

Cross-sections

If outline is False and vertexData is None, a filled cross-section of the mesh is drawn. This is accomplished using a three-pass technique, roughly following that described at http://glbook.gamedev.net/GLBOOK/glbook.gamedev.net/moglgp/advclip.html:

  1. The front face of the mesh is rendered to the stencil buffer.

  2. The back face is rendered to the stencil buffer, and subtracted from the front face.

  3. This intersection (of the mesh with a plane at the slice Z location) is then rendered to the canvas.

This cross-section is filled with the MeshOpts.colour property.

Outlines

If outline is True or vertexData is not None, the intersection of the mesh triangles with the viewing plane is calculated. These lines are then rendered as GL_LINES primitives.

When a mesh outline is drawn on a canvas, the calculated line vertices, and corresponding mesh faces (triangles) are cached via the OverlayList.setData() method. This is so that other parts of FSLeyes can access this information if necessary (e.g. the OrthoViewProfile provides mesh-specific interaction). For a canvas which is showing a plane orthogonal to display axis X, Y or Z, this data will be given a key of 'crosssection_0', 'crosssection_1', or 'crosssection_2' respectively.

Colouring

These lines will be coloured in one of the following ways:

When MeshOpts.vertexData is not None, the GLMesh class makes use of the glmesh vertex and fragment shaders. These shaders are managed by two OpenGL version-specific modules - gl14.glmesh_funcs, and gl21.glmesh_funcs. These version specific modules must provide the following functions:

  • compileShaders(GLMesh): Compiles vertex/fragment shaders.

  • updateShaderState(GLMesh, **kwargs): Updates vertex/fragment shaders. Should expect the following keyword arguments:

    • useNegCmap: Boolean which is True if a negative colour map

      should be used

    • cmapXform: Transformation matrix which transforms from vertex

      data into colour map texture coordinates.

    • flatColour: Colour to use for fragments which are outside

      of the clipping range.

  • preDraw(GLMesh): Prepare for drawing (e.g. load shaders)

  • draw(GLMesh, glType, vertices, indices=None, normals=None, vdata=None): # noqa

    Draws mesh using shaders.

  • postDraw(GLMesh): Clean up after drawing

3D rendering

3D mesh rendering is much simpler than 2D rendering. The mesh is simply rendered to the canvas, and coloured in the same way as described above. Whether the 3D mesh is coloured with a flat colour, or according to vertex data, shader programs are used which colour the mesh, and also apply a simple lighting effect.

Interpolation

When the MeshOpts.interpolation property is set to 'nearest', the mesh vertices and indices need to be modified. In order to achieve nearest neighbour interpolation (a.k.a. flat shading) , each vertex of a triangle must be given the same vertex data value. This means that vertices cannot be shared by different triangles. So when the interpolation property changes, the updateVertices() method will re-generate the vertices and indices accordingly. The getVertexData() method will modify the vertex data that gets passed to the shader accordingly too.

__init__(overlay, overlayList, displayCtx, canvas, threedee)[source]

Create a GLMesh.

Parameters
  • overlay – A Mesh overlay.

  • overlayList – The OverlayList

  • displayCtx – The DisplayContext managing the scene.

  • canvas – The canvas drawing this GLMesh.

  • threedee – 2D or 3D rendering.

destroy()[source]

Must be called when this GLMesh is no longer needed. Removes some property listeners and destroys the colour map textures and off-screen RenderTexture.

ready()[source]

Overrides GLObject.ready(). Always returns True.

addListeners()[source]

Called by __init__(). Adds some property listeners to the Display and MeshOpts instances so the OpenGL representation can be updated when the display properties are changed..

removeListeners()[source]

Called by destroy(). Removes all of the listeners added by the addListeners() method.

registerLut()[source]

Registers property listeners with the currently registered LookupTable (the MeshOpts.lut property).

deregisterLut()[source]

De-registers property listeners from the currently registered LookupTable.

updateVertices(*a)[source]

Called by __init__(), and when certain display properties change. (Re-)generates the mesh vertices, indices and normals (if being displayed in 3D). They are stored as attributes called vertices, indices, and normals respectively.

frontFace()[source]

Returns the face of the mesh triangles which which will be facing outwards, either GL_CCW or GL_CW. This will differ depending on the mesh-to-display transformation matrix.

This method is only used in 3D rendering.

getDisplayBounds()[source]

Overrides GLObject.getDisplayBounds(). Returns a bounding box which contains the mesh vertices.

draw2DOutlineEnabled()[source]

Only relevent for 2D rendering. Returns True if outline mode should be used, False otherwise.

needShader()[source]

Returns True if a shader should be loaded, False otherwise. Relevant for both 2D and 3D rendering.

preDraw(xform=None, bbox=None)[source]

Overrides GLObject.preDraw(). Performs some pre-drawing configuration, which might involve loading shaders, and/or setting the size of the backing RenderTexture instance based on the current viewport size.

draw2D(zpos, axes, xform=None, bbox=None)[source]

Overrids GLObject.draw2D(). Draws a 2D slice of the Mesh, at the specified Z location.

draw3D(xform=None, bbox=None)[source]

Overrides GLObject.draw3D(). Draws a 3D rendering of the mesh.

postDraw(xform=None, bbox=None)[source]

Overrides GLObject.postDraw(). May call the gl14.glmesh_funcs.postDraw() or gl21.glmesh_funcs.postDraw() function.

drawOutline(zpos, axes, xform=None, bbox=None)[source]

Called by draw2D() when MeshOpts.outline is True or MeshOpts.vertexData is not None. Calculates the intersection of the mesh with the viewing plane, and renders it as a set of GL_LINES. If MeshOpts.vertexData is None, the draw is performed using immediate mode OpenGL.

Otherwise, the gl14.glmesh_funcs.draw() or gl21.glmesh_funcs.draw() function is used, which performs shader-based rendering.

draw2DMesh(xform=None, bbox=None)[source]

Not to be confused with draw2D(). Called by draw2D() for Mesh overlays which are actually 2D (with a flat third dimension).

drawCrossSection(zpos, axes, lo, hi, dest)[source]

Renders a filled cross-section of the mesh to an off-screen RenderTexture. See:

http://glbook.gamedev.net/GLBOOK/glbook.gamedev.net/moglgp/advclip.html

Parameters
  • zpos – Position along the z axis

  • axes – Tuple containing (x, y, z) axis indices.

  • lo – Tuple containing the low bounds on each axis.

  • hi – Tuple containing the high bounds on each axis.

  • dest – The RenderTexture to render to.

calculateViewport(lo, hi, axes, bbox=None)[source]

Called by draw2D(). Calculates an appropriate viewport (the horizontal/vertical minimums/maximums in display coordinates) given the lo and hi GLMesh display bounds, and a display bbox.

calculateIntersection(zpos, axes, bbox=None)[source]

Uses the Mesh.planeIntersection() method to calculate the intersection of the mesh with the viewing plane at the given zpos.

Parameters
  • zpos – Z axis coordinate at which the intersection is to be calculated

  • axes – Tuple containing the (x, y, z) axis indices.

  • bbox – A tuple containing a ([xlo, ylo, zlo], [xhi, yhi, zhi]) bounding box to which the calculation can be restricted.

Returns

A tuple containing:

  • A (n, 2, 3) array which contains the two vertices of a line for every intersected face (triangle) in the mesh.

  • A (n, 3) array containing the intersected faces (indices into the Mesh.vertices array).

  • A (n, 2, 3) array containing the barycentric coordinates of the intersection line vertices.

  • A (4, 4) array containing a transformation matrix for transforming the line vertices into the display coordinate system. May be None, indicating that no transformation is necessary.

Note

The line vertices, and corresponding mesh triangle face indices, which make up the cross section are saved via the OverlayList.setData() method, with a key 'crosssection_[zax]', where [zax] is set to the index of the display Z axis.

getVertexData(vdtype, faces=None, dists=None)[source]

If MeshOpts.vertexData (or MeshOpts.modulateData) is not None, this method returns the vertex data to use for the current vertex data index.

faces and dists are used by the drawOutline() method, which draws a cross-section of the mesh. The dists array contains barycentric coordinates for each line vertex, and is used to linearly interpolate between the values of the vertices of the intersected triangles (defined in faces).

If MeshOpts.vertexData is None, this method returns None.

Parameters

vdtype – Use 'vertex' for MeshOpts.vertexData, or 'modulate' for MeshOpts.modulateData.

refreshCmapTextures(*a, **kwa)[source]

Called when various Display or MeshOpts` properties change. Refreshes the ColourMapTexture instances corresponding to the MeshOpts.cmap and MeshOpts.negativeCmap properties, and the LookupTableTexture corresponding to the MeshOpts.lut property.

Parameters

notify – Must be passed as a keyword argument. If True (the default) GLObject.notify() is called after the textures have been updated.

compileShaders()[source]

(Re)Compiles the vertex/fragment shader program(s), via a call to the GL-version specific compileShaders function.

updateShaderState()[source]

Updates the vertex/fragment shader program(s) state, via a call to the GL-version specific updateShaderState function.

__module__ = 'fsleyes.gl.glmesh'