fsleyes.gl.routines

This module contains a collection of miscellaneous OpenGL and geometric routines.

fsleyes.gl.routines.clear(bgColour)[source]

Clears the current frame buffer, and does some standard setup operations.

fsleyes.gl.routines.enabled(capabilities, enable=True)[source]

This function can be used as a context manager to temporarily enable/disable one or more GL capabilities (i.e. something that you pass to glEnable and glDisable, or glEnableClientState and glDisableClientState), for a piece of code, and restore their previous state afterwards.

Parameters
  • capabilities – One or more OpenGL capabilities to be temporarily enabled/disabled, e.g. GL_BLEND, GL_TEXTURE_2D, etc.

  • enable – Whether the capabilities are to be enabled (the default) or disabled.

fsleyes.gl.routines.disabled(capabilities)[source]

Can be used as a context manager to temporarily disable the given GL capabilities - see enabled().

fsleyes.gl.routines.show2D(xax, yax, width, height, lo, hi, flipx=False, flipy=False)[source]

Configures the OpenGL viewport for 2D othorgraphic display.

Parameters
  • xax – Index (into lo and hi) of the axis which corresponds to the horizontal screen axis.

  • yax – Index (into lo and hi) of the axis which corresponds to the vertical screen axis.

  • width – Canvas width in pixels.

  • height – Canvas height in pixels.

  • lo – Tuple containing the mininum (x, y, z) display coordinates.

  • hi – Tuple containing the maxinum (x, y, z) display coordinates.

  • flipx – If True, the x axis is inverted.

  • flipy – If True, the y axis is inverted.

fsleyes.gl.routines.lookAt(eye, centre, up)[source]

Replacement for gluLookAt`. Creates a transformation matrix which transforms the display coordinate system such that a camera at position (0, 0, 0), and looking towards (0, 0, -1), will see a scene as if from position ``eye, oriented up, and looking towards centre.

See: https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml

fsleyes.gl.routines.ortho(lo, hi, width, height, zoom)[source]

Generates an orthographic projection matrix. The display coordinate system origin (0, 0, 0) is mapped to the centre of the clipping space.

  • The horizontal axis is scaled to::

    [-(hi[0] - lo[0]) / 2, (hi[0] - lo[0]) / 2]

  • The vertical axis is scaled to::

    [-(hi[1] - lo[1]) / 2, (hi[1] - lo[1]) / 2]

Parameters
  • lo – Low (x, y, z) bounds.

  • hi – High (x, y, z) bounds.

  • width – Canvas width in pixels

  • height – Canvas height in pixels

  • zoom – Zoom factor. Required to determine suitable near and far clipping plane locations.

Returns

A tuple containing:

  • The (4, 4) projection matrix

  • A list of three (min, max) tuples, defining the limits for each axis.

fsleyes.gl.routines.adjust(x, y, w, h)[source]

Adjust the given x and y values by the aspect ratio defined by the given w and h values.

fsleyes.gl.routines.preserveAspectRatio(width, height, xmin, xmax, ymin, ymax, grow=True)[source]

Adjusts the given x/y limits so that they can be displayed on a display of the given width and height, while preserving the aspect ratio.

Parameters
  • width – Display width

  • height – Display height

  • xmin – Low x limit

  • xmax – High x limit

  • ymin – Low y limit

  • ymax – High y limit

  • grow – If True (the default), the x/y limits are expanded to preserve the aspect ratio. Otherwise, they are shrunken.

fsleyes.gl.routines.text2D(text, pos, fontSize, displaySize, angle=None, fixedWidth=False, calcSize=False)[source]

Renders a 2D string using glutStrokeCharacter.

Parameters
  • text – The text to render. Only ASCII characters 32-127 (and newlines) are supported.

  • pos – 2D text position in pixels.

  • fontSize – Font size in pixels

  • displaySize(width, height) of the canvas in pixels.

  • angle – Angle (in degrees) by which to rotate the text.

  • fixedWidth – If True, a fixed-width font is used. Otherwise a variable-width font is used.

  • calcSize – If True, the text is not rendered. Instead, the size of the text, in pixels, is calculated and returned (before any rotation by the angle).

fsleyes.gl.routines.pointGrid(shape, resolution, xform, xax, yax, origin='centre', bbox=None)[source]

Calculates a uniform grid of points, in the display coordinate system (as specified by the given Display object properties) along the x-y plane (as specified by the xax/yax indices), at which the given image should be sampled for display purposes.

This function returns a tuple containing:

  • a numpy array of shape (N, 3), containing the coordinates of the centre of every sampling point in the display coordinate system.

  • the horizontal distance (along xax) between adjacent points

  • the vertical distance (along yax) between adjacent points

  • The number of samples along the horizontal axis (xax)

  • The number of samples along the vertical axis (yax)

Parameters
  • shape – The shape of the data to be sampled.

  • resolution – The desired resolution in display coordinates, along each display axis.

  • xform – A transformation matrix which converts from data coordinates to the display coordinate system.

  • xax – The horizontal display coordinate system axis (0, 1, or 2).

  • yax – The vertical display coordinate system axis (0, 1, or 2).

  • origincentre or corner. See the affine.axisBounds() function.

  • bbox – An optional sequence of three (low, high) values, defining the bounding box in the display coordinate system which should be considered - the generated grid will be constrained to lie within this bounding box.

fsleyes.gl.routines.pointGrid3D(shape, xform=None, origin='centre', bbox=None)[source]

Generates a 3D grid of points into an image of the given shape, with the given xform defining the index to display coordinate transform.

note: Not implemented properly yet.

fsleyes.gl.routines.samplePointsToTriangleStrip(coords, xpixdim, ypixdim, xlen, ylen, xax, yax)[source]

Given a regular 2D grid of points at which an image is to be sampled (for example, that generated by the pointGrid() function above), converts those points into an OpenGL vertex triangle strip.

A grid of M*N points is represented by M*2*(N + 1) vertices. For example, this image represents a 4*3 grid, with periods representing vertex locations:

.___.___.___.___.
|   |   |   |   |
|   |   |   |   |
.---.---.---.---.
.___.___.__ .___.
|   |   |   |   |
|   |   |   |   |
.---.---.---.---.
.___.___.___.___.
|   |   |   |   |
|   |   |   |   |
.___.___.___.___.

Vertex locations which are vertically adjacent represent the same point in space. Such vertex pairs are unable to be combined because, in OpenGL, they must be represented by distinct vertices (we can’t apply multiple colours/texture coordinates to a single vertex location) So we have to repeat these vertices in order to achieve accurate colouring of each voxel.

We draw each horizontal row of samples one by one, using two triangles to draw each voxel. In order to eliminate the need to specify six vertices for every voxel, and hence to reduce the amount of memory used, we are using a triangle strip to draw each row of voxels. This image depicts a triangle strip used to draw a row of three samples (periods represent vertex locations):

1   3   5   7
.   .   .   .
|\ |\ |\ |
| \| \| \|
.   .   .   .
0   2   4   6

In order to use a single OpenGL call to draw multiple non-contiguous voxel rows, between every column we add a couple of ‘dummy’ vertices, which will then be interpreted by OpenGL as ‘degenerate triangles’, and will not be drawn. So in reality, a 4*3 slice would be drawn as follows (with vertices labelled from [a-z0-9]:

 v   x   z   1   33
 |\ |\ |\ |\ |
 | \| \| \| \|
uu   w   y   0   2
 l   n   p   r   tt
 |\ |\ |\ |\ |
 | \| \| \| \|
kk   m   o   q   s
 b   d   f   h   jj
 |\ |\ |\ |\ |
 | \| \| \| \|
 a   c   e   g   i

These repeated/degenerate vertices are dealt with by using a vertex index array. See these links for good overviews of triangle strips and degenerate triangles in OpenGL:

A tuple is returned containing:

  • A 2D numpy.float32 array of shape (2 * (xlen + 1) * ylen), 3), containing the coordinates of all triangle strip vertices which represent the entire grid of sample points.

  • A 2D numpy.float32 array of shape (2 * (xlen + 1) * ylen), 3), containing the centre of every grid, to be used for texture coordinates/colour lookup.

  • A 1D numpy.uint32 array of size ylen * (2 * (xlen + 1) + 2) - 2 containing indices into the first array, defining the order in which the vertices need to be rendered. There are more indices than vertex coordinates due to the inclusion of repeated/degenerate vertices.

Parameters
  • coords – N*3 array of points, the sampling locations.

  • xpixdim – Length of one sample along the horizontal axis.

  • ypixdim – Length of one sample along the vertical axis.

  • xlen – Number of samples along the horizontal axis.

  • ylen – Number of samples along the vertical axis.

  • xax – Display coordinate system axis which corresponds to the horizontal screen axis.

  • yax – Display coordinate system axis which corresponds to the vertical screen axis.

fsleyes.gl.routines.voxelGrid(points, xax, yax, xpixdim, ypixdim)[source]

Given a N*3 array of points (assumed to be voxel coordinates), creates an array of vertices which can be used to render each point as an unfilled rectangle.

Parameters
  • points – An N*3 array of voxel xyz coordinates

  • xax – XYZ axis index that maps to the horizontal scren axis

  • yax – XYZ axis index that maps to the vertical scren axis

  • xpixdim – Length of a voxel along the x axis.

  • ypixdim – Length of a voxel along the y axis.

fsleyes.gl.routines.voxelBlock(*args, **kwargs)[source]

Generates a numpy array containing all ones, centered at the specified voxel.

Parameters

dtype – The data type of the returned numpy array. Defaults to uint8.

All other arguments are passed through to the voxelBox() function - see that function for details on the arguments.

Returns

A tuple containing:

  • The numpy array

  • Voxel coordinates specifying the offset of the position of this array in the image.

fsleyes.gl.routines.voxelBox(voxel, shape, dims, boxSize, axes=(0, 1, 2), bias=None, bounded=True)[source]

Generates a ‘box’, a cuboid region, in a voxel coordinate system, centered at a specific voxel.

The corners of the box are returnd as a numpy array of shape (8, 3).

Parameters
  • voxel – Coordinates of the voxel around which the block is to be centred.

  • shape – Shape of the image in which the block is to be located.

  • dims – Size of the image voxels along each dimension.

  • boxSize – Desired width/height/depth of the box in scaled voxels. May be either a single value, or a sequence of three values.

  • axes – Axes along which the block is to be located.

  • biaslow, high, or None. The box can only be centered on the voxel if the specified boxSize results in an odd number of voxels along each voxel axis. If this is not the case, more voxels must be added to one side of the box centre. You can specify that these voxels are added to the high side (i.e. larger voxel coordinate) or the low side of the voxel. Specifying None will force the box to have an odd number of voxels along each axis, and thus have the voxel in the true centre of the box.

  • bounded – If True (the default), and the specified voxel would result in part of the block being located outside of the image shape, the block is truncated to fit inside the image bounds.

fsleyes.gl.routines.slice2D(dataShape, xax, yax, zpos, voxToDisplayMat, displayToVoxMat, geometry='triangles', origin='centre', bbox=None)[source]

Generates and returns vertices which denote a slice through an array of the given dataShape, parallel to the plane defined by the given xax and yax and at the given z position, in the space defined by the given voxToDisplayMat.

If geometry is triangles (the default), six vertices are returned, arranged as follows:

  4----5
1  \  |
|\ \ |
| \ \|
|  \  3
0----2

Otherwise, if geometry is square, four vertices are returned, arranged as follows:

3---2
|   |
|   |
|   |
0---1

If origin is set to centre (the default), it is assumed that a voxel at location (x, y, z) is located in the space:

(x - 0.5 : x + 0.5, y - 0.5 : y + 0.5, z - 0.5 : z + 0.5)

Otherwise, if origin is set to corner, a voxel at location (x, y, z) is assumed to be located in the space:

(x : x + 1, y : y + 1, z : z + 1)
Parameters
  • dataShape – Number of elements along each dimension in the image data.

  • xax – Index of display axis which corresponds to the horizontal screen axis.

  • yax – Index of display axis which corresponds to the vertical screen axis.

  • zpos – Position of the slice along the screen z axis.

  • voxToDisplayMat – Affine transformation matrix which transforms from voxel/array indices into the display coordinate system.

  • displayToVoxMat – Inverse of the voxToDisplayMat.

  • geometrysquare or triangle.

  • origincentre or corner. See the affine.axisBounds() function.

  • bbox – An optional sequence of three (low, high) values, defining the bounding box in the display coordinate system which should be considered - the generated grid will be constrained to lie within this bounding box.

Returns a tuple containing:

  • A N*3 numpy.float32 array containing the vertex locations of a slice through the data, where N=6 if geometry=triangles, or N=4 if geometry=square,

  • A N*3 numpy.float32 array containing the voxel coordinates that correspond to the vertex locations.

fsleyes.gl.routines.boundingBox(dataShape, voxToDisplayMat, displayToVoxMat, geometry='triangles', origin='centre', bbox=None)[source]

Generates a bounding box to represent a 3D image of the given shape, in the coordinate system defined by the voxToDisplayMat affine.

See the slice2D() function for details on the arguments.

Returns a tuple containing:

  • A N*3 numpy.float32 array containing the vertex locations of a bounding box N=36 if geometry=triangles, or N=24 if geometry=square,

  • A N*3 numpy.float32 array containing the voxel coordinates that correspond to the vertex locations.

fsleyes.gl.routines.subsample(data, resolution, pixdim=None, volume=None)[source]

Samples the given 3D data according to the given resolution.

Returns a tuple containing:

  • A 3D numpy array containing the sub-sampled data.

  • A tuple containing the (x, y, z) starting indices of the sampled data.

  • A tuple containing the (x, y, z) steps of the sampled data.

Parameters
  • data – The data to be sampled.

  • resolution – Sampling resolution, proportional to the values in pixdim.

  • pixdim – Length of each dimension in the input data (defaults to (1.0, 1.0, 1.0)).

  • volume – If the image is a 4D volume, the volume index of the 3D image to be sampled.

fsleyes.gl.routines.broadcast(vertices, indices, zposes, xforms, zax)[source]

Given a set of vertices and indices (assumed to be 2D representations of some geometry in a 3D space, with the depth axis specified by zax), replicates them across all of the specified Z positions, applying the corresponding transformation to each set of vertices.

Parameters
  • vertices – Vertex array (a N*3 numpy array).

  • indices – Index array.

  • zposes – Positions along the depth axis at which the vertices are to be replicated.

  • xforms – Sequence of transformation matrices, one for each Z position.

  • zax – Index of the ‘depth’ axis

Returns three values:

  • A numpy array containing all of the generated vertices

  • A numpy array containing the original vertices for each of the generated vertices, which may be used as texture coordinates

  • A new numpy array containing all of the generated indices.

fsleyes.gl.routines.planeEquation(xyz1, xyz2, xyz3)[source]

Calculates the equation of a plane which contains each of the given points.

Returns a numpy array containing four values, the coefficients of the equation:

\(a\times x + b\times y + c \times z = d\)

for any point (x, y, z) that lies on the plane.

See http://paulbourke.net/geometry/pointlineplane/ for details on plane equations.

fsleyes.gl.routines.planeEquation2(origin, normal)[source]

Calculates the equation of a plane equation from a normal vector and a single point on the plane.

Returns a numpy array containing four values, the coefficients of the equation:

See also planeEquation().

fsleyes.gl.routines.unitSphere(res)[source]

Generates a unit sphere, as described in the Sphere Generation article, on Paul Bourke’s excellent website:

Parameters

res – Resolution - the number of angles to sample.

Returns

A tuple comprising:

  • a numpy.float32 array of size (res**2, 3) containing a set of (x, y, z) vertices which define the ellipsoid surface.

  • A numpy.uint32 array of size (4 * (res - 1)**2) containing a list of indices into the vertex array, defining a vertex ordering that can be used to draw the ellipsoid using the OpenGL GL_QUAD primitive type.

Todo

Generate indices to use with GL_TRIANGLES instead of GL_QUADS.

fsleyes.gl.routines.fullUnitSphere(res)[source]

Generates a unit sphere in the same way as unitSphere(), but returns all vertices, instead of the unique vertices and an index array.

Parameters

res – Resolution - the number of angles to sample.

Returns

A numpy.float32 array of size (4 * (res - 1)**2, 3) containing the (x, y, z) vertices which can be used to draw a unit sphere (using the GL_QUADS primitive type).

fsleyes.gl.routines.unitCircle(res, triangles=False)[source]

Generates res vertices which form a 2D circle, centered at (0, 0), and with radius 1.

Returns the vertices as a numpy.float32 array of shape (res, 2)

If the triangles argument is True, the vertices are generated with the assumption that they will be drawn as a GL_TRIANGLE_FAN.

fsleyes.gl.routines.polygonIndices(nverts)[source]

Generate triangle indices for simple 2D polygons. Given vertices describing a monotone polygon on a 2D plane, generates an index list into the vertices which can be used to draw the vertices as triangles.