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 ...@@ -28,6 +28,7 @@ import random
import threading import threading
import math import math
import sys import sys
import traceback
from printrun import stltool from printrun import stltool
from printrun.printrun_utils import pixmapfile from printrun.printrun_utils import pixmapfile
...@@ -38,7 +39,8 @@ if "-nogl" not in sys.argv: ...@@ -38,7 +39,8 @@ if "-nogl" not in sys.argv:
from printrun import stlview from printrun import stlview
glview = True glview = True
except: except:
pass print "Could not load 3D viewer for plater:"
traceback.print_exc()
def evalme(s): def evalme(s):
...@@ -173,7 +175,7 @@ class showstl(wx.Window): ...@@ -173,7 +175,7 @@ class showstl(wx.Window):
event.Skip() event.Skip()
def rotateafter(self): def rotateafter(self):
if(self.i != self.previ): if self.i != self.previ:
i = self.parent.l.GetSelection() i = self.parent.l.GetSelection()
if i != wx.NOT_FOUND: if i != wx.NOT_FOUND:
#o = self.models[self.l.GetItemText(i)].offsets #o = self.models[self.l.GetItemText(i)].offsets
...@@ -222,11 +224,8 @@ class showstl(wx.Window): ...@@ -222,11 +224,8 @@ class showstl(wx.Window):
dcs = wx.MemoryDC() dcs = wx.MemoryDC()
for m in self.parent.models.values(): for m in self.parent.models.values():
b = m.bitmap b = m.bitmap
#print b
im = b.ConvertToImage() im = b.ConvertToImage()
#print im
imgc = wx.Point(im.GetWidth() / 2, im.GetHeight() / 2) 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) im = im.Rotate(math.radians(m.rot), imgc, 0)
bm = wx.BitmapFromImage(im) bm = wx.BitmapFromImage(im)
dcs.SelectObject(bm) dcs.SelectObject(bm)
...@@ -237,13 +236,11 @@ class showstl(wx.Window): ...@@ -237,13 +236,11 @@ class showstl(wx.Window):
#if(time.time()-t)>5: #if(time.time()-t)>5:
# break # break
del dc del dc
#print time.time()-t
#s.export()
class stlwin(wx.Frame): 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) wx.Frame.__init__(self, parent, title = _("Plate building tool"), size = size)
self.filenames = filenames
if hasattr(sys,"frozen") and sys.frozen=="windows_exe": if hasattr(sys,"frozen") and sys.frozen=="windows_exe":
self.SetIcon(wx.Icon(sys.executable, wx.BITMAP_TYPE_ICO)) self.SetIcon(wx.Icon(sys.executable, wx.BITMAP_TYPE_ICO))
else: else:
...@@ -279,8 +276,12 @@ class stlwin(wx.Frame): ...@@ -279,8 +276,12 @@ class stlwin(wx.Frame):
#self.SetBackgroundColour((10, 10, 10)) #self.SetBackgroundColour((10, 10, 10))
self.mainsizer.Add(self.panel) self.mainsizer.Add(self.panel)
#self.mainsizer.AddSpacer(10) #self.mainsizer.AddSpacer(10)
if build_dimensions:
self.build_dimensions = build_dimensions
else:
self.build_dimensions = [200, 200, 100, 0, 0, 0]
if glview: if glview:
self.s = stlview.TestGlPanel(self, (580, 580)) self.s = stlview.StlViewPanel(self, (580, 580), build_dimensions = self.build_dimensions)
else: else:
self.s = showstl(self, (580, 580), (0, 0)) self.s = showstl(self, (580, 580), (0, 0))
self.mainsizer.Add(self.s, 1, wx.EXPAND) self.mainsizer.Add(self.s, 1, wx.EXPAND)
...@@ -293,7 +294,7 @@ class stlwin(wx.Frame): ...@@ -293,7 +294,7 @@ class stlwin(wx.Frame):
def autoplate(self, event): def autoplate(self, event):
print _("Autoplating") print _("Autoplating")
separation = 2 separation = 2
bedsize = [200, 200, 100] bedsize = self.build_dimensions[0:3]
cursor = [0, 0, 0] cursor = [0, 0, 0]
newrow = 0 newrow = 0
max = [0, 0] max = [0, 0]
...@@ -372,7 +373,7 @@ class stlwin(wx.Frame): ...@@ -372,7 +373,7 @@ class stlwin(wx.Frame):
def export(self, event): def export(self, event):
dlg = wx.FileDialog(self, _("Pick file to save to"), self.basedir, style = wx.FD_SAVE) 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): if(dlg.ShowModal() == wx.ID_OK):
name = dlg.GetPath() name = dlg.GetPath()
self.writefiles(name) self.writefiles(name)
...@@ -397,15 +398,18 @@ class stlwin(wx.Frame): ...@@ -397,15 +398,18 @@ class stlwin(wx.Frame):
def right(self, event): def right(self, event):
dlg = wx.FileDialog(self, _("Pick file to load"), self.basedir, style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) 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")) dlg.SetWildcard(_("STL files (*.stl;*.STL)|*.stl;*.STL|OpenSCAD files (*.scad)|*.scad"))
if(dlg.ShowModal() == wx.ID_OK): if dlg.ShowModal() == wx.ID_OK:
name = dlg.GetPath() name = dlg.GetPath()
if (name.lower().endswith(".stl")): self.load_file(event, name)
self.load_stl(event, name)
elif (name.lower().endswith(".scad")):
self.load_scad(event, name)
dlg.Destroy() 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): def load_scad(self, event, name):
lf = open(name) lf = open(name)
s = [i.replace("\n", "").replace("\r", "").replace(";", "") for i in lf if "stl" in i] s = [i.replace("\n", "").replace("\r", "").replace(";", "") for i in lf if "stl" in i]
...@@ -491,6 +495,6 @@ class stlwin(wx.Frame): ...@@ -491,6 +495,6 @@ class stlwin(wx.Frame):
if __name__ == '__main__': if __name__ == '__main__':
app = wx.App(False) app = wx.App(False)
main = stlwin() main = stlwin(sys.argv[1:])
main.Show() main.Show()
app.MainLoop() app.MainLoop()
...@@ -270,10 +270,14 @@ class GCode(object): ...@@ -270,10 +270,14 @@ class GCode(object):
cur_z = line.z cur_z = line.z
if cur_z != prev_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)) all_layers.append(Layer(cur_lines))
old_lines = layers.get(prev_z, []) old_lines = layers.get(base_z, [])
old_lines += cur_lines old_lines += cur_lines
layers[prev_z] = old_lines layers[base_z] = old_lines
cur_lines = [] cur_lines = []
layer_id += 1 layer_id += 1
layer_line = 0 layer_line = 0
......
...@@ -15,10 +15,7 @@ ...@@ -15,10 +15,7 @@
from libc.stdlib cimport malloc, free from libc.stdlib cimport malloc, free
from libc.stdint cimport uint32_t from libc.stdint cimport uint32_t
from libc.string cimport strlen, strncpy
cdef extern from "string.h":
char *strncpy(char *dest, char *src, size_t n)
size_t strlen(const char *s)
cdef char* copy_string(object value): cdef char* copy_string(object value):
cdef char* orig = value cdef char* orig = value
......
...@@ -28,221 +28,9 @@ from pyglet.gl import * ...@@ -28,221 +28,9 @@ from pyglet.gl import *
from pyglet import gl from pyglet import gl
from . import gcoder from . import gcoder
from . import stltool from .gl.panel import wxGLPanel
from .libtatlin import actors from .gl.trackball import trackball, mulquat, build_rotmatrix
from .gl.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]]
class GcodeViewPanel(wxGLPanel): class GcodeViewPanel(wxGLPanel):
...@@ -257,11 +45,10 @@ class GcodeViewPanel(wxGLPanel): ...@@ -257,11 +45,10 @@ class GcodeViewPanel(wxGLPanel):
self.parent = realparent if realparent else parent self.parent = realparent if realparent else parent
self.initpos = None self.initpos = None
if build_dimensions: if build_dimensions:
self.dist = max(build_dimensions[0], build_dimensions[1])
self.build_dimensions = build_dimensions self.build_dimensions = build_dimensions
else: else:
self.dist = 200
self.build_dimensions = [200, 200, 100, 0, 0, 0] 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.basequat = [0, 0, 0, 1]
self.mousepos = [0, 0] self.mousepos = [0, 0]
...@@ -374,17 +161,6 @@ class GcodeViewPanel(wxGLPanel): ...@@ -374,17 +161,6 @@ class GcodeViewPanel(wxGLPanel):
self.parent.model.num_layers_to_draw = new_layer self.parent.model.num_layers_to_draw = new_layer
wx.CallAfter(self.Refresh) 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): def wheel(self, event):
"""react to mouse wheel actions: """react to mouse wheel actions:
without shift: set max layer without shift: set max layer
...@@ -407,24 +183,6 @@ class GcodeViewPanel(wxGLPanel): ...@@ -407,24 +183,6 @@ class GcodeViewPanel(wxGLPanel):
else: else:
self.zoom(1/factor, (x, y)) 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): def fit(self):
if not self.parent.model or not self.parent.model.loaded: if not self.parent.model or not self.parent.model.loaded:
return return
......
...@@ -71,7 +71,8 @@ class Platform(object): ...@@ -71,7 +71,8 @@ class Platform(object):
""" """
graduations_major = 10 graduations_major = 10
def __init__(self, build_dimensions): def __init__(self, build_dimensions, light = False):
self.light = light
self.width = build_dimensions[0] self.width = build_dimensions[0]
self.depth = build_dimensions[1] self.depth = build_dimensions[1]
self.height = build_dimensions[2] self.height = build_dimensions[2]
...@@ -102,17 +103,19 @@ class Platform(object): ...@@ -102,17 +103,19 @@ class Platform(object):
elif i % (self.graduations_major / 2) == 0: elif i % (self.graduations_major / 2) == 0:
glColor4f(*self.color_grads_interm) glColor4f(*self.color_grads_interm)
else: else:
if self.light: return False
glColor4f(*self.color_grads_minor) glColor4f(*self.color_grads_minor)
return True
# draw the grid # draw the grid
glBegin(GL_LINES) glBegin(GL_LINES)
for i in range(0, int(math.ceil(self.width + 1))): 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), 0.0, 0.0)
glVertex3f(float(i), self.depth, 0.0) glVertex3f(float(i), self.depth, 0.0)
for i in range(0, int(math.ceil(self.depth + 1))): for i in range(0, int(math.ceil(self.depth + 1))):
color(i) if 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()
......
#!/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): ...@@ -415,7 +415,8 @@ class Gviz(wx.Panel):
if not gcode: if not gcode:
return return
gline = gcoder.Line(gcode) gline = gcoder.Line(gcode)
gline.parse_coordinates(False) split_raw = gcoder.split(gline)
gcoder.parse_coordinates(gline, split_raw, imperial = False)
def _y(y): def _y(y):
return self.build_dimensions[1] - (y - self.build_dimensions[4]) return self.build_dimensions[1] - (y - self.build_dimensions[4])
......
...@@ -88,7 +88,7 @@ def emitstl(filename, facets = [], objname = "stltool_export", binary = 1): ...@@ -88,7 +88,7 @@ def emitstl(filename, facets = [], objname = "stltool_export", binary = 1):
class stl: class stl(object):
def __init__(self, filename = None): def __init__(self, filename = None):
self.facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]] self.facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]]
self.facets = [] self.facets = []
...@@ -102,37 +102,39 @@ class stl: ...@@ -102,37 +102,39 @@ class stl:
self.facetloc = 0 self.facetloc = 0
if filename is None: if filename is None:
return return
self.f = list(open(filename)) with open(filename) as f:
if not self.f[0].startswith("solid"): 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" print "Not an ascii stl solid - attempting to parse as binary"
f = open(filename, "rb") f = open(filename, "rb")
buf = f.read(84) buf = f.read(84)
while(len(buf)<84): while len(buf) < 84:
newdata = f.read(84-len(buf)) newdata = f.read(84 - len(buf))
if not len(newdata): if not len(newdata):
break break
buf+=newdata buf += newdata
facetcount = struct.unpack_from("<I", buf, 80) facetcount = struct.unpack_from("<I", buf, 80)
facetformat = struct.Struct("<ffffffffffffH") facetformat = struct.Struct("<ffffffffffffH")
for i in xrange(facetcount[0]): for i in xrange(facetcount[0]):
buf = f.read(50) buf = f.read(50)
while(len(buf)<50): while len(buf) < 50:
newdata = f.read(50-len(buf)) newdata = f.read(50 - len(buf))
if not len(newdata): if not len(newdata):
break break
buf+=newdata buf += newdata
fd = list(facetformat.unpack(buf)) fd = list(facetformat.unpack(buf))
self.name = "binary soloid" self.name = "binary soloid"
self.facet = [fd[:3],[fd[3:6], fd[6:9], fd[9:12]]] facet = [fd[:3],[fd[3:6], fd[6:9], fd[9:12]]]
self.facets+=[self.facet] self.facets.append(facet)
facet = self.facet self.facetsminz.append((min(map(lambda x:x[2], facet[1])), facet))
self.facetsminz+=[(min(map(lambda x:x[2], facet[1])), facet)] self.facetsmaxz.append((max(map(lambda x:x[2], facet[1])), facet))
self.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])), facet)]
f.close() f.close()
return return
for i in self.f:
if not self.parseline(i):
return
def translate(self, v = [0, 0, 0]): def translate(self, v = [0, 0, 0]):
matrix = [ matrix = [
......
This diff is collapsed.
...@@ -705,11 +705,11 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -705,11 +705,11 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def plate(self, e): def plate(self, e):
import plater import plater
print "plate function activated" print _("Plate function activated")
plater.stlwin(size = (800, 580), callback = self.platecb, parent = self).Show() plater.stlwin(size = (800, 580), callback = self.platecb, parent = self, build_dimensions = self.build_dimensions_list).Show()
def platecb(self, name): def platecb(self, name):
print "plated: "+name print _("Plated %s") % name
self.loadfile(None, name) self.loadfile(None, name)
def sdmenu(self, e): def sdmenu(self, e):
......
...@@ -111,7 +111,7 @@ if len (sys.argv) > 2: ...@@ -111,7 +111,7 @@ if len (sys.argv) > 2:
if not prefix and "PREFIX" in os.environ: if not prefix and "PREFIX" in os.environ:
prefix = os.environ["PREFIX"] prefix = os.environ["PREFIX"]
if not prefix or not len (prefix): if not prefix or not len (prefix):
prefix = "/usr/local" prefix = sys.prefix
if sys.argv[1] in ("install", "uninstall") and len (prefix): if sys.argv[1] in ("install", "uninstall") and len (prefix):
sys.argv += ["--prefix", prefix] sys.argv += ["--prefix", prefix]
...@@ -149,7 +149,7 @@ setup ( ...@@ -149,7 +149,7 @@ setup (
url = "http://github.com/kliment/Printrun/", url = "http://github.com/kliment/Printrun/",
license = "GPLv3", license = "GPLv3",
data_files = data_files, 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"], scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = {"uninstall" : uninstall, cmdclass = {"uninstall" : uninstall,
"install" : install, "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