util Package

Ctypes Module


Return a tuple of c_byte, converted from a list of Python variables.


Return a tuple of c_char, converted from a list of Python variables.


Return a tuple of c_int, converted from a list of Python variables.


Return a tuple of c_short, converted from a list of Python variables.

Clashtest Module

class pi3d.util.Clashtest.Clashtest[source]

Bases: pi3d.util.OffScreenTexture.OffScreenTexture

calls Texture.__init__ but doesn’t need to set file name as texture generated from the framebuffer


draw the shape using the clashtest Shader

Shape object that will be drawn

checks the pixels of the texture to see if there is any change from the first pixel sampled; in which case returns True else returns False.

Keyword argument:
Number of locations to check over the whole image NB this is no longer used - there are fixed 100 checks across the full width at the mid y position. This self.setp value is set in __init__()

Defocus Module

class pi3d.util.Defocus.Defocus[source]

Bases: pi3d.util.OffScreenTexture.OffScreenTexture

For creating a depth-of-field blurring effect on selected objects

calls Texture.__init__ but doesn’t need to set file name as texture generated from the framebuffer


after calling this method all object.draw()s will rendered to this texture and not appear on the display. If you want blurred edges you will have to capture the rendering of an object and its background then re-draw them using the blur() method. Large objects will obviously take a while to draw and re-draw


stop capturing to texture and resume normal rendering to default

blur(shape, dist_fr, dist_to, amount)[source]

draw the shape using the saved texture Arguments:

Shape object that will be drawn
distance from zero plane that will be in focus, float
distance beyond which everything will be at max blur, float
degree of max blur, float. Values over 5 will cause banding

DisplayOpenGL Module

class pi3d.util.DisplayOpenGL.DisplayOpenGL[source]

Bases: object

create_display(x=0, y=0, w=0, h=0, depth=24, samples=4, layer=0, display_config=0, window_title='', use_glx=False)[source]
create_surface(x=0, y=0, w=0, h=0, layer=0)[source]
resize(x=0, y=0, w=0, h=0, layer=0)[source]

FixedString Module

class pi3d.util.FixedString.FixedString(font, string, camera=None, color=(255, 255, 255, 255), shadow=(0, 0, 0, 255), shadow_radius=0, font_size=24, margin=5.0, justify='C', background_color=None, shader=None, f_type='', mipmap=True, width=None)[source]

Bases: pi3d.Texture.Texture

A texture containing a simple string drawn using ImageDraw.

The advantage over a standard String is that it only requires a simple Sprite shape for drawing so the gpu has to only draw two triangles rather than two triangles for each letter.


File path/name to a TrueType font file.
String to write.
Camera object passed on to constructor of sprite
Color in format ‘#RRGGBB’, (255,0,0,255), ‘orange’ etc (as accepted by PIL.ImageDraw) default (255, 255, 255, 255) i.e. white 100% alpha
Color of shadow, default black.
Gaussian blur radius applied to shadow layer, default 0 (no shadow)
Point size for drawing the letters on the internal Texture. default 24
Offsets from the top left corner for the text and space on right and bottom. default 5.0
L(eft), C(entre), R(ight) default C
filled background in ImageDraw format as above. default None i.e. transparent.
can be passed to init otherwise needs to be set in set_shader or draw. default None
filter type. BUMP will generate a normal map (indented by default, +BUMP or BUMP+ will make it stick out), EMBOSS, CONTOUR, BLUR and SMOOTH do what they sound like they will do.

wrapper for Shape.set_shader

draw(shader=None, txtrs=None, ntl=None, shny=None, camera=None)[source]

wrapper for Shape.draw()

Font Module

class pi3d.util.Font.Font(font, color=(255, 255, 255, 255), codepoints=None, add_codepoints=None, font_size=None, image_size=1024, italic_adjustment=1.1, background_color=None, shadow=(0, 0, 0, 255), shadow_radius=0, spacing=None, mipmap=True, filter=None, grid_size=16)[source]

Bases: pi3d.Texture.Texture

A Font contains a TrueType font ready to be rendered in OpenGL.

A font is just a mapping from codepoints (single Unicode characters) to glyphs (graphical representations of those characters).

Font packs one whole font into a single Texture using PIL.ImageFont, then creates a table mapping codepoints to subrectangles of that Texture.

Arguments: font:

File path/name to a TrueType font file.
Color in format ‘#RRGGBB’, (255,0,0,255), ‘orange’ etc (as accepted by PIL.ImageDraw) default (255, 255, 255, 255) i.e. white 100% alpha
Point size for drawing the letters on the internal Texture

Iterable list of characters. All these formats will work:

‘ABCDEabcde ‘ [65, 66, 67, 68, 69, 97, 98, 99, 100, 101, 145, 148, 172, 32] [c for c in range(65, 173)]

Note that Font will ONLY use the codepoints in this list - if you forget to list a codepoint or character here, it won’t be displayed. If you just want to add a few missing codepoints, you’re probably better off using the add_codepoints parameter.

If the string version is used then the program file might need to have the coding defined at the top: # -- coding: utf-8 --

The default is *codepoints*=range(256).

If you are only wanting to add a few codepoints that are missing, you should use the add_codepoints parameter, which just adds codepoints or characters to the default list of codepoints (range(256). All the other comments for the codepoints parameter still apply.
Width and height of the Texture that backs the image. Since the introduction of PointText using Point drawing image_size is no longer used - all Font Textures are 1024.
Adjusts the bounding width to take italics into account. The default value is 1.1; you can get a tighter bounding if you set this down closer to 1, but italics might get cut off at the right. Since PointText this isn’t used.
filled background in ImageDraw format as above. default None i.e. transparent.
Color of shadow, default black.
Gaussian blur radius applied to shadow layer, default 0 (no shadow)
Extra spacing between letters to allow for shadow. The default value None will add spacing equal to the shadow_radius, this will be overridden by any value supplied.
Resulting texture mipmap option, default true
Resulting texture filter option, default None
number rows and cols to divide 1024 pixels. For high res fonts this can be changed 4 -> 16chars, 8 -> 64chars, 10 -> 100chars etc.

Graph Module

class pi3d.util.Graph.Graph(x_values, y_values, width, height, font, title=None, line_width=2, axes_desc=None, legend=None, xpos=0, ypos=0, xmin=None, xmax=None, ymin=None, ymax=None, camera=None, shader=None)[source]

Bases: object

Providing some basic functionality for a GPU accelerated x, y graph (i.e. for real-time display of instrumentation data etc)

1D numpy array
1 or 2D numpy array with size same as x_values in 2nd D draws a line graph or 3D numpy array with size same as x along axis=1 and last axis has 2 values. In this case the graph is drawn as vertical lines
width, height
as expected
pi3d.Font instance
title, line_width
as expected
tuple -> (x.axis.desc, y.axis.desc)
tuple -> (y0.desc, y1.desc, y2.desc…)
xpos, ypos
offset relative to origin of display (centre)
xmin, xmax, ymin, ymax
override sampled values from init data
if no other Shape to be drawn then a 2D Camera can be created here
if no other Shape uses mat_flat shader then one will be created

update all y_values

tick_pos(minv, maxv, num=3)[source]

work out nice looking grid line positions

Gui Module

class pi3d.util.Gui.Gui(font, show_pointer=True, fontscale=0.24)[source]

Bases: object

hold information on all widgets and the pointer, creates a 2D Camera and uv_flat shader. Needs to have a Font object passed to it keeps track of when the last mouse click or key stroke to avoid double counting. Arguments

pi3d.Font object

A Gui instance has to be passed to each gui widget (Button, Menu etc) as it is created to allow resources to the used and for checking.

draw(x, y)[source]

draw all visible widges and pointer at x, y

check(x, y)[source]
class pi3d.util.Gui.Widget(gui, shapes, x, y, callback=None, label=None, label_pos='left', shortcut=None)[source]

Bases: object

contains functionality of buttons and is inherited by other gui components. Arguments:

Gui object parent to this widget
drawable object such as Sprite or String, or list of two to toggle
location of top left corner of this widget
string to use as label
position of label ‘left’, ‘right’, ‘above’, ‘below’
shortcut key to have same effect as clicking wit mouse???
relocate(x, y)[source]
check(x, y)[source]
class pi3d.util.Gui.Button(gui, imgs, x, y, callback=None, label=None, label_pos='left', shortcut=None)[source]

Bases: pi3d.util.Gui.Widget

This inherits pretty much everything it needs from Widget, it just takes a list of images rather than Shapes. Otherwise same Arguments.

list of strings. If these exist as files using the path and file name then those will be used. Otherwise the pi3d/util/icons path will be prepended
class pi3d.util.Gui.Radio(gui, x, y, callback=None, label=None, label_pos='left', shortcut=None)[source]

Bases: pi3d.util.Gui.Button

This is a toggle button with two checkbox images. Same Arguments as Widget but missing the list of Shapes completely.

class pi3d.util.Gui.Scrollbar(gui, x, y, width, start_val=None, callback=None, label=None, label_pos='left', shortcut=None)[source]

Bases: pi3d.util.Gui.Widget

This consists of four Shapes but the first one is duplicated so the Widget.draw() method can be used unchanged. The images are hard coded so no list of Shapes or images needs to be supplied however arguments additional to those for Widget are

width of the scroll (excluding buttons on either end)
proportion of the way across i.e. if width = 200 then start_val of 150 would be three quarters

NB the callback is called with *args equal to the position of the slider so the function needs to be defined with this in mind i.e. def cb(*args): args will then be available as a tuple (0.343,)

class pi3d.util.Gui.MenuItem(gui, text, callback=None, shortcut=None)[source]

Bases: pi3d.util.Gui.Widget

These are the clickable Widgets of the menu system. Instead of a list of Shapes they have a string argument, there is no label or label_pos and the x and y values are obtained from the position and orientation of the parent Menu.

string used to construct a pi3d.String
class pi3d.util.Gui.Menu(parent_item=None, menuitems=[], x=0, y=0, horiz=True, position='right', visible=True)[source]

Bases: object

Container for MenuItems, forming either a horizontal or vertical bar. Arguments

a MenuItem that will make this Menu visible when clicked
a list of MenuItems to be displayed in this Menu
x location will be overwritten unless parent_item == None
similarly the y location
set True (default) for horizontal layout on the menu bar, False for vertical listing
relative to the MenuItem that gives rise to this Menu when clicked ‘right’ or any other text interpreted as below
when an alternative branch of the menu tree is selected or the parent_item is re-clicked this menu is hidden, along with all its children recursively. They are set to visible = False and not drawn and not checked for mouse clicks.
class pi3d.util.Gui.TextBox(gui, txt, x, y, callback=None, label=None, label_pos='left', shortcut=None)[source]

Bases: pi3d.util.Gui.Widget


have to use a slightly different version without the _click() call


Loadable Module

class pi3d.util.Loadable.Loadable[source]

Bases: object


Log Module

class pi3d.util.Log.Log(name=None, level='WARNING', file=None, format=None)[source]

Bases: object

The typical usage of the Log module has a single LOGGER per Python file.

At the top of the file is typically:

LOGGER = pi3d.Log(level=’INFO’, file=’error.log’)

and then later on you can do things like:

  • LOGGER.debug(‘stuff here’)
  • LOGGER.info(‘Some information about %s’, some_name)
  • LOGGER.error(‘Not everything was displayed, sorry!’)
  • LOGGER.error(‘You died with error code %d, message %s’, error_code, msg)
  • LOGGER.critical(‘Your machine is about to explode. Leave the building.’)

(Note that the values for the format string, like “some_name”, “error_code” or “msg” are passed in as arguments - that’s so you never even construct the message if it isn’t going to be displayed.)

*N.B. if name is not passed as an argument then this will set the root logger properties (and all the pi3d module logging will also be logged, which is what you usually want.)*

The level, file, format arguments are passed on to set_logs() see below.

set_logs(level=None, file=None, format=None)[source]

You can redirect, filter or reformat your logging by calling Log.set_logs(). Log.set_logs() has three optional parameters:

can be one of ‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, or ‘CRITICAL’. Everything that’s the current log level or greater is displayed - for example, if your current log level is ‘WARNING’, then you’ll display all warning, error, or critical messages. If this argument is not supplied then the level will not change from previously set.
is the name of a file to which to redirect messages. If this argument is not supplied or is set to None then logging to file will stop if previously set, and will be directed to terminal.
controls what information is in the output messages. The default is
‘%(asctime)s %(levelname)s: %(name)s: %(message)s’
which results in output looking like this:
time LEVEL: filename: Your Message Here.

OffScreenTexture Module

class pi3d.util.OffScreenTexture.TextureShell(_tex, ix, iy, blend, mipmap)[source]

Bases: object

Allows OffscreenTexture to hold a color texture and a depth texture that can be added to Buffer.texture allowing it to have tex() function called as with a normal Texture

class pi3d.util.OffScreenTexture.OffScreenTexture(name='')[source]

Bases: object

For creating special effect after rendering to texture rather than onto the display. Used by Defocus, ShadowCaster, Clashtest etc

new system doesn’t use Texture


PexParticles Module

class pi3d.util.PexParticles.PexParticles(pex_file, emission_rate=10, scale=1.0, rot_rate=None, rot_var=0.0, new_batch=0.1, hardness=2.0, **kwargs)[source]

Bases: pi3d.shape.Points.Points

has to be supplied with a pex xml type file to parse. The results are loaded into new attributes of the instance of this class with identifiers matching the Elements of the pex file. There is zero checking for the correct file format.

pex_file: file name. if “circle” then lite option doesn’t
use texture lookup and used mat_pointsprite shader

emission_rate: new particles per second scale: scale the point size and location rot_rate: UV mapping rotates rot_var: variance in rotation rate new_batch: proportion of emission_rate to batch (for efficiency) hardness: for lite version

The following attributes are created from the pex file and can be subsequently altered. i.e. self.sourcePosition[‘x’] += 2.0

self.texture={name:’particle.png’} self.sourcePosition={x:160.00,y:369.01} self.sourcePositionVariance={x:60.00,y:0.00} self.speed=138.16 self.speedVariance=0.00 self.particleLifeSpan=0.7000 self.particleLifespanVariance=0.0000 self.angle=224.38 self.angleVariance=360.00 self.gravity={x:0.00,y:-1400.00} self.radialAcceleration=0.00 self.tangentialAcceleration=0.00 self.radialAccelVariance=0.00 self.tangentialAccelVariance=-0.00 self.startColor={red:0.15,green:0.06,blue:1.00,alpha:1.00} self.startColorVariance={red:0.00,green:0.00,blue:0.00,alpha:0.00} self.finishColor={red:0.00,green:0.14,blue:0.23,alpha:0.00} self.finishColorVariance={red:0.00,green:0.00,blue:0.00,alpha:0.00} self.maxParticles=300 self.startParticleSize=43.79 self.startParticleSizeVariance=0.00 self.finishParticleSize=138.11 self.FinishParticleSizeVariance=0.00 self.duration=-1.00 self.emitterType=0 self.maxRadius=100.00 self.maxRadiusVariance=0.00 self.minRadius=0.00 self.rotatePerSecond=0.00 self.rotatePerSecondVariance=0.00 self.blendFuncSource=770 self.blendFuncDestination=772 self.rotationStart=0.00 self.rotationStartVariance=0.00 self.rotationEnd=0.00 self.rotationEndVariance=0.00
any_colorchange = None

Buffer.array_buffer holds [0] vertices[0] x position of centre of point relative to centre of screen in pixels [1] vertices[1] y position [2] vertices[2] z depth but fract(z) is used as a multiplier for point size [3] normals[0] rotation in radians [4] normals[1] red and green values to multiply with the texture [5] normals[2] blue and alph values to multiply with the texture. The values

are packed into the whole number and fractional parts of the float i.e. where R and G are between 0.0 and 0.999 normals[:,2] = floor(999 * R) + G
[6] tex_coords[0] distance of left side of sprite square from left side of
texture in uv scale 0.0 to 1.0
[7] tex_coords[1] distance of top of sprite square from top of texture
for lite version using the mat_pointsprite shader

[3:7] hold RGBA in simple float form

make additional numpy array to hold the particle info

arr[0] x velocity arr[1] y velocity arr[2] lifespan arr[3] lifespan remaining arr[4:8] rgba target values arr[8:12] rgba difference arr[12] size delta (finish size - start size) / full_lifespan arr[13] radial acceleration arr[14] tangential acceleration


Pngfont Module

class pi3d.util.Pngfont.Pngfont(font, color=(255, 255, 255, 255))[source]

Bases: pi3d.Texture.Texture

A method of writing in pi3d using ‘hand designed’ fonts, where the top line of the texture contains metainformation about each character.

Mainly superseded by the Font class.

The name of a file containing a PNG texture.
A hex string representing a color.

PointText Module

class pi3d.util.PointText.PointText(font, camera, max_chars=100, point_size=48)[source]

Bases: object

Arguments: font:

A PointFont object.
camera to use for drawing the text. Normally a fixed 2d camera.
maximum number of chars, which determines the number of points in the buffer
size of “default” characters created using the Points class and the font. This is further scaled by the TextBlock.size This refinement is needed to allow pointsize to be different in Points from Font to avoid clipping or overlap of corners when rotation some truetype fonts

Regenerate all text blocks that are linked to data objects and have changed value


Add a text block to the collection, setting the object link to this service and setting the buffer offset allocated to the text block. This is required for the text block to update the buffer allocated to it. Also tracks the next unallocated character in the buffer.


Draw all the text characters. If the re_init flag is set then update the points shape buffer.


PostProcess Module

class pi3d.util.PostProcess.PostProcess(shader='post_base', mipmap=False, add_tex=None, scale=1.0, camera=None, divide=1)[source]

Bases: pi3d.util.OffScreenTexture.OffScreenTexture

For creating a an offscreen texture that can be redrawn using shaders as required by the developer

calls Texture.__init__ but doesn’t need to set file name as texture generated from the framebuffer. Keyword Arguments:

to use when drawing sprite, defaults to post_base, a simple 3x3 convolution that does basic edge detection. Can be copied to project directory and modified as required.
can be set to True with slight cost to speed, or use fxaa shader
list of textures. If additional textures can be used by the shader then they can be added here.
will only render this proportion of the full screen which will then be mapped to the full uv of the Sprite. The camera object passed (below) will need to have the same scale set to avoid perspective distortion
the camera to use for rendering to the offscreen texture
allow the sprite to be created with intermediate vertices to allow interesting vertex shader effects

after calling this method all object.draw()s will rendered to this texture and not appear on the display. Large objects will obviously take a while to draw and re-draw


stop capturing to texture and resume normal rendering to default


draw the shape using the saved texture Keyword Argument:

dictionay object i.e. {a:unif[a], b:unif[b], c:unif[c]} where a,b,c are subscripts of the unif array in Shape available for user custom space i.e. unif[48]…unif[59] corresponding with the vec3 uniform variables unif[16][0] to unif[19][2] NB the values must be three value tuples or 1D arrays

RotateVec Module

pi3d.util.RotateVec.rotate_vec(rx, ry, rz, xyz)[source]

Screenshot Module


Save whatever’s in the display to a file.

Will save whatever has been rendered since the last call to Display.clear().

The file will be saved in the same directory as the app if you don’t add a path to it!

If PIL is not available then the screenshot will be saved as a compressed numpy array and ‘.npz’ will be appended to the filestring you supply. The image can be extracted from the npz file using:

img = np.load(‘filestring.npz’)[‘arr_0’]

If this function is called without any argument then it will not save to file and will return a numpy array of the screen. The array and file, if saved, will have the alpha values removed.

pi3d.util.Screenshot.masked_screenshot(x, y, w, h)[source]

returns numpy array from part of screen so it can be used by applications drawing low resolution offscreen textures using scaling.

ShadowCaster Module

class pi3d.util.ShadowCaster.ShadowCaster(position, light, scale=10.0)[source]

Bases: pi3d.util.OffScreenTexture.OffScreenTexture

For creating a depth-of-field blurring effect on selected objects

calls Texture.__init__ but doesn’t need to set file name as texture generated from the framebuffer

draw_tree(tree, shader)[source]

StereoCam Module

class pi3d.util.StereoCam.StereoCam(shader='uv_flat', mipmap=False, separation=0.4, interlace=0)[source]

Bases: object

For creating an apparatus with two sprites to hold left and right eye views.

This Class is used to hold the 3D Camera which should be used to draw the 3D objects. It also holds a 2D Camera for drawing the Sprites

calls Texture.__init__ but doesn’t need to set file name as texture generated from the framebuffer. Keyword Arguments:

to use when drawing sprite, defaults to uv_flat.
can be set to True with slight cost to speed, or use fxaa shader
distance between the two camera positions - how wide apart the eye views are.
if interlace > 0 then the images are not taken with glScissor and must be drawn with a special interlacing shader.
move_camera(position, rot, tilt, roll=0.0, absolute=True)[source]


array [x,y,z]
rot, tilt, roll
rotations about y, x, z axis (yes it’s not entirely logical for position to be an array and orientation three values but it’s too late to change!)
if set to False then the rotations are treated as relative to the rotated frame of reference i.e. as if signals from VR headset 3 axis gyro.

after calling this method all object.draw()s will rendered to this texture and not appear on the display.

Either 0 or 1 to determine stereoscopic view

stop capturing to texture and resume normal rendering to default


draw the shape using the saved texture


String Module

class pi3d.util.String.String(camera=None, light=None, font=None, string=None, x=0.0, y=0.0, z=1.0, sx=0.003333333333333333, sy=0.003333333333333333, is_3d=True, size=0.24, rx=0.0, ry=0.0, rz=0.0, justify='C')[source]

Bases: pi3d.Shape.Shape

Shape used for writing text on screen. It is a flat, one sided rectangualar plane

Standard Shape constructor without the facility to change z scale or

any of the offset values. Additional keyword arguments:

Pngfont or Font class object.
of ASCI characters in range(32, 128) plus 10 =
Line Feed
sx, sy
These change the actual vertex positions of the shape rather than being used as scaling factors. This is to avoid distortion when the string is drawn using an orthographic camera
alters the values of sx and sy to give reasonable sizes with 2D or 3D drawing
approximate size of the characters in inches - obviously for 3D drawing of strings this will depend on camera fov, display size and how far away the string is placed
default C for central, can be R for right or L for left

Method for quickly changing some characters within a previously generated String. i.e. for changing digits in a readout etc.

NB: 1. if you use a variable width font there will be some distortion as characters are stretched or squashed to the original character’s dimensions. 2. there is no account made of new line characters (TODO) 3. you must make the original string long enough to fit any additional characters you add to new_string 4. you must make sure the Font as used for the String.__init__ contains all the glyphs you may need for subsequent changes.

TextBlock Module

pi3d.util.TextBlock.getattra(obj, attr, default)[source]
class pi3d.util.TextBlock.TextBlockColour(colour=(1.0, 1.0, 1.0, 1.0), textBlock=None)[source]

Bases: object

set_colour(colour=None, alpha=None)[source]
class pi3d.util.TextBlock.TextBlockColourGradient(colour1, colour2, textBlock=None)[source]

Bases: pi3d.util.TextBlock.TextBlockColour

set_colour(colour1=None, colour2=None)[source]

Colour each character with a gradient from colour1 to colour2 Interpolate hsv instead of rgb since it is a more natural change.

class pi3d.util.TextBlock.TextBlock(x, y, z, rot, char_count, data_obj=None, attr=None, text_format='{:s}', size=0.99, spacing='C', space=1.1, colour=(1.0, 1.0, 1.0, 1.0), char_rot=0.0, justify=0.0)[source]

Bases: object

Arguments: x, y, z:

As usual
rotation in degrees
number of characters for this block (capacity it can expand into)
Data object to use in text format
Attribute in data object to use in text format
Thetext format to use including any data formattings
Size of the text 0 to 0.9999
Type of character spacing. C=Constant, M=Multiplier, F=Fixed space between chars
Value to set the spacing to
drawn colour including alpha as format (0.99, 0.99, 0.99, 0.99)
character rotation in degrees
Justification position. 0.0=Left, 0.5=Center, 1.0=Right
set_text_manager(manager, buffer_index)[source]
set_position(x=None, y=None, z=None, rot=None)[source]
set_text(text_format=None, size=None, spacing=None, space=None, char_rot=None, set_pos=True, set_colour=True, wrap=None, line_space=1.0, wrap_pixels=None)[source]

Arguments: text_format:

text to display or a format string for displaying value from data_obj
size of text 0.0 to 0.9999
‘C’, ‘M’ or ‘F’
additional space between character
character rotation in degrees
control whether set_position() is called - default True
control whether set_colour() is called - default True
if set then line breaks insterted to wrap at this number of characters
multiplier for line spacing if multiline TextBlock
if set to value then lines will be wrapped to new line at this distance TODO only aligns accurately with spacing type F
split_lines(txt, width)[source]

TkWin Module

class pi3d.util.TkWin.TkWin(parent, title, width, height, bg='#000000')[source]

Bases: tkinter.Tk

TkWin encapsulates a Tk window and keeps track of the mouse and keyboard.


Parent Tk window or Null for none.
Title for window.
width, height
Dimensions of window.

Utility Module


Normalize a numpy array of 3 component vectors shape=(n,3)


Return the magnitude (root mean square) of the vector.

pi3d.util.Utility.distance(v1, v2)[source]

Return the distance between two points.

pi3d.util.Utility.from_polar(direction=0.0, magnitude=1.0)[source]

Convert polar coordinates into Cartesian (x, y) coordinates.


Vector angle in degrees.
Vector length.
pi3d.util.Utility.from_polar_rad(direction=0.0, magnitude=1.0)[source]

Convert polar coordinates into Cartesian (x, y) coordinates.


Vector angle in radians.
Vector length.
pi3d.util.Utility.vec_sub(x, y)[source]

Return the difference between two vectors.

pi3d.util.Utility.vec_dot(x, y)[source]

Return the dot product of two vectors.

pi3d.util.Utility.vec_cross(a, b)[source]

Return the cross product of two vectors.


Return a vector normalized to unit length for a vector of non-zero length, otherwise returns the original vector.

pi3d.util.Utility.draw_level_of_detail(here, there, mlist)[source]

Level Of Detail checking and rendering. The shader and texture information must be set for all the buf objects in each model before draw_level_of_detail is called.

An (x, y, z) tuple or array of view point.
An (x, y, z) tuple or array of model position.

A list of (distance, model) pairs with increasing distance, e.g.:

[[20, model1], [100, model2], [250, None]]

draw_level_of_detail() selects the first model that is more distant than the distance between the two points here and there, falling back to the last model otherwise. The model None is not rendered and is a good way to make sure that nothing is drawn past a certain distance.