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
80194da7
Commit
80194da7
authored
May 29, 2013
by
Guillaume Seguin
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'experimental' of github.com:kliment/Printrun into experimental
parents
1b8aaff8
91ffeb24
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
198 additions
and
53 deletions
+198
-53
plater.py
plater.py
+4
-1
gcoder.py
printrun/gcoder.py
+9
-9
graph.py
printrun/graph.py
+169
-31
pronsole.py
pronsole.py
+2
-0
pronterface.py
pronterface.py
+14
-12
No files found.
plater.py
View file @
80194da7
...
...
@@ -244,7 +244,10 @@ class showstl(wx.Window):
class
stlwin
(
wx
.
Frame
):
def
__init__
(
self
,
size
=
(
800
,
580
),
callback
=
None
,
parent
=
None
):
wx
.
Frame
.
__init__
(
self
,
parent
,
title
=
_
(
"Plate building tool"
),
size
=
size
)
self
.
SetIcon
(
wx
.
Icon
(
pixmapfile
(
"plater.ico"
),
wx
.
BITMAP_TYPE_ICO
))
if
hasattr
(
sys
,
"frozen"
)
and
sys
.
frozen
==
"windows_exe"
:
self
.
SetIcon
(
wx
.
Icon
(
sys
.
executable
,
wx
.
BITMAP_TYPE_ICO
))
else
:
self
.
SetIcon
(
wx
.
Icon
(
pixmapfile
(
"plater.ico"
),
wx
.
BITMAP_TYPE_ICO
))
self
.
mainsizer
=
wx
.
BoxSizer
(
wx
.
HORIZONTAL
)
self
.
panel
=
wx
.
Panel
(
self
,
-
1
,
size
=
(
150
,
600
),
pos
=
(
0
,
0
))
#self.panel.SetBackgroundColour((10, 10, 10))
...
...
printrun/gcoder.py
View file @
80194da7
...
...
@@ -314,15 +314,15 @@ class GCode(object):
zmin
=
min
(
zm
,
zmin
)
zmax
=
max
(
zM
,
zmax
)
self
.
xmin
=
xmin
self
.
xmax
=
xmax
self
.
ymin
=
ymin
self
.
ymax
=
ymax
self
.
zmin
=
zmin
self
.
zmax
=
zmax
self
.
width
=
xmax
-
xmin
self
.
depth
=
ymax
-
ymin
self
.
height
=
zmax
-
zmin
self
.
xmin
=
xmin
if
not
math
.
isinf
(
xmin
)
else
0
self
.
xmax
=
xmax
if
not
math
.
isinf
(
xmax
)
else
0
self
.
ymin
=
ymin
if
not
math
.
isinf
(
ymin
)
else
0
self
.
ymax
=
ymax
if
not
math
.
isinf
(
ymax
)
else
0
self
.
zmin
=
zmin
if
not
math
.
isinf
(
zmin
)
else
0
self
.
zmax
=
zmax
if
not
math
.
isinf
(
zmax
)
else
0
self
.
width
=
self
.
xmax
-
self
.
xmin
self
.
depth
=
self
.
ymax
-
self
.
ymin
self
.
height
=
self
.
zmax
-
self
.
zmin
def
estimate_duration
(
self
):
lastx
=
lasty
=
lastz
=
laste
=
lastf
=
0.0
...
...
printrun/graph.py
View file @
80194da7
...
...
@@ -16,6 +16,7 @@
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import
wx
,
random
from
math
import
log10
,
floor
,
ceil
from
bufferedcanvas
import
*
...
...
@@ -39,15 +40,18 @@ class Graph(BufferedCanvas):
self
.
timer
=
wx
.
Timer
(
self
)
self
.
Bind
(
wx
.
EVT_TIMER
,
self
.
updateTemperatures
,
self
.
timer
)
self
.
minyvalue
=
0
self
.
maxyvalue
=
250
self
.
rescaley
=
True
# should the Y axis be rescaled dynamically?
if
self
.
rescaley
:
self
.
_ybounds
=
Graph
.
_YBounds
(
self
)
#If rescaley is set then ybars gives merely an estimate
#Note that "bars" actually indicate the number of grid _intervals_
self
.
ybars
=
5
self
.
xbars
=
6
# One bar per 10 second
self
.
xsteps
=
60
# Covering 1 minute in the graph
self
.
y_offset
=
1
# This is to show the line even when value is 0 and maxyvalue
self
.
_lastyvalue
=
0
def
OnPaint
(
self
,
evt
):
dc
=
wx
.
PaintDC
(
self
)
gc
=
wx
.
GraphicsContext
.
Create
(
dc
)
...
...
@@ -57,8 +61,10 @@ class Graph(BufferedCanvas):
self
.
AddBedTargetTemperature
(
self
.
bedtargettemps
[
-
1
])
self
.
AddExtruder0Temperature
(
self
.
extruder0temps
[
-
1
])
self
.
AddExtruder0TargetTemperature
(
self
.
extruder0targettemps
[
-
1
])
#self.AddExtruder1Temperature(self.extruder1temps[-1])
#self.AddExtruder1TargetTemperature(self.extruder1targettemps[-1])
self
.
AddExtruder1Temperature
(
self
.
extruder1temps
[
-
1
])
self
.
AddExtruder1TargetTemperature
(
self
.
extruder1targettemps
[
-
1
])
if
self
.
rescaley
:
self
.
_ybounds
.
update
()
self
.
Refresh
()
def
drawgrid
(
self
,
dc
,
gc
):
...
...
@@ -68,36 +74,35 @@ class Graph(BufferedCanvas):
#b = gc.CreateLinearGradientBrush(0, 0, w, h, col1, col2)
gc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
255
,
0
,
0
,
0
),
4
))
gc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
255
,
0
,
0
,
0
),
1
))
#gc.SetBrush(wx.Brush(wx.Colour(245, 245, 255, 52)))
#gc.SetBrush(gc.CreateBrush(wx.Brush(wx.Colour(0, 0, 0, 255))))
#gc.SetPen(wx.Pen(wx.Colour(255, 0, 0, 0), 4
))
gc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
255
,
0
,
0
,
255
),
1
))
#gc.DrawLines(wx.Point(0, 0), wx.Point(50, 10))
#path = gc.CreatePath()
#path.MoveToPoint(0.0, 0.0)
#path.AddLineToPoint(0.0, 100.0)
#path.AddLineToPoint(100.0, 0.0)
#path.AddCircle( 50.0, 50.0, 50.0 )
#path.CloseSubpath()
#gc.DrawPath(path)
#gc.StrokePath(path)
font
=
wx
.
Font
(
10
,
wx
.
DEFAULT
,
wx
.
NORMAL
,
wx
.
BOLD
)
gc
.
SetFont
(
font
,
wx
.
Colour
(
23
,
44
,
44
))
# draw vertical bars
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
225
,
225
,
225
),
1
))
for
x
in
range
(
self
.
xbars
):
dc
.
DrawLine
(
x
*
(
float
(
self
.
width
)
/
self
.
xbars
),
0
,
x
*
(
float
(
self
.
width
)
/
self
.
xbars
),
self
.
height
)
for
x
in
range
(
self
.
xbars
+
1
):
dc
.
DrawLine
(
x
*
(
float
(
self
.
width
-
1
)
/
(
self
.
xbars
-
1
)),
0
,
x
*
(
float
(
self
.
width
-
1
)
/
(
self
.
xbars
-
1
)),
self
.
height
)
# draw horizontal bars
spacing
=
self
.
_calculate_spacing
()
#spacing between bars, in degrees
yspan
=
self
.
maxyvalue
-
self
.
minyvalue
ybars
=
int
(
yspan
/
spacing
)
#Should be close to self.ybars
firstbar
=
int
(
ceil
(
self
.
minyvalue
/
spacing
))
#in degrees
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
225
,
225
,
225
),
1
))
for
y
in
range
(
self
.
ybars
):
y_pos
=
y
*
(
float
(
self
.
height
)
/
self
.
ybars
)
for
y
in
xrange
(
firstbar
,
firstbar
+
ybars
+
1
):
#y_pos = y*(float(self.height)/self.ybars)
degrees
=
y
*
spacing
y_pos
=
self
.
_y_pos
(
degrees
)
dc
.
DrawLine
(
0
,
y_pos
,
self
.
width
,
y_pos
)
gc
.
DrawText
(
unicode
(
int
(
self
.
maxyvalue
-
(
y
*
(
self
.
maxyvalue
/
self
.
ybars
)))
),
1
,
y_pos
-
(
font
.
GetPointSize
()
/
2
))
gc
.
DrawText
(
unicode
(
y
*
spacing
),
1
,
y_pos
-
(
font
.
GetPointSize
()
/
2
))
if
self
.
timer
.
IsRunning
()
==
False
:
font
=
wx
.
Font
(
14
,
wx
.
DEFAULT
,
wx
.
NORMAL
,
wx
.
BOLD
)
...
...
@@ -110,6 +115,33 @@ class Graph(BufferedCanvas):
#gc.DrawLines([[20, 30], [10, 53]])
#dc.SetPen(wx.Pen(wx.Colour(255, 0, 0, 0), 1))
def
_y_pos
(
self
,
temperature
):
"""Converts a temperature, in degrees, to a pixel position"""
#fraction of the screen from the bottom
frac
=
float
(
temperature
-
self
.
minyvalue
)
/
(
self
.
maxyvalue
-
self
.
minyvalue
)
return
int
(
(
1.0
-
frac
)
*
(
self
.
height
-
1
)
)
def
_calculate_spacing
(
self
):
# Allow grids of spacings 1,2.5,5,10,25,50,100,etc
yspan
=
float
(
self
.
maxyvalue
-
self
.
minyvalue
)
log_yspan
=
log10
(
yspan
/
self
.
ybars
)
exponent
=
int
(
floor
(
log_yspan
)
)
#calculate boundary points between allowed spacings
log1_25
=
log10
(
2
)
+
log10
(
1
)
+
log10
(
2.5
)
-
log10
(
1
+
2.5
)
log25_5
=
log10
(
2
)
+
log10
(
2.5
)
+
log10
(
5
)
-
log10
(
2.5
+
5
)
log5_10
=
log10
(
2
)
+
log10
(
5
)
+
log10
(
10
)
-
log10
(
5
+
10
)
if
log_yspan
-
exponent
<
log1_25
:
return
10
**
exponent
elif
log1_25
<=
log_yspan
-
exponent
<
log25_5
:
return
25
*
10
**
(
exponent
-
1
)
elif
log25_5
<=
log_yspan
-
exponent
<
log5_10
:
return
5
*
10
**
exponent
else
:
return
10
**
(
exponent
+
1
)
def
drawtemperature
(
self
,
dc
,
gc
,
temperature_list
,
text
,
text_xoffset
,
r
,
g
,
b
,
a
):
if
self
.
timer
.
IsRunning
()
==
False
:
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
128
,
128
,
128
,
128
),
1
))
...
...
@@ -117,17 +149,18 @@ class Graph(BufferedCanvas):
dc
.
SetPen
(
wx
.
Pen
(
wx
.
Colour
(
r
,
g
,
b
,
a
),
1
))
x_add
=
float
(
self
.
width
)
/
self
.
xsteps
x_pos
=
float
(
0.0
)
lastxvalue
=
float
(
0.0
)
x_pos
=
0.0
lastxvalue
=
0.0
lastyvalue
=
temperature_list
[
-
1
]
for
temperature
in
(
temperature_list
):
y_pos
=
int
((
float
(
self
.
height
-
self
.
y_offset
)
/
self
.
maxyvalue
)
*
temperature
)
+
self
.
y_offset
y_pos
=
self
.
_y_pos
(
temperature
)
if
(
x_pos
>
0.0
):
# One need 2 points to draw a line.
dc
.
DrawLine
(
lastxvalue
,
self
.
height
-
self
.
_lastyvalue
,
x_pos
,
self
.
height
-
y_pos
)
dc
.
DrawLine
(
lastxvalue
,
lastyvalue
,
x_pos
,
y_pos
)
lastxvalue
=
x_pos
x_pos
=
float
(
x_pos
)
+
x_add
self
.
_
lastyvalue
=
y_pos
lastyvalue
=
y_pos
if
len
(
text
)
>
0
:
font
=
wx
.
Font
(
8
,
wx
.
DEFAULT
,
wx
.
NORMAL
,
wx
.
BOLD
)
...
...
@@ -137,9 +170,7 @@ class Graph(BufferedCanvas):
else
:
gc
.
SetFont
(
font
,
wx
.
Colour
(
r
,
g
,
b
))
#gc.DrawText(text, self.width - (font.GetPointSize() * ((len(text) * text_xoffset + 1))), self.height - self._lastyvalue - (font.GetPointSize() / 2))
gc
.
DrawText
(
text
,
x_pos
-
x_add
-
(
font
.
GetPointSize
()
*
((
len
(
text
)
*
text_xoffset
+
1
))),
self
.
height
-
self
.
_lastyvalue
-
(
font
.
GetPointSize
()
/
2
))
#gc.DrawText(text, self.width - (font.GetPixelSize().GetWidth() * ((len(text) * text_xoffset + 1) + 1)), self.height - self._lastyvalue - (font.GetPointSize() / 2))
gc
.
DrawText
(
text
,
x_pos
-
x_add
-
(
font
.
GetPointSize
()
*
((
len
(
text
)
*
text_xoffset
+
1
))),
lastyvalue
-
(
font
.
GetPointSize
()
/
2
))
def
drawbedtemp
(
self
,
dc
,
gc
):
...
...
@@ -238,3 +269,110 @@ class Graph(BufferedCanvas):
self
.
drawextruder0temp
(
dc
,
gc
)
self
.
drawextruder1targettemp
(
dc
,
gc
)
self
.
drawextruder1temp
(
dc
,
gc
)
class
_YBounds
(
object
):
"""Small helper class to claculate y bounds dynamically"""
def
__init__
(
self
,
graph
,
minimum_scale
=
5.0
,
buffer
=
0.10
):
"""_YBounds(Graph,float,float)
graph parent object to calculate scales for
minimum_scale minimum range to show on the graph
buffer amount of padding to add above & below the
displayed temperatures. Given as a fraction of the
total range. (Eg .05 to use 90
%
of the range for
temperatures)
"""
self
.
graph
=
graph
self
.
min_scale
=
minimum_scale
self
.
buffer
=
buffer
# Frequency to rescale the graph
self
.
update_freq
=
10
self
.
_last_update
=
self
.
update_freq
#number of updates since last full refresh
def
update
(
self
,
forceUpdate
=
False
):
"""Updates graph.minyvalue and graph.maxyvalue based on current temperatures
"""
self
.
_last_update
+=
1
#TODO Smart update. Only do full calculation every 10s. Otherwise, just look at current graph & expand if necessary
if
forceUpdate
or
self
.
_last_update
>=
self
.
update_freq
:
self
.
graph
.
minyvalue
,
self
.
graph
.
maxyvalue
=
self
.
getBounds
()
self
.
_last_update
=
0
else
:
self
.
graph
.
minyvalue
,
self
.
graph
.
maxyvalue
=
self
.
getBoundsQuick
()
def
getBounds
(
self
):
"""
Calculates the bounds based on the current temperatures
Rules:
* Include the full extruder0 history
* Include the current target temp (but not necessarily old settings)
* Include the extruder1 and/or bed temp if
1) The target temp is >0
2) The history has ever been above 5
* Include at least min_scale
* Include at least buffer above & below the extreme temps
"""
extruder0_min
=
min
(
self
.
graph
.
extruder0temps
)
extruder0_max
=
max
(
self
.
graph
.
extruder0temps
)
extruder0_target
=
self
.
graph
.
extruder0targettemps
[
-
1
]
extruder1_min
=
min
(
self
.
graph
.
extruder1temps
)
extruder1_max
=
max
(
self
.
graph
.
extruder1temps
)
extruder1_target
=
self
.
graph
.
extruder1targettemps
[
-
1
]
bed_min
=
min
(
self
.
graph
.
bedtemps
)
bed_max
=
max
(
self
.
graph
.
bedtemps
)
bed_target
=
self
.
graph
.
bedtargettemps
[
-
1
]
miny
=
min
(
extruder0_min
,
extruder0_target
)
maxy
=
max
(
extruder0_max
,
extruder0_target
)
if
extruder1_target
>
0
or
extruder1_max
>
5
:
#use extruder1
miny
=
min
(
miny
,
extruder1_min
,
extruder1_target
)
maxy
=
max
(
maxy
,
extruder1_max
,
extruder1_target
)
if
bed_target
>
0
or
bed_max
>
5
:
#use HBP
miny
=
min
(
miny
,
bed_min
,
bed_target
)
maxy
=
max
(
maxy
,
bed_max
,
bed_target
)
padding
=
(
maxy
-
miny
)
*
self
.
buffer
/
(
1.0
-
2
*
self
.
buffer
)
miny
-=
padding
maxy
+=
padding
if
maxy
-
miny
<
self
.
min_scale
:
extrapadding
=
(
self
.
min_scale
-
maxy
+
miny
)
/
2.0
miny
-=
extrapadding
maxy
+=
extrapadding
return
(
miny
,
maxy
)
def
getBoundsQuick
(
self
):
# Only look at current temps
extruder0_min
=
self
.
graph
.
extruder0temps
[
-
1
]
extruder0_max
=
self
.
graph
.
extruder0temps
[
-
1
]
extruder0_target
=
self
.
graph
.
extruder0targettemps
[
-
1
]
extruder1_min
=
self
.
graph
.
extruder1temps
[
-
1
]
extruder1_max
=
self
.
graph
.
extruder1temps
[
-
1
]
extruder1_target
=
self
.
graph
.
extruder1targettemps
[
-
1
]
bed_min
=
self
.
graph
.
bedtemps
[
-
1
]
bed_max
=
self
.
graph
.
bedtemps
[
-
1
]
bed_target
=
self
.
graph
.
bedtargettemps
[
-
1
]
miny
=
min
(
extruder0_min
,
extruder0_target
)
maxy
=
max
(
extruder0_max
,
extruder0_target
)
if
extruder1_target
>
0
or
extruder1_max
>
5
:
#use extruder1
miny
=
min
(
miny
,
extruder1_min
,
extruder1_target
)
maxy
=
max
(
maxy
,
extruder1_max
,
extruder1_target
)
if
bed_target
>
0
or
bed_max
>
5
:
#use HBP
miny
=
min
(
miny
,
bed_min
,
bed_target
)
maxy
=
max
(
maxy
,
bed_max
,
bed_target
)
#We have to rescale, so add padding
if
miny
<
self
.
graph
.
minyvalue
:
padding
=
(
self
.
graph
.
maxyvalue
-
miny
)
*
self
.
buffer
/
(
1.0
-
self
.
buffer
)
miny
-=
padding
if
maxy
>
self
.
graph
.
maxyvalue
:
padding
=
(
maxy
-
self
.
graph
.
minyvalue
)
*
self
.
buffer
/
(
1.0
-
self
.
buffer
)
maxy
+=
padding
return
min
(
miny
,
self
.
graph
.
minyvalue
),
max
(
maxy
,
self
.
graph
.
maxyvalue
)
pronsole.py
View file @
80194da7
...
...
@@ -608,6 +608,8 @@ class pronsole(cmd.Cmd):
self
.
processing_rc
=
False
def
load_default_rc
(
self
,
rc_filename
=
".pronsolerc"
):
if
rc_filename
==
".pronsolerc"
and
hasattr
(
sys
,
"frozen"
)
and
sys
.
frozen
in
[
"windows_exe"
,
"console_exe"
]:
rc_filename
=
"printrunconf.ini"
try
:
try
:
self
.
load_rc
(
os
.
path
.
join
(
os
.
path
.
expanduser
(
"~"
),
rc_filename
))
...
...
pronterface.py
View file @
80194da7
...
...
@@ -196,7 +196,10 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self
.
filename
=
filename
os
.
putenv
(
"UBUNTU_MENUPROXY"
,
"0"
)
MainWindow
.
__init__
(
self
,
None
,
title
=
_
(
"Printer Interface"
),
size
=
size
);
self
.
SetIcon
(
wx
.
Icon
(
pixmapfile
(
"P-face.ico"
),
wx
.
BITMAP_TYPE_ICO
))
if
hasattr
(
sys
,
"frozen"
)
and
sys
.
frozen
==
"windows_exe"
:
self
.
SetIcon
(
wx
.
Icon
(
sys
.
executable
,
wx
.
BITMAP_TYPE_ICO
))
else
:
self
.
SetIcon
(
wx
.
Icon
(
pixmapfile
(
"P-face.ico"
),
wx
.
BITMAP_TYPE_ICO
))
self
.
panel
=
wx
.
Panel
(
self
,
-
1
,
size
=
size
)
self
.
statuscheck
=
False
...
...
@@ -1367,19 +1370,18 @@ class PronterWindow(MainWindow, pronsole.pronsole):
basedir
=
os
.
path
.
split
(
self
.
filename
)[
0
]
except
:
pass
dlg
=
None
if
filename
is
None
:
dlg
=
wx
.
FileDialog
(
self
,
_
(
"Open file to print"
),
basedir
,
style
=
wx
.
FD_OPEN
|
wx
.
FD_FILE_MUST_EXIST
)
dlg
.
SetWildcard
(
_
(
"OBJ, STL, and GCODE files (*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ)|*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ|All Files (*.*)|*.*"
))
if
(
filename
is
not
None
or
dlg
.
ShowModal
()
==
wx
.
ID_OK
)
:
if
filename
is
not
None
:
dlg
=
None
if
filename
is
None
:
dlg
=
wx
.
FileDialog
(
self
,
_
(
"Open file to print"
),
basedir
,
style
=
wx
.
FD_OPEN
|
wx
.
FD_FILE_MUST_EXIST
)
dlg
.
SetWildcard
(
_
(
"OBJ, STL, and GCODE files (*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ)|*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ|All Files (*.*)|*.*"
))
if
filename
or
dlg
.
ShowModal
()
==
wx
.
ID_OK
:
if
filename
:
name
=
filename
else
:
name
=
dlg
.
GetPath
()
if
not
(
os
.
path
.
exists
(
name
)):
dlg
.
Destroy
()
if
not
os
.
path
.
exists
(
name
):
self
.
status
.
SetStatusText
(
_
(
"File not found!"
))
if
dlg
is
not
None
:
dlg
.
Destroy
()
return
path
=
os
.
path
.
split
(
name
)[
0
]
if
path
!=
self
.
settings
.
last_file_path
:
...
...
@@ -1400,8 +1402,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if
self
.
p
.
online
:
wx
.
CallAfter
(
self
.
printbtn
.
Enable
)
threading
.
Thread
(
target
=
self
.
loadviz
)
.
start
()
if
dlg
is
not
Non
e
:
dlg
.
Destroy
()
els
e
:
dlg
.
Destroy
()
def
loadviz
(
self
):
gcode
=
self
.
fgcode
...
...
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