New Python bindings via Cython
This commit is contained in:
parent
8c23610b0f
commit
2b24b889db
8 changed files with 815 additions and 2 deletions
|
@ -30,6 +30,7 @@ endif()
|
|||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(JACK REQUIRED)
|
||||
find_package(PythonInterp REQUIRED)
|
||||
find_package(Qt4)
|
||||
find_package(FFmpeg)
|
||||
find_package(OpenGL)
|
||||
|
@ -46,4 +47,5 @@ add_definitions(-Wall)
|
|||
add_subdirectory (libol)
|
||||
add_subdirectory (output)
|
||||
add_subdirectory (tools)
|
||||
add_subdirectory (python)
|
||||
add_subdirectory (examples)
|
||||
|
|
|
@ -35,7 +35,7 @@ if(CURSES_FOUND AND FFMPEG_FOUND)
|
|||
DEPENDS ${CMAKE_SOURCE_DIR}/tools/svg2ild.py
|
||||
MAIN_DEPENDENCY ${NAME}.svg
|
||||
DEPENDS ${NAME}.svg ${NAME}.cfg
|
||||
COMMAND python ${CMAKE_SOURCE_DIR}/tools/svg2ild.py -q ${ARGN} -cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.svg ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.ild)
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/svg2ild.py -q ${ARGN} -cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.cfg ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.svg ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.ild)
|
||||
endfunction()
|
||||
|
||||
svg2ild(openlase-logo -noopt)
|
||||
|
|
185
examples/harp2.py
Normal file
185
examples/harp2.py
Normal file
|
@ -0,0 +1,185 @@
|
|||
# OpenLase - a realtime laser graphics toolkit
|
||||
#
|
||||
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 or version 3.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# This is the laser harp sensing portion, which has nothing to do with OpenLase.
|
||||
# You need OpenCV (2.2.0) and PyALSA installed
|
||||
# Pass the destination ALSA MIDI client:port pair as an argument.
|
||||
|
||||
# You may need to edit some constants here
|
||||
|
||||
THRESHOLD=60
|
||||
WIDTH=320
|
||||
HEIGHT=240
|
||||
|
||||
VELOCITY=90
|
||||
|
||||
import sys, math
|
||||
import cv
|
||||
|
||||
from pyalsa import alsaseq
|
||||
import pylase as ol
|
||||
import threading, time
|
||||
|
||||
class LaserThread(threading.Thread):
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.die = False
|
||||
self.dots = []
|
||||
|
||||
def run(self):
|
||||
ol.init()
|
||||
params = ol.RenderParams()
|
||||
params.render_flags = ol.RENDER_NOREORDER | ol.RENDER_GRAYSCALE
|
||||
ol.setRenderParams(params)
|
||||
|
||||
while not self.die:
|
||||
ol.loadIdentity()
|
||||
for x,y in self.dots:
|
||||
ol.dot((x,y), 30, ol.C_WHITE)
|
||||
|
||||
ol.renderFrame(100)
|
||||
ol.shutdown()
|
||||
|
||||
seq = alsaseq.Sequencer(name="default", clientname=sys.argv[0], streams = alsaseq.SEQ_OPEN_DUPLEX, mode = alsaseq.SEQ_NONBLOCK)
|
||||
port = seq.create_simple_port(
|
||||
name='out',
|
||||
type = alsaseq.SEQ_PORT_TYPE_MIDI_GENERIC | alsaseq.SEQ_PORT_TYPE_APPLICATION,
|
||||
caps = alsaseq.SEQ_PORT_CAP_READ | alsaseq.SEQ_PORT_CAP_SUBS_READ)
|
||||
|
||||
def note(n, state=False):
|
||||
if state:
|
||||
etype = alsaseq.SEQ_EVENT_NOTEON
|
||||
else:
|
||||
etype = alsaseq.SEQ_EVENT_NOTEOFF
|
||||
event = alsaseq.SeqEvent(type=etype)
|
||||
event.set_data({'note.channel': 0, 'note.note': n, 'note.velocity': 90})
|
||||
seq.output_event(event)
|
||||
seq.drain_output()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
toport = seq.parse_address(sys.argv[1])
|
||||
seq.connect_ports((seq.client_id, port), toport)
|
||||
|
||||
def getpoints(image):
|
||||
points = []
|
||||
cv.CvtColor(image, grey, cv.CV_RGB2GRAY)
|
||||
cv.Threshold(grey, grey, THRESHOLD, 255, cv.CV_THRESH_BINARY)
|
||||
cv.Copy(grey, grey2)
|
||||
|
||||
storage = cv.CreateMemStorage(0)
|
||||
contour = cv.FindContours(grey, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE)
|
||||
while contour:
|
||||
bound_rect = cv.BoundingRect(list(contour))
|
||||
contour = contour.h_next()
|
||||
|
||||
pt = (bound_rect[0] + bound_rect[2]/2, bound_rect[1] + bound_rect[3]/2)
|
||||
#cv.Circle(image, pt, 2, cv.CV_RGB(255,0,0), 1)
|
||||
points.append(pt)
|
||||
return points
|
||||
|
||||
def near(p1, p2, d):
|
||||
x,y = (p1[0]-p2[0],p1[1]-p2[1])
|
||||
dist = math.sqrt(x**2+y**2)
|
||||
return dist < d
|
||||
|
||||
oldstate = None
|
||||
|
||||
olt = LaserThread()
|
||||
print "Starting thread"
|
||||
|
||||
v_off = -0.1
|
||||
|
||||
n_start = 47
|
||||
n_end = 47 + 25
|
||||
n_off = 0
|
||||
|
||||
offsets = [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0]
|
||||
xpos = [0, 0.5, 1, 1.5, 2, 3, 3.5, 4, 4.5, 5, 5.5, 6]
|
||||
|
||||
def gxpos(x):
|
||||
o = x // 12
|
||||
v = x % 12
|
||||
return xpos[v] + o * 7
|
||||
|
||||
dots = []
|
||||
|
||||
xstart = gxpos(n_start)
|
||||
xend = gxpos(n_end)
|
||||
|
||||
for n in range(n_start, n_end+1):
|
||||
ld = (n + n_off) % len(offsets)
|
||||
off = offsets[ld] * v_off
|
||||
x = 2 * (gxpos(n + n_off) - xstart) / float(xend - xstart)
|
||||
x -= 1.0
|
||||
x *= 0.99
|
||||
dots.append((-x, off))
|
||||
|
||||
olt.dots = dots
|
||||
|
||||
time.sleep(1)
|
||||
camera = cv.CreateCameraCapture(0)
|
||||
cv.SetCaptureProperty(camera, cv.CV_CAP_PROP_FRAME_WIDTH, WIDTH)
|
||||
cv.SetCaptureProperty(camera, cv.CV_CAP_PROP_FRAME_HEIGHT, HEIGHT)
|
||||
cv.SetCaptureProperty(camera, cv.CV_CAP_PROP_BRIGHTNESS, 0)
|
||||
|
||||
image = cv.QueryFrame(camera)
|
||||
image = cv.QueryFrame(camera)
|
||||
image = cv.QueryFrame(camera)
|
||||
|
||||
grey = cv.CreateImage(cv.GetSize(image), cv.IPL_DEPTH_8U, 1)
|
||||
grey2 = cv.CreateImage(cv.GetSize(image), cv.IPL_DEPTH_8U, 1)
|
||||
|
||||
|
||||
olt.start()
|
||||
print "Thread running"
|
||||
|
||||
try:
|
||||
for i in range(30):
|
||||
image = cv.QueryFrame(camera)
|
||||
refpoints = getpoints(image)
|
||||
refpoints.sort(key=lambda x: -x[0])
|
||||
|
||||
print len(refpoints), n_end - n_start + 1
|
||||
|
||||
while True:
|
||||
image = cv.QueryFrame(camera)
|
||||
cpoints = getpoints(image)
|
||||
state = [False]*len(refpoints)
|
||||
for i, rp in enumerate(refpoints):
|
||||
for cp in cpoints:
|
||||
if near(rp,cp,4):
|
||||
break
|
||||
else:
|
||||
state[i] = True
|
||||
|
||||
if oldstate is not None:
|
||||
for i,(j,k) in enumerate(zip(oldstate, state)):
|
||||
if j != k:
|
||||
note(n_start+len(oldstate)-i, k)
|
||||
if k:
|
||||
print "PRESSED: %d"%i
|
||||
else:
|
||||
print "RELEASED: %d"%i
|
||||
oldstate = state
|
||||
|
||||
cv.ShowImage("thresholded", grey2)
|
||||
if cv.WaitKey(10)&0xfff == 27:
|
||||
break
|
||||
except:
|
||||
olt.die = True
|
||||
olt.join()
|
||||
raise
|
44
examples/showtext.py
Normal file
44
examples/showtext.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# OpenLase - a realtime laser graphics toolkit
|
||||
#
|
||||
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 or version 3.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import pylase as ol
|
||||
|
||||
import sys
|
||||
|
||||
if ol.init(10) < 0:
|
||||
sys.exit(1)
|
||||
params = ol.RenderParams()
|
||||
params.render_flags = ol.RENDER_NOREORDER | ol.RENDER_GRAYSCALE
|
||||
params.on_speed = 2/120.0
|
||||
params.off_speed = 2/30.0
|
||||
params.flatness = 0.000001
|
||||
ol.setRenderParams(params)
|
||||
|
||||
lines = sys.argv[1:]
|
||||
|
||||
while True:
|
||||
lc = len(lines)
|
||||
|
||||
font = ol.getDefaultFont()
|
||||
yoff = (lc/2.0) * 0.3
|
||||
|
||||
for i,line in enumerate(lines):
|
||||
w = ol.getStringWidth(font, 0.3, line)
|
||||
ol.drawString(font, (-w/2,yoff-i*0.3), 0.3, ol.C_WHITE, line)
|
||||
|
||||
ftime = ol.renderFrame(60)
|
77
examples/simple.py
Normal file
77
examples/simple.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# OpenLase - a realtime laser graphics toolkit
|
||||
#
|
||||
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 or version 3.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import pylase as ol
|
||||
from math import pi
|
||||
|
||||
ol.init()
|
||||
|
||||
time = 0
|
||||
frames = 0
|
||||
|
||||
while True:
|
||||
ol.loadIdentity3()
|
||||
ol.loadIdentity()
|
||||
|
||||
font = ol.getDefaultFont()
|
||||
s = "Hi!"
|
||||
w = ol.getStringWidth(font, 0.2, s)
|
||||
ol.drawString(font, (-w/2,0.1), 0.2, ol.C_WHITE, s)
|
||||
|
||||
ol.perspective(60, 1, 1, 100)
|
||||
ol.translate3((0, 0, -3))
|
||||
|
||||
for i in range(2):
|
||||
ol.scale3((0.6, 0.6, 0.6))
|
||||
ol.rotate3Z(time * pi * 0.1)
|
||||
ol.rotate3X(time * pi * 0.8)
|
||||
ol.rotate3Y(time * pi * 0.73)
|
||||
|
||||
ol.begin(ol.LINESTRIP)
|
||||
ol.vertex3((-1, -1, -1), ol.C_WHITE)
|
||||
ol.vertex3(( 1, -1, -1), ol.C_WHITE)
|
||||
ol.vertex3(( 1, 1, -1), ol.C_WHITE)
|
||||
ol.vertex3((-1, 1, -1), ol.C_WHITE)
|
||||
ol.vertex3((-1, -1, -1), ol.C_WHITE)
|
||||
ol.vertex3((-1, -1, 1), ol.C_WHITE)
|
||||
ol.end()
|
||||
|
||||
ol.begin(ol.LINESTRIP);
|
||||
ol.vertex3(( 1, 1, 1), ol.C_WHITE)
|
||||
ol.vertex3((-1, 1, 1), ol.C_WHITE)
|
||||
ol.vertex3((-1, -1, 1), ol.C_WHITE)
|
||||
ol.vertex3(( 1, -1, 1), ol.C_WHITE)
|
||||
ol.vertex3(( 1, 1, 1), ol.C_WHITE)
|
||||
ol.vertex3(( 1, 1, -1), ol.C_WHITE)
|
||||
ol.end()
|
||||
|
||||
ol.begin(ol.LINESTRIP)
|
||||
ol.vertex3(( 1, -1, -1), ol.C_WHITE)
|
||||
ol.vertex3(( 1, -1, 1), ol.C_WHITE)
|
||||
ol.end()
|
||||
|
||||
ol.begin(ol.LINESTRIP)
|
||||
ol.vertex3((-1, 1, 1), ol.C_WHITE)
|
||||
ol.vertex3((-1, 1, -1), ol.C_WHITE)
|
||||
ol.end()
|
||||
|
||||
ftime = ol.renderFrame(60)
|
||||
frames += 1
|
||||
time += ftime
|
||||
print "Frame time: %f, FPS:%f"%(ftime, frames/time)
|
||||
|
||||
ol.shutdown()
|
|
@ -25,4 +25,4 @@ target_link_libraries (openlase ${CMAKE_THREAD_LIBS_INIT} m jack)
|
|||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/fontdef.c
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/tools/genfont.py
|
||||
MAIN_DEPENDENCY laserfont.svg
|
||||
COMMAND python ${CMAKE_SOURCE_DIR}/tools/genfont.py ${CMAKE_CURRENT_SOURCE_DIR}/laserfont.svg ${CMAKE_CURRENT_BINARY_DIR}/fontdef.c default_font)
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/genfont.py ${CMAKE_CURRENT_SOURCE_DIR}/laserfont.svg ${CMAKE_CURRENT_BINARY_DIR}/fontdef.c default_font)
|
||||
|
|
23
python/CMakeLists.txt
Normal file
23
python/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
find_package(PythonLibs)
|
||||
find_program(CYTHON_EXECUTABLE cython)
|
||||
|
||||
if(CYTHON_EXECUTABLE MATCHES "NOTFOUND" OR NOT PYTHONLIBS_FOUND)
|
||||
message(STATUS "Will NOT build python bindings (python libs or cython missing)")
|
||||
else()
|
||||
execute_process(COMMAND
|
||||
${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
|
||||
OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
add_custom_command(OUTPUT pylase.c
|
||||
MAIN_DEPENDENCY pylase.pyx
|
||||
COMMAND ${CYTHON_EXECUTABLE} -I ${CMAKE_SOURCE_DIR}/include -o pylase.c "${CMAKE_CURRENT_SOURCE_DIR}/pylase.pyx")
|
||||
list(APPEND ADDITIONAL_MAKE_CLEAN_FILES pylase.c)
|
||||
|
||||
include_directories(${PYTHON_INCLUDE_PATH} ${CMAKE_SOURCE_DIR}/include)
|
||||
add_library(pylase MODULE pylase.c)
|
||||
set_target_properties(pylase PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "pylase"
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_link_libraries(pylase openlase)
|
||||
endif()
|
482
python/pylase.pyx
Normal file
482
python/pylase.pyx
Normal file
|
@ -0,0 +1,482 @@
|
|||
# OpenLase - a realtime laser graphics toolkit
|
||||
#
|
||||
# Copyright (C) 2009-2011 Hector Martin "marcan" <hector@marcansoft.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 or version 3.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
from libc.stdint cimport *
|
||||
|
||||
cdef extern from "libol.h":
|
||||
enum:
|
||||
OL_LINESTRIP
|
||||
OL_BEZIERSTRIP
|
||||
OL_POINTS
|
||||
enum:
|
||||
_RENDER_GRAYSCALE "RENDER_GRAYSCALE"
|
||||
_RENDER_NOREORDER "RENDER_NOREORDER"
|
||||
_RENDER_NOREVERSE "RENDER_NOREVERSE"
|
||||
|
||||
ctypedef struct OLRenderParams:
|
||||
int rate
|
||||
float on_speed
|
||||
float off_speed
|
||||
int start_wait
|
||||
int start_dwell
|
||||
int curve_dwell
|
||||
int corner_dwell
|
||||
int end_dwell
|
||||
int end_wait
|
||||
float curve_angle
|
||||
float flatness
|
||||
float snap
|
||||
int render_flags
|
||||
int min_length
|
||||
int max_framelen
|
||||
|
||||
ctypedef struct OLFrameInfo "OLFrameInfo":
|
||||
int objects
|
||||
int points
|
||||
int resampled_points
|
||||
int resampled_blacks
|
||||
int padding_points
|
||||
|
||||
int olInit(int buffer_count, int max_points)
|
||||
|
||||
void olSetRenderParams(OLRenderParams *params)
|
||||
void olGetRenderParams(OLRenderParams *params)
|
||||
|
||||
ctypedef void (*AudioCallbackFunc)(float *leftbuf, float *rightbuf, int samples)
|
||||
|
||||
void olSetAudioCallback(AudioCallbackFunc f)
|
||||
|
||||
void olLoadIdentity()
|
||||
void olPushMatrix()
|
||||
void olPopMatrix()
|
||||
|
||||
void olMultMatrix(float m[9])
|
||||
void olRotate(float theta)
|
||||
void olTranslate(float x, float y)
|
||||
void olScale(float sx, float sy)
|
||||
|
||||
void olLoadIdentity3()
|
||||
void olPushMatrix3()
|
||||
void olPopMatrix3()
|
||||
|
||||
void olMultMatrix3(float m[16])
|
||||
void olRotate3X(float theta)
|
||||
void olRotate3Y(float theta)
|
||||
void olRotate3Z(float theta)
|
||||
void olTranslate3(float x, float y, float z)
|
||||
void olScale3(float sx, float sy, float sz)
|
||||
|
||||
void olFrustum (float left, float right, float bot, float ttop, float near, float far)
|
||||
void olPerspective(float fovy, float aspect, float zNear, float zFar)
|
||||
|
||||
void olResetColor()
|
||||
void olMultColor(uint32_t color)
|
||||
void olPushColor()
|
||||
void olPopColor()
|
||||
|
||||
void olBegin(int prim)
|
||||
void olVertex(float x, float y, uint32_t color)
|
||||
void olVertex3(float x, float y, float z, uint32_t color)
|
||||
void olEnd()
|
||||
|
||||
void olTransformVertex3(float *x, float *y, float *z)
|
||||
|
||||
ctypedef void (*ShaderFunc)(float *x, float *y, uint32_t *color)
|
||||
ctypedef void (*Shader3Func)(float *x, float *y, float *z, uint32_t *color)
|
||||
|
||||
void olSetVertexPreShader(ShaderFunc f)
|
||||
void olSetVertexShader(ShaderFunc f)
|
||||
void olSetVertex3Shader(Shader3Func f)
|
||||
|
||||
void olSetPixelShader(ShaderFunc f)
|
||||
|
||||
void olRect(float x1, float y1, float x2, float y2, uint32_t color)
|
||||
void olLine(float x1, float y1, float x2, float y2, uint32_t color)
|
||||
void olDot(float x, float y, int points, uint32_t color)
|
||||
|
||||
float olRenderFrame(int max_fps) nogil
|
||||
|
||||
void olGetFrameInfo(OLFrameInfo *info)
|
||||
|
||||
void olShutdown()
|
||||
|
||||
void olSetScissor (float x0, float y0, float x1, float y1)
|
||||
|
||||
void olLog(char *fmt, ...)
|
||||
|
||||
ctypedef char* const_char_ptr "const char*"
|
||||
ctypedef void (*LogCallbackFunc)(char *msg)
|
||||
|
||||
void olSetLogCallback(LogCallbackFunc f)
|
||||
|
||||
LINESTRIP = OL_LINESTRIP
|
||||
BEZIERSTRIP = OL_BEZIERSTRIP
|
||||
POINTS = OL_POINTS
|
||||
|
||||
RENDER_GRAYSCALE = _RENDER_GRAYSCALE
|
||||
RENDER_NOREORDER = _RENDER_NOREORDER
|
||||
RENDER_NOREVERSE = _RENDER_NOREVERSE
|
||||
|
||||
C_RED = 0xff0000
|
||||
C_GREEN = 0x00ff00
|
||||
C_BLUE = 0x0000ff
|
||||
C_WHITE = 0xffffff
|
||||
|
||||
cpdef uint32_t C_GREY(uint8_t x):
|
||||
return 0x010101 * x
|
||||
|
||||
cdef class RenderParams:
|
||||
cdef public int rate
|
||||
cdef public float on_speed
|
||||
cdef public float off_speed
|
||||
cdef public int start_wait
|
||||
cdef public int start_dwell
|
||||
cdef public int curve_dwell
|
||||
cdef public int corner_dwell
|
||||
cdef public int end_dwell
|
||||
cdef public int end_wait
|
||||
cdef public float curve_angle
|
||||
cdef public float flatness
|
||||
cdef public float snap
|
||||
cdef public int render_flags
|
||||
cdef public int min_length
|
||||
cdef public int max_framelen
|
||||
def __init__(self):
|
||||
self.rate = 48000
|
||||
self.on_speed = 2/100.0
|
||||
self.off_speed = 1/30.0
|
||||
self.start_wait = 8
|
||||
self.start_dwell = 3
|
||||
self.curve_dwell = 0
|
||||
self.corner_dwell = 6
|
||||
self.end_dwell = 3
|
||||
self.end_wait = 7
|
||||
self.curve_angle = 0.866
|
||||
self.flatness = 0.00001
|
||||
self.snap = 0.00001
|
||||
self.render_flags = RENDER_GRAYSCALE
|
||||
self.min_length = 0
|
||||
self.max_framelen = 0
|
||||
|
||||
cpdef setRenderParams(params):
|
||||
cdef OLRenderParams cparams
|
||||
cparams.rate = params.rate
|
||||
cparams.on_speed = params.on_speed
|
||||
cparams.off_speed = params.off_speed
|
||||
cparams.start_wait = params.start_wait
|
||||
cparams.start_dwell = params.start_dwell
|
||||
cparams.curve_dwell = params.curve_dwell
|
||||
cparams.corner_dwell = params.corner_dwell
|
||||
cparams.end_dwell = params.end_dwell
|
||||
cparams.end_wait = params.end_wait
|
||||
cparams.curve_angle = params.curve_angle
|
||||
cparams.flatness = params.flatness
|
||||
cparams.snap = params.snap
|
||||
cparams.render_flags = params.render_flags
|
||||
cparams.min_length = params.min_length
|
||||
cparams.max_framelen = params.max_framelen
|
||||
olSetRenderParams(&cparams)
|
||||
|
||||
cpdef getRenderParams():
|
||||
cdef OLRenderParams params
|
||||
olGetRenderParams(¶ms)
|
||||
pyparams = RenderParams()
|
||||
pyparams.rate = params.rate
|
||||
pyparams.on_speed = params.on_speed
|
||||
pyparams.off_speed = params.off_speed
|
||||
pyparams.start_wait = params.start_wait
|
||||
pyparams.start_dwell = params.start_dwell
|
||||
pyparams.curve_dwell = params.curve_dwell
|
||||
pyparams.corner_dwell = params.corner_dwell
|
||||
pyparams.end_dwell = params.end_dwell
|
||||
pyparams.end_wait = params.end_wait
|
||||
pyparams.curve_angle = params.curve_angle
|
||||
pyparams.flatness = params.flatness
|
||||
pyparams.snap = params.snap
|
||||
pyparams.render_flags = params.render_flags
|
||||
pyparams.min_length = params.min_length
|
||||
pyparams.max_framelen = params.max_framelen
|
||||
return pyparams
|
||||
|
||||
cpdef int init(int buffer_count=4, int max_points=30000):
|
||||
cdef int ret = olInit(buffer_count, max_points)
|
||||
if ret < 0:
|
||||
return ret
|
||||
setRenderParams(RenderParams())
|
||||
return ret
|
||||
|
||||
cpdef loadIdentity(): olLoadIdentity()
|
||||
cpdef pushMatrix(): olPushMatrix()
|
||||
cpdef popMatrix(): olPopMatrix()
|
||||
|
||||
cpdef multMatrix(object m):
|
||||
if len(m) == 3:
|
||||
m = m[0] + m[1] + m[2]
|
||||
cdef float cm[9]
|
||||
for i in range(9):
|
||||
cm[i] = m[i]
|
||||
olMultMatrix(cm)
|
||||
|
||||
cpdef rotate(float theta): olRotate(theta)
|
||||
cpdef translate(tuple coord):
|
||||
x, y = coord
|
||||
olTranslate(x, y)
|
||||
cpdef scale(tuple coord):
|
||||
x, y = coord
|
||||
olScale(x, y)
|
||||
|
||||
_py_audiocb = None
|
||||
cdef void _audiocb(float *l, float *r, int samples) with gil:
|
||||
global _py_audiocb
|
||||
if _py_audiocb is not None:
|
||||
buf = _py_audiocb(samples)
|
||||
for i in range(min(len(buf), samples)):
|
||||
l[i], r[i] = buf[i]
|
||||
if len(buf) < samples:
|
||||
for i in range(len(buf), samples):
|
||||
l[i] = r[i] = 0
|
||||
|
||||
cpdef setAudioCallback(object func):
|
||||
global _py_audiocb
|
||||
_py_audiocb = func
|
||||
if func is not None:
|
||||
olSetAudioCallback(_audiocb)
|
||||
else:
|
||||
olSetAudioCallback(NULL)
|
||||
|
||||
cpdef loadIdentity3(): olLoadIdentity3()
|
||||
cpdef pushMatrix3(): olPushMatrix3()
|
||||
cpdef popMatrix3(): olPopMatrix3()
|
||||
|
||||
cpdef multMatrix3(object m):
|
||||
if len(m) == 4:
|
||||
m = m[0] + m[1] + m[2] + m[3]
|
||||
cdef float cm[16]
|
||||
for i in range(16):
|
||||
cm[i] = m[i]
|
||||
olMultMatrix(cm)
|
||||
|
||||
cpdef rotate3X(float theta): olRotate3X(theta)
|
||||
cpdef rotate3Y(float theta): olRotate3Y(theta)
|
||||
cpdef rotate3Z(float theta): olRotate3Z(theta)
|
||||
cpdef translate3(tuple coord):
|
||||
x, y, z = coord
|
||||
olTranslate3(x, y, z)
|
||||
cpdef scale3(tuple coord):
|
||||
x, y, z = coord
|
||||
olScale3(x, y, z)
|
||||
|
||||
cpdef frustum(float left, float right, float bot, float top, float near, float far):
|
||||
olFrustum(left, right, bot, top, near, far)
|
||||
cpdef perspective(float fovy, float aspect, float zNear, float zFar):
|
||||
olPerspective(fovy, aspect, zNear, zFar)
|
||||
|
||||
cpdef resetColor(): olResetColor()
|
||||
cpdef multColor(uint32_t color): olMultColor(color)
|
||||
cpdef pushColor(): olPushColor()
|
||||
cpdef popColor(): olPopColor()
|
||||
|
||||
cpdef begin(int prim): olBegin(prim)
|
||||
cpdef vertex(tuple coord, uint32_t color):
|
||||
x, y = coord
|
||||
olVertex(x, y, color)
|
||||
cpdef vertex3(tuple coord, uint32_t color):
|
||||
x, y, z = coord
|
||||
olVertex3(x, y, z, color)
|
||||
cpdef end(): olEnd()
|
||||
|
||||
cpdef tuple transformVertex3(float x, float y, float z):
|
||||
olTransformVertex3(&x, &y, &z)
|
||||
return x, y, z
|
||||
|
||||
_py_vpreshader = None
|
||||
cdef void _vpreshader(float *x, float *y, uint32_t *color) with gil:
|
||||
global _py_vpreshader
|
||||
if _py_vpreshader is not None:
|
||||
(x[0], y[0]), color[0] = _py_vpreshader((x[0], y[0]), color[0])
|
||||
|
||||
_py_vshader = None
|
||||
cdef void _vshader(float *x, float *y, uint32_t *color) with gil:
|
||||
global _py_vshader
|
||||
if _py_vshader is not None:
|
||||
(x[0], y[0]), color[0] = _py_vshader((x[0], y[0]), color[0])
|
||||
|
||||
_py_v3shader = None
|
||||
cdef void _v3shader(float *x, float *y, float *z, uint32_t *color) with gil:
|
||||
global _py_v3shader
|
||||
if _py_v3shader is not None:
|
||||
(x[0], y[0], z[0]), color[0] = _py_v3shader((x[0], y[0], z[0]), color[0])
|
||||
|
||||
_py_pshader = None
|
||||
cdef void _pshader(float *x, float *y, uint32_t *color) with gil:
|
||||
global _py_pshader
|
||||
if _py_pshader is not None:
|
||||
(x[0], y[0]), color[0] = _py_pshader((x[0], y[0]), color[0])
|
||||
|
||||
cpdef setVertexPreShader(object func):
|
||||
global _py_vpreshader
|
||||
_py_vpreshader = func
|
||||
if func is not None:
|
||||
olSetVertexPreShader(_vpreshader)
|
||||
else:
|
||||
olSetVertexPreShader(NULL)
|
||||
|
||||
cpdef setVertexShader(object func):
|
||||
global _py_vshader
|
||||
_py_vshader = func
|
||||
if func is not None:
|
||||
olSetVertexShader(_vshader)
|
||||
else:
|
||||
olSetVertexShader(NULL)
|
||||
|
||||
cpdef setVertex3Shader(object func):
|
||||
global _py_v3shader
|
||||
_py_v3shader = func
|
||||
if func is not None:
|
||||
olSetVertex3Shader(_v3shader)
|
||||
else:
|
||||
olSetVertex3Shader(NULL)
|
||||
|
||||
cpdef setPixelShader(object func):
|
||||
global _py_pshader
|
||||
_py_pshader = func
|
||||
if func is not None:
|
||||
olSetPixelShader(_pshader)
|
||||
else:
|
||||
olSetPixelShader(NULL)
|
||||
|
||||
cpdef rect(tuple start, tuple end, uint32_t color):
|
||||
x1, y1 = start
|
||||
x2, y2 = end
|
||||
olRect(x1, y1, x2, y2, color)
|
||||
|
||||
cpdef line(tuple start, tuple end, uint32_t color):
|
||||
x1, y1 = start
|
||||
x2, y2 = end
|
||||
olLine(x1, y1, x2, y2, color)
|
||||
|
||||
cpdef dot(tuple coord, int points, uint32_t color):
|
||||
x, y = coord
|
||||
olDot(x, y, points, color)
|
||||
|
||||
cpdef float renderFrame(int max_fps):
|
||||
cdef float ret
|
||||
with nogil:
|
||||
ret = olRenderFrame(max_fps)
|
||||
return ret
|
||||
|
||||
cdef class FrameInfo:
|
||||
cdef readonly int objects
|
||||
cdef readonly int points
|
||||
cdef readonly int resampled_points
|
||||
cdef readonly int resampled_blocks
|
||||
cdef readonly int padding_points
|
||||
|
||||
cpdef getFrameInfo():
|
||||
cdef OLFrameInfo info
|
||||
olGetFrameInfo(&info)
|
||||
pyinfo = FrameInfo()
|
||||
pyinfo.objects = info.objects
|
||||
pyinfo.points = info.points
|
||||
pyinfo.resampled_points = info.resampled_points
|
||||
pyinfo.resampled_blocks = info.resampled_blocks
|
||||
pyinfo.padding_points = info.padding_points
|
||||
return pyinfo
|
||||
|
||||
cpdef shutdown(): olShutdown()
|
||||
|
||||
cpdef setScissor(tuple start, tuple end):
|
||||
x1, y1 = start
|
||||
x2, y2 = end
|
||||
olSetScissor(x1, y1, x2, y2)
|
||||
|
||||
_py_logcb = None
|
||||
cdef void _logcb(const_char_ptr msg):
|
||||
global _py_logcb
|
||||
cdef bytes msg2 = msg
|
||||
if _py_logcb is not None:
|
||||
_py_logcb(msg2)
|
||||
|
||||
cpdef setLogCallback(object func):
|
||||
global _py_logcb
|
||||
_py_logcb = func
|
||||
if func is not None:
|
||||
olSetLogCallback(_logcb)
|
||||
else:
|
||||
olSetLogCallback(NULL)
|
||||
|
||||
cdef extern from "text.h":
|
||||
ctypedef struct _Font "Font"
|
||||
|
||||
_Font *olGetDefaultFont()
|
||||
float olGetCharWidth(_Font *fnt, char c)
|
||||
float olGetStringWidth(_Font *fnt, float height, char *s)
|
||||
float olGetCharOverlap(_Font *font, float height)
|
||||
float olDrawChar(_Font *fnt, float x, float y, float height, uint32_t color, char c)
|
||||
float olDrawString(_Font *fnt, float x, float y, float height, uint32_t color, char *s)
|
||||
|
||||
cdef class Font:
|
||||
cdef _Font *font
|
||||
|
||||
cpdef getDefaultFont():
|
||||
f = Font()
|
||||
f.font = olGetDefaultFont()
|
||||
return f
|
||||
|
||||
cpdef float getCharWidth(object font, char c):
|
||||
cdef Font fnt = font
|
||||
return olGetCharWidth(fnt.font, c)
|
||||
cpdef float getStringWidth(object font, float height, char *s):
|
||||
cdef Font fnt = font
|
||||
return olGetStringWidth(fnt.font, height, s)
|
||||
cpdef float getCharOverlap(object font, float height):
|
||||
cdef Font fnt = font
|
||||
return olGetCharOverlap(fnt.font, height)
|
||||
cpdef float drawChar(object font, tuple coord, float height, uint32_t color, char c):
|
||||
cdef Font fnt = font
|
||||
x, y = coord
|
||||
return olDrawChar(fnt.font, x, y, height, color, c)
|
||||
cpdef float drawString(object font, tuple coord, float height, uint32_t color, char *s):
|
||||
cdef Font fnt = font
|
||||
x, y = coord
|
||||
return olDrawString(fnt.font, x, y, height, color, s)
|
||||
|
||||
cdef extern from "ilda.h":
|
||||
ctypedef struct _IldaFile "IldaFile"
|
||||
|
||||
_IldaFile *olLoadIlda(char *filename)
|
||||
void olDrawIlda(_IldaFile *ild)
|
||||
void olDrawIlda3D(_IldaFile *ild)
|
||||
void olFreeIlda(_IldaFile *ild)
|
||||
|
||||
cdef class IldaFile:
|
||||
cdef _IldaFile *ilda
|
||||
def __del__(self):
|
||||
olFreeIlda(self.ilda)
|
||||
|
||||
cpdef loadIlda(char *file):
|
||||
f = IldaFile()
|
||||
f.ilda = olLoadIlda(file)
|
||||
return f
|
||||
|
||||
cpdef drawIlda(object ilda):
|
||||
cdef IldaFile f = ilda
|
||||
olDrawIlda(f.ilda)
|
||||
|
||||
cpdef drawIlda3D(object ilda):
|
||||
cdef IldaFile f = ilda
|
||||
olDrawIlda3D(f.ilda)
|
Loading…
Add table
Reference in a new issue