Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
Printrun
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
Printrun
Commits
2e9ee973
Commit
2e9ee973
authored
Jul 08, 2013
by
D1plo1d
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:kliment/Printrun
parents
d2c59593
f3e6d0e1
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
456 additions
and
913 deletions
+456
-913
plater.py
plater.py
+23
-19
gcoder.py
printrun/gcoder.py
+6
-2
gcoder_line.pyx
printrun/gcoder_line.pyx
+1
-4
gcview.py
printrun/gcview.py
+4
-246
__init__.py
printrun/gl/__init__.py
+0
-0
__init__.py
printrun/gl/libtatlin/__init__.py
+0
-0
actors.py
printrun/gl/libtatlin/actors.py
+10
-7
panel.py
printrun/gl/panel.py
+191
-0
trackball.py
printrun/gl/trackball.py
+90
-0
gviz.py
printrun/gviz.py
+2
-1
stltool.py
printrun/stltool.py
+19
-17
stlview.py
printrun/stlview.py
+105
-612
pronterface.py
pronterface.py
+3
-3
setup.py
setup.py
+2
-2
No files found.
plater.py
View file @
2e9ee973
...
...
@@ -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
()
printrun/gcoder.py
View file @
2e9ee973
...
...
@@ -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
...
...
printrun/gcoder_line.pyx
View file @
2e9ee973
...
...
@@ -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
...
...
printrun/gcview.py
View file @
2e9ee973
...
...
@@ -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
...
...
printrun/
libtatlin
/__init__.py
→
printrun/
gl
/__init__.py
View file @
2e9ee973
File moved
printrun/gl/libtatlin/__init__.py
0 → 100644
View file @
2e9ee973
printrun/libtatlin/actors.py
→
printrun/
gl/
libtatlin/actors.py
View file @
2e9ee973
...
...
@@ -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,19 +103,21 @@ 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
)
glVertex3f
(
float
(
i
),
0.0
,
0.0
)
glVertex3f
(
float
(
i
),
self
.
depth
,
0.0
)
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
)
glVertex3f
(
0
,
float
(
i
),
0.0
)
glVertex3f
(
self
.
width
,
float
(
i
),
0.0
)
if
color
(
i
):
glVertex3f
(
0
,
float
(
i
),
0.0
)
glVertex3f
(
self
.
width
,
float
(
i
),
0.0
)
glEnd
()
# draw fill
...
...
printrun/gl/panel.py
0 → 100644
View file @
2e9ee973
#!/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
)
printrun/gl/trackball.py
0 → 100644
View file @
2e9ee973
#!/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
]]
printrun/gviz.py
View file @
2e9ee973
...
...
@@ -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
])
...
...
printrun/stltool.py
View file @
2e9ee973
...
...
@@ -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
=
[
...
...
printrun/stlview.py
View file @
2e9ee973
This diff is collapsed.
Click to expand it.
pronterface.py
View file @
2e9ee973
...
...
@@ -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
):
...
...
setup.py
View file @
2e9ee973
...
...
@@ -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
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment