PyOpenGL keyboard won’t respond?


Below code generates above beautiful image. One problem is keyboard wouldn't respond at all. keyboard() takes a string value when any key is pressed, ESC or q quit the program. All the example codes in PyOpenGL-Demo fail to respond keyboard also. This has been driving me nut! 
def keyboard(key, x, y):
    # Allow to quit by pressing 'Esc' or 'q'
    if ch == chr(27):
    if ch == 'q':

I checked how Geodome handles keyboard event. It was identical to PyOpenGL code. glutKeyboardFunc() calls the user defined keyboard function.


The keyboard function of Geodome as below takes unsigned char value.

/* change view angle, exit upon ESC */
static void
key(unsigned char k, int x, int y)
    switch (k) {
      case '2': tesselate_cmd(2, radius) ; break;
      case '3': tesselate_cmd(3, radius) ; break;
      case '4': tesselate_cmd(4, radius) ; break;
      case '5': tesselate_cmd(5, radius) ; break;
      case '6': tesselate_cmd(6, radius) ; break;
      case '7': tesselate_cmd(7, radius) ; break;
      case '8': tesselate_cmd(8, radius) ; break;
      case '9': tesselate_cmd(9, radius) ; break;
      case 'z': view_roty += 4.0; break;

I inserted print() line that shows key's data type and actual value to debug the problem.

def keyboard(key, x, y):
    ch = key.decode("utf-8")
    print(type(key), key, type(ch), ch)
    # Allow to quit by pressing 'Esc' or 'q'
    if ch == chr(27):
    if ch == 'q':
        print('Good bye!')

glutKeyboardFunc() is returning bytes object while keyboard()'s key parameter is expecting string object. So if condition becomes unknown that makes non-responsive to any keyboard event.

$ python3
<class 'bytes'> b'a' <class 'str'> a
<class 'bytes'> b'b' <class 'str'> b
<class 'bytes'> b'c' <class 'str'> c
<class 'bytes'> b'1' <class 'str'> 1

Fixed keyboard function

def keyboard(bkey, x, y):
    # Convert bytes object to string 
    key = bkey.decode("utf-8")
    # Allow to quit by pressing 'Esc' or 'q'
    if key == chr(27):
    if key == 'q':
# python3
# Python Programming in OpenGL by Stan Blank, p100
# 4/26/2016

from OpenGL.GLUT import *       # GL Utilities Toolkit
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
import random
import sys

# Set the width and height of the window with global variables
# Set the axis range globally
global width
global height
global axrng
global stepsize

# Initial values
width = 500
height = 500
axrng = 10.0
stepsize = (2.0 * axrng) / width

# convert degree to radian
def rad(x):
    return np.pi/180.0 * x

def init():
    # red, green, blue, alpha from 0.0 to 1.0
    glClearColor(1.0, 1.0, 1.0, 1.0)

    # (x-left, x-right, y-bottom, y-top) set the coordinate system ranges
    # -1.0 to 1.0 for both x and y, origin(0,0) in the center
    # gluOrtho2D(-5.0, 5.0, -5.0, 5.0)

def plotmathart():

    for x in np.arange(-axrng, axrng, stepsize): # 0.04
        for y in np.arange(-axrng, axrng, stepsize):
            r = np.cos(x) + np.sin(y)
            glColor3f(np.cos(y*r), np.cos(x*y*r), np.sin(r*x))
            glVertex2f(x, y)

# Keep the aspect ratio of the graphics window and
# anything we draw will look in proper proportion
# OpenGL set w and h values as the graphics window's size changes
def reshape(w, h):

    # To insure we don't have a zero widow height
    if h == 0:
        h = 1
# Fill the entire graphic window
    glViewport(0, 0, w, h)

    # Set the projection matrix or the world view

    # Load the identity matrix

    # Set the aspect ratio of the plot
    if w <= h:
        gluOrtho2D(-axrng, axrng, -axrng*h/w, axrng*h/w)
        # gluOrtho2D(-axrng*w/h, axrng*w/h, -axrng, axrng)
        gluOrtho2D(-axrng*h/w, axrng*h/w, -axrng, axrng)

    # Set the matrix for the object we are drawing

def keyboard(key, x, y):
    # Allow to quit by pressing 'Esc' or 'q'
    if ch == chr(27):
    if ch == 'q':

Since we declared the reshape function as the glutReshapeFunc() in def main():
, when the program runs, OpenGL/GLUT assumes that the creatio n of the graphics window constitutes a “reshaping” of the window and the reshape function is automatically called or triggered by GLUT.
def main():
    global width
    global height

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowPosition(100, 100)
    glutInitWindowSize(width, height)
    glutCreateWindow("Math Art Patterns")


Posted in GNU/Linux | Tagged , , , , , | Leave a comment

grep reports Binary file xxx matches

Yesterday I ran into weird problem that grep wouldn’t find some functions in C source files, which drove me nut. ‘It can’t be or can it?’ I hardly do C programming and my confidence is low nowdays. I forgot how to create Makefile for building source codes.

I was looking for which source file contains tesselate() function running grep commands and was seeing empty console.

$ grep -n tesselate *.c
Binary file dome_math.c matches

Why couldn’t I think about the message seriouslY? dome_math.c has to be a text file and I knew it.

There was a bug report.
bug#19388: grep 2.21-1 identifies iso encoded text files as binary

Until I test new version of grep, I’ll use -a option to search words in source files.

$ file *.c
3ds_utils.c: C source, ISO-8859 text
dome_3ds.c: C source, ASCII text
dome.c: C source, ASCII text
dome_cover.c: C source, ASCII text
dome_file.c: C source, ASCII text
dome_layout.c: C source, ASCII text
dome_math.c: C source, ISO-8859 text
dome_struts.c: C source, ASCII text
main.c: C source, ASCII text
utils.c: C source, ASCII text

$ grep -a tesselate dome_math.c
static void tesselate1(const Dome *in, Face face, int f, Dome *out,
tesselate(const Dome *in, Dome *out, int f)
tesselate1(in, in->faces[i], f, out, &fcount, could not be a binary file. &vcount, &ecount);
tesselate1(const Dome *in, Face face, int f, Dome *out,
fprintf(stderr, “Internal error: out of faces in tesselate\n”);
fprintf(stderr, “Internal error: out of vertices in tesselate\n”);

$ grep tesselate dome_math.c
Binary file dome_math.c matches

Posted in GNU/Linux | Tagged | Leave a comment

Building the second dome

I decided to build another dome that shields the dome from water.

The dome model’s radius is around 50 cm.


I got to use 3D Printer and OpenSCAD this time. I consider 3D Printer as a powerful engineering tool that saves a lot of time and resources during the early design stage.

I’m working on geodesic dome generator using OpenSCAD so that I’ll produce plastic parts to build a scaled-down dome model before I will start build the real one.

Dome faces

Dome frames

Source code

Posted in Reprap 3D Printer, Science and technologies | Tagged , , , , , | Leave a comment

Accessing vector element

OpenSCAD does not support manipulate variables like Python or other programming languages yet. Or I haven’t found how to do it.

V = 
     // 1st row  
    [0, [0, 0, 19.69]],                  // 0
    // 2nd row
    // [10.3516, 0, -10.3517],      // 2 bug 
    [1, [10.3516, 0, 16.7493]],          // 2 correct     
    [2, [3.19883,9.845,16.7493]],        // 12 
    [3, [-8.37466,6.08454,16.7493]],     // 9        
    [4, [-8.37466,-6.08454,16.7493]],    // 6
    [5, [3.19883,-9.845,16.7493]]        // 1

// Not working 
function get_vertex(p) = lookup(p, [0: len(V)-1]);

module lookup_test2()
    for (i = [0 : len(V)-1])
        echo(i, get_vertex(i));

module search_test()
    for (i = [0 : len(V)-1])
        index = search(str(i), V, 1, 0);


ECHO: [0]
ECHO: [0, [0, 0, 19.69]]
ECHO: [0, 0, 19.69]
ECHO: [1]
ECHO: [1, [10.3516, 0, 16.7493]]
ECHO: [10.3516, 0, 16.7493]
ECHO: [2]
ECHO: [2, [3.19883, 9.845, 16.7493]]
ECHO: [3.19883, 9.845, 16.7493]
ECHO: [3]
ECHO: [3, [-8.37466, 6.08454, 16.7493]]
ECHO: [-8.37466, 6.08454, 16.7493]
ECHO: [4]
ECHO: [4, [-8.37466, -6.08454, 16.7493]]
ECHO: [-8.37466, -6.08454, 16.7493]
ECHO: [5]
ECHO: [5, [3.19883, -9.845, 16.7493]]
ECHO: [3.19883, -9.845, 16.7493]
Posted in Reprap 3D Printer | Tagged , , , | Leave a comment

Getting started with an Arduino Mini – Header Pins and USB from an Arduino Uno

Posted in Science and technologies | Tagged , , | Leave a comment

Printed Colemak keyboard

Now I have a real Colemak keyboard.  How many years it has taken?

I used the key cap generator.
Parametric Cherry MX/Alps Keycap for Mechanical Keyboards

I created a short module that creates a key cap per letter.

module generate_keycap(font_name, font_size, key_row, letter, h, x, y, z, l_a)
        translate([x, y, z]) rotate([l_a, 0, 0])
            #linear_extrude(height = h, center = true, convexity = 10, twist = 0)
            text(letter, size=font_size, font=font_name);

// ']'
translate([0, 0, 0]) 
    generate_keycap(&quot;Courier&quot;, 8, 4, &quot;/&quot;, 3.5, -4.5, 1, 7, -20);

// translate([20*0, 0, 0])
//    generate_keycap(&quot;Courier&quot;, 8, 3, &quot;R&quot;, 3, -4.5, 1, 5);

// translate([20, 0, 0])
//    generate_keycap(&quot;Courier&quot;, 8, 3, &quot;D&quot;, 3, -4.5, 1, 5);

Filament: eSun PLA 1.75 mm
Layer height: 0.1 mm

Raft option for the key cap printing

Raft layers: 2
Contact Z distance: 0.1
Pattern: rectilinear grid
Pattern spacing: 0.5
Pattern angle: 45
Interface layers: 3
Interface pattern spacing: 0.5
Dont’ support bridges: on



Posted in Reprap 3D Printer | Tagged , , , , , | Leave a comment

Bulbul Junior 3D Printer -new belt tensioner

Previous version
It was akward, looked ugly. To adjust belt tension of one axis, it requires to loose the vertex frame then turn the belt adjuster bolt. The problem is when the vertex frame is moves up, it affects alignment of the whole frame.

New version


M3x30 (I used M3x35) x1
M3x15 x2
F623ZZ x2
M3 washer x8 (used five washers on the idler)
M3 nut x3

M3x30 bolt x1
M3 nut x1
M3 washer x1
Leftside of the idler bearings – M3 washer x3
Rightside of the idler bearings – M3 washer x2


M3x15 x2
M3 washer x2
M3 nut x2Bulbul_Junior_20160331_0041


Posted in DIY, Reprap 3D Printer | Tagged , , | Leave a comment