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
77ac4453
Commit
77ac4453
authored
May 21, 2013
by
Guillaume Seguin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rework gcview to make it cleaner, better and faster
parent
bf64e797
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
132 additions
and
634 deletions
+132
-634
gcview.py
printrun/gcview.py
+132
-634
No files found.
printrun/gcview.py
100755 → 100644
View file @
77ac4453
#!/usr/bin/python
# This file is part of the Printrun suite.
#
# Printrun is free software: you can redistribute it and/or modify
...
...
@@ -16,43 +17,39 @@
import
os
import
math
import
stltool
import
wx
from
wx
import
glcanvas
import
time
import
threading
import
gcoder
import
pyglet
pyglet
.
options
[
'shadow_window'
]
=
False
pyglet
.
options
[
'debug_gl'
]
=
False
from
pyglet.gl
import
*
pyglet
.
options
[
'debug_gl'
]
=
True
import
stltool
import
threading
from
pyglet.gl
import
*
from
pyglet
import
gl
from
pyglet.graphics.vertexbuffer
import
create_buffer
from
printrun.libtatlin
import
actors
class
GLPanel
(
wx
.
Panel
):
class
wx
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
)
super
(
wxGLPanel
,
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
()
self
.
sizer
.
Fit
(
self
)
# bind events
self
.
canvas
.
Bind
(
wx
.
EVT_ERASE_BACKGROUND
,
self
.
processEraseBackgroundEvent
)
...
...
@@ -89,12 +86,12 @@ class GLPanel(wx.Panel):
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
()
# This is a 'perfect' time to initialize OpenGL ... only if we need to
if
not
self
.
GLinitialized
:
self
.
OnInitGL
()
self
.
GLinitialized
=
True
...
...
@@ -104,7 +101,7 @@ class GLPanel(wx.Panel):
def
Destroy
(
self
):
#clean up the pyglet OpenGL context
#
self.pygletcontext.destroy()
self
.
pygletcontext
.
destroy
()
#call the super method
super
(
wx
.
Panel
,
self
)
.
Destroy
()
...
...
@@ -116,51 +113,23 @@ class GLPanel(wx.Panel):
#create a pyglet context for this panel
self
.
pmat
=
(
GLdouble
*
16
)()
self
.
mvmat
=
(
GLdouble
*
16
)()
self
.
pygletcontext
=
Context
(
current_context
)
self
.
pygletcontext
=
gl
.
Context
(
gl
.
current_context
)
self
.
pygletcontext
.
set_current
()
self
.
dist
=
1000
self
.
vpmat
=
None
#normal gl init
glClearColor
(
0
,
0
,
0
,
1
)
glColor3f
(
1
,
0
,
0
)
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
)
# Uncomment this line for a wireframe view
#glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
# Simple light setup. On Windows GL_LIGHT0 is enabled by default,
# but this is not the case on Linux or Mac, so remember to always
# include it.
glEnable
(
GL_LIGHTING
)
glEnable
(
GL_LIGHT0
)
glEnable
(
GL_LIGHT1
)
# Define a simple function to create ctypes arrays of floats:
def
vec
(
*
args
):
return
(
GLfloat
*
len
(
args
))(
*
args
)
glLightfv
(
GL_LIGHT0
,
GL_POSITION
,
vec
(
.5
,
.5
,
1
,
0
))
glLightfv
(
GL_LIGHT0
,
GL_SPECULAR
,
vec
(
.5
,
.5
,
1
,
1
))
glLightfv
(
GL_LIGHT0
,
GL_DIFFUSE
,
vec
(
1
,
1
,
1
,
1
))
glLightfv
(
GL_LIGHT1
,
GL_POSITION
,
vec
(
1
,
0
,
.5
,
0
))
glLightfv
(
GL_LIGHT1
,
GL_DIFFUSE
,
vec
(
.5
,
.5
,
.5
,
1
))
glLightfv
(
GL_LIGHT1
,
GL_SPECULAR
,
vec
(
1
,
1
,
1
,
1
))
glMaterialfv
(
GL_FRONT_AND_BACK
,
GL_AMBIENT_AND_DIFFUSE
,
vec
(
0.5
,
0
,
0.3
,
1
))
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()
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
.
OnInitGL
()
self
.
GLinitialized
=
True
self
.
pmat
=
(
GLdouble
*
16
)()
self
.
mvmat
=
(
GLdouble
*
16
)()
glViewport
(
0
,
0
,
width
,
height
)
glMatrixMode
(
GL_PROJECTION
)
glLoadIdentity
()
...
...
@@ -170,8 +139,6 @@ class GLPanel(wx.Panel):
#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
:
...
...
@@ -180,13 +147,9 @@ class GLPanel(wx.Panel):
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
()
#==========================================================================
...
...
@@ -204,262 +167,8 @@ class GLPanel(wx.Panel):
'''called in the middle of ondraw after the buffer has been cleared'''
pass
def
_dist
(
dist
):
"""return axis length, or 0 if None"""
if
dist
is
None
:
return
0
else
:
return
float
(
dist
)
class
gcpoint
(
object
):
"""gcode point
stub for first line"""
def
__init__
(
self
,
x
=
0
,
y
=
0
,
z
=
0
,
e
=
0
):
self
.
x
=
x
self
.
y
=
y
self
.
z
=
z
self
.
e
=
e
self
.
length
=
0
class
gcline
(
object
):
"""gcode move line
Once initialised, it knows its position, length and extrusion ratio
Returns lines into gcview batch()
"""
def
__init__
(
self
,
x
=
None
,
y
=
None
,
z
=
None
,
e
=
None
,
f
=
None
,
prev_gcline
=
None
,
orgline
=
False
):
if
prev_gcline
is
None
:
self
.
prev_gcline
=
gcpoint
()
else
:
self
.
prev_gcline
=
prev_gcline
if
x
is
None
:
self
.
x
=
self
.
prev_gcline
.
x
else
:
self
.
x
=
float
(
x
)
if
y
is
None
:
self
.
y
=
self
.
prev_gcline
.
y
else
:
self
.
y
=
float
(
y
)
if
z
is
None
:
self
.
z
=
self
.
prev_gcline
.
z
else
:
self
.
z
=
float
(
z
)
if
e
is
None
:
self
.
e
=
self
.
prev_gcline
.
e
else
:
self
.
e
=
float
(
e
)
self
.
f
=
f
self
.
orgline
=
orgline
self
.
calc_delta
()
self
.
calc_len
()
def
__str__
(
self
):
return
u"line from
%
s,
%
s,
%
s to
%
s,
%
s,
%
s with extrusion ratio
%
s and feedrate
%
s
\n
%
s"
%
(
self
.
prev_gcline
.
x
,
self
.
prev_gcline
.
y
,
self
.
prev_gcline
.
z
,
self
.
x
,
self
.
y
,
self
.
z
,
self
.
extrusion_ratio
,
self
.
f
,
self
.
orgline
,
)
def
calc_delta
(
self
,
prev_gcline
=
None
):
if
prev_gcline
is
None
:
prev_gcline
=
self
.
prev_gcline
if
self
.
prev_gcline
is
not
None
:
self
.
dx
=
self
.
x
-
prev_gcline
.
x
self
.
dy
=
self
.
y
-
prev_gcline
.
y
self
.
dz
=
self
.
z
-
prev_gcline
.
z
self
.
de
=
self
.
e
-
prev_gcline
.
e
else
:
self
.
dx
=
self
.
x
self
.
dy
=
self
.
y
self
.
dz
=
self
.
z
self
.
de
=
self
.
e
def
calc_len
(
self
):
if
self
.
dz
!=
0
:
self
.
length
=
math
.
sqrt
(
self
.
dx
**
2
+
self
.
dy
**
2
+
self
.
dz
**
2
)
else
:
self
.
length
=
math
.
sqrt
(
self
.
dx
**
2
+
self
.
dy
**
2
)
if
self
.
de
:
self
.
extrusion_ratio
=
self
.
length
/
self
.
de
else
:
self
.
extrusion_ratio
=
0
def
glline
(
self
):
return
[
self
.
prev_gcline
.
x
,
self
.
prev_gcline
.
y
,
self
.
prev_gcline
.
z
,
self
.
x
,
self
.
y
,
self
.
z
,
]
def
glcolor
(
self
,
upper_limit
=
None
,
lower_limit
=
0
,
max_feedrate
=
0
):
if
self
.
extrusion_ratio
==
0
:
return
[
255
,
255
,
255
,
0
,
0
,
0
]
else
:
blue_color
=
0
green_color
=
0
if
upper_limit
is
not
None
:
if
self
.
extrusion_ratio
<=
lower_limit
:
blue_color
=
0
else
:
blue_color
=
int
((
self
.
extrusion_ratio
-
lower_limit
)
/
(
upper_limit
-
lower_limit
)
*
255
)
else
:
blue_color
=
0
if
max_feedrate
>
0
and
self
.
f
>
0
:
green_color
=
int
((
self
.
f
/
max_feedrate
)
*
255
)
if
green_color
>
255
:
green_color
=
255
if
green_color
<
0
:
green_color
=
0
if
blue_color
>
255
:
blue_color
=
255
if
blue_color
<
0
:
blue_color
=
0
return
[
255
,
green_color
,
blue_color
,
128
,
green_color
,
blue_color
/
4
]
def
float_from_line
(
axe
,
line
):
return
float
(
line
.
split
(
axe
)[
1
]
.
split
(
" "
)[
0
])
class
gcThreadRenderer
(
threading
.
Thread
):
def
__init__
(
self
,
gcview
,
lines
):
threading
.
Thread
.
__init__
(
self
)
self
.
gcview
=
gcview
self
.
lines
=
lines
print
"q init"
def
run
(
self
):
for
line
in
self
.
lines
:
layer_name
=
line
.
z
if
line
.
z
not
in
self
.
gcview
.
layers
:
self
.
gcview
.
layers
[
line
.
z
]
=
pyglet
.
graphics
.
Batch
()
self
.
gcview
.
layerlist
=
self
.
gcview
.
layers
.
keys
()
self
.
gcview
.
layerlist
.
sort
()
self
.
gcview
.
layers
[
line
.
z
]
.
add
(
2
,
GL_LINES
,
None
,
(
"v3f"
,
line
.
glline
()),
(
"c3B"
,
line
.
glcolor
(
self
.
gcview
.
upper_limit
,
self
.
gcview
.
lower_limit
,
self
.
gcview
.
max_feedrate
)))
self
.
gcview
.
t2
=
time
.
time
()
print
"Rendered lines in
%
fs"
%
(
self
.
gcview
.
t2
-
self
.
gcview
.
t1
)
class
gcview
(
object
):
"""gcode visualiser
Holds opengl objects for all layers
"""
def
__init__
(
self
,
lines
,
batch
,
w
=
0.5
,
h
=
0.5
):
if
len
(
lines
)
==
0
:
return
print
"Loading
%
s lines"
%
(
len
(
lines
))
#End pos of previous mode
self
.
prev
=
gcpoint
()
# Correction for G92 moves
self
.
delta
=
[
0
,
0
,
0
,
0
]
self
.
layers
=
{}
self
.
t0
=
time
.
time
()
self
.
lastf
=
0
lines
=
[
self
.
transform
(
i
)
for
i
in
lines
]
lines
=
[
i
for
i
in
lines
if
i
is
not
None
]
self
.
t1
=
time
.
time
()
print
"transformed
%
s lines in
%
fs"
%
(
len
(
lines
),
self
.
t1
-
self
.
t0
)
self
.
upper_limit
=
0
self
.
lower_limit
=
None
self
.
max_feedrate
=
0
for
line
in
lines
:
if
line
.
extrusion_ratio
and
line
.
length
>
0.005
:
#lines shorter than 0.003 can have large extrusion ratio
if
line
.
extrusion_ratio
>
self
.
upper_limit
:
self
.
upper_limit
=
line
.
extrusion_ratio
if
self
.
lower_limit
is
None
or
line
.
extrusion_ratio
<
self
.
lower_limit
:
self
.
lower_limit
=
line
.
extrusion_ratio
if
line
.
f
>
self
.
max_feedrate
:
self
.
max_feedrate
=
line
.
f
#print upper_limit, lower_limit
#self.render_gl(lines)
q
=
gcThreadRenderer
(
self
,
lines
)
q
.
setDaemon
(
True
)
q
.
start
()
def
transform
(
self
,
line
):
"""transforms line of gcode into gcline object (or None if its not move)
Tracks coordinates across resets in self.delta
"""
orgline
=
line
line
=
line
.
split
(
";"
)[
0
]
cur
=
[
None
,
None
,
None
,
None
,
None
]
if
len
(
line
)
>
0
:
if
"G92"
in
line
:
#Recalculate delta on G92 (reset)
if
(
"X"
in
line
):
try
:
self
.
delta
[
0
]
=
float_from_line
(
"X"
,
line
)
+
self
.
prev
.
x
except
:
self
.
delta
[
0
]
=
0
if
(
"Y"
in
line
):
try
:
self
.
delta
[
1
]
=
float_from_line
(
"Y"
,
line
)
+
self
.
prev
.
y
except
:
self
.
delta
[
1
]
=
0
if
(
"Z"
in
line
):
try
:
self
.
delta
[
2
]
=
float_from_line
(
"Z"
,
line
)
+
self
.
prev
.
z
except
:
self
.
delta
[
2
]
=
0
if
(
"E"
in
line
):
try
:
self
.
delta
[
3
]
=
float_from_line
(
"E"
,
line
)
+
self
.
prev
.
e
except
:
self
.
delta
[
3
]
=
0
return
None
if
"G1"
in
line
or
"G0"
in
line
:
#Create new gcline
if
(
"X"
in
line
):
cur
[
0
]
=
float_from_line
(
"X"
,
line
)
+
self
.
delta
[
0
]
if
(
"Y"
in
line
):
cur
[
1
]
=
float_from_line
(
"Y"
,
line
)
+
self
.
delta
[
1
]
if
(
"Z"
in
line
):
cur
[
2
]
=
float_from_line
(
"Z"
,
line
)
+
self
.
delta
[
2
]
if
(
"E"
in
line
):
cur
[
3
]
=
float_from_line
(
"E"
,
line
)
+
self
.
delta
[
3
]
if
"F"
in
line
:
cur
[
4
]
=
float_from_line
(
"F"
,
line
)
if
cur
==
[
None
,
None
,
None
,
None
,
None
]:
return
None
else
:
#print cur
if
cur
[
4
]
is
None
:
cur
[
4
]
=
self
.
lastf
else
:
self
.
lastf
=
cur
[
4
]
r
=
gcline
(
x
=
cur
[
0
],
y
=
cur
[
1
],
z
=
cur
[
2
],
e
=
cur
[
3
],
f
=
cur
[
4
],
prev_gcline
=
self
.
prev
,
orgline
=
orgline
)
self
.
prev
=
r
return
r
return
None
def
delete
(
self
):
#for i in self.vlists:
# i.delete()
#self.vlists = []
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];
...
...
@@ -537,15 +246,15 @@ def mulquat(q1, rq):
q1
[
3
]
*
rq
[
3
]
-
q1
[
0
]
*
rq
[
0
]
-
q1
[
1
]
*
rq
[
1
]
-
q1
[
2
]
*
rq
[
2
]]
class
TestGlPanel
(
GLPanel
):
class
GcodeViewPanel
(
wx
GLPanel
):
def
__init__
(
self
,
parent
,
size
,
id
=
wx
.
ID_ANY
):
super
(
TestGlPanel
,
self
)
.
__init__
(
parent
,
id
,
wx
.
DefaultPosition
,
s
ize
,
0
)
def
__init__
(
self
,
parent
,
id
=
wx
.
ID_ANY
):
super
(
GcodeViewPanel
,
self
)
.
__init__
(
parent
,
id
,
wx
.
DefaultPosition
,
wx
.
DefaultS
ize
,
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
.
initialized
=
0
self
.
canvas
.
Bind
(
wx
.
EVT_MOUSEWHEEL
,
self
.
wheel
)
self
.
parent
=
parent
self
.
initpos
=
None
...
...
@@ -553,64 +262,67 @@ class TestGlPanel(GLPanel):
self
.
bedsize
=
[
200
,
200
]
self
.
transv
=
[
0
,
0
,
-
self
.
dist
]
self
.
basequat
=
[
0
,
0
,
0
,
1
]
wx
.
CallAfter
(
self
.
forceresize
)
self
.
mousepos
=
[
0
,
0
]
def
create_objects
(
self
):
'''create opengl objects when opengl is initialized'''
for
obj
in
self
.
parent
.
objects
:
if
obj
.
model
and
obj
.
model
.
loaded
and
not
obj
.
model
.
initialized
:
obj
.
model
.
init
()
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'''
if
self
.
vpmat
is
None
:
return
self
.
create_objects
()
#glLoadIdentity()
#print list(self.pmat)
if
self
.
rot
==
1
:
glLoadIdentity
()
glMultMatrixd
(
self
.
mvmat
)
else
:
glLoadIdentity
()
glTranslatef
(
*
self
.
transv
)
glPushMatrix
()
glTranslatef
(
-
self
.
parent
.
platform
.
width
/
2
,
-
self
.
parent
.
platform
.
depth
/
2
,
0
)
for
obj
in
self
.
parent
.
objects
:
if
not
obj
.
model
or
not
obj
.
model
.
loaded
or
not
obj
.
model
.
initialized
:
continue
glPushMatrix
()
glTranslatef
(
*
(
obj
.
offsets
))
glRotatef
(
obj
.
rot
,
0.0
,
0.0
,
1.0
)
glScalef
(
*
obj
.
scale
)
obj
.
model
.
display
()
glPopMatrix
()
glPopMatrix
()
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
+=
[
300
]
print
v
self
.
add_file
(
"../prusa/metric-prusa/x-end-idler.stl"
,
v
)
def
forceresize
(
self
):
self
.
SetClientSize
((
self
.
GetClientSize
()[
0
],
self
.
GetClientSize
()[
1
]
+
1
))
self
.
SetClientSize
((
self
.
GetClientSize
()[
0
],
self
.
GetClientSize
()[
1
]
-
1
))
threading
.
Thread
(
target
=
self
.
update
)
.
start
()
self
.
initialized
=
0
def
move_shape
(
self
,
delta
):
"""moves shape (selected in l, which is list ListBox of shapes)
by an offset specified in tuple delta.
Positive numbers move to (rigt, down)"""
name
=
self
.
parent
.
l
.
GetSelection
()
if
name
==
wx
.
NOT_FOUND
:
return
False
name
=
self
.
parent
.
l
.
GetString
(
name
)
model
=
self
.
parent
.
models
[
name
]
model
.
offsets
=
[
model
.
offsets
[
0
]
+
delta
[
0
],
model
.
offsets
[
1
]
+
delta
[
1
],
model
.
offsets
[
2
]
]
self
.
Refresh
()
return
True
print
"Double-click at "
+
str
(
v
)
+
" in "
print
self
def
move
(
self
,
event
):
"""react to mouse actions:
no mouse: show red mousedrop
LMB: move active object,
with shift rotate viewport
RMB: nothing
with shift move viewport
LMB: rotate viewport
RMB: move viewport
"""
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
return
#print self.initpos
p1
=
self
.
initpos
self
.
initpos
=
None
...
...
@@ -642,7 +354,7 @@ 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
:
...
...
@@ -659,51 +371,35 @@ class TestGlPanel(GLPanel):
glLoadIdentity
()
glTranslatef
(
self
.
transv
[
0
],
self
.
transv
[
1
],
0
)
glTranslatef
(
0
,
0
,
self
.
transv
[
2
])
if
(
self
.
rot
)
:
if
self
.
rot
:
glMultMatrixd
(
build_rotmatrix
(
self
.
basequat
))
glGetDoublev
(
GL_MODELVIEW_MATRIX
,
self
.
mvmat
)
self
.
rot
=
1
self
.
initpos
=
None
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
def
rotate_shape
(
self
,
angle
):
"""rotates acive shape
positive angle is clockwise
"""
name
=
self
.
parent
.
l
.
GetSelection
()
if
name
==
wx
.
NOT_FOUND
:
return
False
name
=
self
.
parent
.
l
.
GetString
(
name
)
model
=
self
.
parent
.
models
[
name
]
model
.
rot
+=
angle
return
wx
.
CallAfter
(
self
.
Refresh
)
def
wheel
(
self
,
event
):
"""react to mouse wheel actions:
rotate object
with shift zoom viewport
without shift: set max layer
with shift
:
zoom viewport
"""
z
=
event
.
GetWheelRotation
()
angle
=
10
if
not
event
.
ShiftDown
():
i
=
self
.
parent
.
l
.
GetSelection
()
if
i
<
0
:
try
:
self
.
parent
.
setlayerindex
(
z
)
except
:
pass
if
event
.
ShiftDown
():
if
not
self
.
parent
.
model
:
return
if
z
>
0
:
self
.
rotate_shape
(
angle
/
2
)
max_layers
=
self
.
parent
.
model
.
max_layers
current_layer
=
self
.
parent
.
model
.
num_layers_to_draw
new_layer
=
min
(
max_layers
,
current_layer
+
1
)
self
.
parent
.
model
.
num_layers_to_draw
=
new_layer
else
:
self
.
rotate_shape
(
-
angle
/
2
)
current_layer
=
self
.
parent
.
model
.
num_layers_to_draw
new_layer
=
max
(
1
,
current_layer
-
1
)
self
.
parent
.
model
.
num_layers_to_draw
=
new_layer
wx
.
CallAfter
(
self
.
Refresh
)
return
if
z
>
0
:
self
.
transv
[
2
]
+=
angle
...
...
@@ -712,10 +408,11 @@ class TestGlPanel(GLPanel):
glLoadIdentity
()
glTranslatef
(
*
self
.
transv
)
if
(
self
.
rot
)
:
if
self
.
rot
:
glMultMatrixd
(
build_rotmatrix
(
self
.
basequat
))
glGetDoublev
(
GL_MODELVIEW_MATRIX
,
self
.
mvmat
)
self
.
rot
=
1
wx
.
CallAfter
(
self
.
Refresh
)
def
keypress
(
self
,
event
):
"""gets keypress events and moves/rotates acive shape"""
...
...
@@ -745,268 +442,69 @@ class TestGlPanel(GLPanel):
if
keycode
==
93
:
self
.
rotate_shape
(
angle
)
event
.
Skip
()
def
update
(
self
):
while
(
1
):
dt
=
0.05
time
.
sleep
(
0.05
)
try
:
wx
.
CallAfter
(
self
.
Refresh
)
except
:
return
def
anim
(
self
,
obj
):
g
=
50
*
9.8
v
=
20
dt
=
0.05
basepos
=
obj
.
offsets
[
2
]
obj
.
offsets
[
2
]
+=
obj
.
animoffset
while
obj
.
offsets
[
2
]
>
-
1
:
time
.
sleep
(
dt
)
obj
.
offsets
[
2
]
-=
v
*
dt
v
+=
g
*
dt
if
(
obj
.
offsets
[
2
]
<
0
):
obj
.
scale
[
2
]
*=
1
-
3
*
dt
#return
v
=
v
/
4
while
obj
.
offsets
[
2
]
<
basepos
:
time
.
sleep
(
dt
)
obj
.
offsets
[
2
]
+=
v
*
dt
v
-=
g
*
dt
obj
.
scale
[
2
]
*=
1
+
5
*
dt
obj
.
scale
[
2
]
=
1.0
def
create_objects
(
self
):
'''create opengl objects when opengl is initialized'''
self
.
initialized
=
1
wx
.
CallAfter
(
self
.
Refresh
)
def
drawmodel
(
self
,
m
,
n
):
batch
=
pyglet
.
graphics
.
Batch
()
stl
=
stlview
(
m
.
facets
,
batch
=
batch
)
m
.
batch
=
batch
m
.
animoffset
=
300
#print m
#threading.Thread(target = self.anim, args = (m, )).start()
wx
.
CallAfter
(
self
.
Refresh
)
def
update_object_resize
(
self
):
'''called when the window recieves only if opengl is initialized'''
pass
class
GCObject
(
object
):
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
:
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
()
glPushMatrix
()
glTranslatef
(
self
.
mousepos
[
0
]
-
self
.
bedsize
[
0
]
/
2
,
self
.
mousepos
[
1
]
-
self
.
bedsize
[
1
]
/
2
,
0
)
glBegin
(
GL_TRIANGLES
)
glMaterialfv
(
GL_FRONT_AND_BACK
,
GL_AMBIENT_AND_DIFFUSE
,
vec
(
1
,
0
,
0
,
1
))
glNormal3f
(
0
,
0
,
1
)
glVertex3f
(
2
,
2
,
0
)
glVertex3f
(
-
2
,
2
,
0
)
glVertex3f
(
-
2
,
-
2
,
0
)
glVertex3f
(
2
,
-
2
,
0
)
glVertex3f
(
2
,
2
,
0
)
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
)
glEnable
(
GL_LINE_SMOOTH
)
glEnable
(
GL_BLEND
)
glBlendFunc
(
GL_SRC_ALPHA
,
GL_ONE_MINUS_SRC_ALPHA
)
glHint
(
GL_LINE_SMOOTH_HINT
,
GL_NICEST
)
glLineWidth
(
1.5
)
for
i
in
self
.
parent
.
models
.
values
():
glPushMatrix
()
glTranslatef
(
*
(
i
.
offsets
))
glRotatef
(
i
.
rot
,
0.0
,
0.0
,
1.0
)
glScalef
(
*
i
.
scale
)
#glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.93, 0.37, 0.25, 1))
glEnable
(
GL_COLOR_MATERIAL
)
if
i
.
curlayer
==
-
1
:
# curlayer == -1 means we are over the top.
glLineWidth
(
0.8
)
[
i
.
gc
.
layers
[
j
]
.
draw
()
for
j
in
i
.
gc
.
layerlist
]
else
:
glLineWidth
(
0.6
)
tmpindex
=
i
.
gc
.
layerlist
.
index
(
i
.
curlayer
)
if
tmpindex
>=
5
:
thin_layer
=
i
.
gc
.
layerlist
[
tmpindex
-
5
]
[
i
.
gc
.
layers
[
j
]
.
draw
()
for
j
in
i
.
gc
.
layerlist
if
j
<=
thin_layer
]
if
tmpindex
>
4
:
glLineWidth
(
0.9
)
i
.
gc
.
layers
[
i
.
gc
.
layerlist
[
tmpindex
-
4
]]
.
draw
()
if
tmpindex
>
3
:
glLineWidth
(
1.1
)
i
.
gc
.
layers
[
i
.
gc
.
layerlist
[
tmpindex
-
3
]]
.
draw
()
if
tmpindex
>
2
:
glLineWidth
(
1.3
)
i
.
gc
.
layers
[
i
.
gc
.
layerlist
[
tmpindex
-
2
]]
.
draw
()
if
tmpindex
>
1
:
glLineWidth
(
2.2
)
i
.
gc
.
layers
[
i
.
gc
.
layerlist
[
tmpindex
-
1
]]
.
draw
()
glLineWidth
(
3.5
)
i
.
gc
.
layers
[
i
.
curlayer
]
.
draw
()
glLineWidth
(
1.5
)
glDisable
(
GL_COLOR_MATERIAL
)
glPopMatrix
()
glPopMatrix
()
#print "drawn batch"
def
__init__
(
self
,
model
):
self
.
offsets
=
[
0
,
0
,
0
]
self
.
rot
=
0
self
.
curlayer
=
0.0
self
.
scale
=
[
1.0
,
1.0
,
1.0
]
self
.
batch
=
pyglet
.
graphics
.
Batch
()
self
.
model
=
model
def
GetSelection
(
self
):
return
wx
.
NOT_FOUND
class
G
C
Frame
(
wx
.
Frame
):
class
G
codeView
Frame
(
wx
.
Frame
):
'''A simple class for using OpenGL with wxPython.'''
def
__init__
(
self
,
parent
,
ID
,
title
,
pos
=
wx
.
DefaultPosition
,
def
__init__
(
self
,
parent
,
ID
,
title
,
build_dimensions
,
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
=
-
1
m
.
scale
=
[
1.0
,
1.0
,
1.0
]
m
.
batch
=
pyglet
.
graphics
.
Batch
()
m
.
gc
=
gcview
([],
batch
=
m
.
batch
)
self
.
models
=
{
"GCODE"
:
m
}
self
.
l
=
d
()
self
.
modelindex
=
0
self
.
GLPanel1
=
TestGlPanel
(
self
,
size
)
def
addfile
(
self
,
gcode
=
[]):
self
.
models
[
"GCODE"
]
.
gc
.
delete
()
self
.
models
[
"GCODE"
]
.
gc
=
gcview
(
gcode
,
batch
=
self
.
models
[
"GCODE"
]
.
batch
)
self
.
setlayerindex
(
None
)
super
(
GcodeViewFrame
,
self
)
.
__init__
(
parent
,
ID
,
title
,
pos
,
size
,
style
)
self
.
p
=
self
# Hack for backwards compatibility with gviz API
self
.
platform
=
actors
.
Platform
(
build_dimensions
)
self
.
model
=
None
self
.
objects
=
[
GCObject
(
self
.
platform
),
GCObject
(
None
)]
self
.
glpanel
=
GcodeViewPanel
(
self
)
def
addfile
(
self
,
gcode
=
None
):
self
.
model
=
actors
.
GcodeModel
()
if
gcode
:
self
.
model
.
load_data
(
gcode
)
self
.
objects
[
-
1
]
.
model
=
self
.
model
wx
.
CallAfter
(
self
.
Refresh
)
def
clear
(
self
):
self
.
models
[
"GCODE"
]
.
gc
.
delete
()
self
.
models
[
"GCODE"
]
.
gc
=
gcview
([],
batch
=
self
.
models
[
"GCODE"
]
.
batch
)
self
.
model
=
None
self
.
objects
[
-
1
]
.
model
=
None
wx
.
CallAfter
(
self
.
Refresh
)
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
[
"GCODE"
]
try
:
mlk
=
m
.
gc
.
layerlist
except
:
mlk
=
[]
if
z
is
None
:
self
.
modelindex
=
-
1
elif
z
>
0
:
if
self
.
modelindex
<
len
(
mlk
)
-
1
:
if
self
.
modelindex
>
-
1
:
model
=
self
.
objects
[
-
1
]
.
model
if
not
model
:
return
mlk
=
sorted
(
m
.
gc
.
layers
.
keys
())
if
z
>
0
and
self
.
modelindex
<
len
(
mlk
)
-
1
:
self
.
modelindex
+=
1
else
:
self
.
modelindex
=
-
1
elif
z
<
0
:
if
self
.
modelindex
>
0
:
if
z
<
0
and
self
.
modelindex
>
0
:
self
.
modelindex
-=
1
elif
self
.
modelindex
==
-
1
:
self
.
modelindex
=
len
(
mlk
)
if
self
.
modelindex
>=
0
:
m
.
curlayer
=
mlk
[
self
.
modelindex
]
wx
.
CallAfter
(
self
.
SetTitle
,
"Gcode view, shift to move. Layer
%
d/
%
d, Z =
%
f"
%
(
self
.
modelindex
,
len
(
mlk
),
m
.
curlayer
))
else
:
m
.
curlayer
=
-
1
wx
.
CallAfter
(
self
.
SetTitle
,
"Gcode view, shift to move view, mousewheel to set layer"
)
wx
.
CallAfter
(
self
.
SetTitle
,
"Gcode view, shift to move. Layer
%
d, Z =
%
f"
%
(
self
.
modelindex
,
m
.
curlayer
))
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
))
if
__name__
==
"__main__"
:
import
sys
for
filename
in
sys
.
argv
:
if
".gcode"
in
filename
:
frame
.
addfile
(
list
(
open
(
filename
)))
elif
".stl"
in
filename
:
#TODO: add stl here
pass
#frame = wx.Frame(None, -1, "GL Window", size = (400, 400))
#panel = TestGlPanel(frame, size = (300, 300))
app
=
wx
.
App
(
redirect
=
False
)
build_dimensions
=
[
200
,
200
,
100
,
0
,
0
,
0
]
frame
=
GcodeViewFrame
(
None
,
wx
.
ID_ANY
,
'Gcode view, shift to move view, mousewheel to set layer'
,
size
=
(
400
,
400
),
build_dimensions
=
build_dimensions
)
frame
.
addfile
(
gcoder
.
GCode
(
open
(
sys
.
argv
[
1
])))
frame
.
Show
(
True
)
app
.
MainLoop
()
app
.
Destroy
()
if
__name__
==
"__main__"
:
#import cProfile
#print cProfile.run("main()")
main
()
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