Commit bf64e797 authored by Guillaume Seguin's avatar Guillaume Seguin

Rework libtatlin.actors to use pyglet and fit into our framework

Several small modifications were required, such as providing build dimensions,
adding some flags, translating numpy arrays into pyglet VBOs and using the
right pyglet GL API function names.
parent 552a04f9
...@@ -16,21 +16,15 @@ ...@@ -16,21 +16,15 @@
# along with this program; if not, write to the Free Software Foundation, # along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from __future__ import division
import math
import numpy
import logging
import time import time
import numpy
import math
from OpenGL.GL import * from pyglet.gl import *
from OpenGL.GLE import * from pyglet import gl
from OpenGL.arrays.vbo import VBO from pyglet.graphics.vertexbuffer import create_buffer
import vector
from gcodeparser import Movement
from . import vector
def compile_display_list(func, *options): def compile_display_list(func, *options):
display_list = glGenLists(1) display_list = glGenLists(1)
...@@ -39,6 +33,12 @@ def compile_display_list(func, *options): ...@@ -39,6 +33,12 @@ def compile_display_list(func, *options):
glEndList() glEndList()
return display_list return display_list
def numpy2vbo(nparray, target = GL_ARRAY_BUFFER, usage = GL_STATIC_DRAW):
vbo = create_buffer(nparray.nbytes, target = target, usage = usage, vbo = True)
vbo.bind()
vbo.set_data(nparray.ctypes.data)
return vbo
class BoundingBox(object): class BoundingBox(object):
""" """
A rectangular box (cuboid) enclosing a 3D model, defined by lower and upper corners. A rectangular box (cuboid) enclosing a 3D model, defined by lower and upper corners.
...@@ -69,9 +69,13 @@ class Platform(object): ...@@ -69,9 +69,13 @@ class Platform(object):
""" """
graduations_major = 10 graduations_major = 10
def __init__(self, width, depth): def __init__(self, build_dimensions):
self.width = width self.width = build_dimensions[0]
self.depth = depth self.depth = build_dimensions[1]
self.height = build_dimensions[2]
self.xoffset = build_dimensions[3]
self.yoffset = build_dimensions[4]
self.zoffset = build_dimensions[5]
self.color_grads_minor = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.1) self.color_grads_minor = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.1)
self.color_grads_interm = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.2) self.color_grads_interm = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.2)
...@@ -79,6 +83,7 @@ class Platform(object): ...@@ -79,6 +83,7 @@ class Platform(object):
self.color_fill = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.05) self.color_fill = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.05)
self.initialized = False self.initialized = False
self.loaded = True
def init(self): def init(self):
self.display_list = compile_display_list(self.draw) self.display_list = compile_display_list(self.draw)
...@@ -87,31 +92,31 @@ class Platform(object): ...@@ -87,31 +92,31 @@ class Platform(object):
def draw(self): def draw(self):
glPushMatrix() glPushMatrix()
glTranslate(-self.width / 2, -self.depth / 2, 0) glTranslatef(self.xoffset, self.yoffset, self.zoffset)
def color(i): def color(i):
if i % self.graduations_major == 0: if i % self.graduations_major == 0:
glColor(*self.color_grads_major) glColor4f(*self.color_grads_major)
elif i % (self.graduations_major / 2) == 0: elif i % (self.graduations_major / 2) == 0:
glColor(*self.color_grads_interm) glColor4f(*self.color_grads_interm)
else: else:
glColor(*self.color_grads_minor) glColor4f(*self.color_grads_minor)
# draw the grid # draw the grid
glBegin(GL_LINES) glBegin(GL_LINES)
for i in range(0, self.width + 1): for i in range(0, int(math.ceil(self.width + 1))):
color(i) color(i)
glVertex3f(float(i), 0.0, 0.0) glVertex3f(float(i), 0.0, 0.0)
glVertex3f(float(i), self.depth, 0.0) glVertex3f(float(i), self.depth, 0.0)
for i in range(0, self.depth + 1): for i in range(0, int(math.ceil(self.depth + 1))):
color(i) color(i)
glVertex3f(0, float(i), 0.0) glVertex3f(0, float(i), 0.0)
glVertex3f(self.width, float(i), 0.0) glVertex3f(self.width, float(i), 0.0)
glEnd() glEnd()
# draw fill # draw fill
glColor(*self.color_fill) glColor4f(*self.color_fill)
glRectf(0.0, 0.0, float(self.width), float(self.depth)) glRectf(0.0, 0.0, float(self.width), float(self.depth))
glPopMatrix() glPopMatrix()
...@@ -119,7 +124,6 @@ class Platform(object): ...@@ -119,7 +124,6 @@ class Platform(object):
def display(self, mode_2d=False): def display(self, mode_2d=False):
glCallList(self.display_list) glCallList(self.display_list)
class Model(object): class Model(object):
""" """
Parent class for models that provides common functionality. Parent class for models that provides common functionality.
...@@ -185,6 +189,11 @@ class Model(object): ...@@ -185,6 +189,11 @@ class Model(object):
def height(self): def height(self):
return self.bounding_box.height return self.bounding_box.height
def movement_angle(src, dst, precision=0):
x = dst[0] - src[0]
y = dst[1] - src[1]
angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle
return round(angle, precision)
class GcodeModel(Model): class GcodeModel(Model):
""" """
...@@ -197,6 +206,8 @@ class GcodeModel(Model): ...@@ -197,6 +206,8 @@ class GcodeModel(Model):
[0.4, 0.1, 0.0], [0.4, 0.1, 0.0],
], 'f') ], 'f')
loaded = False
def load_data(self, model_data, callback=None): def load_data(self, model_data, callback=None):
t_start = time.time() t_start = time.time()
...@@ -204,29 +215,34 @@ class GcodeModel(Model): ...@@ -204,29 +215,34 @@ class GcodeModel(Model):
color_list = [] color_list = []
self.layer_stops = [0] self.layer_stops = [0]
arrow_list = [] arrow_list = []
num_layers = len(model_data) num_layers = len(model_data.all_layers)
for layer_idx, layer in enumerate(model_data): prev_pos = (0, 0, 0)
for movement in layer: for layer_idx, layer in enumerate(model_data.all_layers):
vertex_list.append(movement.src) for gline in layer.lines:
vertex_list.append(movement.dst) if not gline.is_move:
continue
vertex_list.append(prev_pos)
vertex_list.append(gline.current_pos)
arrow = self.arrow arrow = self.arrow
# position the arrow with respect to movement # position the arrow with respect to movement
arrow = vector.rotate(arrow, movement.angle(), 0.0, 0.0, 1.0) arrow = vector.rotate(arrow, movement_angle(prev_pos, gline.current_pos), 0.0, 0.0, 1.0)
arrow_list.extend(arrow) arrow_list.extend(arrow)
vertex_color = self.movement_color(movement) vertex_color = self.movement_color(gline)
color_list.append(vertex_color) color_list.append(vertex_color)
prev_pos = gline.current_pos
self.layer_stops.append(len(vertex_list)) self.layer_stops.append(len(vertex_list))
if callback: if callback:
callback(layer_idx + 1, num_layers) callback(layer_idx + 1, num_layers)
self.vertices = numpy.array(vertex_list, 'f') self.vertices = numpy.array(vertex_list, dtype = GLfloat)
self.colors = numpy.array(color_list, 'f') self.colors = numpy.array(color_list, dtype = GLfloat)
self.arrows = numpy.array(arrow_list, 'f') self.arrows = numpy.array(arrow_list, dtype = GLfloat)
# by translating the arrow vertices outside of the loop, we achieve a # by translating the arrow vertices outside of the loop, we achieve a
# significant performance gain thanks to numpy. it would be really nice # significant performance gain thanks to numpy. it would be really nice
...@@ -241,11 +257,12 @@ class GcodeModel(Model): ...@@ -241,11 +257,12 @@ class GcodeModel(Model):
self.num_layers_to_draw = self.max_layers self.num_layers_to_draw = self.max_layers
self.arrows_enabled = True self.arrows_enabled = True
self.initialized = False self.initialized = False
self.loaded = True
t_end = time.time() t_end = time.time()
logging.info('Initialized Gcode model in %.2f seconds' % (t_end - t_start)) print ('Initialized Gcode model in %.2f seconds' % (t_end - t_start))
logging.info('Vertex count: %d' % len(self.vertices)) print ('Vertex count: %d' % len(self.vertices))
def movement_color(self, move): def movement_color(self, move):
""" """
...@@ -254,6 +271,7 @@ class GcodeModel(Model): ...@@ -254,6 +271,7 @@ class GcodeModel(Model):
# default movement color is gray # default movement color is gray
color = [0.6, 0.6, 0.6, 0.6] color = [0.6, 0.6, 0.6, 0.6]
"""
extruder_on = (move.flags & Movement.FLAG_EXTRUDER_ON or extruder_on = (move.flags & Movement.FLAG_EXTRUDER_ON or
move.delta_e > 0) move.delta_e > 0)
outer_perimeter = (move.flags & Movement.FLAG_PERIMETER and outer_perimeter = (move.flags & Movement.FLAG_PERIMETER and
...@@ -267,6 +285,9 @@ class GcodeModel(Model): ...@@ -267,6 +285,9 @@ class GcodeModel(Model):
color = [1.0, 0.875, 0.0, 0.6] # yellow color = [1.0, 0.875, 0.0, 0.6] # yellow
elif extruder_on: elif extruder_on:
color = [1.0, 0.0, 0.0, 0.6] # red color = [1.0, 0.0, 0.0, 0.6] # red
"""
if move.extruding:
color = [1.0, 0.0, 0.0, 0.6] # red
return color return color
...@@ -275,18 +296,18 @@ class GcodeModel(Model): ...@@ -275,18 +296,18 @@ class GcodeModel(Model):
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
def init(self): def init(self):
self.vertex_buffer = VBO(self.vertices, 'GL_STATIC_DRAW') self.vertex_buffer = numpy2vbo(self.vertices)
self.vertex_color_buffer = VBO(self.colors.repeat(2, 0), 'GL_STATIC_DRAW') # each pair of vertices shares the color self.vertex_color_buffer = numpy2vbo(self.colors.repeat(2, 0)) # each pair of vertices shares the color
if self.arrows_enabled: if self.arrows_enabled:
self.arrow_buffer = VBO(self.arrows, 'GL_STATIC_DRAW') self.arrow_buffer = numpy2vbo(self.arrows)
self.arrow_color_buffer = VBO(self.colors.repeat(3, 0), 'GL_STATIC_DRAW') # each triplet of vertices shares the color self.arrow_color_buffer = numpy2vbo(self.colors.repeat(3, 0)) # each triplet of vertices shares the color
self.initialized = True self.initialized = True
def display(self, mode_2d=False): def display(self, mode_2d=False):
glPushMatrix() glPushMatrix()
glTranslate(self.offset_x, self.offset_y, 0) glTranslatef(self.offset_x, self.offset_y, 0)
glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY) glEnableClientState(GL_COLOR_ARRAY)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment