PyOpenGL keyboard won’t respond?

PyMathArt

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):
        sys.exit()
    if ch == 'q':
        sys.exit()

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

 glutKeyboardFunc(keyboard)

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

/* change view angle, exit upon ESC */
/* ARGSUSED1 */
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):
        sys.exit()
    if ch == 'q':
        print('Good bye!')
    sys.exit()

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 PyMathArt.py
<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):
        sys.exit()
    if key == 'q':
        print("Bye!")
        sys.exit()
# python3
# http://www.math.uiuc.edu/~gfrancis/illimath/StanBlank/PyOpenGL.pdf
# Python Programming in OpenGL by Stan Blank, p100
# 4/26/2016
# PyMathArt.py

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():
    glClear(GL_COLOR_BUFFER_BIT)
    glBegin(GL_POINTS)

    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)
    glEnd()
    glFlush()

# 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
    glMatrixMode(GL_PROJECTION)

    # Load the identity matrix
    glLoadIdentity()

    # Set the aspect ratio of the plot
    if w <= h:
        gluOrtho2D(-axrng, axrng, -axrng*h/w, axrng*h/w)
    else:
        # 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
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

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

"""
Since we declared the reshape function as the glutReshapeFunc() in def main():
, when the pypolar.py 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

    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowPosition(100, 100)
    glutInitWindowSize(width, height)
    glutCreateWindow("Math Art Patterns")
    glutReshapeFunc(reshape)
    glutDisplayFunc(plotmathart)
    glutKeyboardFunc(keyboard)

    init()
    glutMainLoop()

main()
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
https://lists.gnu.org/archive/html/bug-grep/2014-12/msg00049.html

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.

Geodome
R50cm_dome_default_bottom

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
R50cm_dome_flat_bottom

Dome frames
R50cm_dome_frame_flat_bottom

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(index);
        echo(V[index[0]]);
        echo(V[index[0]][1]);        
        //echo(V[index][0]][1]);
    }    
}

Output

ECHO: [0]
ECHO: 0
ECHO: [0, [0, 0, 19.69]]
ECHO: [0, 0, 19.69]
ECHO: [1]
ECHO: 1
ECHO: [1, [10.3516, 0, 16.7493]]
ECHO: [10.3516, 0, 16.7493]
ECHO: [2]
ECHO: 2
ECHO: [2, [3.19883, 9.845, 16.7493]]
ECHO: [3.19883, 9.845, 16.7493]
ECHO: [3]
ECHO: 3
ECHO: [3, [-8.37466, 6.08454, 16.7493]]
ECHO: [-8.37466, 6.08454, 16.7493]
ECHO: [4]
ECHO: 4
ECHO: [4, [-8.37466, -6.08454, 16.7493]]
ECHO: [-8.37466, -6.08454, 16.7493]
ECHO: [5]
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
http://www.thingiverse.com/thing:468651

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)
{
    difference()
    {
        key(key_profiles[key_row]);
    
        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

Slic3r
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

Bulbul_Junior_20160402_0078Bulbul_Junior_20160402_0080Bulbul_Junior_20160402_0082

Bulbul_Junior_20160402_0086Bulbul_Junior_20160402_0084

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
Bulbul_Junior_20160331_0045

Source: http://www.thingiverse.com/make:208879

Parts:
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
Bulbul_Junior_20160331_0037

Bulbul_Junior_20160331_0039

M3x15 x2
M3 washer x2
M3 nut x2Bulbul_Junior_20160331_0041

Bulbul_Junior_20160331_0043

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