Commit 2e9ee973 authored by D1plo1d's avatar D1plo1d

Merge branch 'master' of github.com:kliment/Printrun

parents d2c59593 f3e6d0e1
......@@ -28,6 +28,7 @@ import random
import threading
import math
import sys
import traceback
from printrun import stltool
from printrun.printrun_utils import pixmapfile
......@@ -38,7 +39,8 @@ if "-nogl" not in sys.argv:
from printrun import stlview
glview = True
except:
pass
print "Could not load 3D viewer for plater:"
traceback.print_exc()
def evalme(s):
......@@ -173,7 +175,7 @@ class showstl(wx.Window):
event.Skip()
def rotateafter(self):
if(self.i != self.previ):
if self.i != self.previ:
i = self.parent.l.GetSelection()
if i != wx.NOT_FOUND:
#o = self.models[self.l.GetItemText(i)].offsets
......@@ -222,11 +224,8 @@ class showstl(wx.Window):
dcs = wx.MemoryDC()
for m in self.parent.models.values():
b = m.bitmap
#print b
im = b.ConvertToImage()
#print im
imgc = wx.Point(im.GetWidth() / 2, im.GetHeight() / 2)
#print math.radians(5*(self.i-self.previ))
im = im.Rotate(math.radians(m.rot), imgc, 0)
bm = wx.BitmapFromImage(im)
dcs.SelectObject(bm)
......@@ -237,13 +236,11 @@ class showstl(wx.Window):
#if(time.time()-t)>5:
# break
del dc
#print time.time()-t
#s.export()
class stlwin(wx.Frame):
def __init__(self, size = (800, 580), callback = None, parent = None):
def __init__(self, filenames = [], size = (800, 580), callback = None, parent = None, build_dimensions = None):
wx.Frame.__init__(self, parent, title = _("Plate building tool"), size = size)
self.filenames = filenames
if hasattr(sys,"frozen") and sys.frozen=="windows_exe":
self.SetIcon(wx.Icon(sys.executable, wx.BITMAP_TYPE_ICO))
else:
......@@ -279,8 +276,12 @@ class stlwin(wx.Frame):
#self.SetBackgroundColour((10, 10, 10))
self.mainsizer.Add(self.panel)
#self.mainsizer.AddSpacer(10)
if build_dimensions:
self.build_dimensions = build_dimensions
else:
self.build_dimensions = [200, 200, 100, 0, 0, 0]
if glview:
self.s = stlview.TestGlPanel(self, (580, 580))
self.s = stlview.StlViewPanel(self, (580, 580), build_dimensions = self.build_dimensions)
else:
self.s = showstl(self, (580, 580), (0, 0))
self.mainsizer.Add(self.s, 1, wx.EXPAND)
......@@ -293,7 +294,7 @@ class stlwin(wx.Frame):
def autoplate(self, event):
print _("Autoplating")
separation = 2
bedsize = [200, 200, 100]
bedsize = self.build_dimensions[0:3]
cursor = [0, 0, 0]
newrow = 0
max = [0, 0]
......@@ -372,7 +373,7 @@ class stlwin(wx.Frame):
def export(self, event):
dlg = wx.FileDialog(self, _("Pick file to save to"), self.basedir, style = wx.FD_SAVE)
dlg.SetWildcard(_("STL files (;*.stl;*.STL;)"))
dlg.SetWildcard(_("STL files (*.stl;*.STL)|*.stl;*.STL"))
if(dlg.ShowModal() == wx.ID_OK):
name = dlg.GetPath()
self.writefiles(name)
......@@ -397,15 +398,18 @@ class stlwin(wx.Frame):
def right(self, event):
dlg = wx.FileDialog(self, _("Pick file to load"), self.basedir, style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard(_("STL files (;*.stl;*.STL;)|*.stl|OpenSCAD files (;*.scad;)|*.scad"))
if(dlg.ShowModal() == wx.ID_OK):
dlg.SetWildcard(_("STL files (*.stl;*.STL)|*.stl;*.STL|OpenSCAD files (*.scad)|*.scad"))
if dlg.ShowModal() == wx.ID_OK:
name = dlg.GetPath()
if (name.lower().endswith(".stl")):
self.load_stl(event, name)
elif (name.lower().endswith(".scad")):
self.load_scad(event, name)
self.load_file(event, name)
dlg.Destroy()
def load_file(self, event, filename):
if filename.lower().endswith(".stl"):
self.load_stl(event, filename)
elif filename.lower().endswith(".scad"):
self.load_scad(event, filename)
def load_scad(self, event, name):
lf = open(name)
s = [i.replace("\n", "").replace("\r", "").replace(";", "") for i in lf if "stl" in i]
......@@ -491,6 +495,6 @@ class stlwin(wx.Frame):
if __name__ == '__main__':
app = wx.App(False)
main = stlwin()
main = stlwin(sys.argv[1:])
main.Show()
app.MainLoop()
......@@ -270,10 +270,14 @@ class GCode(object):
cur_z = line.z
if cur_z != prev_z:
if prev_z is not None:
base_z = (prev_z - (prev_z % 0.1)) if abs(cur_z - prev_z) < 0.01 else prev_z
else:
base_z = None
all_layers.append(Layer(cur_lines))
old_lines = layers.get(prev_z, [])
old_lines = layers.get(base_z, [])
old_lines += cur_lines
layers[prev_z] = old_lines
layers[base_z] = old_lines
cur_lines = []
layer_id += 1
layer_line = 0
......
......@@ -15,10 +15,7 @@
from libc.stdlib cimport malloc, free
from libc.stdint cimport uint32_t
cdef extern from "string.h":
char *strncpy(char *dest, char *src, size_t n)
size_t strlen(const char *s)
from libc.string cimport strlen, strncpy
cdef char* copy_string(object value):
cdef char* orig = value
......
......@@ -28,221 +28,9 @@ from pyglet.gl import *
from pyglet import gl
from . import gcoder
from . import stltool
from .libtatlin import actors
class wxGLPanel(wx.Panel):
'''A simple class for using OpenGL with wxPython.'''
orthographic = True
def __init__(self, parent, id, pos = wx.DefaultPosition,
size = wx.DefaultSize, style = 0):
# Forcing a no full repaint to stop flickering
style = style | wx.NO_FULL_REPAINT_ON_RESIZE
super(wxGLPanel, self).__init__(parent, id, pos, size, style)
self.GLinitialized = False
self.mview_initialized = False
attribList = (glcanvas.WX_GL_RGBA, # RGBA
glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered
glcanvas.WX_GL_DEPTH_SIZE, 24) # 24 bit
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.canvas = glcanvas.GLCanvas(self, attribList = attribList)
self.context = glcanvas.GLContext(self.canvas)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self.sizer.Fit(self)
# bind events
self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent)
self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent)
self.canvas.Bind(wx.EVT_PAINT, self.processPaintEvent)
def processEraseBackgroundEvent(self, event):
'''Process the erase background event.'''
pass # Do nothing, to avoid flashing on MSWin
def processSizeEvent(self, event):
'''Process the resize event.'''
size = self.GetClientSize()
self.winsize = (size.width, size.height)
self.width, self.height = size.width, size.height
if (wx.VERSION > (2,9) and self.canvas.IsShownOnScreen()) or self.canvas.GetContext():
# Make sure the frame is shown before calling SetCurrent.
self.canvas.SetCurrent(self.context)
self.OnReshape(size.width, size.height)
self.canvas.Refresh(False)
event.Skip()
#wx.CallAfter(self.Refresh)
def processPaintEvent(self, event):
'''Process the drawing event.'''
self.canvas.SetCurrent(self.context)
if not self.GLinitialized:
self.OnInitGL()
self.GLinitialized = True
self.OnDraw()
event.Skip()
def Destroy(self):
#clean up the pyglet OpenGL context
self.pygletcontext.destroy()
#call the super method
super(wx.Panel, self).Destroy()
#==========================================================================
# GLFrame OpenGL Event Handlers
#==========================================================================
def OnInitGL(self):
'''Initialize OpenGL for use in the window.'''
#create a pyglet context for this panel
self.pygletcontext = gl.Context(gl.current_context)
self.pygletcontext.canvas = self
self.pygletcontext.set_current()
#normal gl init
glClearColor(0.98, 0.98, 0.78, 1)
glClearDepth(1.0) # set depth value to 1
glDepthFunc(GL_LEQUAL)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
self.OnReshape(*self.GetClientSize())
def OnReshape(self, width, height):
'''Reshape the OpenGL viewport based on the dimensions of the window.'''
if not self.GLinitialized:
self.GLinitialized = True
self.OnInitGL()
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
if self.orthographic:
glOrtho(-width / 2, width / 2, -height / 2, height / 2, 0.1, 3 * self.dist)
else:
gluPerspective(60., float(width) / height, 10.0, 3 * self.dist)
if not self.mview_initialized:
self.reset_mview(0.9)
self.mview_initialized = True
# Wrap text to the width of the window
if self.GLinitialized:
self.pygletcontext.set_current()
self.update_object_resize()
def reset_mview(self, factor):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
if self.orthographic:
ratio = factor * float(min(self.width, self.height)) / self.dist
glScalef(ratio, ratio, 1)
def OnDraw(self, *args, **kwargs):
"""Draw the window."""
self.pygletcontext.set_current()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.draw_objects()
self.canvas.SwapBuffers()
#==========================================================================
# To be implemented by a sub class
#==========================================================================
def create_objects(self):
'''create opengl objects when opengl is initialized'''
pass
def update_object_resize(self):
'''called when the window recieves only if opengl is initialized'''
pass
def draw_objects(self):
'''called in the middle of ondraw after the buffer has been cleared'''
pass
def trackball(p1x, p1y, p2x, p2y, r):
TRACKBALLSIZE = r
#float a[3]; /* Axis of rotation */
#float phi; /* how much to rotate about axis */
#float p1[3], p2[3], d[3];
#float t;
if (p1x == p2x and p1y == p2y):
return [0.0, 0.0, 0.0, 1.0]
p1 = [p1x, p1y, project_to_sphere(TRACKBALLSIZE, p1x, p1y)]
p2 = [p2x, p2y, project_to_sphere(TRACKBALLSIZE, p2x, p2y)]
a = stltool.cross(p2, p1)
d = map(lambda x, y: x - y, p1, p2)
t = math.sqrt(sum(map(lambda x: x * x, d))) / (2.0 * TRACKBALLSIZE)
if (t > 1.0):
t = 1.0
if (t < -1.0):
t = -1.0
phi = 2.0 * math.asin(t)
return axis_to_quat(a, phi)
def vec(*args):
return (GLfloat * len(args))(*args)
def axis_to_quat(a, phi):
#print a, phi
lena = math.sqrt(sum(map(lambda x: x * x, a)))
q = map(lambda x: x * (1 / lena), a)
q = map(lambda x: x * math.sin(phi / 2.0), q)
q.append(math.cos(phi / 2.0))
return q
def build_rotmatrix(q):
m = (GLdouble * 16)()
m[0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2])
m[1] = 2.0 * (q[0] * q[1] - q[2] * q[3])
m[2] = 2.0 * (q[2] * q[0] + q[1] * q[3])
m[3] = 0.0
m[4] = 2.0 * (q[0] * q[1] + q[2] * q[3])
m[5] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0])
m[6] = 2.0 * (q[1] * q[2] - q[0] * q[3])
m[7] = 0.0
m[8] = 2.0 * (q[2] * q[0] - q[1] * q[3])
m[9] = 2.0 * (q[1] * q[2] + q[0] * q[3])
m[10] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0])
m[11] = 0.0
m[12] = 0.0
m[13] = 0.0
m[14] = 0.0
m[15] = 1.0
return m
def project_to_sphere(r, x, y):
d = math.sqrt(x * x + y * y)
if (d < r * 0.70710678118654752440):
return math.sqrt(r * r - d * d)
else:
t = r / 1.41421356237309504880
return t * t / d
def mulquat(q1, rq):
return [q1[3] * rq[0] + q1[0] * rq[3] + q1[1] * rq[2] - q1[2] * rq[1],
q1[3] * rq[1] + q1[1] * rq[3] + q1[2] * rq[0] - q1[0] * rq[2],
q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0],
q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]]
from .gl.panel import wxGLPanel
from .gl.trackball import trackball, mulquat, build_rotmatrix
from .gl.libtatlin import actors
class GcodeViewPanel(wxGLPanel):
......@@ -257,11 +45,10 @@ class GcodeViewPanel(wxGLPanel):
self.parent = realparent if realparent else parent
self.initpos = None
if build_dimensions:
self.dist = max(build_dimensions[0], build_dimensions[1])
self.build_dimensions = build_dimensions
else:
self.dist = 200
self.build_dimensions = [200, 200, 100, 0, 0, 0]
self.dist = max(self.build_dimensions[0], self.build_dimensions[1])
self.basequat = [0, 0, 0, 1]
self.mousepos = [0, 0]
......@@ -374,17 +161,6 @@ class GcodeViewPanel(wxGLPanel):
self.parent.model.num_layers_to_draw = new_layer
wx.CallAfter(self.Refresh)
def zoom(self, factor, to = None):
glMatrixMode(GL_MODELVIEW)
if to:
delta_x = to[0]
delta_y = to[1]
glTranslatef(delta_x, delta_y, 0)
glScalef(factor, factor, 1)
if to:
glTranslatef(-delta_x, -delta_y, 0)
wx.CallAfter(self.Refresh)
def wheel(self, event):
"""react to mouse wheel actions:
without shift: set max layer
......@@ -407,24 +183,6 @@ class GcodeViewPanel(wxGLPanel):
else:
self.zoom(1/factor, (x, y))
def mouse_to_3d(self, x, y):
x = float(x)
y = self.height - float(y)
# The following could work if we were not initially scaling to zoom on the bed
#if self.orthographic:
# return (x - self.width / 2, y - self.height / 2, 0)
pmat = (GLdouble * 16)()
mvmat = (GLdouble * 16)()
viewport = (GLint * 4)()
px = (GLdouble)()
py = (GLdouble)()
pz = (GLdouble)()
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_PROJECTION_MATRIX, pmat)
glGetDoublev(GL_MODELVIEW_MATRIX, mvmat)
gluUnProject(x, y, 1.0, mvmat, pmat, viewport, px, py, pz)
return (px.value, py.value, pz.value)
def fit(self):
if not self.parent.model or not self.parent.model.loaded:
return
......
......@@ -71,7 +71,8 @@ class Platform(object):
"""
graduations_major = 10
def __init__(self, build_dimensions):
def __init__(self, build_dimensions, light = False):
self.light = light
self.width = build_dimensions[0]
self.depth = build_dimensions[1]
self.height = build_dimensions[2]
......@@ -102,17 +103,19 @@ class Platform(object):
elif i % (self.graduations_major / 2) == 0:
glColor4f(*self.color_grads_interm)
else:
if self.light: return False
glColor4f(*self.color_grads_minor)
return True
# draw the grid
glBegin(GL_LINES)
for i in range(0, int(math.ceil(self.width + 1))):
color(i)
if color(i):
glVertex3f(float(i), 0.0, 0.0)
glVertex3f(float(i), self.depth, 0.0)
for i in range(0, int(math.ceil(self.depth + 1))):
color(i)
if color(i):
glVertex3f(0, float(i), 0.0)
glVertex3f(self.width, float(i), 0.0)
glEnd()
......
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
# Printrun 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 3 of the License, or
# (at your option) any later version.
#
# Printrun 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 Printrun. If not, see <http://www.gnu.org/licenses/>.
import os
import math
import wx
from wx import glcanvas
import pyglet
pyglet.options['debug_gl'] = True
from pyglet.gl import *
from pyglet import gl
class wxGLPanel(wx.Panel):
'''A simple class for using OpenGL with wxPython.'''
orthographic = True
def __init__(self, parent, id, pos = wx.DefaultPosition,
size = wx.DefaultSize, style = 0):
# Forcing a no full repaint to stop flickering
style = style | wx.NO_FULL_REPAINT_ON_RESIZE
super(wxGLPanel, self).__init__(parent, id, pos, size, style)
self.GLinitialized = False
self.mview_initialized = False
attribList = (glcanvas.WX_GL_RGBA, # RGBA
glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered
glcanvas.WX_GL_DEPTH_SIZE, 24) # 24 bit
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.canvas = glcanvas.GLCanvas(self, attribList = attribList)
self.context = glcanvas.GLContext(self.canvas)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.SetSizerAndFit(self.sizer)
# bind events
self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent)
self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent)
self.canvas.Bind(wx.EVT_PAINT, self.processPaintEvent)
def processEraseBackgroundEvent(self, event):
'''Process the erase background event.'''
pass # Do nothing, to avoid flashing on MSWin
def processSizeEvent(self, event):
'''Process the resize event.'''
size = self.GetClientSize()
self.width, self.height = size.width, size.height
if (wx.VERSION > (2,9) and self.canvas.IsShownOnScreen()) or self.canvas.GetContext():
# Make sure the frame is shown before calling SetCurrent.
self.canvas.SetCurrent(self.context)
self.OnReshape(size.width, size.height)
self.canvas.Refresh(False)
event.Skip()
def processPaintEvent(self, event):
'''Process the drawing event.'''
self.canvas.SetCurrent(self.context)
if not self.GLinitialized:
self.OnInitGL()
self.GLinitialized = True
self.OnDraw()
event.Skip()
def Destroy(self):
#clean up the pyglet OpenGL context
self.pygletcontext.destroy()
#call the super method
super(wx.Panel, self).Destroy()
#==========================================================================
# GLFrame OpenGL Event Handlers
#==========================================================================
def OnInitGL(self):
'''Initialize OpenGL for use in the window.'''
#create a pyglet context for this panel
self.pygletcontext = gl.Context(gl.current_context)
self.pygletcontext.canvas = self
self.pygletcontext.set_current()
#normal gl init
glClearColor(0.98, 0.98, 0.78, 1)
glClearDepth(1.0) # set depth value to 1
glDepthFunc(GL_LEQUAL)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
self.OnReshape(*self.GetClientSize())
def OnReshape(self, width, height):
'''Reshape the OpenGL viewport based on the dimensions of the window.'''
if not self.GLinitialized:
self.GLinitialized = True
self.OnInitGL()
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
if self.orthographic:
glOrtho(-width / 2, width / 2, -height / 2, height / 2, 0.1, 3 * self.dist)
else:
gluPerspective(60., float(width) / height, 10.0, 3 * self.dist)
if not self.mview_initialized:
self.reset_mview(0.9)
self.mview_initialized = True
# Wrap text to the width of the window
if self.GLinitialized:
self.pygletcontext.set_current()
self.update_object_resize()
def reset_mview(self, factor):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
if self.orthographic:
ratio = factor * float(min(self.width, self.height)) / self.dist
glScalef(ratio, ratio, 1)
def OnDraw(self, *args, **kwargs):
"""Draw the window."""
self.pygletcontext.set_current()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.draw_objects()
self.canvas.SwapBuffers()
#==========================================================================
# To be implemented by a sub class
#==========================================================================
def create_objects(self):
'''create opengl objects when opengl is initialized'''
pass
def update_object_resize(self):
'''called when the window recieves only if opengl is initialized'''
pass
def draw_objects(self):
'''called in the middle of ondraw after the buffer has been cleared'''
pass
#==========================================================================
# Utils
#==========================================================================
def mouse_to_3d(self, x, y, z = 1.0):
x = float(x)
y = self.height - float(y)
# The following could work if we were not initially scaling to zoom on the bed
#if self.orthographic:
# return (x - self.width / 2, y - self.height / 2, 0)
pmat = (GLdouble * 16)()
mvmat = (GLdouble * 16)()
viewport = (GLint * 4)()
px = (GLdouble)()
py = (GLdouble)()
pz = (GLdouble)()
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_PROJECTION_MATRIX, pmat)
glGetDoublev(GL_MODELVIEW_MATRIX, mvmat)
gluUnProject(x, y, z, mvmat, pmat, viewport, px, py, pz)
return (px.value, py.value, pz.value)
def zoom(self, factor, to = None):
glMatrixMode(GL_MODELVIEW)
if to:
delta_x = to[0]
delta_y = to[1]
glTranslatef(delta_x, delta_y, 0)
glScalef(factor, factor, 1)
if to:
glTranslatef(-delta_x, -delta_y, 0)
wx.CallAfter(self.Refresh)
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
# Printrun 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 3 of the License, or
# (at your option) any later version.
#
# Printrun 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 Printrun. If not, see <http://www.gnu.org/licenses/>.
import math
from pyglet.gl import *
def cross(v1, v2):
return [v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]]
def trackball(p1x, p1y, p2x, p2y, r):
TRACKBALLSIZE = r
if p1x == p2x and p1y == p2y:
return [0.0, 0.0, 0.0, 1.0]
p1 = [p1x, p1y, project_to_sphere(TRACKBALLSIZE, p1x, p1y)]
p2 = [p2x, p2y, project_to_sphere(TRACKBALLSIZE, p2x, p2y)]
a = cross(p2, p1)
d = map(lambda x, y: x - y, p1, p2)
t = math.sqrt(sum(map(lambda x: x * x, d))) / (2.0 * TRACKBALLSIZE)
if t > 1.0:
t = 1.0
if t < -1.0:
t = -1.0
phi = 2.0 * math.asin(t)
return axis_to_quat(a, phi)
def axis_to_quat(a, phi):
lena = math.sqrt(sum(map(lambda x: x * x, a)))
q = map(lambda x: x * (1 / lena), a)
q = map(lambda x: x * math.sin(phi / 2.0), q)
q.append(math.cos(phi / 2.0))
return q
def build_rotmatrix(q):
m = (GLdouble * 16)()
m[0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2])
m[1] = 2.0 * (q[0] * q[1] - q[2] * q[3])
m[2] = 2.0 * (q[2] * q[0] + q[1] * q[3])
m[3] = 0.0
m[4] = 2.0 * (q[0] * q[1] + q[2] * q[3])
m[5] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0])
m[6] = 2.0 * (q[1] * q[2] - q[0] * q[3])
m[7] = 0.0
m[8] = 2.0 * (q[2] * q[0] - q[1] * q[3])
m[9] = 2.0 * (q[1] * q[2] + q[0] * q[3])
m[10] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0])
m[11] = 0.0
m[12] = 0.0
m[13] = 0.0
m[14] = 0.0
m[15] = 1.0
return m
def project_to_sphere(r, x, y):
d = math.sqrt(x * x + y * y)
if (d < r * 0.70710678118654752440):
return math.sqrt(r * r - d * d)
else:
t = r / 1.41421356237309504880
return t * t / d
def mulquat(q1, rq):
return [q1[3] * rq[0] + q1[0] * rq[3] + q1[1] * rq[2] - q1[2] * rq[1],
q1[3] * rq[1] + q1[1] * rq[3] + q1[2] * rq[0] - q1[0] * rq[2],
q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0],
q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]]
......@@ -415,7 +415,8 @@ class Gviz(wx.Panel):
if not gcode:
return
gline = gcoder.Line(gcode)
gline.parse_coordinates(False)
split_raw = gcoder.split(gline)
gcoder.parse_coordinates(gline, split_raw, imperial = False)
def _y(y):
return self.build_dimensions[1] - (y - self.build_dimensions[4])
......
......@@ -88,7 +88,7 @@ def emitstl(filename, facets = [], objname = "stltool_export", binary = 1):
class stl:
class stl(object):
def __init__(self, filename = None):
self.facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]]
self.facets = []
......@@ -102,37 +102,39 @@ class stl:
self.facetloc = 0
if filename is None:
return
self.f = list(open(filename))
if not self.f[0].startswith("solid"):
with open(filename) as f:
data = f.read()
if "facet normal" in data[1:300] and "outer loop" in data[1:300]:
lines = data.split("\n")
for line in lines:
if not self.parseline(line):
return
else:
print "Not an ascii stl solid - attempting to parse as binary"
f = open(filename, "rb")
buf = f.read(84)
while(len(buf)<84):
newdata = f.read(84-len(buf))
while len(buf) < 84:
newdata = f.read(84 - len(buf))
if not len(newdata):
break
buf+=newdata
buf += newdata
facetcount = struct.unpack_from("<I", buf, 80)
facetformat = struct.Struct("<ffffffffffffH")
for i in xrange(facetcount[0]):
buf = f.read(50)
while(len(buf)<50):
newdata = f.read(50-len(buf))
while len(buf) < 50:
newdata = f.read(50 - len(buf))
if not len(newdata):
break
buf+=newdata
buf += newdata
fd = list(facetformat.unpack(buf))
self.name = "binary soloid"
self.facet = [fd[:3],[fd[3:6], fd[6:9], fd[9:12]]]
self.facets+=[self.facet]
facet = self.facet
self.facetsminz+=[(min(map(lambda x:x[2], facet[1])), facet)]
self.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])), facet)]
facet = [fd[:3],[fd[3:6], fd[6:9], fd[9:12]]]
self.facets.append(facet)
self.facetsminz.append((min(map(lambda x:x[2], facet[1])), facet))
self.facetsmaxz.append((max(map(lambda x:x[2], facet[1])), facet))
f.close()
return
for i in self.f:
if not self.parseline(i):
return
def translate(self, v = [0, 0, 0]):
matrix = [
......
......@@ -28,83 +28,62 @@ pyglet.options['debug_gl'] = True
from pyglet.gl import *
from .gl.panel import wxGLPanel
from .gl.trackball import trackball, mulquat, build_rotmatrix
from .gl.libtatlin import actors
class GLPanel(wx.Panel):
'''A simple class for using OpenGL with wxPython.'''
def __init__(self, parent, id, pos = wx.DefaultPosition,
size = wx.DefaultSize, style = 0):
# Forcing a no full repaint to stop flickering
style = style | wx.NO_FULL_REPAINT_ON_RESIZE
#call super function
super(GLPanel, self).__init__(parent, id, pos, size, style)
#init gl canvas data
self.GLinitialized = False
attribList = (glcanvas.WX_GL_RGBA, # RGBA
glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered
glcanvas.WX_GL_DEPTH_SIZE, 24) # 24 bit
# Create the canvas
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.canvas = glcanvas.GLCanvas(self, attribList = attribList)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.SetSizer(self.sizer)
#self.sizer.Fit(self)
self.Layout()
# bind events
self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent)
self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent)
self.canvas.Bind(wx.EVT_PAINT, self.processPaintEvent)
def vec(*args):
return (GLfloat * len(args))(*args)
#==========================================================================
# Canvas Proxy Methods
#==========================================================================
def GetGLExtents(self):
'''Get the extents of the OpenGL canvas.'''
return self.canvas.GetClientSize()
class stlview(object):
def __init__(self, facets, batch):
# Create the vertex and normal arrays.
vertices = []
normals = []
def SwapBuffers(self):
'''Swap the OpenGL buffers.'''
self.canvas.SwapBuffers()
for i in facets:
for j in i[1]:
vertices.extend(j)
normals.extend(i[0])
#==========================================================================
# wxPython Window Handlers
#==========================================================================
def processEraseBackgroundEvent(self, event):
'''Process the erase background event.'''
pass # Do nothing, to avoid flashing on MSWin
def processSizeEvent(self, event):
'''Process the resize event.'''
if self.canvas.GetContext():
# Make sure the frame is shown before calling SetCurrent.
self.Show()
self.canvas.SetCurrent()
size = self.GetGLExtents()
self.winsize = (size.width, size.height)
self.width, self.height = size.width, size.height
self.OnReshape(size.width, size.height)
self.canvas.Refresh(False)
event.Skip()
# Create a list of triangle indices.
indices = range(3 * len(facets)) # [[3*i, 3*i+1, 3*i+2] for i in xrange(len(facets))]
#print indices[:10]
self.vertex_list = batch.add_indexed(len(vertices) // 3,
GL_TRIANGLES,
None, # group,
indices,
('v3f/static', vertices),
('n3f/static', normals))
def processPaintEvent(self, event):
'''Process the drawing event.'''
self.canvas.SetCurrent()
def delete(self):
self.vertex_list.delete()
# This is a 'perfect' time to initialize OpenGL ... only if we need to
if not self.GLinitialized:
self.OnInitGL()
self.GLinitialized = True
class StlViewPanel(wxGLPanel):
self.OnDraw()
event.Skip()
def __init__(self, parent, size, id = wx.ID_ANY, build_dimensions = None):
super(StlViewPanel, self).__init__(parent, id, wx.DefaultPosition, size, 0)
self.batches = []
self.rot = 0
self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.move)
self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.double)
self.initialized = 1
self.canvas.Bind(wx.EVT_MOUSEWHEEL, self.wheel)
self.parent = parent
self.initpos = None
if build_dimensions:
self.build_dimensions = build_dimensions
else:
self.build_dimensions = [200, 200, 100, 0, 0, 0]
self.platform = actors.Platform(self.build_dimensions, light = True)
self.dist = max(self.build_dimensions[0], self.build_dimensions[1])
self.basequat = [0, 0, 0, 1]
wx.CallAfter(self.forceresize)
self.mousepos = (0, 0)
def Destroy(self):
#clean up the pyglet OpenGL context
#self.pygletcontext.destroy()
#call the super method
super(wx.Panel, self).Destroy()
def OnReshape(self, width, height):
self.mview_initialized = False
super(StlViewPanel, self).OnReshape(width, height)
#==========================================================================
# GLFrame OpenGL Event Handlers
......@@ -112,13 +91,9 @@ class GLPanel(wx.Panel):
def OnInitGL(self):
'''Initialize OpenGL for use in the window.'''
#create a pyglet context for this panel
self.pmat = (GLdouble * 16)()
self.mvmat = (GLdouble * 16)()
self.pygletcontext = Context(current_context)
self.pygletcontext.canvas = self
self.pygletcontext.set_current()
self.dist = 1000
self.vpmat = None
#normal gl init
glClearColor(0, 0, 0, 1)
glColor3f(1, 0, 0)
......@@ -149,351 +124,15 @@ class GLPanel(wx.Panel):
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, vec(1, 1, 1, 1))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50)
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, vec(0, 0.1, 0, 0.9))
#create objects to draw
#self.create_objects()
def OnReshape(self, width, height):
'''Reshape the OpenGL viewport based on the dimensions of the window.'''
if not self.GLinitialized:
self.OnInitGL()
self.GLinitialized = True
self.pmat = (GLdouble * 16)()
self.mvmat = (GLdouble * 16)()
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60., width / float(height), .1, 1000.)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
#pyglet stuff
self.vpmat = (GLint * 4)(0, 0, *list(self.GetClientSize()))
glGetDoublev(GL_PROJECTION_MATRIX, self.pmat)
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
#glMatrixMode(GL_PROJECTION)
# Wrap text to the width of the window
if self.GLinitialized:
self.pygletcontext.set_current()
self.update_object_resize()
def OnDraw(self, *args, **kwargs):
"""Draw the window."""
#clear the context
self.canvas.SetCurrent()
self.pygletcontext.set_current()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
#draw objects
self.draw_objects()
#update screen
self.SwapBuffers()
#==========================================================================
# To be implemented by a sub class
#==========================================================================
def create_objects(self):
'''create opengl objects when opengl is initialized'''
pass
def update_object_resize(self):
'''called when the window recieves only if opengl is initialized'''
pass
def draw_objects(self):
'''called in the middle of ondraw after the buffer has been cleared'''
pass
class stlview(object):
def __init__(self, facets, batch):
# Create the vertex and normal arrays.
vertices = []
normals = []
for i in facets:
for j in i[1]:
vertices.extend(j)
normals.extend(i[0])
# Create a list of triangle indices.
indices = range(3 * len(facets)) # [[3*i, 3*i+1, 3*i+2] for i in xrange(len(facets))]
#print indices[:10]
self.vertex_list = batch.add_indexed(len(vertices) // 3,
GL_TRIANGLES,
None, # group,
indices,
('v3f/static', vertices),
('n3f/static', normals))
def delete(self):
self.vertex_list.delete()
def vdiff(v, o):
return [x[0] - x[1] for x in zip(v, o)]
class gcview(object):
def __init__(self, gcode, batch, w = 0.5, h = 0.5):
# Create the vertex and normal arrays.
vertices = []
normals = []
self.prev = [0.001, 0.001, 0.001, 0.001]
self.fline = 1
self.vlists = []
self.layers = {}
t0 = time.time()
if gcode:
lines = [self.transform(gline) for gline in gcode.lines]
lines = [line for line in lines if line]
print len(lines)
else:
lines = []
print "transformed lines in %fs" % (time.time() - t0)
t0 = time.time()
layertemp = {}
lasth = None
counter = 0
if len(lines) == 0:
return
for i in lines:
counter += 1
if i[0][2] not in layertemp:
layertemp[i[0][2]] = [[], []]
if lasth is not None:
self.layers[lasth] = pyglet.graphics.Batch()
lt = layertemp[lasth][0]
indices = range(len(layertemp[lasth][0]) // 3) # [[3*i, 3*i+1, 3*i+2] for i in xrange(len(facets))]
self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0]) // 3,
GL_TRIANGLES,
None, # group,
indices,
('v3f/static', layertemp[lasth][0]),
('n3f/static', layertemp[lasth][1])))
lasth = i[0][2]
spoints, epoints, S, E = self.genline(i, h, w)
verticestoadd = [[
spoints[(j + 1) % 8],
epoints[(j) % 8],
spoints[j],
epoints[j],
spoints[(j + 1) % 8],
epoints[(j + 1) % 8]
] for j in xrange(8)]
normalstoadd = [map(vdiff, v, [S, E, S, E, S, E]) for v in verticestoadd]
v1 = []
map(v1.extend, verticestoadd)
v2 = []
map(v2.extend, v1)
n1 = []
map(n1.extend, normalstoadd)
n2 = []
map(n2.extend, n1)
layertemp[i[0][2]][0] += v2
vertices += v2
layertemp[i[0][2]][1] += n2
normals += n2
print "appended lines in %fs" % (time.time() - t0)
t0 = time.time()
# Create a list of triangle indices.
indices = range(3 * 16 * len(lines)) # [[3*i, 3*i+1, 3*i+2] for i in xrange(len(facets))]
self.vlists.append(batch.add_indexed(len(vertices) // 3,
GL_TRIANGLES,
None, # group,
indices,
('v3f/static', vertices),
('n3f/static', normals)))
if lasth is not None:
self.layers[lasth] = pyglet.graphics.Batch()
indices = range(len(layertemp[lasth][0])) # [[3*i, 3*i+1, 3*i+2] for i in xrange(len(facets))]
self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0]) // 3,
GL_TRIANGLES,
None, # group,
indices,
('v3f/static', layertemp[lasth][0]),
('n3f/static', layertemp[lasth][1])))
def genline(self, i, h, w):
S = i[0][:3]
E = i[1][:3]
v = map(lambda x, y: x - y, E, S)
vlen = math.sqrt(float(sum(map(lambda a: a * a, v[:3]))))
if vlen == 0:
vlen = 0.01
sq2 = math.sqrt(2.0) / 2.0
htw = float(h) / w
d = w / 2.0
if i[1][3] == i[0][3]:
d = 0.05
points = [[d, 0, 0],
[sq2 * d, sq2 * d, 0],
[0, d, 0],
[-sq2 * d, sq2 * d, 0],
[-d, 0, 0],
[-sq2 * d, -sq2 * d, 0],
[0, -d, 0],
[sq2 * d, -sq2 * d, 0]
]
axis = stltool.cross([0, 0, 1], v)
alen = math.sqrt(float(sum(map(lambda a: a * a, v[:3]))))
if alen > 0:
axis = map(lambda m: m / alen, axis)
angle = math.acos(v[2] / vlen)
def vrot(v, axis, angle):
kxv = stltool.cross(axis, v)
kdv = sum(map(lambda x, y: x * y, axis, v))
return map(lambda x, y, z: x * math.cos(angle) + y * math.sin(angle) + z * kdv * (1.0 - math.cos(angle)), v, kxv, axis)
points = map(lambda x: vrot(x, axis, angle), points)
points = map(lambda x: [x[0], x[1], htw * x[2]], points)
def vadd(v, o):
return map(sum, zip(v, o))
spoints = map(lambda x: vadd(S, x), points)
epoints = map(lambda x: vadd(E, x), points)
return spoints, epoints, S, E
def transform(self, gline):
cur = self.prev[:]
isg92 = (gline.command == "G92")
if gline.is_move or isg92:
if gline.x is not None:
cur[0] = gline.x
if gline.y is not None:
cur[1] = gline.y
if gline.z is not None:
cur[2] = gline.z
if gline.e is not None:
cur[3] = gline.e
if self.prev == cur:
return None
elif self.fline or isg92:
self.prev = cur
self.fline = 0
return None
else:
r = [self.prev, cur]
self.prev = cur
return r
else:
return None
def delete(self):
for i in self.vlists:
i.delete()
self.vlists = []
def trackball(p1x, p1y, p2x, p2y, r):
TRACKBALLSIZE = r
#float a[3]; /* Axis of rotation */
#float phi; /* how much to rotate about axis */
#float p1[3], p2[3], d[3];
#float t;
if (p1x == p2x and p1y == p2y):
return [0.0, 0.0, 0.0, 1.0]
p1 = [p1x, p1y, project_to_sphere(TRACKBALLSIZE, p1x, p1y)]
p2 = [p2x, p2y, project_to_sphere(TRACKBALLSIZE, p2x, p2y)]
a = stltool.cross(p2, p1)
d = map(lambda x, y: x - y, p1, p2)
t = math.sqrt(sum(map(lambda x: x * x, d))) / (2.0 * TRACKBALLSIZE)
if (t > 1.0):
t = 1.0
if (t < -1.0):
t = -1.0
phi = 2.0 * math.asin(t)
return axis_to_quat(a, phi)
def vec(*args):
return (GLfloat * len(args))(*args)
def axis_to_quat(a, phi):
#print a, phi
lena = math.sqrt(sum(map(lambda x: x * x, a)))
q = map(lambda x: x * (1 / lena), a)
q = map(lambda x: x * math.sin(phi / 2.0), q)
q.append(math.cos(phi / 2.0))
return q
def build_rotmatrix(q):
m = (GLdouble * 16)()
m[0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2])
m[1] = 2.0 * (q[0] * q[1] - q[2] * q[3])
m[2] = 2.0 * (q[2] * q[0] + q[1] * q[3])
m[3] = 0.0
m[4] = 2.0 * (q[0] * q[1] + q[2] * q[3])
m[5] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0])
m[6] = 2.0 * (q[1] * q[2] - q[0] * q[3])
m[7] = 0.0
m[8] = 2.0 * (q[2] * q[0] - q[1] * q[3])
m[9] = 2.0 * (q[1] * q[2] + q[0] * q[3])
m[10] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0])
m[11] = 0.0
m[12] = 0.0
m[13] = 0.0
m[14] = 0.0
m[15] = 1.0
return m
def project_to_sphere(r, x, y):
d = math.sqrt(x * x + y * y)
if (d < r * 0.70710678118654752440):
return math.sqrt(r * r - d * d)
else:
t = r / 1.41421356237309504880
return t * t / d
def mulquat(q1, rq):
return [q1[3] * rq[0] + q1[0] * rq[3] + q1[1] * rq[2] - q1[2] * rq[1],
q1[3] * rq[1] + q1[1] * rq[3] + q1[2] * rq[0] - q1[0] * rq[2],
q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0],
q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]]
class TestGlPanel(GLPanel):
def __init__(self, parent, size, id = wx.ID_ANY):
super(TestGlPanel, self).__init__(parent, id, wx.DefaultPosition, size, 0)
self.batches = []
self.rot = 0
self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.move)
self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.double)
self.initialized = 1
self.canvas.Bind(wx.EVT_MOUSEWHEEL, self.wheel)
self.parent = parent
self.initpos = None
self.dist = 200
self.bedsize = [200, 200]
self.transv = [0, 0, -self.dist]
self.basequat = [0, 0, 0, 1]
wx.CallAfter(self.forceresize)
self.mousepos = [0, 0]
if self.parent.filenames:
for filename in self.parent.filenames:
self.parent.load_file(None, filename)
def double(self, event):
p = event.GetPositionTuple()
sz = self.GetClientSize()
v = map(lambda m, w, b: b * m / w, p, sz, self.bedsize)
v[1] = self.bedsize[1] - v[1]
v = map(lambda m, w, b: b * m / w, p, sz, self.build_dimensions[0:2])
v[1] = self.build_dimensions[1] - v[1]
v += [300]
print "Double-click at "+str(v)+" in "
print self
......@@ -531,42 +170,29 @@ class TestGlPanel(GLPanel):
RMB: nothing
with shift move viewport
"""
self.mousepos = event.GetPositionTuple()
if event.Dragging() and event.LeftIsDown():
if self.initpos == None:
self.initpos = event.GetPositionTuple()
else:
if not event.ShiftDown():
currentpos = event.GetPositionTuple()
delta = (
(currentpos[0] - self.initpos[0]),
-(currentpos[1] - self.initpos[1])
)
self.move_shape(delta)
self.initpos = None
p1 = self.initpos
p2 = event.GetPositionTuple()
x1, y1, _ = self.mouse_to_3d(p1[0], p1[1])
x2, y2, _ = self.mouse_to_3d(p2[0], p2[1])
self.move_shape((x2 - x1, y2 - y1))
self.initpos = p2
return
#print self.initpos
p1 = self.initpos
self.initpos = None
p2 = event.GetPositionTuple()
sz = self.GetClientSize()
p1x = (float(p1[0]) - sz[0] / 2) / (sz[0] / 2)
p1y = -(float(p1[1]) - sz[1] / 2) / (sz[1] / 2)
p2x = (float(p2[0]) - sz[0] / 2) / (sz[0] / 2)
p2y = -(float(p2[1]) - sz[1] / 2) / (sz[1] / 2)
#print p1x, p1y, p2x, p2y
quat = trackball(p1x, p1y, p2x, p2y, -self.transv[2] / 250.0)
if self.rot:
quat = trackball(p1x, p1y, p2x, p2y, 0.8)
self.basequat = mulquat(self.basequat, quat)
#else:
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
#self.basequat = quatx
mat = build_rotmatrix(self.basequat)
glLoadIdentity()
glTranslatef(self.transv[0], self.transv[1], 0)
glTranslatef(0, 0, self.transv[2])
glMultMatrixd(mat)
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
self.rot = 1
self.initpos = p2
elif event.ButtonUp(wx.MOUSE_BTN_LEFT):
if self.initpos is not None:
......@@ -575,35 +201,19 @@ class TestGlPanel(GLPanel):
if self.initpos is not None:
self.initpos = None
elif event.Dragging() and event.RightIsDown() and event.ShiftDown():
elif event.Dragging() and event.RightIsDown():
if self.initpos is None:
self.initpos = event.GetPositionTuple()
else:
p1 = self.initpos
p2 = event.GetPositionTuple()
sz = self.GetClientSize()
p1 = list(p1)
p2 = list(p2)
p1[1] *= -1
p2[1] *= -1
self.transv = map(lambda x, y, z, c: c - self.dist * (x - y) / z, list(p1) + [0], list(p2) + [0], list(sz) + [1], self.transv)
glLoadIdentity()
glTranslatef(self.transv[0], self.transv[1], 0)
glTranslatef(0, 0, self.transv[2])
if(self.rot):
glMultMatrixd(build_rotmatrix(self.basequat))
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
self.rot = 1
self.initpos = None
if self.orthographic:
x1, y1, _ = self.mouse_to_3d(p1[0], p1[1])
x2, y2, _ = self.mouse_to_3d(p2[0], p2[1])
glTranslatef(x2 - x1, y2 - y1, 0)
else:
#mouse is moving without a button press
p = event.GetPositionTuple()
sz = self.GetClientSize()
v = map(lambda m, w, b: b * m / w, p, sz, self.bedsize)
v[1] = self.bedsize[1] - v[1]
self.mousepos = v
glTranslatef(p2[0] - p1[0], -(p2[1] - p1[1]), 0)
self.initpos = p2
def rotate_shape(self, angle):
"""rotates acive shape
......@@ -621,34 +231,21 @@ class TestGlPanel(GLPanel):
rotate object
with shift zoom viewport
"""
z = event.GetWheelRotation()
angle = 10
delta = event.GetWheelRotation()
if not event.ShiftDown():
i = self.parent.l.GetSelection()
if i < 0:
try:
self.parent.setlayerindex(z)
except:
pass
return
if z > 0:
angle = 10
if delta > 0:
self.rotate_shape(angle / 2)
else:
self.rotate_shape(-angle / 2)
return
if z > 0:
self.transv[2] += angle
else:
self.transv[2] -= angle
glLoadIdentity()
glTranslatef(*self.transv)
if(self.rot):
glMultMatrixd(build_rotmatrix(self.basequat))
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
self.rot = 1
factor = 1.05
x, y = event.GetPositionTuple()
x, y, _ = self.mouse_to_3d(x, y)
if delta > 0:
self.zoom(factor, (x, y))
else:
self.zoom(1/factor, (x, y))
def keypress(self, event):
"""gets keypress events and moves/rotates acive shape"""
......@@ -711,6 +308,8 @@ class TestGlPanel(GLPanel):
def create_objects(self):
'''create opengl objects when opengl is initialized'''
if not self.platform.initialized:
self.platform.init()
self.initialized = 1
wx.CallAfter(self.Refresh)
......@@ -729,61 +328,22 @@ class TestGlPanel(GLPanel):
def draw_objects(self):
'''called in the middle of ondraw after the buffer has been cleared'''
if self.vpmat is None:
return
if not self.initialized:
self.create_objects()
#glLoadIdentity()
#print list(self.pmat)
if self.rot == 1:
glLoadIdentity()
glMultMatrixd(self.mvmat)
else:
glLoadIdentity()
glTranslatef(*self.transv)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1))
glBegin(GL_LINES)
glNormal3f(0, 0, 1)
rows = 10
cols = 10
zheight = 50
for i in xrange(-rows, rows + 1):
if i % 5 == 0:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.6, 0.6, 0.6, 1))
else:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1))
glVertex3f(10 * -cols, 10 * i, 0)
glVertex3f(10 * cols, 10 * i, 0)
for i in xrange(-cols, cols + 1):
if i % 5 == 0:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.6, 0.6, 0.6, 1))
else:
glPushMatrix()
glTranslatef(0, 0, -self.dist)
glMultMatrixd(build_rotmatrix(self.basequat)) # Rotate according to trackball
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1))
glVertex3f(10 * i, 10 * -rows, 0)
glVertex3f(10 * i, 10 * rows, 0)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.6, 0.6, 0.6, 1))
glVertex3f(10 * -cols, 10 * -rows, 0)
glVertex3f(10 * -cols, 10 * -rows, zheight)
glVertex3f(10 * cols, 10 * rows, 0)
glVertex3f(10 * cols, 10 * rows, zheight)
glVertex3f(10 * cols, 10 * -rows, 0)
glVertex3f(10 * cols, 10 * -rows, zheight)
glVertex3f(10 * -cols, 10 * rows, 0)
glVertex3f(10 * -cols, 10 * rows, zheight)
glVertex3f(10 * -cols, 10 * rows, zheight)
glVertex3f(10 * cols, 10 * rows, zheight)
glVertex3f(10 * cols, 10 * rows, zheight)
glVertex3f(10 * cols, 10 * -rows, zheight)
glVertex3f(10 * cols, 10 * -rows, zheight)
glVertex3f(10 * -cols, 10 * -rows, zheight)
glVertex3f(10 * -cols, 10 * -rows, zheight)
glVertex3f(10 * -cols, 10 * rows, zheight)
glEnd()
glTranslatef(- self.build_dimensions[3] - self.platform.width/2,
- self.build_dimensions[4] - self.platform.depth/2, 0) # Move origin to bottom left of platform
# Draw platform
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
self.platform.draw()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
# Draw mouse
glPushMatrix()
glTranslatef(self.mousepos[0] - self.bedsize[0] / 2, self.mousepos[1] - self.bedsize[1] / 2, 0)
x, y, z = self.mouse_to_3d(self.mousepos[0], self.mousepos[1], 0.9)
glTranslatef(x, y, z)
glBegin(GL_TRIANGLES)
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(1, 0, 0, 1))
glNormal3f(0, 0, 1)
......@@ -795,94 +355,27 @@ class TestGlPanel(GLPanel):
glVertex3f(-2, -2, 0)
glEnd()
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.3, 0.7, 0.5, 1))
#glTranslatef(0, 40, 0)
glPopMatrix()
glPushMatrix()
glTranslatef(-100, -100, 0)
# Draw objects
for i in self.parent.models.values():
glPushMatrix()
glTranslatef(*(i.offsets))
glRotatef(i.rot, 0.0, 0.0, 1.0)
glScalef(*i.scale)
try:
if i.curlayer in i.gc.layers:
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.13, 0.37, 0.25, 1))
[i.gc.layers[j].draw() for j in i.gc.layers.keys() if j < i.curlayer]
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.5, 0.6, 0.9, 1))
b = i.gc.layers[i.curlayer]
b.draw()
else:
i.batch.draw()
except:
i.batch.draw()
glPopMatrix()
glPopMatrix()
#print "drawn batch"
class GCFrame(wx.Frame):
'''A simple class for using OpenGL with wxPython.'''
def __init__(self, parent, ID, title, pos = wx.DefaultPosition,
size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
super(GCFrame, self).__init__(parent, ID, title, pos, (size[0] + 150, size[1]), style)
class d:
def GetSelection(self):
return wx.NOT_FOUND
self.p = self
m = d()
m.offsets = [0, 0, 0]
m.rot = 0
m.curlayer = 0.0
m.scale = [1.0, 1.0, 1.0]
m.batch = pyglet.graphics.Batch()
m.gc = gcview(None, batch = m.batch)
self.models = {"": m}
self.l = d()
self.modelindex = 0
self.GLPanel1 = TestGlPanel(self, size)
def addfile(self, gcode = []):
self.models[""].gc.delete()
self.models[""].gc = gcview(gcode, batch = self.models[""].batch)
def clear(self):
self.models[""].gc.delete()
self.models[""].gc = gcview([], batch = self.models[""].batch)
def Show(self, arg = True):
wx.Frame.Show(self, arg)
self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] + 1))
self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] - 1))
self.Refresh()
wx.FutureCall(500, self.GLPanel1.forceresize)
#threading.Thread(target = self.update).start()
#self.initialized = 0
def setlayerindex(self, z):
m = self.models[""]
mlk = sorted(m.gc.layers.keys())
if z > 0 and self.modelindex < len(mlk) - 1:
self.modelindex += 1
if z < 0 and self.modelindex > 0:
self.modelindex -= 1
m.curlayer = mlk[self.modelindex]
wx.CallAfter(self.SetTitle, "Gcode view, shift to move. Layer %d, Z = %f" % (self.modelindex, m.curlayer))
glPopMatrix()
def main():
app = wx.App(redirect = False)
frame = GCFrame(None, wx.ID_ANY, 'Gcode view, shift to move view, mousewheel to set layer', size = (400, 400))
frame.addfile(list(open("carriage dump_export.gcode")))
#frame = wx.Frame(None, -1, "GL Window", size = (400, 400))
#panel = TestGlPanel(frame)
#frame.Show(True)
#app.MainLoop()
frame = wx.Frame(None, -1, "GL Window", size = (400, 400))
panel = StlViewPanel(frame)
frame.Show(True)
app.MainLoop()
app.Destroy()
if __name__ == "__main__":
import cProfile
print cProfile.run("main()")
main()
......@@ -705,11 +705,11 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def plate(self, e):
import plater
print "plate function activated"
plater.stlwin(size = (800, 580), callback = self.platecb, parent = self).Show()
print _("Plate function activated")
plater.stlwin(size = (800, 580), callback = self.platecb, parent = self, build_dimensions = self.build_dimensions_list).Show()
def platecb(self, name):
print "plated: "+name
print _("Plated %s") % name
self.loadfile(None, name)
def sdmenu(self, e):
......
......@@ -111,7 +111,7 @@ if len (sys.argv) > 2:
if not prefix and "PREFIX" in os.environ:
prefix = os.environ["PREFIX"]
if not prefix or not len (prefix):
prefix = "/usr/local"
prefix = sys.prefix
if sys.argv[1] in ("install", "uninstall") and len (prefix):
sys.argv += ["--prefix", prefix]
......@@ -149,7 +149,7 @@ setup (
url = "http://github.com/kliment/Printrun/",
license = "GPLv3",
data_files = data_files,
packages = ["printrun", "printrun.cairosvg"],
packages = ["printrun", "printrun.cairosvg", "printrun.server", "printrun.gl", "printrun.gl.libtatlin"],
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = {"uninstall" : uninstall,
"install" : install,
......
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