Commit 33cd617c authored by Guillaume Seguin's avatar Guillaume Seguin

Fix a shitton of flake8 warnings and errors

parent 5a0b0269
......@@ -17,14 +17,13 @@
# Set up Internationalization using gettext
# searching for installed locales on /usr/share; uses relative folder if not found (windows)
import os, Queue, re
import os
from printrun.printrun_utils import install_locale
install_locale('plater')
import wx
import time
import random
import threading
import math
import sys
......@@ -102,11 +101,10 @@ class showstl(wx.Window):
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]
]
model.offsets = [model.offsets[0] + delta[0],
model.offsets[1] + delta[1],
model.offsets[2]
]
self.Refresh()
return True
......@@ -114,10 +112,9 @@ class showstl(wx.Window):
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
if(self.initpos is not None):
currentpos = event.GetPositionTuple()
delta = (
0.5 * (currentpos[0] - self.initpos[0]),
- 0.5 * (currentpos[1] - self.initpos[1])
)
delta = (0.5 * (currentpos[0] - self.initpos[0]),
-0.5 * (currentpos[1] - self.initpos[1])
)
self.move_shape(delta)
self.Refresh()
self.initpos = None
......@@ -205,10 +202,8 @@ class showstl(wx.Window):
self.paint(dc = dc)
def paint(self, coord1 = "x", coord2 = "y", dc = None):
coords = {"x": 0, "y": 1, "z": 2}
if dc is None:
dc = wx.ClientDC(self)
offset = [0, 0]
scale = 2
dc.SetPen(wx.Pen(wx.Colour(100, 100, 100)))
for i in xrange(20):
......@@ -220,7 +215,6 @@ class showstl(wx.Window):
dc.DrawLine(i * scale * 50, 0, i * scale * 50, 400)
dc.SetBrush(wx.Brush(wx.Colour(128, 255, 128)))
dc.SetPen(wx.Pen(wx.Colour(128, 128, 128)))
t = time.time()
dcs = wx.MemoryDC()
for m in self.parent.models.values():
b = m.bitmap
......@@ -241,7 +235,7 @@ class stlwin(wx.Frame):
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":
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))
......@@ -330,8 +324,9 @@ class stlwin(wx.Frame):
self.Refresh()
def clear(self, event):
result = wx.MessageBox(_('Are you sure you want to clear the grid? All unsaved changes will be lost.'), _('Clear the grid?'),
wx.YES_NO | wx.ICON_QUESTION)
result = wx.MessageBox(_('Are you sure you want to clear the grid? All unsaved changes will be lost.'),
_('Clear the grid?'),
wx.YES_NO | wx.ICON_QUESTION)
if (result == 2):
self.models = {}
self.l.Clear()
......@@ -442,7 +437,6 @@ class stlwin(wx.Frame):
return
path = os.path.split(name)[0]
self.basedir = path
t = time.time()
#print name
if name.lower().endswith(".stl"):
#Filter out the path, just show the STL filename.
......
......@@ -19,14 +19,21 @@ from serial import Serial, SerialException
from select import error as SelectError
from threading import Thread, Lock
from Queue import Queue, Empty as QueueEmpty
import time, getopt, sys
import platform, os, traceback, errno
import time
import getopt
import sys
import platform
import os
import traceback
import errno
import socket
import re
from functools import wraps
from collections import deque
from printrun.GCodeAnalyzer import GCodeAnalyzer
from printrun import gcoder
from printrun.printrun_utils import install_locale
install_locale('pronterface')
def locked(f):
@wraps(f)
......@@ -52,15 +59,18 @@ def disable_hup(port):
class printcore():
def __init__(self, port = None, baud = None):
"""Initializes a printcore instance. Pass the port and baud rate to connect immediately
"""
"""Initializes a printcore instance. Pass the port and baud rate to
connect immediately"""
self.baud = None
self.port = None
self.analyzer = GCodeAnalyzer()
self.printer = None #Serial instance connected to the printer, None when disconnected
self.clear = 0 #clear to send, enabled after responses
self.online = False #The printer has responded to the initial command and is active
self.printing = False #is a print currently running, true if printing, false if paused
self.printer = None # Serial instance connected to the printer,
# should be None when disconnected
self.clear = 0 # clear to send, enabled after responses
self.online = False # The printer has responded to the initial command
# and is active
self.printing = False # is a print currently running, true if printing
# , false if paused
self.mainqueue = None
self.priqueue = Queue(0)
self.queueindex = 0
......@@ -71,19 +81,19 @@ class printcore():
self.log = deque(maxlen = 10000)
self.sent = []
self.writefailures = 0
self.tempcb = None #impl (wholeline)
self.recvcb = None #impl (wholeline)
self.sendcb = None #impl (wholeline)
self.preprintsendcb = None #impl (wholeline)
self.printsendcb = None #impl (wholeline)
self.layerchangecb = None #impl (wholeline)
self.errorcb = None #impl (wholeline)
self.startcb = None #impl ()
self.endcb = None #impl ()
self.onlinecb = None #impl ()
self.loud = False #emit sent and received lines to terminal
self.greetings = ['start','Grbl ']
self.wait = 0 # default wait period for send(), send_now()
self.tempcb = None # impl (wholeline)
self.recvcb = None # impl (wholeline)
self.sendcb = None # impl (wholeline)
self.preprintsendcb = None # impl (wholeline)
self.printsendcb = None # impl (wholeline)
self.layerchangecb = None # impl (wholeline)
self.errorcb = None # impl (wholeline)
self.startcb = None # impl ()
self.endcb = None # impl ()
self.onlinecb = None # impl ()
self.loud = False # emit sent and received lines to terminal
self.greetings = ['start', 'Grbl ']
self.wait = 0 # default wait period for send(), send_now()
self.read_thread = None
self.stop_read_thread = False
self.send_thread = None
......@@ -144,7 +154,8 @@ class printcore():
pass
self.writefailures = 0
if not is_serial:
self.printer_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.printer_tcp = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
self.timeout = 0.25
self.printer_tcp.settimeout(1.0)
try:
......@@ -162,7 +173,9 @@ class printcore():
disable_hup(self.port)
self.printer_tcp = None
try:
self.printer = Serial(port = self.port, baudrate = self.baud, timeout = 0.25)
self.printer = Serial(port = self.port,
baudrate = self.baud,
timeout = 0.25)
except SerialException as e:
print _("Could not connect to %s at baudrate %s:") % (self.port, self.baud)
self.printer = None
......@@ -199,27 +212,29 @@ class printcore():
return line
except SelectError as e:
if 'Bad file descriptor' in e.args[1]:
print "Can't read from printer (disconnected?) (SelectError {0}): {1}".format(e.errno, e.strerror)
print _("Can't read from printer (disconnected?) (SelectError {0}): {1}").format(e.errno, e.strerror)
return None
else:
print "SelectError ({0}): {1}".format(e.errno, e.strerror)
print _("SelectError ({0}): {1}").format(e.errno, e.strerror)
raise
except SerialException as e:
print "Can't read from printer (disconnected?) (SerialException): {0}".format(e)
print _("Can't read from printer (disconnected?) (SerialException): {0}").format(e)
return None
except socket.error as e:
print "Can't read from printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror)
print _("Can't read from printer (disconnected?) (Socket error {0}): {1}").format(e.errno, e.strerror)
return None
except OSError as e:
if e.errno == errno.EAGAIN: # Not a real error, no data was available
if e.errno == errno.EAGAIN: # Not a real error, no data was available
return ""
print "Can't read from printer (disconnected?) (OS Error {0}): {1}".format(e.errno, e.strerror)
print _("Can't read from printer (disconnected?) (OS Error {0}): {1}").format(e.errno, e.strerror)
return None
def _listen_can_continue(self):
if self.printer_tcp:
return not self.stop_read_thread and self.printer
return not self.stop_read_thread and self.printer and self.printer.isOpen()
return (not self.stop_read_thread
and self.printer
and self.printer.isOpen())
def _listen_until_online(self):
while not self.online and self._listen_can_continue():
......@@ -227,7 +242,7 @@ class printcore():
empty_lines = 0
while self._listen_can_continue():
line = self._readline()
if line == None: break # connection problem
if line is None: break # connection problem
# workaround cases where M105 was sent before printer Serial
# was online an empty line means read timeout was reached,
# meaning no data was received thus we count those empty lines,
......@@ -241,7 +256,8 @@ class printcore():
empty_lines += 1
if empty_lines == 15: break
else: empty_lines = 0
if line.startswith(tuple(self.greetings)) or line.startswith('ok') or "T:" in line:
if line.startswith(tuple(self.greetings)) \
or line.startswith('ok') or "T:" in line:
if self.onlinecb:
try: self.onlinecb()
except: pass
......@@ -256,7 +272,7 @@ class printcore():
self._listen_until_online()
while self._listen_can_continue():
line = self._readline()
if line == None:
if line is None:
break
if line.startswith('DEBUG_'):
continue
......@@ -274,7 +290,8 @@ class printcore():
# Teststrings for resend parsing # Firmware exp. result
# line="rs N2 Expected checksum 67" # Teacup 2
if line.lower().startswith("resend") or line.startswith("rs"):
line = line.replace("N:"," ").replace("N"," ").replace(":"," ")
for haystack in ["N:", "N", ":"]:
line = line.replace(haystack, " ")
linewords = line.split()
while len(linewords) != 0:
try:
......@@ -311,13 +328,14 @@ class printcore():
time.sleep(0.001)
def _checksum(self, command):
return reduce(lambda x, y:x^y, map(ord, command))
return reduce(lambda x, y: x ^ y, map(ord, command))
def startprint(self, gcode, startindex = 0):
"""Start a print, gcode is an array of gcode commands.
returns True on success, False if already printing.
The print queue will be replaced with the contents of the data array, the next line will be set to 0 and the firmware notified.
Printing will then start in a parallel thread.
The print queue will be replaced with the contents of the data array,
the next line will be set to 0 and the firmware notified. Printing
will then start in a parallel thread.
"""
if self.printing or not self.online or not self.printer:
return False
......@@ -331,25 +349,23 @@ class printcore():
return True
self.clear = False
resuming = (startindex != 0)
self.print_thread = Thread(target = self._print, kwargs = {"resuming": resuming})
self.print_thread = Thread(target = self._print,
kwargs = {"resuming": resuming})
self.print_thread.start()
return True
# run a simple script if it exists, no multithreading
def runSmallScript(self, filename):
if filename == None: return
if filename is None: return
f = None
try:
f = open(filename)
with open(filename) as f:
for i in f:
l = i.replace("\n", "")
l = l[:l.find(";")] # remove comments
self.send_now(l)
except:
pass
if f != None:
for i in f:
l = i.replace("\n", "")
l = l[:l.find(";")] #remove comment
self.send_now(l)
f.close()
pass
def pause(self):
"""Pauses the print, saving the current position.
......@@ -358,51 +374,57 @@ class printcore():
self.paused = True
self.printing = False
# try joining the print thread: enclose it in try/except because we might be calling it from the thread itself
# try joining the print thread: enclose it in try/except because we
# might be calling it from the thread itself
try:
self.print_thread.join()
self.print_thread.join()
except:
pass
pass
self.print_thread = None
# saves the status
self.pauseX = self.analyzer.x-self.analyzer.xOffset;
self.pauseY = self.analyzer.y-self.analyzer.yOffset;
self.pauseZ = self.analyzer.z-self.analyzer.zOffset;
self.pauseE = self.analyzer.e-self.analyzer.eOffset;
self.pauseF = self.analyzer.f;
self.pauseRelative = self.analyzer.relative;
self.pauseX = self.analyzer.x - self.analyzer.xOffset
self.pauseY = self.analyzer.y - self.analyzer.yOffset
self.pauseZ = self.analyzer.z - self.analyzer.zOffset
self.pauseE = self.analyzer.e - self.analyzer.eOffset
self.pauseF = self.analyzer.f
self.pauseRelative = self.analyzer.relative
def resume(self):
"""Resumes a paused print.
"""
if not self.paused: return False
if self.paused:
#restores the status
self.send_now("G90") # go to absolute coordinates
xyFeedString = ""
zFeedString = ""
if self.xy_feedrate != None: xyFeedString = " F" + str(self.xy_feedrate)
if self.z_feedrate != None: zFeedString = " F" + str(self.z_feedrate)
self.send_now("G1 X" + str(self.pauseX) + " Y" + str(self.pauseY) + xyFeedString)
self.send_now("G1 Z" + str(self.pauseZ) + zFeedString)
self.send_now("G92 E" + str(self.pauseE))
if self.pauseRelative: self.send_now("G91") # go back to relative if needed
#reset old feed rate
self.send_now("G1 F" + str(self.pauseF))
# restores the status
self.send_now("G90") # go to absolute coordinates
xyFeedString = ""
zFeedString = ""
if self.xy_feedrate is not None:
xyFeedString = " F" + str(self.xy_feedrate)
if self.z_feedrate is not None:
zFeedString = " F" + str(self.z_feedrate)
self.send_now("G1 X%s Y%s%s" % (self.pauseX, self.pauseY,
xyFeedString))
self.send_now("G1 Z" + str(self.pauseZ) + zFeedString)
self.send_now("G92 E" + str(self.pauseE))
# go back to relative if needed
if self.pauseRelative: self.send_now("G91")
# reset old feed rate
self.send_now("G1 F" + str(self.pauseF))
self.paused = False
self.printing = True
self.print_thread = Thread(target = self._print, kwargs = {"resuming": True})
self.print_thread = Thread(target = self._print,
kwargs = {"resuming": True})
self.print_thread.start()
def send(self, command, wait = 0):
"""Adds a command to the checksummed main command queue if printing, or sends the command immediately if not printing
"""
"""Adds a command to the checksummed main command queue if printing, or
sends the command immediately if not printing"""
if self.online:
if self.printing:
......@@ -413,8 +435,8 @@ class printcore():
print "Not connected to printer."
def send_now(self, command, wait = 0):
"""Sends a command to the printer ahead of the command queue, without a checksum
"""
"""Sends a command to the printer ahead of the command queue, without a
checksum"""
if self.online:
self.priqueue.put_nowait(command)
else:
......@@ -451,10 +473,10 @@ class printcore():
def processHostCommand(self, command):
command = command.lstrip()
if command.startswith(";@pause"):
if self.pronterface != None:
self.pronterface.pause(None)
else:
self.pause()
if self.pronterface is not None:
self.pronterface.pause(None)
else:
self.pause()
def _sendnext(self):
if not self.printer:
......@@ -489,12 +511,12 @@ class printcore():
else:
next_gline = None
gline = self.preprintsendcb(gline, next_gline)
if gline == None:
if gline is None:
self.queueindex += 1
self.clear = True
return
tline = gline.raw
if tline.lstrip().startswith(";@"): # check for host command
if tline.lstrip().startswith(";@"): # check for host command
self.processHostCommand(tline)
self.queueindex += 1
self.clear = True
......@@ -526,7 +548,8 @@ class printcore():
self.sentlines[lineno] = command
if self.printer:
self.sent.append(command)
self.analyzer.Analyze(command) # run the command through the analyzer
# run the command through the analyzer
self.analyzer.Analyze(command)
if self.loud:
print "SENT:", command
if self.sendcb:
......@@ -537,13 +560,13 @@ class printcore():
if self.printer_tcp: self.printer.flush()
self.writefailures = 0
except socket.error as e:
print "Can't write to printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror)
print _("Can't write to printer (disconnected?) (Socket error {0}): {1}").format(e.errno, e.strerror)
self.writefailures += 1
except SerialException as e:
print "Can't write to printer (disconnected?) (SerialException): {0}".format(e)
print _("Can't write to printer (disconnected?) (SerialException): {0}").format(e)
self.writefailures += 1
except RuntimeError as e:
print "Socket connection broken, disconnected. ({0}): {1}".format(e.errno, e.strerror)
print _("Socket connection broken, disconnected. ({0}): {1}").format(e.errno, e.strerror)
self.writefailures += 1
if __name__ == '__main__':
......@@ -559,16 +582,17 @@ if __name__ == '__main__':
for o, a in opts:
if o in ('-h', '--help'):
# FIXME: Fix help
print "Opts are: --help , -b --baud = baudrate, -v --verbose, -s --statusreport"
print "Opts are: --help, -b --baud = baudrate, -v --verbose, \
-s --statusreport"
sys.exit(1)
if o in ('-b', '--baud'):
baud = int(a)
if o in ('-v','--verbose'):
if o in ('-v', '--verbose'):
loud = True
elif o in ('-s','--statusreport'):
elif o in ('-s', '--statusreport'):
statusreport = True
if len (args) > 1:
if len(args) > 1:
port = args[-2]
filename = args[-1]
print "Printing: %s on %s with baudrate %d" % (filename, port, baud)
......@@ -590,7 +614,9 @@ if __name__ == '__main__':
while p.printing:
time.sleep(1)
if statusreport:
sys.stdout.write("Progress: %02.1f%%\r" % (100 * float(p.queueindex) / len(p.mainqueue),) )
sys.stdout.write("Progress: %02.1f%%\r"
% (100 * float(p.queueindex)
/ len(p.mainqueue),))
sys.stdout.flush()
p.disconnect()
sys.exit(0)
......
......@@ -30,7 +30,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import re
import gcoder
class GCodeAnalyzer():
......@@ -70,7 +69,7 @@ class GCodeAnalyzer():
def Analyze(self, gcode):
gline = gcoder.Line(gcode)
split_raw = gcoder.split(gline)
if gline.command.startswith(";@"): return # code is a host command
if gline.command.startswith(";@"): return # code is a host command
gcoder.parse_coordinates(gline, split_raw, self.imperial)
code_g = int(gline.command[1:]) if gline.command.startswith("G") else None
code_m = int(gline.command[1:]) if gline.command.startswith("M") else None
......@@ -81,9 +80,8 @@ class GCodeAnalyzer():
self.lastY = self.y
self.lastZ = self.z
self.lastE = self.e
eChanged = False;
code_f = gline.f
if code_f != None:
if code_f is not None:
self.f = code_f
code_x = gline.x
......@@ -92,27 +90,24 @@ class GCodeAnalyzer():
code_e = gline.e
if self.relative:
if code_x != None: self.x += code_x
if code_y != None: self.y += code_y
if code_z != None: self.z += code_z
if code_e != None:
if code_x is not None: self.x += code_x
if code_y is not None: self.y += code_y
if code_z is not None: self.z += code_z
if code_e is not None:
if code_e != 0:
eChanged = True
self.e += code_e
else:
# absolute coordinates
if code_x != None: self.x = self.xOffset + code_x
if code_y != None: self.y = self.yOffset + code_y
if code_z != None: self.z = self.zOffset + code_z
if code_e != None:
if code_x is not None: self.x = self.xOffset + code_x
if code_y is not None: self.y = self.yOffset + code_y
if code_z is not None: self.z = self.zOffset + code_z
if code_e is not None:
if self.eRelative:
if code_e != 0:
eChanged = True
self.e += code_e
else:
# e is absolute. Is it changed?
if self.e != self.eOffset + code_e:
eChanged = True
self.e = self.eOffset + code_e
#limit checking
"""
......@@ -137,20 +132,20 @@ class GCodeAnalyzer():
code_z = gline.z
code_e = gline.e
homeAll = False
if code_x == None and code_y == None and code_z == None: homeAll = True
if code_x != None or homeAll:
if code_x is None and code_y is None and code_z is None: homeAll = True
if code_x is not None or homeAll:
self.hasHomeX = True
self.xOffset = 0
self.x = self.homeX
if code_y != None or homeAll:
if code_y is not None or homeAll:
self.hasHomeY = True
self.yOffset = 0
self.y = self.homeY
if code_z != None or homeAll:
if code_z is not None or homeAll:
self.hasHomeZ = True
self.zOffset = 0
self.z = self.homeZ
if code_e != None:
if code_e is not None:
self.eOffset = 0
self.e = 0
elif code_g == 162:
......@@ -162,16 +157,16 @@ class GCodeAnalyzer():
code_y = gline.y
code_z = gline.z
homeAll = False
if code_x == None and code_y == None and code_z == None: homeAll = True
if code_x != None or homeAll:
if code_x is None and code_y is None and code_z is None: homeAll = True
if code_x is not None or homeAll:
self.hasHomeX = True
self.xOffset = 0
self.x = self.maxX
if code_y != None or homeAll:
if code_y is not None or homeAll:
self.hasHomeY = True
self.yOffset = 0
self.y = self.maxY
if code_z != None or homeAll:
if code_z is not None or homeAll:
self.hasHomeZ = True
self.zOffset = 0
self.z = self.maxZ
......@@ -182,20 +177,20 @@ class GCodeAnalyzer():
code_y = gline.y
code_z = gline.z
code_e = gline.e
if code_x != None:
if code_x is not None:
self.xOffset = self.x - float(code_x)
self.x = self.xOffset
if code_y != None:
if code_y is not None:
self.yOffset = self.y - float(code_y)
self.y = self.yOffset
if code_z != None:
if code_z is not None:
self.zOffset = self.z - float(code_z)
self.z = self.zOffset
if code_e != None:
if code_e is not None:
self.xOffset = self.e - float(code_e)
self.e = self.eOffset
#End code_g != None
if code_m != None:
#End code_g is not None
if code_m is not None:
if code_m == 82: self.eRelative = False
elif code_m == 83: self.eRelative = True
......
......@@ -38,16 +38,15 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
NOTE: Skeinforge is tightly integrated with Tkinter and there appears to be a dependency which stops radio-button values from being saved.
Perhaps this can be solved, but at the moment this dialog cannot modify radio button values. One will have to use the main Skeinforge application.
"""
self.moduleSettingsMap = {
'dimension':['Filament Diameter (mm):','Retraction Distance (millimeters):', 'Retraction Distance (millimeters):','Extruder Retraction Speed (mm/s):'],
'carve':['Layer Height = Extrusion Thickness (mm):', 'Extrusion Width (mm):'],
'chamber':['Heated PrintBed Temperature (Celcius):', 'Turn print Bed Heater Off at Shut Down', 'Turn Extruder Heater Off at Shut Down'],
'cool':['Activate Cool.. but use with a fan!', 'Use Cool if layer takes shorter than(seconds):'],
'fill':['Activate Fill:', 'Infill Solidity (ratio):', 'Fully filled Layers (each top and bottom):', 'Extra Shells on Sparse Layer (layers):', 'Extra Shells on Alternating Solid Layer (layers):'],
'multiply':['Number of Columns (integer):', 'Number of Rows (integer):'],
'raft':['First Layer Main Feedrate (mm/s):','First Layer Perimeter Feedrate (mm/s):','First Layer Flow Rate Infill(scaler):','First Layer Flow Rate Perimeter(scaler):',],
'speed':['Main Feed Rate (mm/s):','Main Flow Rate (scaler):','Perimeter Feed Rate (mm/s):','Perimeter Flow Rate (scaler):','Travel Feed Rate (mm/s):']
}
self.moduleSettingsMap = {'dimension': ['Filament Diameter (mm):', 'Retraction Distance (millimeters):', 'Retraction Distance (millimeters):', 'Extruder Retraction Speed (mm/s):'],
'carve': ['Layer Height = Extrusion Thickness (mm):', 'Extrusion Width (mm):'],
'chamber': ['Heated PrintBed Temperature (Celcius):', 'Turn print Bed Heater Off at Shut Down', 'Turn Extruder Heater Off at Shut Down'],
'cool': ['Activate Cool.. but use with a fan!', 'Use Cool if layer takes shorter than(seconds):'],
'fill': ['Activate Fill:', 'Infill Solidity (ratio):', 'Fully filled Layers (each top and bottom):', 'Extra Shells on Sparse Layer (layers):', 'Extra Shells on Alternating Solid Layer (layers):'],
'multiply': ['Number of Columns (integer):', 'Number of Rows (integer):'],
'raft': ['First Layer Main Feedrate (mm/s):', 'First Layer Perimeter Feedrate (mm/s):', 'First Layer Flow Rate Infill(scaler):', 'First Layer Flow Rate Perimeter(scaler):'],
'speed': ['Main Feed Rate (mm/s):', 'Main Flow Rate (scaler):', 'Perimeter Feed Rate (mm/s):', 'Perimeter Flow Rate (scaler):', 'Travel Feed Rate (mm/s):']
}
self.scrollbarPanel = wx.ScrolledWindow(self, -1, style = wx.TAB_TRAVERSAL)
self.settingsSizer = self.getProfileSettings()
......@@ -140,7 +139,7 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
isDirty = False
for setting in settings.getReadRepository(repo).preferences:
if setting.name == settingName:
if setting.value == None or str(x.GetValue()) != str(setting.value):
if setting.value is None or str(x.GetValue()) != str(setting.value):
print('Saving ... ' + settingName + ' = ' + str(x.GetValue()))
setting.value = x.GetValue()
isDirty = True
......
......@@ -62,15 +62,15 @@ class BufferedCanvas(wx.Panel):
ID=-1,
pos = wx.DefaultPosition,
size = wx.DefaultSize,
style = wx.NO_FULL_REPAINT_ON_RESIZE|wx.WANTS_CHARS):
style = wx.NO_FULL_REPAINT_ON_RESIZE | wx.WANTS_CHARS):
wx.Panel.__init__(self, parent, ID, pos, size, style)
# Bind events
self.Bind(wx.EVT_PAINT, self.onPaint)
# Disable background erasing (flicker-licious)
def disable_event(*pargs,**kwargs):
pass # the sauce, please
def disable_event(*pargs, **kwargs):
pass # the sauce, please
self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event)
##
......
......@@ -17,27 +17,30 @@
#Interactive RepRap e axis calibration program
#(C) Nathan Zadoks 2011
s = 300 #Extrusion speed (mm/min)
n = 100 #Default length to extrude
m= 0 #User-entered measured extrusion length
k = 300 #Default amount of steps per mm
port='/dev/ttyUSB0' #Default serial port to connect to printer
temp = 210 #Default extrusion temperature
s = 300 # Extrusion speed (mm/min)
n = 100 # Default length to extrude
m = 0 # User-entered measured extrusion length
k = 300 # Default amount of steps per mm
port = '/dev/ttyUSB0' # Default serial port to connect to printer
temp = 210 # Default extrusion temperature
tempmax = 250 #Maximum extrusion temperature
tempmax = 250 # Maximum extrusion temperature
t = int(n*60)/s #Time to wait for extrusion
t = int(n * 60) / s # Time to wait for extrusion
try:
from printdummy import printcore
except ImportError:
from printcore import printcore
import time, getopt, sys, os
import time
import getopt
import sys
import os
def float_input(prompt=''):
import sys
f = None
while f == None:
while f is None:
s = raw_input(prompt)
try:
f = float(s)
......@@ -46,14 +49,13 @@ def float_input(prompt=''):
sys.stderr.flush()
return f
def wait(t, m=''):
import time, sys
sys.stdout.write(m+'['+(' '*t)+']\r'+m+'[')
sys.stdout.write(m + '[' + (' ' * t) + ']\r' + m + '[')
sys.stdout.flush()
for i in range(t):
for s in ['|\b','/\b','-\b','\\\b','|']:
for s in ['|\b', '/\b', '-\b', '\\\b', '|']:
sys.stdout.write(s)
sys.stdout.flush()
time.sleep(1.0/5)
time.sleep(1.0 / 5)
print
def w(s):
sys.stdout.write(s)
......@@ -62,31 +64,31 @@ def w(s):
def heatup(p, temp, s = 0):
curtemp = gettemp(p)
p.send_now('M109 S%03d'%temp)
p.send_now('M109 S%03d' % temp)
p.temp = 0
if not s: w("Heating extruder up..")
f = False
while curtemp<=(temp-1):
while curtemp <= (temp - 1):
p.send_now('M105')
time.sleep(0.5)
if not f:
time.sleep(1.5)
f = True
curtemp = gettemp(p)
if curtemp: w(u"\rHeating extruder up.. %3d \xb0C"%curtemp)
if curtemp: w(u"\rHeating extruder up.. %3d \xb0C" % curtemp)
if s: print
else: print "\nReady."
def gettemp(p):
try: p.logl
except: setattr(p,'logl',0)
except: setattr(p, 'logl', 0)
try: p.temp
except: setattr(p,'temp',0)
except: setattr(p, 'temp', 0)
for n in range(p.logl, len(p.log)):
line = p.log[n]
if 'T:' in line:
try:
setattr(p,'temp',int(line.split('T:')[1].split()[0]))
setattr(p, 'temp', int(line.split('T:')[1].split()[0]))
except: print line
p.logl = len(p.log)
return p.temp
......@@ -101,35 +103,35 @@ help = u"""
-t --temp Extrusion temperature in degrees Celsius (default: %d \xb0C, max %d \xb0C)
-p --port Serial port the printer is connected to (default: %s)
-h --help This cruft.
"""[1:-1].encode('utf-8')%(sys.argv[0], n, k, temp, tempmax, port if port else 'auto')
"""[1:-1].encode('utf-8') % (sys.argv[0], n, k, temp, tempmax, port if port else 'auto')
try:
opts, args = getopt.getopt(sys.argv[1:],"hl:s:t:p:",["help", "length=", "steps=", "temp=", "port="])
opts, args = getopt.getopt(sys.argv[1:], "hl:s:t:p:", ["help", "length=", "steps=", "temp=", "port="])
except getopt.GetoptError, err:
print str(err)
print help
sys.exit(2)
for o, a in opts:
if o in ('-h','--help'):
if o in ('-h', '--help'):
print help
sys.exit()
elif o in ('-l','--length'):
elif o in ('-l', '--length'):
n = float(a)
elif o in ('-s','--steps'):
elif o in ('-s', '--steps'):
k = int(a)
elif o in ('-t','--temp'):
elif o in ('-t', '--temp'):
temp = int(a)
if temp>=tempmax:
print (u'%d \xb0C? Are you insane?'.encode('utf-8')%temp)+(" That's over nine thousand!" if temp>9000 else '')
if temp >= tempmax:
print (u'%d \xb0C? Are you insane?'.encode('utf-8') % temp) + (" That's over nine thousand!" if temp > 9000 else '')
sys.exit(255)
elif o in ('-p','--port'):
elif o in ('-p', '--port'):
port = a
#Show initial parameters
print "Initial parameters"
print "Steps per mm: %3d steps"%k
print "Length extruded: %3d mm"%n
print "Steps per mm: %3d steps" % k
print "Length extruded: %3d mm" % n
print
print "Serial port: %s"%(port if port else 'auto')
print "Serial port: %s" % (port if port else 'auto')
p = None
try:
......@@ -148,18 +150,18 @@ try:
heatup(p, temp)
#Calibration loop
while n!=m:
while n != m:
heatup(p, temp, True)
p.send_now("G92 E0") #Reset e axis
p.send_now("G1 E%d F%d"%(n, s)) #Extrude length of filament
wait(t,'Extruding.. ')
p.send_now("G92 E0") # Reset e axis
p.send_now("G1 E%d F%d" % (n, s)) # Extrude length of filament
wait(t, 'Extruding.. ')
m = float_input("How many millimeters of filament were extruded? ")
if m == 0: continue
if n!=m:
k = (n/m)*k
p.send_now("M92 E%d"%int(round(k))) #Set new step count
print "Steps per mm: %3d steps"%k #Tell user
print 'Calibration completed.' #Yay!
if n != m:
k = (n / m) * k
p.send_now("M92 E%d" % int(round(k))) # Set new step count
print "Steps per mm: %3d steps" % k # Tell user
print 'Calibration completed.' # Yay!
except KeyboardInterrupt:
pass
finally:
......
......@@ -24,7 +24,10 @@ class ExcluderWindow(gviz.GvizWindow):
def __init__(self, excluder, *args, **kwargs):
super(ExcluderWindow, self).__init__(*args, **kwargs)
self.SetTitle(_("Part excluder: draw rectangles where print instructions should be ignored"))
self.toolbar.AddLabelTool(128, " " + _("Reset selection"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset selection"), longHelp = "")
self.toolbar.AddLabelTool(128, " " + _("Reset selection"),
wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
shortHelp = _("Reset selection"),
longHelp = "")
self.Bind(wx.EVT_TOOL, self.reset_selection, id = 128)
self.parent = excluder
self.p.paint_overlay = self.paint_selection
......@@ -39,7 +42,8 @@ class ExcluderWindow(gviz.GvizWindow):
self.p.build_dimensions[1] - (y - self.p.build_dimensions[4]))
def mouse(self, event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT) or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
if event.ButtonUp(wx.MOUSE_BTN_LEFT) \
or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
self.initpos = None
elif event.Dragging() and event.RightIsDown():
e = event.GetPositionTuple()
......@@ -74,11 +78,11 @@ class ExcluderWindow(gviz.GvizWindow):
def _line_scaler(self, orig):
x0, y0 = self.gcode_to_real(orig[0], orig[1])
x0 = self.p.scale[0]*x0 + self.p.translate[0]
y0 = self.p.scale[1]*y0 + self.p.translate[1]
x0 = self.p.scale[0] * x0 + self.p.translate[0]
y0 = self.p.scale[1] * y0 + self.p.translate[1]
x1, y1 = self.gcode_to_real(orig[2], orig[3])
x1 = self.p.scale[0]*x1 + self.p.translate[0]
y1 = self.p.scale[1]*y1 + self.p.translate[1]
x1 = self.p.scale[0] * x1 + self.p.translate[0]
y1 = self.p.scale[1] * y1 + self.p.translate[1]
width = max(x0, x1) - min(x0, x1) + 1
height = max(y0, y1) - min(y0, y1) + 1
return (min(x0, x1), min(y0, y1), width, height,)
......@@ -86,7 +90,8 @@ class ExcluderWindow(gviz.GvizWindow):
def paint_selection(self, dc):
dc = wx.GCDC(dc)
dc.SetPen(wx.TRANSPARENT_PEN)
dc.DrawRectangleList([self._line_scaler(rect) for rect in self.parent.rectangles],
dc.DrawRectangleList([self._line_scaler(rect)
for rect in self.parent.rectangles],
None, wx.Brush((200, 200, 200, 150)))
def reset_selection(self, event):
......@@ -117,6 +122,7 @@ class Excluder(object):
if __name__ == '__main__':
import sys
import gcoder
gcode = gcoder.GCode(open(sys.argv[1]))
app = wx.App(False)
ex = Excluder()
......
......@@ -23,17 +23,18 @@ from array import array
gcode_parsed_args = ["x", "y", "e", "f", "z", "i", "j"]
gcode_parsed_nonargs = ["g", "t", "m", "n"]
to_parse = "".join(gcode_parsed_args + gcode_parsed_nonargs)
gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|([%s])([-+]?[0-9]*\.?[0-9]*)" % to_parse)
m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|([XYZ]):?([-+]?[0-9]*\.?[0-9]*)")
gcode_exp = re.compile("\([^\(\)]*\)|;.*|[/\*].*\n|([%s])([-+]?[0-9]*\.?[0-9]*)" % to_parse)
m114_exp = re.compile("\([^\(\)]*\)|[/\*].*\n|([XYZ]):?([-+]?[0-9]*\.?[0-9]*)")
specific_exp = "(?:\([^\(\)]*\))|(?:;.*)|(?:[/\*].*\n)|(%s[-+]?[0-9]*\.?[0-9]*)"
move_gcodes = ["G0", "G1", "G2", "G3"]
class PyLine(object):
__slots__ = ('x','y','z','e','f','i','j',
__slots__ = ('x', 'y', 'z', 'e', 'f', 'i', 'j',
'raw', 'command', 'is_move',
'relative','relative_e',
'current_x', 'current_y', 'current_z', 'extruding', 'current_tool',
'relative', 'relative_e',
'current_x', 'current_y', 'current_z', 'extruding',
'current_tool',
'gcview_end_vertex')
def __init__(self, l):
......@@ -75,7 +76,7 @@ def parse_coordinates(line, split_raw, imperial = False, force = False):
for bit in split_raw:
code = bit[0]
if code not in gcode_parsed_nonargs and bit[1]:
setattr(line, code, unit_factor*float(bit[1]))
setattr(line, code, unit_factor * float(bit[1]))
class Layer(list):
......@@ -92,14 +93,12 @@ class Layer(list):
xmax = float("-inf")
ymax = float("-inf")
zmax = float("-inf")
relative = False
relative_e = False
for line in self:
if not line.is_move and line.command != "G92":
continue
if line.is_move:
x = line.x
x = line.x
y = line.y
z = line.z
......@@ -107,7 +106,7 @@ class Layer(list):
x = current_x + (x or 0)
y = current_y + (y or 0)
z = current_z + (z or 0)
current_x = x or current_x
current_y = y or current_y
current_z = z or current_z
......@@ -126,12 +125,13 @@ class Layer(list):
else:
current_x = line.x or current_x
current_y = line.y or current_y
current_z = line.z or current_z
current_z = line.z or current_z
line.current_x = current_x
line.current_y = current_y
line.current_z = current_z
return (current_x, current_y, current_z), (xmin, xmax), (ymin, ymax), (zmin, zmax)
return ((current_x, current_y, current_z),
(xmin, xmax), (ymin, ymax), (zmin, zmax))
class GCode(object):
......@@ -161,9 +161,9 @@ class GCode(object):
est_layer_height = None
def __init__(self,data):
def __init__(self, data):
self.lines = [Line(l2) for l2 in
(l.strip() for l in data)
(l.strip() for l in data)
if l2]
self._preprocess_lines()
self.filament_length = self._preprocess_extrusion()
......@@ -190,7 +190,7 @@ class GCode(object):
return gline
def _preprocess_lines(self, lines = None):
"""Checks for G20, G21, G90 and G91, sets imperial and relative flags"""
"""Checks for imperial/relativeness settings and tool changes"""
if not lines:
lines = self.lines
imperial = self.imperial
......@@ -227,16 +227,16 @@ class GCode(object):
self.relative = relative
self.relative_e = relative_e
self.current_tool = current_tool
def _preprocess_extrusion(self, lines = None, cur_e = 0):
if not lines:
lines = self.lines
total_e = 0
max_e = 0
for line in lines:
if line.e == None:
if line.e is None:
continue
if line.is_move:
if line.relative_e:
......@@ -251,7 +251,7 @@ class GCode(object):
cur_e = line.e
return max_e
# FIXME : looks like this needs to be tested with list Z on move
def _create_layers(self):
layers = {}
......@@ -268,23 +268,24 @@ class GCode(object):
cur_z = None
cur_lines = []
for line in self.lines:
if line.command == "G92" and line.z != None:
if line.command == "G92" and line.z is not None:
cur_z = line.z
elif line.is_move:
if line.z != None:
if line.z is not None:
if line.relative:
cur_z += line.z
else:
cur_z = line.z
# FIXME: the logic behind this code seems to work, but it might be broken
# FIXME: the logic behind this code seems to work, but it might be
# broken
if cur_z != prev_z:
if prev_z is not None and last_layer_z is not None:
offset = self.est_layer_height if self.est_layer_height else 0.01
if abs(prev_z - last_layer_z) < offset:
if self.est_layer_height is None:
zs = sorted([l.z for l in all_layers if l.z != None])
heights = [round(zs[i+1] - zs[i], 3) for i in range(len(zs) - 1)]
zs = sorted([l.z for l in all_layers if l.z is not None])
heights = [round(zs[i + 1] - zs[i], 3) for i in range(len(zs) - 1)]
if len(heights) >= 2: self.est_layer_height = heights[1]
elif heights: self.est_layer_height = heights[0]
else: self.est_layer_height = 0.1
......@@ -303,7 +304,7 @@ class GCode(object):
layer_id += 1
layer_line = 0
last_layer_z = base_z
prev_base_z = base_z
cur_lines.append(line)
......@@ -322,7 +323,7 @@ class GCode(object):
cur_lines = layers[zindex]
has_movement = False
for l in layers[zindex]:
if l.is_move and l.e != None:
if l.is_move and l.e is not None:
has_movement = True
break
if has_movement:
......@@ -357,7 +358,8 @@ class GCode(object):
current_z = 0
for l in self.all_layers:
(current_x, current_y, current_z), (xm, xM), (ym, yM), (zm, zM) = l._preprocess(current_x, current_y, current_z)
(current_x, current_y, current_z), (xm, xM), (ym, yM), (zm, zM) = \
l._preprocess(current_x, current_y, current_z)
xmin = min(xm, xmin)
xmax = max(xM, xmax)
ymin = min(ym, ymin)
......@@ -376,18 +378,16 @@ class GCode(object):
self.height = self.zmax - self.zmin
def estimate_duration(self):
lastx = lasty = lastz = laste = lastf = 0.0
x = y = z = e = f = 0.0
lastx = lasty = laste = lastf = 0.0
x = y = e = f = 0.0
currenttravel = 0.0
totaltravel = 0.0
moveduration = 0.0
totalduration = 0.0
acceleration = 1500.0 #mm/s/s ASSUMING THE DEFAULT FROM SPRINTER !!!!
layerduration = 0.0
acceleration = 1500.0 # mm/s/s ASSUMING THE DEFAULT FROM SPRINTER !!!
layerbeginduration = 0.0
layercount = 0
#TODO:
# get device caps from firmware: max speed, acceleration/axis (including extruder)
# get device caps from firmware: max speed, acceleration/axis
# (including extruder)
# calculate the maximum move duration accounting for above ;)
for layer in self.all_layers:
for line in layer:
......@@ -400,19 +400,30 @@ class GCode(object):
else:
moveduration /= 1000.0
else:
x = line.x if line.x != None else lastx
y = line.y if line.y != None else lasty
e = line.e if line.e != None else laste
f = line.f / 60.0 if line.f != None else lastf # mm/s vs mm/m => divide by 60
# given last feedrate and current feedrate calculate the distance needed to achieve current feedrate.
# if travel is longer than req'd distance, then subtract distance to achieve full speed, and add the time it took to get there.
# then calculate the time taken to complete the remaining distance
x = line.x if line.x is not None else lastx
y = line.y if line.y is not None else lasty
e = line.e if line.e is not None else laste
# mm/s vs mm/m => divide by 60
f = line.f / 60.0 if line.f is not None else lastf
# given last feedrate and current feedrate calculate the
# distance needed to achieve current feedrate.
# if travel is longer than req'd distance, then subtract
# distance to achieve full speed, and add the time it took
# to get there.
# then calculate the time taken to complete the remaining
# distance
# FIXME: this code has been proven to be super wrong when 2
# subsquent moves are in opposite directions, as requested
# speed is constant but printer has to fully decellerate
# and reaccelerate
currenttravel = math.hypot(x - lastx, y - lasty)
if currenttravel == 0 and line.e != None:
if currenttravel == 0 and line.e is not None:
currenttravel = abs(line.e) if line.relative_e else abs(line.e - laste)
if f == lastf: # Feedrate hasn't changed, no acceleration/decceleration planned
# Feedrate hasn't changed, no acceleration/decceleration planned
if f == lastf:
moveduration = currenttravel / f if f != 0 else 0.
else:
# FIXME: review this better
......@@ -420,10 +431,10 @@ class GCode(object):
# shouldn't we instead look at three consecutive moves ?
distance = 2 * abs(((lastf + f) * (f - lastf) * 0.5) / acceleration) # multiply by 2 because we have to accelerate and decelerate
if distance <= currenttravel and lastf + f != 0 and f != 0:
moveduration = 2 * distance / (lastf + f) # This is distance / mean(lastf, f)
moveduration = 2 * distance / (lastf + f) # This is distance / mean(lastf, f)
moveduration += (currenttravel - distance) / f
else:
moveduration = 2 * currenttravel / (lastf + f) # This is currenttravel / mean(lastf, f)
moveduration = 2 * currenttravel / (lastf + f) # This is currenttravel / mean(lastf, f)
# FIXME: probably a little bit optimistic, but probably a much better estimate than the previous one:
# moveduration = math.sqrt(2 * distance / acceleration) # probably buggy : not taking actual travel into account
......@@ -437,7 +448,8 @@ class GCode(object):
layer.duration = totalduration - layerbeginduration
layerbeginduration = totalduration
return "%d layers, %s" % (len(self.layers), str(datetime.timedelta(seconds = int(totalduration))))
totaltime = datetime.timedelta(seconds = int(totalduration))
return "%d layers, %s" % (len(self.layers), str(totaltime))
def main():
if len(sys.argv) < 2:
......@@ -445,12 +457,15 @@ def main():
return
print "Line object size:", sys.getsizeof(Line("G0 X0"))
gcode = GCode(open(sys.argv[1]))
gcode = GCode(open(sys.argv[1]))
print "Dimensions:"
print "\tX: %0.02f - %0.02f (%0.02f)" % (gcode.xmin,gcode.xmax,gcode.width)
print "\tY: %0.02f - %0.02f (%0.02f)" % (gcode.ymin,gcode.ymax,gcode.depth)
print "\tZ: %0.02f - %0.02f (%0.02f)" % (gcode.zmin,gcode.zmax,gcode.height)
xdims = (gcode.xmin, gcode.xmax, gcode.width)
print "\tX: %0.02f - %0.02f (%0.02f)" % xdims
ydims = (gcode.ymin, gcode.ymax, gcode.depth)
print "\tY: %0.02f - %0.02f (%0.02f)" % ydims
zdims = (gcode.zmin, gcode.zmax, gcode.height)
print "\tZ: %0.02f - %0.02f (%0.02f)" % zdims
print "Filament used: %0.02fmm" % gcode.filament_length
print "Number of layers: %d" % gcode.num_layers()
print "Estimated duration: %s" % gcode.estimate_duration()
......
......@@ -15,23 +15,17 @@
# 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
from . import gcoder
from .gl.panel import wxGLPanel
from .gl.trackball import trackball, mulquat, build_rotmatrix
from .gl.libtatlin import actors
from pyglet.gl import glPushMatrix, glPopMatrix, \
glTranslatef, glRotatef, glScalef, glMultMatrixd
from .gviz import GvizBaseFrame
from printrun_utils import imagefile, install_locale
......@@ -39,9 +33,10 @@ install_locale('pronterface')
class GcodeViewPanel(wxGLPanel):
def __init__(self, parent, id = wx.ID_ANY, build_dimensions = None, realparent = None):
super(GcodeViewPanel, self).__init__(parent, id, wx.DefaultPosition, wx.DefaultSize, 0)
self.batches = []
def __init__(self, parent, id = wx.ID_ANY,
build_dimensions = None, realparent = None):
super(GcodeViewPanel, self).__init__(parent, id, wx.DefaultPosition,
wx.DefaultSize, 0)
self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.move)
self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.double)
self.canvas.Bind(wx.EVT_KEY_DOWN, self.keypress)
......@@ -73,18 +68,23 @@ class GcodeViewPanel(wxGLPanel):
def draw_objects(self):
'''called in the middle of ondraw after the buffer has been cleared'''
self.create_objects()
glPushMatrix()
if self.orthographic:
glTranslatef(0, 0, -3 * self.dist) # Move back
glTranslatef(0, 0, -3 * self.dist) # Move back
else:
glTranslatef(0, 0, -self.dist) # Move back
glMultMatrixd(build_rotmatrix(self.basequat)) # Rotate according to trackball
glTranslatef(- self.build_dimensions[3] - self.parent.platform.width/2,
- self.build_dimensions[4] - self.parent.platform.depth/2, 0) # Move origin to bottom left of platform
glTranslatef(0, 0, -self.dist) # Move back
# Rotate according to trackball
glMultMatrixd(build_rotmatrix(self.basequat))
# Move origin to bottom left of platform
platformx0 = -self.build_dimensions[3] - self.parent.platform.width / 2
platformy0 = -self.build_dimensions[4] - self.parent.platform.depth / 2
glTranslatef(platformx0, platformy0, 0)
for obj in self.parent.objects:
if not obj.model or not obj.model.loaded or not obj.model.initialized:
if not obj.model \
or not obj.model.loaded \
or not obj.model.initialized:
continue
glPushMatrix()
glTranslatef(*(obj.offsets))
......@@ -100,7 +100,7 @@ class GcodeViewPanel(wxGLPanel):
self.parent.clickcb(event)
def handle_rotation(self, event):
if self.initpos == None:
if self.initpos is None:
self.initpos = event.GetPositionTuple()
else:
p1 = self.initpos
......@@ -194,7 +194,7 @@ class GcodeViewPanel(wxGLPanel):
if delta > 0:
self.zoom(factor, (x, y))
else:
self.zoom(1/factor, (x, y))
self.zoom(1 / factor, (x, y))
def fit(self):
if not self.parent.model or not self.parent.model.loaded:
......@@ -257,18 +257,18 @@ class GCObject(object):
self.rot = 0
self.curlayer = 0.0
self.scale = [1.0, 1.0, 1.0]
self.batch = pyglet.graphics.Batch()
self.model = model
class GcodeViewMainWrapper(object):
def __init__(self, parent, build_dimensions):
self.glpanel = GcodeViewPanel(parent, realparent = self, build_dimensions = build_dimensions)
self.glpanel = GcodeViewPanel(parent, realparent = self,
build_dimensions = build_dimensions)
self.glpanel.SetMinSize((150, 150))
self.clickcb = None
self.widget = self.glpanel
self.refresh_timer = wx.CallLater(100, self.Refresh)
self.p = self # Hack for backwards compatibility with gviz API
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)]
......@@ -306,12 +306,13 @@ class GcodeViewFrame(GvizBaseFrame):
def __init__(self, parent, ID, title, build_dimensions, objects = None,
pos = wx.DefaultPosition, size = wx.DefaultSize,
style = wx.DEFAULT_FRAME_STYLE):
super(GcodeViewFrame, self).__init__(parent, ID, title, pos, size, style)
super(GcodeViewFrame, self).__init__(parent, ID, title,
pos, size, style)
panel, vbox = self.create_base_ui()
self.refresh_timer = wx.CallLater(100, self.Refresh)
self.p = self # Hack for backwards compatibility with gviz API
self.p = self # Hack for backwards compatibility with gviz API
self.clonefrom = objects
self.platform = actors.Platform(build_dimensions)
if objects:
......@@ -320,14 +321,18 @@ class GcodeViewFrame(GvizBaseFrame):
self.model = None
self.objects = [GCObject(self.platform), GCObject(None)]
self.toolbar.AddLabelTool(6, " " + _("Fit to plate"), wx.Image(imagefile('fit.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Fit to plate [F]"), longHelp = '')
fit_image = wx.Image(imagefile('fit.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
self.toolbar.AddLabelTool(6, " " + _("Fit to plate"), fit_image,
shortHelp = _("Fit to plate [F]"),
longHelp = '')
self.toolbar.Realize()
self.glpanel = GcodeViewPanel(panel, build_dimensions = build_dimensions,
self.glpanel = GcodeViewPanel(panel,
build_dimensions = build_dimensions,
realparent = self)
vbox.Add(self.glpanel, 1, flag = wx.EXPAND)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.zoom_to_center(1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.zoom_to_center(1/1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.zoom_to_center(1 / 1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.layerup(), id = 3)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.layerdown(), id = 4)
self.Bind(wx.EVT_TOOL, lambda x: self.glpanel.resetview(), id = 5)
......@@ -367,7 +372,9 @@ if __name__ == "__main__":
import sys
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)
title = 'Gcode view, shift to move view, mousewheel to set layer'
frame = GcodeViewFrame(None, wx.ID_ANY, title, size = (400, 400),
build_dimensions = build_dimensions)
gcode = gcoder.GCode(open(sys.argv[1]))
frame.addfile(gcode)
......@@ -377,14 +384,15 @@ if __name__ == "__main__":
first_move = gcode.lines[i]
break
last_move = None
for i in range(len(gcode.lines)-1,-1,-1):
for i in range(len(gcode.lines) - 1, -1, -1):
if gcode.lines[i].is_move:
last_move = gcode.lines[i]
break
nsteps = 20
steptime = 500
lines = [first_move] + [gcode.lines[int(float(i)*(len(gcode.lines)-1)/nsteps)] for i in range(1, nsteps)] + [last_move]
lines = [first_move] + [gcode.lines[int(float(i) * (len(gcode.lines) - 1) / nsteps)] for i in range(1, nsteps)] + [last_move]
current_line = 0
def setLine():
global current_line
frame.set_current_gline(lines[current_line])
......
......@@ -21,8 +21,13 @@ import numpy
import math
import logging
from pyglet.gl import *
from pyglet import gl
from pyglet.gl import glPushMatrix, glPopMatrix, glTranslatef, \
glGenLists, glNewList, GL_COMPILE, glEndList, glCallList, \
GL_ARRAY_BUFFER, GL_STATIC_DRAW, glColor4f, glVertex3f, glRectf, \
glBegin, glEnd, GL_LINES, glEnable, glDisable, glGetFloatv, \
GL_LINE_SMOOTH, glLineWidth, GL_LINE_WIDTH, GLfloat, GL_FLOAT, \
glVertexPointer, glColorPointer, glDrawArrays, \
glEnableClientState, glDisableClientState, GL_VERTEX_ARRAY, GL_COLOR_ARRAY
from pyglet.graphics.vertexbuffer import create_buffer, VertexBufferObject
from printrun.printrun_utils import install_locale
......@@ -80,13 +85,13 @@ class Platform(object):
self.yoffset = build_dimensions[4]
self.zoffset = build_dimensions[5]
self.color_grads_minor = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.1)
self.color_grads_minor = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.1)
self.color_grads_interm = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.2)
self.color_grads_major = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.33)
self.color_fill = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.05)
self.color_grads_major = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.33)
self.color_fill = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.05)
self.initialized = False
self.loaded = True
self.loaded = True
def init(self):
self.display_list = compile_display_list(self.draw)
......@@ -111,12 +116,12 @@ class Platform(object):
glBegin(GL_LINES)
for i in range(0, int(math.ceil(self.width + 1))):
if color(i):
glVertex3f(float(i), 0.0, 0.0)
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))):
if color(i):
glVertex3f(0, float(i), 0.0)
glVertex3f(0, float(i), 0.0)
glVertex3f(self.width, float(i), 0.0)
glEnd()
......@@ -136,7 +141,7 @@ class PrintHead(object):
self.height = 5
self.initialized = False
self.loaded = True
self.loaded = True
def init(self):
self.display_list = compile_display_list(self.draw)
......@@ -232,7 +237,7 @@ class Model(object):
def movement_angle(src, dst, precision=0):
x = dst[0] - src[0]
y = dst[1] - src[1]
angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle
angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle
return round(angle, precision)
class GcodeModel(Model):
......@@ -253,15 +258,14 @@ class GcodeModel(Model):
def load_data(self, model_data, callback=None):
t_start = time.time()
self.dims = ((model_data.xmin,model_data.xmax,model_data.width),
(model_data.ymin,model_data.ymax,model_data.depth),
(model_data.zmin,model_data.zmax,model_data.height))
self.dims = ((model_data.xmin, model_data.xmax, model_data.width),
(model_data.ymin, model_data.ymax, model_data.depth),
(model_data.zmin, model_data.zmax, model_data.height))
vertex_list = []
color_list = []
vertex_list = []
color_list = []
self.layer_stops = [0]
arrow_list = []
num_layers = len(model_data.all_layers)
num_layers = len(model_data.all_layers)
prev_pos = (0, 0, 0)
for layer_idx, layer in enumerate(model_data.all_layers):
......@@ -284,14 +288,14 @@ class GcodeModel(Model):
callback(layer_idx + 1, num_layers)
self.vertices = numpy.array(vertex_list, dtype = GLfloat)
self.colors = numpy.array(color_list, dtype = GLfloat).repeat(2, 0)
self.colors = numpy.array(color_list, dtype = GLfloat).repeat(2, 0)
self.max_layers = len(self.layer_stops) - 1
self.max_layers = len(self.layer_stops) - 1
self.num_layers_to_draw = self.max_layers
self.printed_until = -1
self.only_current = False
self.initialized = False
self.loaded = True
self.printed_until = -1
self.only_current = False
self.initialized = False
self.loaded = True
t_end = time.time()
......@@ -323,8 +327,8 @@ class GcodeModel(Model):
# ------------------------------------------------------------------------
def init(self):
self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos)
self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color
self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos)
self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color
self.initialized = True
def display(self, mode_2d=False):
......@@ -359,7 +363,7 @@ class GcodeModel(Model):
else:
end_prev_layer = -1
end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)]
glDisableClientState(GL_COLOR_ARRAY)
glColor4f(*self.color_printed)
......@@ -384,14 +388,14 @@ class GcodeModel(Model):
# Draw current layer
if end_prev_layer >= 0:
glDisableClientState(GL_COLOR_ARRAY)
# Backup & increase line width
orig_linewidth = (GLfloat)()
glGetFloatv(GL_LINE_WIDTH, orig_linewidth)
glLineWidth(2.0)
glColor4f(*self.color_current_printed)
if cur_end > end_prev_layer:
glDrawArrays(GL_LINES, end_prev_layer, cur_end - end_prev_layer)
......@@ -413,4 +417,3 @@ class GcodeModel(Model):
self.vertex_buffer.unbind()
self.vertex_color_buffer.unbind()
......@@ -15,9 +15,6 @@
# 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
......@@ -64,7 +61,7 @@ class wxGLPanel(wx.Panel):
def processSizeEvent(self, event):
'''Process the resize event.'''
if (wx.VERSION > (2,9) and self.canvas.IsShownOnScreen()) or self.canvas.GetContext():
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()
......@@ -74,7 +71,7 @@ class wxGLPanel(wx.Panel):
def processPaintEvent(self, event):
'''Process the drawing event.'''
self.canvas.SetCurrent(self.context)
self.OnInitGL()
self.OnDraw()
event.Skip()
......@@ -110,7 +107,7 @@ class wxGLPanel(wx.Panel):
self.OnReshape()
def OnReshape(self):
'''Reshape the OpenGL viewport based on the dimensions of the window.'''
"""Reshape the OpenGL viewport based on the size of the window"""
size = self.GetClientSize()
oldwidth, oldheight = self.width, self.height
width, height = size.width, size.height
......@@ -174,7 +171,8 @@ class wxGLPanel(wx.Panel):
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
# 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)()
......@@ -183,7 +181,7 @@ class wxGLPanel(wx.Panel):
px = (GLdouble)()
py = (GLdouble)()
pz = (GLdouble)()
glGetIntegerv(GL_VIEWPORT, viewport);
glGetIntegerv(GL_VIEWPORT, viewport)
glGetDoublev(GL_PROJECTION_MATRIX, pmat)
glGetDoublev(GL_MODELVIEW_MATRIX, mvmat)
gluUnProject(x, y, z, mvmat, pmat, viewport, px, py, pz)
......
......@@ -17,10 +17,12 @@
import math
from pyglet.gl import *
from pyglet.gl import GLdouble
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]]
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
......@@ -85,6 +87,6 @@ def project_to_sphere(r, x, y):
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]]
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]]
......@@ -15,14 +15,18 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import wx, random
import wx
from math import log10, floor, ceil
from bufferedcanvas import *
from printrun.printrun_utils import install_locale
install_locale('pronterface')
from bufferedcanvas import BufferedCanvas
class GraphWindow(wx.Frame):
def __init__(self, root, size = (600, 600)):
wx.Frame.__init__(self, None, title = _("Temperature graph"), size = size)
super(GraphWindow, self).__init__(None, title = _("Temperature graph"),
size = size)
panel = wx.Panel(self, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
self.graph = Graph(panel, wx.ID_ANY, root)
......@@ -39,27 +43,27 @@ class Graph(BufferedCanvas):
super(Graph, self).__init__(parent, id, pos, size, style)
self.root = root
self.extruder0temps = [0]
self.extruder0temps = [0]
self.extruder0targettemps = [0]
self.extruder1temps = [0]
self.extruder1temps = [0]
self.extruder1targettemps = [0]
self.bedtemps = [0]
self.bedtargettemps = [0]
self.bedtemps = [0]
self.bedtargettemps = [0]
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?
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.ybars = 5
self.xbars = 6 # One bar per 10 second
self.xsteps = 60 # Covering 1 minute in the graph
self.window = None
......@@ -75,10 +79,6 @@ class Graph(BufferedCanvas):
def __del__(self):
if self.window: self.window.Close()
def OnPaint(self, evt):
dc = wx.PaintDC(self)
gc = wx.GraphicsContext.Create(dc)
def updateTemperatures(self, event):
self.AddBedTemperature(self.bedtemps[-1])
self.AddBedTargetTemperature(self.bedtargettemps[-1])
......@@ -91,7 +91,9 @@ class Graph(BufferedCanvas):
self.Refresh()
def drawgrid(self, dc, gc):
#cold, medium, hot = wx.Colour(0, 167, 223), wx.Colour(239, 233, 119), wx.Colour(210, 50.100)
#cold, medium, hot = wx.Colour(0, 167, 223),\
# wx.Colour(239, 233, 119),\
# wx.Colour(210, 50.100)
#col1 = wx.Colour(255, 0, 0, 255)
#col2 = wx.Colour(255, 255, 255, 128)
......@@ -111,26 +113,32 @@ class Graph(BufferedCanvas):
# draw vertical bars
dc.SetPen(wx.Pen(wx.Colour(225, 225, 225), 1))
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)
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
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 xrange(firstbar,firstbar+ybars+1):
for y in range(firstbar, firstbar + ybars + 1):
#y_pos = y*(float(self.height)/self.ybars)
degrees = y*spacing
degrees = y * spacing
y_pos = self._y_pos(degrees)
dc.DrawLine(0, y_pos, self.width, y_pos)
gc.DrawText(unicode(y*spacing), 1, y_pos - (font.GetPointSize() / 2))
gc.DrawText(unicode(y * spacing),
1, y_pos - (font.GetPointSize() / 2))
if self.timer.IsRunning() == False:
if self.timer.IsRunning() is False:
font = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD)
gc.SetFont(font, wx.Colour(3, 4, 4))
gc.DrawText("Graph offline", self.width/2 - (font.GetPointSize() * 3), self.height/2 - (font.GetPointSize() * 1))
gc.DrawText("Graph offline",
self.width / 2 - (font.GetPointSize() * 3),
self.height / 2 - (font.GetPointSize() * 1))
#dc.DrawCircle(50, 50, 1)
......@@ -138,47 +146,49 @@ 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):
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) )
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) )
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
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)
return 10 ** (exponent + 1)
def drawtemperature(self, dc, gc, temperature_list, text, text_xoffset, r, g, b, a):
if self.timer.IsRunning() == False:
def drawtemperature(self, dc, gc, temperature_list,
text, text_xoffset, r, g, b, a):
if self.timer.IsRunning() is False:
dc.SetPen(wx.Pen(wx.Colour(128, 128, 128, 128), 1))
else:
dc.SetPen(wx.Pen(wx.Colour(r, g, b, a), 1))
x_add = float(self.width)/self.xsteps
x_add = float(self.width) / self.xsteps
x_pos = 0.0
lastxvalue = 0.0
lastyvalue = temperature_list[-1]
for temperature in (temperature_list):
y_pos = self._y_pos(temperature)
if (x_pos > 0.0): # One need 2 points to draw a line.
if (x_pos > 0.0): # One need 2 points to draw a line.
dc.DrawLine(lastxvalue, lastyvalue, x_pos, y_pos)
lastxvalue = x_pos
......@@ -188,34 +198,39 @@ class Graph(BufferedCanvas):
if len(text) > 0:
font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD)
#font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
if self.timer.IsRunning() == False:
if self.timer.IsRunning() is False:
gc.SetFont(font, wx.Colour(128, 128, 128))
else:
gc.SetFont(font, wx.Colour(r, g, b))
gc.DrawText(text, x_pos - x_add - (font.GetPointSize() * ((len(text) * text_xoffset + 1))), lastyvalue - (font.GetPointSize() / 2))
text_size = len(text) * text_xoffset + 1
gc.DrawText(text,
x_pos - x_add - (font.GetPointSize() * text_size),
lastyvalue - (font.GetPointSize() / 2))
def drawbedtemp(self, dc, gc):
self.drawtemperature(dc, gc, self.bedtemps, "Bed", 2, 255, 0, 0, 128)
self.drawtemperature(dc, gc, self.bedtemps,
"Bed", 2, 255, 0, 0, 128)
def drawbedtargettemp(self, dc, gc):
self.drawtemperature(dc, gc, self.bedtargettemps, "Bed Target", 2, 255, 120, 0, 128)
self.drawtemperature(dc, gc, self.bedtargettemps,
"Bed Target", 2, 255, 120, 0, 128)
def drawextruder0temp(self, dc, gc):
self.drawtemperature(dc, gc, self.extruder0temps, "Ex0", 1, 0, 155, 255, 128)
self.drawtemperature(dc, gc, self.extruder0temps,
"Ex0", 1, 0, 155, 255, 128)
def drawextruder0targettemp(self, dc, gc):
self.drawtemperature(dc, gc, self.extruder0targettemps, "Ex0 Target", 2, 0, 5, 255, 128)
self.drawtemperature(dc, gc, self.extruder0targettemps,
"Ex0 Target", 2, 0, 5, 255, 128)
def drawextruder1temp(self, dc, gc):
self.drawtemperature(dc, gc, self.extruder1temps, "Ex1", 3, 55, 55, 0, 128)
self.drawtemperature(dc, gc, self.extruder1temps,
"Ex1", 3, 55, 55, 0, 128)
def drawextruder1targettemp(self, dc, gc):
self.drawtemperature(dc, gc, self.extruder1targettemps, "Ex1 Target", 2, 55, 55, 0, 128)
self.drawtemperature(dc, gc, self.extruder1targettemps,
"Ex1 Target", 2, 55, 55, 0, 128)
def SetBedTemperature(self, value):
self.bedtemps.pop()
......@@ -224,7 +239,7 @@ class Graph(BufferedCanvas):
def AddBedTemperature(self, value):
self.bedtemps.append(value)
if (len(self.bedtemps)-1) * float(self.width)/self.xsteps > self.width:
if float(len(self.bedtemps) - 1) / self.xsteps > 1:
self.bedtemps.pop(0)
def SetBedTargetTemperature(self, value):
......@@ -234,7 +249,7 @@ class Graph(BufferedCanvas):
def AddBedTargetTemperature(self, value):
self.bedtargettemps.append(value)
if (len(self.bedtargettemps)-1) * float(self.width)/self.xsteps > self.width:
if float(len(self.bedtargettemps) - 1) / self.xsteps > 1:
self.bedtargettemps.pop(0)
def SetExtruder0Temperature(self, value):
......@@ -244,7 +259,7 @@ class Graph(BufferedCanvas):
def AddExtruder0Temperature(self, value):
self.extruder0temps.append(value)
if (len(self.extruder0temps)-1) * float(self.width)/self.xsteps > self.width:
if float(len(self.extruder0temps) - 1) / self.xsteps > 1:
self.extruder0temps.pop(0)
def SetExtruder0TargetTemperature(self, value):
......@@ -254,7 +269,7 @@ class Graph(BufferedCanvas):
def AddExtruder0TargetTemperature(self, value):
self.extruder0targettemps.append(value)
if (len(self.extruder0targettemps)-1) * float(self.width)/self.xsteps > self.width:
if float(len(self.extruder0targettemps) - 1) / self.xsteps > 1:
self.extruder0targettemps.pop(0)
def SetExtruder1Temperature(self, value):
......@@ -264,7 +279,7 @@ class Graph(BufferedCanvas):
def AddExtruder1Temperature(self, value):
self.extruder1temps.append(value)
if (len(self.extruder1temps)-1) * float(self.width)/self.xsteps > self.width:
if float(len(self.extruder1temps) - 1) / self.xsteps > 1:
self.extruder1temps.pop(0)
def SetExtruder1TargetTemperature(self, value):
......@@ -274,7 +289,7 @@ class Graph(BufferedCanvas):
def AddExtruder1TargetTemperature(self, value):
self.extruder1targettemps.append(value)
if (len(self.extruder1targettemps)-1) * float(self.width)/self.xsteps > self.width:
if float(len(self.extruder1targettemps) - 1) / self.xsteps > 1:
self.extruder1targettemps.pop(0)
def StartPlotting(self, time):
......@@ -304,7 +319,7 @@ class Graph(BufferedCanvas):
class _YBounds(object):
"""Small helper class to claculate y bounds dynamically"""
def __init__(self, graph, minimum_scale=5.0,buffer=0.10):
def __init__(self, graph, minimum_scale=5.0, buffer=0.10):
"""_YBounds(Graph,float,float)
graph parent object to calculate scales for
......@@ -320,18 +335,21 @@ class Graph(BufferedCanvas):
# Frequency to rescale the graph
self.update_freq = 10
self._last_update = self.update_freq #number of updates since last full refresh
#number of updates since last full refresh
self._last_update = self.update_freq
def update(self,forceUpdate=False):
"""Updates graph.minyvalue and graph.maxyvalue based on current temperatures
"""
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
# 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()
bounds = self.getBoundsQuick()
self.graph.minyvalue, self.graph.maxyvalue = bounds
def getBounds(self):
"""
......@@ -339,7 +357,8 @@ class Graph(BufferedCanvas):
Rules:
* Include the full extruder0 history
* Include the current target temp (but not necessarily old settings)
* 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
......@@ -358,23 +377,23 @@ class Graph(BufferedCanvas):
miny = min(extruder0_min, extruder0_target)
maxy = max(extruder0_max, extruder0_target)
if extruder1_target > 0 or extruder1_max > 5: #use extruder1
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
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)
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
if maxy - miny < self.min_scale:
extrapadding = (self.min_scale - maxy + miny) / 2.0
miny -= extrapadding
maxy += extrapadding
return (miny,maxy)
return (miny, maxy)
def getBoundsQuick(self):
# Only look at current temps
......@@ -390,20 +409,21 @@ class Graph(BufferedCanvas):
miny = min(extruder0_min, extruder0_target)
maxy = max(extruder0_max, extruder0_target)
if extruder1_target > 0 or extruder1_max > 5: #use extruder1
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
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
bufratio = self.buffer / (1.0 - self.buffer)
if miny < self.graph.minyvalue:
padding = (self.graph.maxyvalue-miny)*self.buffer/(1.0-self.buffer)
padding = (self.graph.maxyvalue - miny) * bufratio
miny -= padding
if maxy > self.graph.maxyvalue:
padding = (maxy-self.graph.minyvalue)*self.buffer/(1.0-self.buffer)
padding = (maxy - self.graph.minyvalue) * bufratio
maxy += padding
return min(miny,self.graph.minyvalue),max(maxy,self.graph.maxyvalue)
return (min(miny, self.graph.minyvalue),
max(maxy, self.graph.maxyvalue))
......@@ -67,7 +67,7 @@ class XYZControlsSizer(wx.GridBagSizer):
def add_extra_controls(self, root, parentpanel, extra_buttons = None):
standalone_mode = extra_buttons is not None
base_line = 1 if standalone_mode else 2
root.monitorbox = wx.CheckBox(parentpanel,-1, _("Watch"))
root.monitorbox = wx.CheckBox(parentpanel, -1, _("Watch"))
root.monitorbox.SetValue(bool(root.settings.monitor))
root.monitorbox.SetToolTip(wx.ToolTip("Monitor Temperatures in Graph"))
if standalone_mode:
......@@ -76,17 +76,17 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
self.Add(root.monitorbox, pos = (base_line + 1, 5))
root.monitorbox.Bind(wx.EVT_CHECKBOX, root.setmonitor)
self.Add(wx.StaticText(parentpanel,-1, _("Heat:")), pos = (base_line + 0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
htemp_choices = [root.temps[i]+" ("+i+")" for i in sorted(root.temps.keys(), key = lambda x:root.temps[x])]
self.Add(wx.StaticText(parentpanel, -1, _("Heat:")), pos = (base_line + 0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
htemp_choices = [root.temps[i] + " (" + i + ")" for i in sorted(root.temps.keys(), key = lambda x:root.temps[x])]
root.settoff = make_button(parentpanel, _("Off"), lambda e: root.do_settemp("off"), _("Switch Hotend Off"), size = (38,-1), style = wx.BU_EXACTFIT)
root.settoff = make_button(parentpanel, _("Off"), lambda e: root.do_settemp("off"), _("Switch Hotend Off"), size = (38, -1), style = wx.BU_EXACTFIT)
root.printerControls.append(root.settoff)
self.Add(root.settoff, pos = (base_line + 0, 2), span = (1, 1))
if root.settings.last_temperature not in map(float, root.temps.values()):
htemp_choices = [str(root.settings.last_temperature)] + htemp_choices
root.htemp = wx.ComboBox(parentpanel, -1,
choices = htemp_choices, style = wx.CB_DROPDOWN, size = (80,-1))
root.htemp = wx.ComboBox(parentpanel, -1, choices = htemp_choices,
style = wx.CB_DROPDOWN, size = (80, -1))
root.htemp.SetToolTip(wx.ToolTip("Select Temperature for Hotend"))
root.htemp.Bind(wx.EVT_COMBOBOX, root.htemp_change)
......@@ -95,17 +95,17 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
root.printerControls.append(root.settbtn)
self.Add(root.settbtn, pos = (base_line + 0, 4), span = (1, 1))
self.Add(wx.StaticText(parentpanel,-1, _("Bed:")), pos = (base_line + 1, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
btemp_choices = [root.bedtemps[i]+" ("+i+")" for i in sorted(root.bedtemps.keys(), key = lambda x:root.temps[x])]
self.Add(wx.StaticText(parentpanel, -1, _("Bed:")), pos = (base_line + 1, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
btemp_choices = [root.bedtemps[i] + " (" + i + ")" for i in sorted(root.bedtemps.keys(), key = lambda x:root.temps[x])]
root.setboff = make_button(parentpanel, _("Off"), lambda e:root.do_bedtemp("off"), _("Switch Heated Bed Off"), size = (38,-1), style = wx.BU_EXACTFIT)
root.setboff = make_button(parentpanel, _("Off"), lambda e: root.do_bedtemp("off"), _("Switch Heated Bed Off"), size = (38, -1), style = wx.BU_EXACTFIT)
root.printerControls.append(root.setboff)
self.Add(root.setboff, pos = (base_line + 1, 2), span = (1, 1))
if root.settings.last_bed_temperature not in map(float, root.bedtemps.values()):
btemp_choices = [str(root.settings.last_bed_temperature)] + btemp_choices
root.btemp = wx.ComboBox(parentpanel, -1,
choices = btemp_choices, style = wx.CB_DROPDOWN, size = (80,-1))
root.btemp = wx.ComboBox(parentpanel, -1, choices = btemp_choices,
style = wx.CB_DROPDOWN, size = (80, -1))
root.btemp.SetToolTip(wx.ToolTip("Select Temperature for Heated Bed"))
root.btemp.Bind(wx.EVT_COMBOBOX, root.btemp_change)
self.Add(root.btemp, pos = (base_line + 1, 3), span = (1, 1))
......@@ -125,16 +125,16 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
if i.split()[0] == str(root.settings.last_bed_temperature).split('.')[0] or i.split()[0] == str(root.settings.last_bed_temperature):
root.btemp.SetValue(i)
for i in htemp_choices:
if i.split()[0] == str(root.settings.last_temperature).split('.')[0] or i.split()[0] == str(root.settings.last_temperature) :
if i.split()[0] == str(root.settings.last_temperature).split('.')[0] or i.split()[0] == str(root.settings.last_temperature):
root.htemp.SetValue(i)
if( '(' not in root.btemp.Value):
if '(' not in root.btemp.Value:
root.btemp.SetValue(root.btemp.Value + ' (user)')
if( '(' not in root.htemp.Value):
if '(' not in root.htemp.Value:
root.htemp.SetValue(root.htemp.Value + ' (user)')
root.tempdisp = wx.StaticText(parentpanel,-1, "")
root.tempdisp = wx.StaticText(parentpanel, -1, "")
if not extra_buttons:
ebuttonspanel = root.newPanel(parentpanel)
ebuttonssizer = wx.BoxSizer(wx.HORIZONTAL)
......@@ -143,13 +143,13 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
esettingspanel = root.newPanel(parentpanel)
esettingssizer = wx.BoxSizer(wx.HORIZONTAL)
root.edist = wx.SpinCtrl(esettingspanel,-1, "5", min = 0, max = 1000, size = (70,-1))
root.edist = wx.SpinCtrl(esettingspanel, -1, "5", min = 0, max = 1000, size = (70, -1))
root.edist.SetBackgroundColour((225, 200, 200))
root.edist.SetForegroundColour("black")
esettingssizer.Add(root.edist, flag = wx.ALIGN_CENTER | wx.RIGHT, border = 5)
esettingssizer.Add(wx.StaticText(esettingspanel, -1, _("mm @")), flag = wx.ALIGN_CENTER | wx.RIGHT, border = 5)
root.edist.SetToolTip(wx.ToolTip("Amount to Extrude or Retract (mm)"))
root.efeedc = wx.SpinCtrl(esettingspanel,-1, str(root.settings.e_feedrate), min = 0, max = 50000, size = (70,-1))
root.efeedc = wx.SpinCtrl(esettingspanel, -1, str(root.settings.e_feedrate), min = 0, max = 50000, size = (70, -1))
root.efeedc.SetToolTip(wx.ToolTip("Extrude / Retract speed (mm/min)"))
root.efeedc.SetBackgroundColour((225, 200, 200))
root.efeedc.SetForegroundColour("black")
......@@ -166,12 +166,14 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
self.Add(root.hottgauge, pos = (gauges_base_line + 0, 0), span = (1, 6), flag = wx.EXPAND)
root.bedtgauge = TempGauge(parentpanel, size = (-1, 24), title = _("Bed:"), maxval = 150)
self.Add(root.bedtgauge, pos = (gauges_base_line + 1, 0), span = (1, 6), flag = wx.EXPAND)
def hotendgauge_scroll_setpoint(e):
rot = e.GetWheelRotation()
if rot > 0:
root.do_settemp(str(root.hsetpoint + 1))
elif rot < 0:
root.do_settemp(str(max(0, root.hsetpoint - 1)))
def bedgauge_scroll_setpoint(e):
rot = e.GetWheelRotation()
if rot > 0:
......@@ -193,16 +195,14 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
root.graph.Bind(wx.EVT_LEFT_DOWN, root.graph.showwin)
if extra_buttons:
pos_mapping = {
(2,5):(0,0),
(4,0):(3,0),
(4,2):(3,2),
}
span_mapping = {
(2,5):(1,3),
(4,0):(1,2),
(4,2):(1,3),
}
pos_mapping = {(2, 5): (0, 0),
(4, 0): (3, 0),
(4, 2): (3, 2),
}
span_mapping = {(2, 5): (1, 3),
(4, 0): (1, 2),
(4, 2): (1, 3),
}
for i in extra_buttons:
btn = extra_buttons[i]
self.Add(btn, pos = pos_mapping[i.pos], span = span_mapping[i.pos], flag = wx.EXPAND)
......@@ -222,14 +222,13 @@ class LeftPane(wx.GridBagSizer):
self.Add(llts, pos = (0, 0), span = (1, 6))
self.xyzsizer = XYZControlsSizer(root, parentpanel)
self.Add(self.xyzsizer, pos = (1, 0), span = (1, 6), flag = wx.ALIGN_CENTER)
self.extra_buttons = {}
ebuttons = []
for i in root.cpbuttons:
if not standalone_mode and i.pos and i.pos[0] == 4:
continue
btn = make_custom_button(root, parentpanel, i)
if i.pos == None:
if i.pos is None:
if i.span == 0:
llts.Add(btn)
elif not standalone_mode:
......@@ -237,12 +236,12 @@ class LeftPane(wx.GridBagSizer):
else:
self.extra_buttons[i] = btn
root.xyfeedc = wx.SpinCtrl(parentpanel,-1, str(root.settings.xy_feedrate), min = 0, max = 50000, size = (70,-1))
root.xyfeedc = wx.SpinCtrl(parentpanel, -1, str(root.settings.xy_feedrate), min = 0, max = 50000, size = (70, -1))
root.xyfeedc.SetToolTip(wx.ToolTip("Set Maximum Speed for X & Y axes (mm/min)"))
llts.Add(wx.StaticText(parentpanel,-1, _("XY:")), flag = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
llts.Add(wx.StaticText(parentpanel, -1, _("XY:")), flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
llts.Add(root.xyfeedc)
llts.Add(wx.StaticText(parentpanel,-1, _("mm/min Z:")), flag = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
root.zfeedc = wx.SpinCtrl(parentpanel,-1, str(root.settings.z_feedrate), min = 0, max = 50000, size = (70,-1))
llts.Add(wx.StaticText(parentpanel, -1, _("mm/min Z:")), flag = wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
root.zfeedc = wx.SpinCtrl(parentpanel, -1, str(root.settings.z_feedrate), min = 0, max = 50000, size = (70, -1))
root.zfeedc.SetToolTip(wx.ToolTip("Set Maximum Speed for Z axis (mm/min)"))
llts.Add(root.zfeedc,)
......@@ -262,12 +261,16 @@ class NoViz(object):
def clear(self, *a):
pass
def addfile(self, *a, **kw):
pass
def addgcode(self, *a, **kw):
pass
def Refresh(self, *a):
pass
def setlayer(self, *a):
pass
......@@ -291,10 +294,10 @@ class VizPane(wx.BoxSizer):
traceback.print_exc()
if use2dview:
root.gviz = gviz.Gviz(parentpanel, (300, 300),
build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gviz.SetToolTip(wx.ToolTip("Click to examine / edit\n layers of loaded file"))
root.gviz.showall = 1
root.gviz.Bind(wx.EVT_LEFT_DOWN, root.showwin)
......@@ -312,11 +315,10 @@ class VizPane(wx.BoxSizer):
print "Falling back to 2D view, and here is the backtrace:"
traceback.print_exc()
if not use3dview:
root.gwindow = gviz.GvizWindow(
build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gwindow = gviz.GvizWindow(build_dimensions = root.build_dimensions_list,
grid = (root.settings.preview_grid_step1, root.settings.preview_grid_step2),
extrusion_width = root.settings.preview_extrusion_width,
bgcolor = root.settings.bgcolor)
root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide())
if not isinstance(root.gviz, NoViz):
self.Add(root.gviz.widget, 1, flag = wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL)
......@@ -326,8 +328,8 @@ class LogPane(wx.BoxSizer):
def __init__(self, root, parentpanel = None):
super(LogPane, self).__init__(wx.VERTICAL)
if not parentpanel: parentpanel = root.panel
root.logbox = wx.TextCtrl(parentpanel, style = wx.TE_MULTILINE, size = (350,-1))
root.logbox.SetMinSize((100,-1))
root.logbox = wx.TextCtrl(parentpanel, style = wx.TE_MULTILINE, size = (350, -1))
root.logbox.SetMinSize((100, -1))
root.logbox.SetEditable(0)
self.Add(root.logbox, 1, wx.EXPAND)
lbrs = wx.BoxSizer(wx.HORIZONTAL)
......@@ -351,26 +353,25 @@ def MainToolbar(root, parentpanel = None, use_wrapsizer = False):
root.locker.Bind(wx.EVT_CHECKBOX, root.lock)
root.locker.SetToolTip(wx.ToolTip(_("Lock graphical interface")))
glob = wx.BoxSizer(wx.HORIZONTAL)
origpanel = parentpanel
parentpanel = root.newPanel(parentpanel)
glob.Add(parentpanel, 1, flag = wx.EXPAND)
glob.Add(root.locker, 0)
glob.Add(root.locker, 0)
ToolbarSizer = wx.WrapSizer if use_wrapsizer and wx.VERSION > (2, 9) else wx.BoxSizer
self = ToolbarSizer(wx.HORIZONTAL)
root.rescanbtn = make_sized_button(parentpanel, _("Port"), root.rescanports, _("Communication Settings\nClick to rescan ports"))
self.Add(root.rescanbtn, 0, wx.TOP|wx.LEFT, 0)
self.Add(root.rescanbtn, 0, wx.TOP | wx.LEFT, 0)
root.serialport = wx.ComboBox(parentpanel, -1,
choices = root.scanserial(),
style = wx.CB_DROPDOWN, size = (-1, 25))
root.serialport = wx.ComboBox(parentpanel, -1, choices = root.scanserial(),
style = wx.CB_DROPDOWN, size = (-1, 25))
root.serialport.SetToolTip(wx.ToolTip("Select Port Printer is connected to"))
root.rescanports()
self.Add(root.serialport)
self.Add(wx.StaticText(parentpanel,-1, "@"), 0, wx.RIGHT|wx.ALIGN_CENTER, 0)
self.Add(wx.StaticText(parentpanel, -1, "@"), 0, wx.RIGHT | wx.ALIGN_CENTER, 0)
root.baud = wx.ComboBox(parentpanel, -1,
choices = ["2400", "9600", "19200", "38400", "57600", "115200", "250000"],
style = wx.CB_DROPDOWN, size = (100, 25))
choices = ["2400", "9600", "19200", "38400",
"57600", "115200", "250000"],
style = wx.CB_DROPDOWN, size = (100, 25))
root.baud.SetToolTip(wx.ToolTip("Select Baud rate for printer communication"))
try:
root.baud.SetValue("115200")
......@@ -396,7 +397,7 @@ def MainToolbar(root, parentpanel = None, use_wrapsizer = False):
return self
class MainWindow(wx.Frame):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
# this list will contain all controls that should be only enabled
......@@ -438,9 +439,9 @@ class MainWindow(wx.Frame):
self.mainsizer_page1.Add(page1panel2, 1)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.splitterwindow = wx.SplitterWindow(page2panel, style = wx.SP_3D)
page2sizer1 = wx.BoxSizer(wx.HORIZONTAL)
page2sizer1 = wx.BoxSizer(wx.HORIZONTAL)
page2panel1 = self.newPanel(self.splitterwindow)
page2sizer2 = wx.BoxSizer(wx.HORIZONTAL)
page2sizer2 = wx.BoxSizer(wx.HORIZONTAL)
page2panel2 = self.newPanel(self.splitterwindow)
vizpane = VizPane(self, page2panel1)
page2sizer1.Add(vizpane, 1, wx.EXPAND)
......@@ -477,9 +478,9 @@ class MainWindow(wx.Frame):
i.Disable()
self.cbuttons_reload()
minsize = self.lowersizer.GetMinSize() # lower pane
minsize = self.lowersizer.GetMinSize() # lower pane
minsize[1] = self.notebook.GetSize()[1]
self.SetMinSize(self.ClientToWindowSize(minsize)) # client to window
self.SetMinSize(self.ClientToWindowSize(minsize)) # client to window
self.Fit()
def createGui(self, compact = False):
......@@ -491,7 +492,7 @@ class MainWindow(wx.Frame):
upperpanel.SetSizer(self.uppersizer)
lowerpanel.SetSizer(self.lowersizer)
left_pane = LeftPane(self, lowerpanel)
left_pane.Layout() # required to get correct rows/cols counts
left_pane.Layout() # required to get correct rows/cols counts
left_sizer = wx.BoxSizer(wx.VERTICAL)
left_sizer.Add(left_pane, 0)
self.lowersizer.Add(left_sizer, 0, wx.EXPAND)
......@@ -524,9 +525,9 @@ class MainWindow(wx.Frame):
# This prevents resizing below a reasonnable value
# We sum the lowersizer (left pane / viz / log) min size
# the toolbar height and the statusbar/menubar sizes
minsize = self.lowersizer.GetMinSize() # lower pane
minsize[1] += self.uppersizer.GetMinSize()[1] # toolbar height
self.SetMinSize(self.ClientToWindowSize(minsize)) # client to window
minsize = self.lowersizer.GetMinSize() # lower pane
minsize[1] += self.uppersizer.GetMinSize()[1] # toolbar height
self.SetMinSize(self.ClientToWindowSize(minsize)) # client to window
# disable all printer controls until we connect to a printer
self.pausebtn.Disable()
......
......@@ -15,7 +15,7 @@
from Queue import Queue
from collections import deque
import wx, time
import wx
from printrun import gcoder
from printrun_utils import imagefile, install_locale
......@@ -41,9 +41,9 @@ class GvizBaseFrame(wx.Frame):
self.toolbar.AddSimpleTool(3, wx.Image(imagefile('arrow_up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Up a Layer [U]"), '')
self.toolbar.AddSimpleTool(4, wx.Image(imagefile('arrow_down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Move Down a Layer [D]"), '')
self.toolbar.AddLabelTool(5, " " + _("Reset view"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset view"), longHelp = '')
vbox.Add(self.toolbar, 0, border = 5)
panel.SetSizer(vbox)
hbox.Add(panel, 1, flag = wx.EXPAND)
......@@ -65,7 +65,7 @@ ID_EXIT = 110
class GvizWindow(GvizBaseFrame):
def __init__(self, f = None, size = (600, 600), build_dimensions = [200, 200, 100, 0, 0, 0], grid = (10, 50), extrusion_width = 0.5, bgcolor = "#000000"):
super(GvizWindow, self).__init__(None, title = _("Gcode view, shift to move view, mousewheel to set layer"), size = size)
panel, vbox = self.create_base_ui()
self.p = Gviz(panel, size = size, build_dimensions = build_dimensions, grid = grid, extrusion_width = extrusion_width, bgcolor = bgcolor, realparent = self)
......@@ -74,12 +74,12 @@ class GvizWindow(GvizBaseFrame):
#self.toolbar.AddSimpleTool(6, wx.Image(imagefile('inject.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), _("Insert Code at start of this layer"), '')
self.toolbar.Realize()
vbox.Add(self.p, 1, wx.EXPAND)
self.SetMinSize(self.ClientToWindowSize(vbox.GetMinSize()))
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(-1, -1, 1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x:self.p.zoom(-1, -1, 1/1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x:self.p.layerup(), id = 3)
self.Bind(wx.EVT_TOOL, lambda x:self.p.layerdown(), id = 4)
self.Bind(wx.EVT_TOOL, lambda x: self.p.zoom(-1, -1, 1.2), id = 1)
self.Bind(wx.EVT_TOOL, lambda x: self.p.zoom(-1, -1, 1 / 1.2), id = 2)
self.Bind(wx.EVT_TOOL, lambda x: self.p.layerup(), id = 3)
self.Bind(wx.EVT_TOOL, lambda x: self.p.layerdown(), id = 4)
self.Bind(wx.EVT_TOOL, self.resetview, id = 5)
#self.Bind(wx.EVT_TOOL, lambda x:self.p.inject(), id = 6)
......@@ -140,23 +140,25 @@ class GvizWindow(GvizBaseFrame):
if x in kzi:
self.p.zoom(cx, cy, 1.2)
if x in kzo:
self.p.zoom(cx, cy, 1/1.2)
self.p.zoom(cx, cy, 1 / 1.2)
def zoom(self, event):
z = event.GetWheelRotation()
if event.ShiftDown():
if z > 0: self.p.layerdown()
if z > 0: self.p.layerdown()
elif z < 0: self.p.layerup()
else:
if z > 0: self.p.zoom(event.GetX(), event.GetY(), 1.2)
elif z < 0: self.p.zoom(event.GetX(), event.GetY(), 1/1.2)
if z > 0: self.p.zoom(event.GetX(), event.GetY(), 1.2)
elif z < 0: self.p.zoom(event.GetX(), event.GetY(), 1 / 1.2)
class Gviz(wx.Panel):
# Mark canvas as dirty when setting showall
_showall = 0
def _get_showall(self):
return self._showall
def _set_showall(self, showall):
if showall != self._showall:
self.dirty = 1
......@@ -168,7 +170,7 @@ class Gviz(wx.Panel):
self.widget = self
size = [max(1.0, x) for x in size]
ratio = size[0] / size[1]
self.SetMinSize((150, 150/ratio))
self.SetMinSize((150, 150 / ratio))
self.parent = realparent if realparent else parent
self.size = size
self.build_dimensions = build_dimensions
......@@ -183,17 +185,17 @@ class Gviz(wx.Panel):
self.arcpens = {}
self.layers = []
self.layerindex = 0
self.filament_width = extrusion_width # set it to 0 to disable scaling lines with zoom
self.filament_width = extrusion_width # set it to 0 to disable scaling lines with zoom
self.update_basescale()
self.scale = self.basescale
penwidth = max(1.0, self.filament_width*((self.scale[0]+self.scale[1])/2.0))
penwidth = max(1.0, self.filament_width * ((self.scale[0] + self.scale[1]) / 2.0))
self.translate = [0.0, 0.0]
self.mainpen = wx.Pen(wx.Colour(0, 0, 0), penwidth)
self.arcpen = wx.Pen(wx.Colour(255, 0, 0), penwidth)
self.travelpen = wx.Pen(wx.Colour(10, 80, 80), penwidth)
self.hlpen = wx.Pen(wx.Colour(200, 50, 50), penwidth)
self.fades = [wx.Pen(wx.Colour(250-0.6**i*100, 250-0.6**i*100, 200-0.4**i*50), penwidth) for i in xrange(6)]
self.penslist = [self.mainpen, self.travelpen, self.hlpen]+self.fades
self.fades = [wx.Pen(wx.Colour(250 - 0.6 ** i * 100, 250 - 0.6 ** i * 100, 200 - 0.4 ** i * 50), penwidth) for i in xrange(6)]
self.penslist = [self.mainpen, self.travelpen, self.hlpen] + self.fades
self.showall = 0
self.hilight = deque()
self.hilightarcs = deque()
......@@ -207,8 +209,8 @@ class Gviz(wx.Panel):
def inject(self):
#import pdb; pdb.set_trace()
print"Inject code here..."
print "Layer "+str(self.layerindex +1)+" - Z = "+str(self.layers[self.layerindex])+" mm"
print "Inject code here..."
print "Layer " + str(self.layerindex + 1) + " - Z = " + str(self.layers[self.layerindex]) + " mm"
def clearhilights(self):
self.hilight.clear()
......@@ -255,11 +257,11 @@ class Gviz(wx.Panel):
wx.CallAfter(self.Refresh)
def update_basescale(self):
self.basescale = 2*[min(float(self.size[0] - 1)/self.build_dimensions[0],
float(self.size[1] - 1)/self.build_dimensions[1])]
self.basescale = 2 * [min(float(self.size[0] - 1) / self.build_dimensions[0],
float(self.size[1] - 1) / self.build_dimensions[1])]
def resize(self, event):
old_basescale = self.basescale
old_basescale = self.basescale
self.size = self.GetClientSizeTuple()
self.update_basescale()
zoomratio = float(self.basescale[0]) / old_basescale[0]
......@@ -273,25 +275,25 @@ class Gviz(wx.Panel):
self.translate = [x - (x - self.translate[0]) * factor,
y - (y - self.translate[1]) * factor]
penwidth = max(1.0, self.filament_width*((self.scale[0]+self.scale[1])/2.0))
penwidth = max(1.0, self.filament_width * ((self.scale[0] + self.scale[1]) / 2.0))
for pen in self.penslist:
pen.SetWidth(penwidth)
self.dirty = 1
wx.CallAfter(self.Refresh)
def _line_scaler(self, x):
return (self.scale[0]*x[0],
self.scale[1]*x[1],
self.scale[0]*x[2],
self.scale[1]*x[3],)
return (self.scale[0] * x[0],
self.scale[1] * x[1],
self.scale[0] * x[2],
self.scale[1] * x[3],)
def _arc_scaler(self, x):
return (self.scale[0]*x[0],
self.scale[1]*x[1],
self.scale[0]*x[2],
self.scale[1]*x[3],
self.scale[0]*x[4],
self.scale[1]*x[5],)
return (self.scale[0] * x[0],
self.scale[1] * x[1],
self.scale[0] * x[2],
self.scale[1] * x[3],
self.scale[0] * x[4],
self.scale[1] * x[5],)
def _drawlines(self, dc, lines, pens):
scaled_lines = map(self._line_scaler, lines)
......@@ -305,8 +307,8 @@ class Gviz(wx.Panel):
dc.DrawArc(*scaled_arcs[i])
def repaint_everything(self):
width = self.scale[0]*self.build_dimensions[0]
height = self.scale[1]*self.build_dimensions[1]
width = self.scale[0] * self.build_dimensions[0]
height = self.scale[1] * self.build_dimensions[1]
self.blitmap = wx.EmptyBitmap(width + 1, height + 1, -1)
dc = wx.MemoryDC()
dc.SelectObject(self.blitmap)
......@@ -315,21 +317,21 @@ class Gviz(wx.Panel):
dc.SetPen(wx.Pen(wx.Colour(180, 180, 150)))
for grid_unit in self.grid:
if grid_unit > 0:
for x in xrange(int(self.build_dimensions[0]/grid_unit)+1):
draw_x = self.scale[0]*x*grid_unit
for x in xrange(int(self.build_dimensions[0] / grid_unit) + 1):
draw_x = self.scale[0] * x * grid_unit
dc.DrawLine(draw_x, 0, draw_x, height)
for y in xrange(int(self.build_dimensions[1]/grid_unit)+1):
draw_y = self.scale[1]*(self.build_dimensions[1]-y*grid_unit)
for y in xrange(int(self.build_dimensions[1] / grid_unit) + 1):
draw_y = self.scale[1] * (self.build_dimensions[1] - y * grid_unit)
dc.DrawLine(0, draw_y, width, draw_y)
dc.SetPen(wx.Pen(wx.Colour(0, 0, 0)))
if not self.showall:
# Draw layer gauge
dc.SetBrush(wx.Brush((43, 144, 255)))
dc.DrawRectangle(width-15, 0, 15, height)
dc.DrawRectangle(width - 15, 0, 15, height)
dc.SetBrush(wx.Brush((0, 255, 0)))
if self.layers:
dc.DrawRectangle(width-14, (1.0-(1.0*(self.layerindex+1))/len(self.layers))*height, 13, height-1)
dc.DrawRectangle(width - 14, (1.0 - (1.0 * (self.layerindex + 1)) / len(self.layers)) * height, 13, height - 1)
if self.showall:
for i in self.layers:
......@@ -393,6 +395,7 @@ class Gviz(wx.Panel):
def add_parsed_gcodes(self, gcode):
def _y(y):
return self.build_dimensions[1] - (y - self.build_dimensions[4])
def _x(x):
return x - self.build_dimensions[3]
......@@ -412,22 +415,22 @@ class Gviz(wx.Panel):
for gline in layer:
if not gline.is_move:
continue
target = self.lastpos[:]
target[0] = gline.current_x
target[1] = gline.current_y
target[2] = gline.current_z
target[5] = 0.0
target[6] = 0.0
if gline.e != None:
if gline.e is not None:
if gline.relative_e:
target[3] += gline.e
else:
target[3] = gline.e
if gline.f != None: target[4] = gline.f
if gline.i != None: target[5] = gline.i
if gline.j != None: target[6] = gline.j
if gline.f is not None: target[4] = gline.f
if gline.i is not None: target[5] = gline.i
if gline.j is not None: target[6] = gline.j
start_pos = self.lastpos[:]
if gline.command in ["G0", "G1"]:
......@@ -460,6 +463,7 @@ class Gviz(wx.Panel):
def _y(y):
return self.build_dimensions[1] - (y - self.build_dimensions[4])
def _x(x):
return x - self.build_dimensions[3]
......@@ -467,17 +471,17 @@ class Gviz(wx.Panel):
return
start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
target = start_pos[:]
target[5] = 0.0
target[6] = 0.0
if gline.x != None: target[0] = gline.x
if gline.y != None: target[1] = gline.y
if gline.z != None: target[2] = gline.z
if gline.e != None: target[3] = gline.e
if gline.f != None: target[4] = gline.f
if gline.i != None: target[5] = gline.i
if gline.j != None: target[6] = gline.j
if gline.x is not None: target[0] = gline.x
if gline.y is not None: target[1] = gline.y
if gline.z is not None: target[2] = gline.z
if gline.e is not None: target[3] = gline.e
if gline.f is not None: target[4] = gline.f
if gline.i is not None: target[5] = gline.i
if gline.j is not None: target[6] = gline.j
z = target[2]
if not hilight and z not in self.layers:
......
......@@ -13,25 +13,30 @@
# 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, sys
import os
import sys
import gettext
# Set up Internationalization using gettext
# searching for installed locales on /usr/share; uses relative folder if not found (windows)
# searching for installed locales on /usr/share; uses relative folder if not
# found (windows)
def install_locale(domain):
if os.path.exists('/usr/share/pronterface/locale'):
gettext.install(domain, '/usr/share/pronterface/locale', unicode = 1)
elif os.path.exists('/usr/local/share/pronterface/locale'):
gettext.install(domain, '/usr/local/share/pronterface/locale', unicode = 1)
gettext.install(domain, '/usr/local/share/pronterface/locale',
unicode = 1)
else:
gettext.install(domain, './locale', unicode = 1)
def imagefile(filename):
for prefix in ['/usr/local/share/pronterface/images', '/usr/share/pronterface/images']:
for prefix in ['/usr/local/share/pronterface/images',
'/usr/share/pronterface/images']:
candidate = os.path.join(prefix, filename)
if os.path.exists(candidate):
return candidate
local_candidate = os.path.join(os.path.dirname(sys.argv[0]), "images", filename)
local_candidate = os.path.join(os.path.dirname(sys.argv[0]),
"images", filename)
if os.path.exists(local_candidate):
return local_candidate
else:
......@@ -49,13 +54,15 @@ def lookup_file(filename, prefixes):
return filename
def pixmapfile(filename):
return lookup_file(filename, ['/usr/local/share/pixmaps', '/usr/share/pixmaps'])
return lookup_file(filename, ['/usr/local/share/pixmaps',
'/usr/share/pixmaps'])
def sharedfile(filename):
return lookup_file(filename, ['/usr/local/share/pronterface', '/usr/share/pronterface'])
return lookup_file(filename, ['/usr/local/share/pronterface',
'/usr/share/pronterface'])
def configfile(filename):
return lookup_file(filename, [os.path.expanduser("~/.printrun/"),])
return lookup_file(filename, [os.path.expanduser("~/.printrun/"), ])
class RemainingTimeEstimator(object):
......@@ -88,7 +95,7 @@ class RemainingTimeEstimator(object):
if idx == self.last_idx:
return self.last_estimate
layer, line = self.gcode.idxs(idx)
layer_progress = (1 - (float(line+1) / self.current_layer_lines))
layer_progress = (1 - (float(line + 1) / self.current_layer_lines))
remaining = layer_progress * self.current_layer_estimate + self.remaining_layers_estimate
estimate = self.drift * remaining
total = estimate + printtime
......
......@@ -25,15 +25,16 @@ class MacroEditor(wx.Dialog):
if gcode:
title = " %s"
self.gcode = gcode
wx.Dialog.__init__(self, None, title = title % macro_name, style = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
wx.Dialog.__init__(self, None, title = title % macro_name,
style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
self.callback = callback
self.panel = wx.Panel(self,-1)
self.panel = wx.Panel(self, -1)
titlesizer = wx.BoxSizer(wx.HORIZONTAL)
titletext = wx.StaticText(self.panel,-1, " _") #title%macro_name)
self.titletext = wx.StaticText(self.panel, -1, " _") # title%macro_name)
#title.SetFont(wx.Font(11, wx.NORMAL, wx.NORMAL, wx.BOLD))
titlesizer.Add(titletext, 1)
self.findb = wx.Button(self.panel, -1, _("Find"), style = wx.BU_EXACTFIT) #New button for "Find" (Jezmy)
self.findb.Bind(wx.EVT_BUTTON, self.find)
titlesizer.Add(self.titletext, 1)
self.findb = wx.Button(self.panel, -1, _("Find"), style = wx.BU_EXACTFIT) # New button for "Find" (Jezmy)
self.findb.Bind(wx.EVT_BUTTON, self.find)
self.okb = wx.Button(self.panel, -1, _("Save"), style = wx.BU_EXACTFIT)
self.okb.Bind(wx.EVT_BUTTON, self.save)
self.Bind(wx.EVT_CLOSE, self.close)
......@@ -44,12 +45,12 @@ class MacroEditor(wx.Dialog):
titlesizer.Add(self.cancelb)
topsizer = wx.BoxSizer(wx.VERTICAL)
topsizer.Add(titlesizer, 0, wx.EXPAND)
self.e = wx.TextCtrl(self.panel, style = wx.HSCROLL|wx.TE_MULTILINE|wx.TE_RICH2, size = (400, 400))
self.e = wx.TextCtrl(self.panel, style = wx.HSCROLL | wx.TE_MULTILINE | wx.TE_RICH2, size = (400, 400))
if not self.gcode:
self.e.SetValue(self.unindent(definition))
else:
self.e.SetValue("\n".join(definition))
topsizer.Add(self.e, 1, wx.ALL+wx.EXPAND)
topsizer.Add(self.e, 1, wx.ALL | wx.EXPAND)
self.panel.SetSizer(topsizer)
topsizer.Layout()
topsizer.Fit(self)
......@@ -59,29 +60,28 @@ class MacroEditor(wx.Dialog):
def find(self, ev):
# Ask user what to look for, find it and point at it ... (Jezmy)
S = self.e.GetStringSelection()
if not S :
if not S:
S = "Z"
FindValue = wx.GetTextFromUser('Please enter a search string:', caption = "Search", default_value = S, parent = None)
somecode = self.e.GetValue()
numLines = len(somecode)
position = somecode.find(FindValue, self.e.GetInsertionPoint())
if position == -1 :
position = somecode.find(FindValue, self.e.GetInsertionPoint())
if position == -1:
# ShowMessage(self,-1, "Not found!")
titletext = wx.TextCtrl(self.panel,-1, "Not Found!")
self.titletext.SetLabel(_("Not Found!"))
else:
# self.title.SetValue("Position : "+str(position))
titletext = wx.TextCtrl(self.panel,-1, str(position))
self.titletext.SetLabel(str(position))
# ananswer = wx.MessageBox(str(numLines)+" Lines detected in file\n"+str(position), "OK")
self.e.SetFocus()
self.e.SetInsertionPoint(position)
self.e.SetSelection(position, position + len(FindValue))
self.e.SetSelection(position, position + len(FindValue))
self.e.ShowPosition(position)
def ShowMessage(self, ev , message):
dlg = wxMessageDialog(self, message,
"Info!", wxOK | wxICON_INFORMATION)
def ShowMessage(self, ev, message):
dlg = wx.MessageDialog(self, message,
"Info!", wx.OK | wx.ICON_INFORMATION)
dlg.ShowModal()
dlg.Destroy()
......@@ -96,7 +96,7 @@ class MacroEditor(wx.Dialog):
self.Destroy()
def unindent(self, text):
self.indent_chars = text[:len(text)-len(text.lstrip())]
self.indent_chars = text[:len(text) - len(text.lstrip())]
if len(self.indent_chars) == 0:
self.indent_chars = " "
unindented = ""
......@@ -110,6 +110,7 @@ class MacroEditor(wx.Dialog):
else:
unindented += line + "\n"
return unindented
def reindent(self, text):
lines = re.split(r"(?:\r\n?|\n)", text)
if len(lines) <= 1:
......@@ -127,7 +128,8 @@ SETTINGS_GROUPS = {"Printer": _("Printer settings"),
class PronterOptionsDialog(wx.Dialog):
"""Options editor"""
def __init__(self, pronterface):
wx.Dialog.__init__(self, parent = None, title = _("Edit settings"), size = (400, 500), style = wx.DEFAULT_DIALOG_STYLE)
wx.Dialog.__init__(self, parent = None, title = _("Edit settings"),
size = (400, 500), style = wx.DEFAULT_DIALOG_STYLE)
panel = wx.Panel(self)
header = wx.StaticBox(panel, label = _("Settings"))
sbox = wx.StaticBoxSizer(header, wx.VERTICAL)
......@@ -152,12 +154,12 @@ class PronterOptionsDialog(wx.Dialog):
grid.AddGrowableCol(1)
grid.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
for setting in settings:
label,widget = setting.get_label(grouppanel),setting.get_widget(grouppanel)
grid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ALIGN_RIGHT)
grid.Add(widget, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND)
if hasattr(label,"set_default"):
label, widget = setting.get_label(grouppanel), setting.get_widget(grouppanel)
grid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.ALIGN_RIGHT)
grid.Add(widget, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND)
if hasattr(label, "set_default"):
label.Bind(wx.EVT_MOUSE_EVENTS, label.set_default)
if hasattr(widget,"Bind"):
if hasattr(widget, "Bind"):
widget.Bind(wx.EVT_MOUSE_EVENTS, label.set_default)
grouppanel.SetSizer(grid)
sbox.Add(notebook, 1, wx.EXPAND)
......@@ -181,29 +183,30 @@ def PronterOptions(pronterface):
class ButtonEdit(wx.Dialog):
"""Custom button edit dialog"""
def __init__(self, pronterface):
wx.Dialog.__init__(self, None, title = _("Custom button"), style = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
wx.Dialog.__init__(self, None, title = _("Custom button"),
style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
self.pronterface = pronterface
topsizer = wx.BoxSizer(wx.VERTICAL)
grid = wx.FlexGridSizer(rows = 0, cols = 2, hgap = 4, vgap = 2)
grid.AddGrowableCol(1, 1)
grid.Add(wx.StaticText(self,-1, _("Button title")), 0, wx.BOTTOM|wx.RIGHT)
self.name = wx.TextCtrl(self,-1, "")
grid.Add(wx.StaticText(self, -1, _("Button title")), 0, wx.BOTTOM | wx.RIGHT)
self.name = wx.TextCtrl(self, -1, "")
grid.Add(self.name, 1, wx.EXPAND)
grid.Add(wx.StaticText(self, -1, _("Command")), 0, wx.BOTTOM|wx.RIGHT)
self.command = wx.TextCtrl(self,-1, "")
grid.Add(wx.StaticText(self, -1, _("Command")), 0, wx.BOTTOM | wx.RIGHT)
self.command = wx.TextCtrl(self, -1, "")
xbox = wx.BoxSizer(wx.HORIZONTAL)
xbox.Add(self.command, 1, wx.EXPAND)
self.command.Bind(wx.EVT_TEXT, self.macrob_enabler)
self.macrob = wx.Button(self,-1, "..", style = wx.BU_EXACTFIT)
self.macrob = wx.Button(self, -1, "..", style = wx.BU_EXACTFIT)
self.macrob.Bind(wx.EVT_BUTTON, self.macrob_handler)
xbox.Add(self.macrob, 0)
grid.Add(xbox, 1, wx.EXPAND)
grid.Add(wx.StaticText(self,-1, _("Color")), 0, wx.BOTTOM|wx.RIGHT)
self.color = wx.TextCtrl(self,-1, "")
grid.Add(wx.StaticText(self, -1, _("Color")), 0, wx.BOTTOM | wx.RIGHT)
self.color = wx.TextCtrl(self, -1, "")
grid.Add(self.color, 1, wx.EXPAND)
topsizer.Add(grid, 0, wx.EXPAND)
topsizer.Add( (0, 0), 1)
topsizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.ALIGN_CENTER)
topsizer.Add((0, 0), 1)
topsizer.Add(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL), 0, wx.ALIGN_CENTER)
self.SetSizer(topsizer)
def macrob_enabler(self, e):
......@@ -212,9 +215,9 @@ class ButtonEdit(wx.Dialog):
try:
if macro == "":
valid = True
elif self.pronterface.macros.has_key(macro):
elif macro in self.pronterface.macros:
valid = True
elif hasattr(self.pronterface.__class__, u"do_"+macro):
elif hasattr(self.pronterface.__class__, u"do_" + macro):
valid = False
elif len([c for c in macro if not c.isalnum() and c != "_"]):
valid = False
......@@ -223,7 +226,7 @@ class ButtonEdit(wx.Dialog):
except:
if macro == "":
valid = True
elif self.pronterface.macros.has_key(macro):
elif macro in self.pronterface.macros:
valid = True
elif len([c for c in macro if not c.isalnum() and c != "_"]):
valid = False
......@@ -235,13 +238,14 @@ class ButtonEdit(wx.Dialog):
macro = self.command.GetValue()
macro = self.pronterface.edit_macro(macro)
self.command.SetValue(macro)
if self.name.GetValue()=="":
if self.name.GetValue() == "":
self.name.SetValue(macro)
class TempGauge(wx.Panel):
def __init__(self, parent, size = (200, 22), title = "", maxval = 240, gaugeColour = None):
wx.Panel.__init__(self, parent,-1, size = size)
def __init__(self, parent, size = (200, 22), title = "",
maxval = 240, gaugeColour = None):
wx.Panel.__init__(self, parent, -1, size = size)
self.Bind(wx.EVT_PAINT, self.paint)
self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.width, self.height = size
......@@ -253,9 +257,9 @@ class TempGauge(wx.Panel):
self.recalc()
def recalc(self):
mmax = max(int(self.setpoint*1.05), self.max)
self.scale = float(self.width-2)/float(mmax)
self.ypt = max(16, int(self.scale*max(self.setpoint, self.max/6)))
mmax = max(int(self.setpoint * 1.05), self.max)
self.scale = float(self.width - 2) / float(mmax)
self.ypt = max(16, int(self.scale * max(self.setpoint, self.max / 6)))
def SetValue(self, value):
self.value = value
......@@ -269,18 +273,18 @@ class TempGauge(wx.Panel):
if val < vmin: return cmin
if val > vmax: return cmax
if val <= vmid:
lo, hi, val, valhi = cmin, cmid, val-vmin, vmid-vmin
lo, hi, val, valhi = cmin, cmid, val - vmin, vmid - vmin
else:
lo, hi, val, valhi = cmid, cmax, val-vmid, vmax-vmid
vv = float(val)/valhi
rgb = lo.Red()+(hi.Red()-lo.Red())*vv, lo.Green()+(hi.Green()-lo.Green())*vv, lo.Blue()+(hi.Blue()-lo.Blue())*vv
rgb = map(lambda x:x*0.8, rgb)
lo, hi, val, valhi = cmid, cmax, val - vmid, vmax - vmid
vv = float(val) / valhi
rgb = lo.Red() + (hi.Red() - lo.Red()) * vv, lo.Green() + (hi.Green() - lo.Green()) * vv, lo.Blue() + (hi.Blue() - lo.Blue()) * vv
rgb = map(lambda x: x * 0.8, rgb)
return wx.Colour(*map(int, rgb))
def paint(self, ev):
self.width, self.height = self.GetClientSizeTuple()
self.recalc()
x0, y0, x1, y1, xE, yE = 1, 1, self.ypt+1, 1, self.width+1-2, 20
x0, y0, x1, y1, xE, yE = 1, 1, self.ypt + 1, 1, self.width + 1 - 2, 20
dc = wx.PaintDC(self)
dc.SetBackground(wx.Brush((255, 255, 255)))
dc.Clear()
......@@ -290,60 +294,60 @@ class TempGauge(wx.Panel):
gc = wx.GraphicsContext.Create(dc)
# draw shadow first
# corners
gc.SetBrush(gc.CreateRadialGradientBrush(xE-7, 9, xE-7, 9, 8, shadow1, shadow2))
gc.DrawRectangle(xE-7, 1, 8, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(xE-7, 17, xE-7, 17, 8, shadow1, shadow2))
gc.DrawRectangle(xE-7, 17, 8, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(x0+6, 17, x0+6, 17, 8, shadow1, shadow2))
gc.DrawRectangle(0, 17, x0+6, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(xE - 7, 9, xE - 7, 9, 8, shadow1, shadow2))
gc.DrawRectangle(xE - 7, 1, 8, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(xE - 7, 17, xE - 7, 17, 8, shadow1, shadow2))
gc.DrawRectangle(xE - 7, 17, 8, 8)
gc.SetBrush(gc.CreateRadialGradientBrush(x0 + 6, 17, x0 + 6, 17, 8, shadow1, shadow2))
gc.DrawRectangle(0, 17, x0 + 6, 8)
# edges
gc.SetBrush(gc.CreateLinearGradientBrush(xE-6, 0, xE+1, 0, shadow1, shadow2))
gc.DrawRectangle(xE-7, 9, 8, 8)
gc.SetBrush(gc.CreateLinearGradientBrush(x0, yE-2, x0, yE+5, shadow1, shadow2))
gc.DrawRectangle(x0+6, yE-2, xE-12, 7)
gc.SetBrush(gc.CreateLinearGradientBrush(xE - 6, 0, xE + 1, 0, shadow1, shadow2))
gc.DrawRectangle(xE - 7, 9, 8, 8)
gc.SetBrush(gc.CreateLinearGradientBrush(x0, yE - 2, x0, yE + 5, shadow1, shadow2))
gc.DrawRectangle(x0 + 6, yE - 2, xE - 12, 7)
# draw gauge background
gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0, x1+1, y1, cold, medium))
gc.DrawRoundedRectangle(x0, y0, x1+4, yE, 6)
gc.SetBrush(gc.CreateLinearGradientBrush(x1-2, y1, xE, y1, medium, hot))
gc.DrawRoundedRectangle(x1-2, y1, xE-x1, yE, 6)
gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0, x1 + 1, y1, cold, medium))
gc.DrawRoundedRectangle(x0, y0, x1 + 4, yE, 6)
gc.SetBrush(gc.CreateLinearGradientBrush(x1 - 2, y1, xE, y1, medium, hot))
gc.DrawRoundedRectangle(x1 - 2, y1, xE - x1, yE, 6)
# draw gauge
width = 12
w1 = y0+9-width/2
w2 = w1+width
value = x0+max(10, min(self.width+1-2, int(self.value*self.scale)))
#gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0+3, x0, y0+15, gauge1, gauge2))
w1 = y0 + 9 - width / 2
w2 = w1 + width
value = x0 + max(10, min(self.width + 1 - 2, int(self.value * self.scale)))
#gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0 + 3, x0, y0 + 15, gauge1, gauge2))
#gc.SetBrush(gc.CreateLinearGradientBrush(0, 3, 0, 15, wx.Colour(255, 255, 255), wx.Colour(255, 90, 32)))
gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0+3, x0, y0+15, gauge1, self.interpolatedColour(value, x0, x1, xE, cold, medium, hot)))
gc.SetBrush(gc.CreateLinearGradientBrush(x0, y0 + 3, x0, y0 + 15, gauge1, self.interpolatedColour(value, x0, x1, xE, cold, medium, hot)))
val_path = gc.CreatePath()
val_path.MoveToPoint(x0, w1)
val_path.AddLineToPoint(value, w1)
val_path.AddLineToPoint(value+2, w1+width/4)
val_path.AddLineToPoint(value+2, w2-width/4)
val_path.AddLineToPoint(value + 2, w1 + width / 4)
val_path.AddLineToPoint(value + 2, w2 - width / 4)
val_path.AddLineToPoint(value, w2)
#val_path.AddLineToPoint(value-4, 10)
val_path.AddLineToPoint(x0, w2)
gc.DrawPath(val_path)
# draw setpoint markers
setpoint = x0+max(10, int(self.setpoint*self.scale))
setpoint = x0 + max(10, int(self.setpoint * self.scale))
gc.SetBrush(gc.CreateBrush(wx.Brush(wx.Colour(0, 0, 0))))
setp_path = gc.CreatePath()
setp_path.MoveToPoint(setpoint-4, y0)
setp_path.AddLineToPoint(setpoint+4, y0)
setp_path.AddLineToPoint(setpoint, y0+5)
setp_path.MoveToPoint(setpoint-4, yE)
setp_path.AddLineToPoint(setpoint+4, yE)
setp_path.AddLineToPoint(setpoint, yE-5)
setp_path.MoveToPoint(setpoint - 4, y0)
setp_path.AddLineToPoint(setpoint + 4, y0)
setp_path.AddLineToPoint(setpoint, y0 + 5)
setp_path.MoveToPoint(setpoint - 4, yE)
setp_path.AddLineToPoint(setpoint + 4, yE)
setp_path.AddLineToPoint(setpoint, yE - 5)
gc.DrawPath(setp_path)
# draw readout
text = u"T\u00B0 %u/%u"%(self.value, self.setpoint)
text = u"T\u00B0 %u/%u" % (self.value, self.setpoint)
#gc.SetFont(gc.CreateFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD), wx.WHITE))
#gc.DrawText(text, 29,-2)
gc.SetFont(gc.CreateFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD), wx.WHITE))
gc.DrawText(self.title, x0+19, y0+4)
gc.DrawText(text, x0+119, y0+4)
gc.DrawText(self.title, x0 + 19, y0 + 4)
gc.DrawText(text, x0 + 119, y0 + 4)
gc.SetFont(gc.CreateFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)))
gc.DrawText(self.title, x0+18, y0+3)
gc.DrawText(text, x0+118, y0+3)
gc.DrawText(self.title, x0 + 18, y0 + 3)
gc.DrawText(text, x0 + 118, y0 + 3)
class SpecialButton(object):
......@@ -355,7 +359,8 @@ class SpecialButton(object):
tooltip = None
custom = None
def __init__(self, label, command, background = None, pos = None, span = None, tooltip = None, custom = False):
def __init__(self, label, command, background = None, pos = None,
span = None, tooltip = None, custom = False):
self.label = label
self.command = command
self.pos = pos
......
......@@ -13,19 +13,21 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import sys, struct, math
import sys
import struct
import math
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]]
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 genfacet(v):
veca = [v[1][0]-v[0][0], v[1][1]-v[0][1], v[1][2]-v[0][2]]
vecb = [v[2][0]-v[1][0], v[2][1]-v[1][1], v[2][2]-v[1][2]]
veca = [v[1][0] - v[0][0], v[1][1] - v[0][1], v[1][2] - v[0][2]]
vecb = [v[2][0] - v[1][0], v[2][1] - v[1][1], v[2][2] - v[1][2]]
vecx = cross(veca, vecb)
vlen = math.sqrt(sum(map(lambda x:x*x, vecx)))
vlen = math.sqrt(sum(map(lambda x: x * x, vecx)))
if vlen == 0:
vlen = 1
normal = map(lambda x:x/vlen, vecx)
normal = map(lambda x: x / vlen, vecx)
return [normal, v]
I = [
......@@ -40,14 +42,14 @@ def transpose(matrix):
#return [[v[i] for v in matrix] for i in xrange(len(matrix[0]))]
def multmatrix(vector, matrix):
return map(sum, transpose(map(lambda x:[x[0]*p for p in x[1]], zip(vector, transpose(matrix)))))
return map(sum, transpose(map(lambda x: [x[0] * p for p in x[1]], zip(vector, transpose(matrix)))))
def applymatrix(facet, matrix = I):
#return facet
#return [map(lambda x:-1.0*x, multmatrix(facet[0]+[1], matrix)[:3]), map(lambda x:multmatrix(x+[1], matrix)[:3], facet[1])]
return genfacet(map(lambda x:multmatrix(x+[1], matrix)[:3], facet[1]))
return genfacet(map(lambda x: multmatrix(x + [1], matrix)[:3], facet[1]))
f = [[0, 0, 0],[[-3.022642, 0.642482, -9.510565],[-3.022642, 0.642482, -9.510565],[-3.022642, 0.642482, -9.510565]]]
f = [[0, 0, 0], [[-3.022642, 0.642482, -9.510565], [-3.022642, 0.642482, -9.510565], [-3.022642, 0.642482, -9.510565]]]
m = [
[1, 0, 0, 0],
[0, 1, 0, 0],
......@@ -60,37 +62,35 @@ def emitstl(filename, facets = [], objname = "stltool_export", binary = 1):
return
if binary:
f = open(filename, "wb")
buf = "".join(["\0"]*80)
buf+=struct.pack("<I", len(facets))
buf = "".join(["\0"] * 80)
buf += struct.pack("<I", len(facets))
facetformat = struct.Struct("<ffffffffffffH")
for i in facets:
l = list(i[0][:])
for j in i[1]:
l+=j[:]
l+=[0]
l += j[:]
l += [0]
#print len(l)
buf+=facetformat.pack(*l)
buf += facetformat.pack(*l)
f.write(buf)
f.close()
return
f = open(filename, "w")
f.write("solid "+objname+"\n")
f.write("solid " + objname + "\n")
for i in facets:
f.write(" facet normal "+" ".join(map(str, i[0]))+"\n outer loop\n")
f.write(" facet normal " + " ".join(map(str, i[0])) + "\n outer loop\n")
for j in i[1]:
f.write(" vertex "+" ".join(map(str, j))+"\n")
f.write(" endloop"+"\n")
f.write(" endfacet"+"\n")
f.write("endsolid "+objname+"\n")
f.write(" vertex " + " ".join(map(str, j)) + "\n")
f.write(" endloop" + "\n")
f.write(" endfacet" + "\n")
f.write("endsolid " + objname + "\n")
f.close()
class stl(object):
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.facetsminz = []
self.facetsmaxz = []
......@@ -129,57 +129,51 @@ class stl(object):
buf += newdata
fd = list(facetformat.unpack(buf))
self.name = "binary soloid"
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.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))
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
def translate(self, v = [0, 0, 0]):
matrix = [
[1, 0, 0, v[0]],
[0, 1, 0, v[1]],
[0, 0, 1, v[2]],
[0, 0, 0, 1]
]
matrix = [[1, 0, 0, v[0]],
[0, 1, 0, v[1]],
[0, 0, 1, v[2]],
[0, 0, 0, 1]
]
return self.transform(matrix)
def rotate(self, v = [0, 0, 0]):
import math
z = v[2]
matrix1 = [
[math.cos(math.radians(z)),-math.sin(math.radians(z)), 0, 0],
[math.sin(math.radians(z)), math.cos(math.radians(z)), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
]
matrix1 = [[math.cos(math.radians(z)), -math.sin(math.radians(z)), 0, 0],
[math.sin(math.radians(z)), math.cos(math.radians(z)), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
]
y = v[0]
matrix2 = [
[1, 0, 0, 0],
[0, math.cos(math.radians(y)),-math.sin(math.radians(y)), 0],
[0, math.sin(math.radians(y)), math.cos(math.radians(y)), 0],
[0, 0, 0, 1]
]
matrix2 = [[1, 0, 0, 0],
[0, math.cos(math.radians(y)), -math.sin(math.radians(y)), 0],
[0, math.sin(math.radians(y)), math.cos(math.radians(y)), 0],
[0, 0, 0, 1]
]
x = v[1]
matrix3 = [
[math.cos(math.radians(x)), 0,-math.sin(math.radians(x)), 0],
[0, 1, 0, 0],
[math.sin(math.radians(x)), 0, math.cos(math.radians(x)), 0],
[0, 0, 0, 1]
]
matrix3 = [[math.cos(math.radians(x)), 0, -math.sin(math.radians(x)), 0],
[0, 1, 0, 0],
[math.sin(math.radians(x)), 0, math.cos(math.radians(x)), 0],
[0, 0, 0, 1]
]
return self.transform(matrix1).transform(matrix2).transform(matrix3)
def scale(self, v = [0, 0, 0]):
matrix = [
[v[0], 0, 0, 0],
[0, v[1], 0, 0],
[0, 0, v[2], 0],
[0, 0, 0, 1]
]
matrix = [[v[0], 0, 0, 0],
[0, v[1], 0, 0],
[0, 0, v[2], 0],
[0, 0, 0, 1]
]
return self.transform(matrix)
def transform(self, m = I):
s = stl()
s.facets = [applymatrix(i, m) for i in self.facets]
......@@ -189,20 +183,20 @@ class stl(object):
s.facetloc = 0
s.name = self.name
for facet in s.facets:
s.facetsminz+=[(min(map(lambda x:x[2], facet[1])), facet)]
s.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])), facet)]
s.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
s.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
return s
def export(self, f = sys.stdout):
f.write("solid "+self.name+"\n")
f.write("solid " + self.name + "\n")
for i in self.facets:
f.write(" facet normal "+" ".join(map(str, i[0]))+"\n")
f.write(" outer loop"+"\n")
f.write(" facet normal " + " ".join(map(str, i[0])) + "\n")
f.write(" outer loop" + "\n")
for j in i[1]:
f.write(" vertex "+" ".join(map(str, j))+"\n")
f.write(" endloop"+"\n")
f.write(" endfacet"+"\n")
f.write("endsolid "+self.name+"\n")
f.write(" vertex " + " ".join(map(str, j)) + "\n")
f.write(" endloop" + "\n")
f.write(" endfacet" + "\n")
f.write("endsolid " + self.name + "\n")
f.flush()
def parseline(self, l):
......@@ -216,33 +210,34 @@ class stl(object):
self.insolid = 0
return 0
elif l.startswith("facet normal"):
l = l.replace(", ",".")
l = l.replace(", ", ".")
self.infacet = 11
self.facetloc = 0
self.facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]]
self.facet[0]=map(float, l.split()[2:])
self.facet = [[0, 0, 0], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
self.facet[0] = map(float, l.split()[2:])
elif l.startswith("endfacet"):
self.infacet = 0
self.facets+=[self.facet]
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)]
self.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
self.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
elif l.startswith("vertex"):
l = l.replace(", ",".")
self.facet[1][self.facetloc]=map(float, l.split()[1:])
self.facetloc+=1
l = l.replace(", ", ".")
self.facet[1][self.facetloc] = map(float, l.split()[1:])
self.facetloc += 1
return 1
if __name__ == "__main__":
s = stl("../../Downloads/frame-vertex-neo-foot-x4.stl")
for i in xrange(11, 11):
working = s.facets[:]
for j in reversed(sorted(s.facetsminz)):
if(j[0]>i):
if(j[0] > i):
working.remove(j[1])
else:
break
for j in (sorted(s.facetsmaxz)):
if(j[0]<i):
if(j[0] < i):
working.remove(j[1])
else:
break
......
......@@ -15,11 +15,7 @@
# 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 stltool
import wx
from wx import glcanvas
import time
import threading
......@@ -140,7 +136,7 @@ class StlViewPanel(wxGLPanel):
v = map(lambda m, w, b: b * m / w, p, sz, self.build_dimensions[0:2])
v[1] = self.build_dimensions[1] - v[1]
v += [300]
print "Double-click at "+str(v)+" in "
print "Double-click at " + str(v) + " in "
print self
def forceresize(self):
......@@ -160,11 +156,10 @@ class StlViewPanel(wxGLPanel):
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]
]
model.offsets = [model.offsets[0] + delta[0],
model.offsets[1] + delta[1],
model.offsets[2]
]
self.Refresh()
return True
......@@ -178,7 +173,7 @@ class StlViewPanel(wxGLPanel):
"""
self.mousepos = event.GetPositionTuple()
if event.Dragging() and event.LeftIsDown():
if self.initpos == None:
if self.initpos is None:
self.initpos = event.GetPositionTuple()
else:
if not event.ShiftDown():
......@@ -251,7 +246,7 @@ class StlViewPanel(wxGLPanel):
if delta > 0:
self.zoom(factor, (x, y))
else:
self.zoom(1/factor, (x, y))
self.zoom(1 / factor, (x, y))
def keypress(self, event):
"""gets keypress events and moves/rotates acive shape"""
......@@ -283,8 +278,7 @@ class StlViewPanel(wxGLPanel):
event.Skip()
def update(self):
while(1):
dt = 0.05
while True:
time.sleep(0.05)
try:
wx.CallAfter(self.Refresh)
......@@ -321,7 +315,7 @@ class StlViewPanel(wxGLPanel):
def drawmodel(self, m, n):
batch = pyglet.graphics.Batch()
stl = stlview(m.facets, batch = batch)
stlview(m.facets, batch = batch)
m.batch = batch
m.animoffset = 300
#print m
......@@ -338,10 +332,10 @@ class StlViewPanel(wxGLPanel):
glPushMatrix()
glTranslatef(0, 0, -self.dist)
glMultMatrixd(build_rotmatrix(self.basequat)) # Rotate according to trackball
glMultMatrixd(build_rotmatrix(self.basequat)) # Rotate according to trackball
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1))
glTranslatef(- self.build_dimensions[3] - self.platform.width/2,
- self.build_dimensions[4] - self.platform.depth/2, 0) # Move origin to bottom left of platform
glTranslatef(- self.build_dimensions[3] - self.platform.width / 2,
- self.build_dimensions[4] - self.platform.depth / 2, 0) # Move origin to bottom left of platform
# Draw platform
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
self.platform.draw()
......@@ -378,7 +372,7 @@ class StlViewPanel(wxGLPanel):
def main():
app = wx.App(redirect = False)
frame = wx.Frame(None, -1, "GL Window", size = (400, 400))
panel = StlViewPanel(frame)
StlViewPanel(frame)
frame.Show(True)
app.MainLoop()
app.Destroy()
......
......@@ -13,9 +13,10 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import wx, os, math
from bufferedcanvas import *
from printrun_utils import *
import wx
import math
from bufferedcanvas import BufferedCanvas
from printrun_utils import imagefile
def sign(n):
if n < 0: return -1
......@@ -94,10 +95,10 @@ class XYButtons(BufferedCanvas):
ylen = y2 - y1
pxlen = x1 - pos.x
pylen = y1 - pos.y
return abs(xlen*pylen-ylen*pxlen)/math.sqrt(xlen**2+ylen**2)
return abs(xlen * pylen - ylen * pxlen) / math.sqrt(xlen ** 2 + ylen ** 2)
def distanceToPoint(self, x1, y1, x2, y2):
return math.sqrt((x1-x2)**2 + (y1-y2)**2)
return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
def cycleKeypadIndex(self):
idx = self.keypad_idx + 1
......@@ -110,11 +111,11 @@ class XYButtons(BufferedCanvas):
def getMovement(self):
xdir = [1, 0, -1, 0, 0, 0][self.quadrant]
ydir = [0, 1, 0, -1, 0 ,0][self.quadrant]
zdir = [0, 0, 0, 0, 1 ,-1][self.quadrant]
magnitude = math.pow(10, self.concentric-1)
ydir = [0, 1, 0, -1, 0, 0][self.quadrant]
zdir = [0, 0, 0, 0, 1, -1][self.quadrant]
magnitude = math.pow(10, self.concentric - 1)
if not zdir == 0:
magnitude=min(magnitude,10)
magnitude = min(magnitude, 10)
return (magnitude * xdir, magnitude * ydir, magnitude * zdir)
def lookupConcentric(self, radius):
......@@ -128,15 +129,15 @@ class XYButtons(BufferedCanvas):
def getQuadrantConcentricFromPosition(self, pos):
rel_x = pos[0] - XYButtons.center[0]
rel_y = pos[1] - XYButtons.center[1]
radius = math.sqrt(rel_x**2 + rel_y**2)
radius = math.sqrt(rel_x ** 2 + rel_y ** 2)
if rel_x > rel_y and rel_x > -rel_y:
quadrant = 0 # Right
quadrant = 0 # Right
elif rel_x <= rel_y and rel_x > -rel_y:
quadrant = 3 # Down
quadrant = 3 # Down
elif rel_x > rel_y and rel_x < -rel_y:
quadrant = 1 # Up
quadrant = 1 # Up
else:
quadrant = 2 # Left
quadrant = 2 # Left
idx = self.lookupConcentric(radius)
return (quadrant, idx)
......@@ -149,7 +150,7 @@ class XYButtons(BufferedCanvas):
return None
def drawPartialPie(self, gc, center, r1, r2, angle1, angle2):
p1 = wx.Point(center.x + r1*math.cos(angle1), center.y + r1*math.sin(angle1))
p1 = wx.Point(center.x + r1 * math.cos(angle1), center.y + r1 * math.sin(angle1))
path = gc.CreatePath()
path.MoveToPoint(p1.x, p1.y)
......@@ -167,22 +168,22 @@ class XYButtons(BufferedCanvas):
fudge = -0.02
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
if quadrant == 0:
a1, a2 = (-math.pi*0.25, math.pi*0.25)
a1, a2 = (-math.pi * 0.25, math.pi * 0.25)
center.x += inner_ring_radius
elif quadrant == 1:
a1, a2 = (math.pi*1.25, math.pi*1.75)
a1, a2 = (math.pi * 1.25, math.pi * 1.75)
center.y -= inner_ring_radius
elif quadrant == 2:
a1, a2 = (math.pi*0.75, math.pi*1.25)
a1, a2 = (math.pi * 0.75, math.pi * 1.25)
center.x -= inner_ring_radius
elif quadrant == 3:
a1, a2 = (math.pi*0.25, math.pi*0.75)
a1, a2 = (math.pi * 0.25, math.pi * 0.75)
center.y += inner_ring_radius
r1 = XYButtons.concentric_circle_radii[concentric]
r2 = XYButtons.concentric_circle_radii[concentric+1]
r2 = XYButtons.concentric_circle_radii[concentric + 1]
self.drawPartialPie(gc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
self.drawPartialPie(gc, center, r1 - inner_ring_radius, r2 - inner_ring_radius, a1 + fudge, a2 - fudge)
def drawCorner(self, gc, x, y, angle = 0.0):
w, h = XYButtons.corner_size
......@@ -191,12 +192,12 @@ class XYButtons(BufferedCanvas):
gc.Translate(x, y)
gc.Rotate(angle)
path = gc.CreatePath()
path.MoveToPoint(-w/2, -h/2)
path.AddLineToPoint(w/2, -h/2)
path.AddLineToPoint(w/2, -h/2+h/3)
path.AddLineToPoint(-w/2+w/3, h/2)
path.AddLineToPoint(-w/2, h/2)
path.AddLineToPoint(-w/2, -h/2)
path.MoveToPoint(-w / 2, -h / 2)
path.AddLineToPoint(w / 2, -h / 2)
path.AddLineToPoint(w / 2, -h / 2 + h / 3)
path.AddLineToPoint(-w / 2 + w / 3, h / 2)
path.AddLineToPoint(-w / 2, h / 2)
path.AddLineToPoint(-w / 2, -h / 2)
gc.DrawPath(path)
gc.PopState()
......@@ -207,25 +208,23 @@ class XYButtons(BufferedCanvas):
inset = 10
if corner == 0:
x, y = (cx - ww/2 + inset, cy - wh/2 + inset)
self.drawCorner(gc, x+w/2, y+h/2, 0)
x, y = (cx - ww / 2 + inset, cy - wh / 2 + inset)
self.drawCorner(gc, x + w / 2, y + h / 2, 0)
elif corner == 1:
x, y = (cx + ww/2 - inset, cy - wh/2 + inset)
self.drawCorner(gc, x-w/2, y+h/2, math.pi/2)
x, y = (cx + ww / 2 - inset, cy - wh / 2 + inset)
self.drawCorner(gc, x - w / 2, y + h / 2, math.pi / 2)
elif corner == 2:
x, y = (cx + ww/2 - inset, cy + wh/2 - inset)
self.drawCorner(gc, x-w/2, y-h/2, math.pi)
x, y = (cx + ww / 2 - inset, cy + wh / 2 - inset)
self.drawCorner(gc, x - w / 2, y - h / 2, math.pi)
elif corner == 3:
x, y = (cx - ww/2 + inset, cy + wh/2 - inset)
self.drawCorner(gc, x+w/2, y-h/2, math.pi*3/2)
x, y = (cx - ww / 2 + inset, cy + wh / 2 - inset)
self.drawCorner(gc, x + w / 2, y - h / 2, math.pi * 3 / 2)
def draw(self, dc, w, h):
dc.SetBackground(wx.Brush(self.bgcolor))
dc.Clear()
gc = wx.GraphicsContext.Create(dc)
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
if self.bg_bmp:
w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
gc.DrawBitmap(self.bg_bmp, 0, 0, w, h)
......@@ -235,32 +234,30 @@ class XYButtons(BufferedCanvas):
gc.SetPen(wx.Pen(wx.Colour(100, 100, 100, 172), 4))
gc.SetBrush(wx.Brush(wx.Colour(0, 0, 0, 128)))
if self.concentric != None:
if self.concentric is not None:
if self.concentric < len(XYButtons.concentric_circle_radii):
if self.quadrant != None:
if self.quadrant is not None:
self.highlightQuadrant(gc, self.quadrant, self.concentric)
elif self.corner != None:
elif self.corner is not None:
self.highlightCorner(gc, self.corner)
if self.keypad_idx >= 0:
padw, padh = (self.keypad_bmp.GetWidth(), self.keypad_bmp.GetHeight())
pos = XYButtons.keypad_positions[self.keypad_idx]
pos = (pos[0] - padw/2 - 3, pos[1] - padh/2 - 3)
pos = (pos[0] - padw / 2 - 3, pos[1] - padh / 2 - 3)
gc.DrawBitmap(self.keypad_bmp, pos[0], pos[1], padw, padh)
# Draw label overlays
gc.SetPen(wx.Pen(wx.Colour(255, 255, 255, 128), 1))
gc.SetBrush(wx.Brush(wx.Colour(255, 255, 255, 128+64)))
gc.SetBrush(wx.Brush(wx.Colour(255, 255, 255, 128 + 64)))
for idx, kpos in XYButtons.label_overlay_positions.items():
if idx != self.concentric:
r = kpos[2]
gc.DrawEllipse(kpos[0]-r, kpos[1]-r, r*2, r*2)
gc.DrawEllipse(kpos[0] - r, kpos[1] - r, r * 2, r * 2)
else:
gc.SetPen(wx.Pen(self.bgcolor, 0))
gc.SetBrush(wx.Brush(self.bgcolormask))
gc.DrawRectangle(0, 0, w, h)
# Used to check exact position of keypad dots, should we ever resize the bg image
# for idx, kpos in XYButtons.label_overlay_positions.items():
# dc.DrawCircle(kpos[0], kpos[1], kpos[2])
......@@ -268,7 +265,6 @@ class XYButtons(BufferedCanvas):
## ------ ##
## Events ##
## ------ ##
def OnTopLevelKey(self, evt):
# Let user press escape on any control, and return focus here
if evt.GetKeyCode() == wx.WXK_ESCAPE:
......@@ -296,18 +292,17 @@ class XYButtons(BufferedCanvas):
else:
evt.Skip()
return
self.concentric = self.keypad_idx
x, y, z = self.getMovement()
if x!=0 or y!=0 and self.moveCallback:
if x != 0 or y != 0 and self.moveCallback:
self.moveCallback(x, y)
if z!=0 and self.zCallback:
if z != 0 and self.zCallback:
self.zCallback(z)
elif evt.GetKeyCode() == wx.WXK_SPACE:
self.spacebarCallback()
def OnMotion(self, event):
if not self.enabled:
return
......@@ -319,10 +314,10 @@ class XYButtons(BufferedCanvas):
idx = self.mouseOverKeypad(mpos)
self.quadrant = None
self.concentric = None
if idx == None:
if idx is None:
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
riseDist = self.distanceToLine(mpos, center.x-1, center.y-1, center.x+1, center.y+1)
fallDist = self.distanceToLine(mpos, center.x-1, center.y+1, center.x+1, center.y-1)
riseDist = self.distanceToLine(mpos, center.x - 1, center.y - 1, center.x + 1, center.y + 1)
fallDist = self.distanceToLine(mpos, center.x - 1, center.y + 1, center.x + 1, center.y - 1)
self.quadrant, self.concentric = self.getQuadrantConcentricFromPosition(mpos)
# If mouse hovers in space between quadrants, don't commit to a quadrant
......@@ -352,17 +347,17 @@ class XYButtons(BufferedCanvas):
mpos = event.GetPosition()
idx = self.mouseOverKeypad(mpos)
if idx == None:
if idx is None:
self.quadrant, self.concentric = self.getQuadrantConcentricFromPosition(mpos)
if self.concentric != None:
if self.concentric is not None:
if self.concentric < len(XYButtons.concentric_circle_radii):
if self.quadrant != None:
x, y, z = self.getMovement()
if self.quadrant is not None:
x, y, z = self.getMovement()
if self.moveCallback:
self.lastMove = (x, y)
self.lastCorner = None
self.moveCallback(x, y)
elif self.corner != None:
elif self.corner is not None:
if self.cornerCallback:
self.lastCorner = self.corner
self.lastMove = None
......
......@@ -13,9 +13,10 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import wx, os, math
from bufferedcanvas import *
from printrun_utils import *
import wx
import math
from bufferedcanvas import BufferedCanvas
from printrun_utils import imagefile
def sign(n):
if n < 0: return -1
......@@ -23,7 +24,7 @@ def sign(n):
else: return 0
class ZButtons(BufferedCanvas):
button_ydistances = [7, 30, 55, 83] # ,112
button_ydistances = [7, 30, 55, 83] # ,112
center = (30, 118)
label_overlay_positions = {
0: (1, 18, 11),
......@@ -36,7 +37,7 @@ class ZButtons(BufferedCanvas):
self.bg_bmp = wx.Image(imagefile("control_z.png"), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
self.range = None
self.direction = None
self.orderOfMagnitudeIdx = 0 # 0 means '1', 1 means '10', 2 means '100', etc.
self.orderOfMagnitudeIdx = 0 # 0 means '1', 1 means '10', 2 means '100', etc.
self.moveCallback = moveCallback
self.enabled = False
# Remember the last clicked value, so we can repeat when spacebar pressed
......@@ -83,11 +84,11 @@ class ZButtons(BufferedCanvas):
fudge = 11
x = 0 + fudge
w = 59 - fudge*2
w = 59 - fudge * 2
if rng >= 0:
k = 1 if dir > 0 else 0
y = ZButtons.center[1] - (dir * ZButtons.button_ydistances[rng+k])
h = ZButtons.button_ydistances[rng+1] - ZButtons.button_ydistances[rng]
y = ZButtons.center[1] - (dir * ZButtons.button_ydistances[rng + k])
h = ZButtons.button_ydistances[rng + 1] - ZButtons.button_ydistances[rng]
gc.DrawRoundedRectangle(x, y, w, h, 4)
# gc.DrawRectangle(x, y, w, h)
# self.drawPartialPie(dc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
......@@ -107,16 +108,16 @@ class ZButtons(BufferedCanvas):
if self.enabled:
# Draw label overlays
gc.SetPen(wx.Pen(wx.Colour(255, 255, 255, 128), 1))
gc.SetBrush(wx.Brush(wx.Colour(255, 255, 255, 128+64)))
gc.SetBrush(wx.Brush(wx.Colour(255, 255, 255, 128 + 64)))
for idx, kpos in ZButtons.label_overlay_positions.items():
if kpos and idx != self.range:
r = kpos[2]
gc.DrawEllipse(ZButtons.center[0]-kpos[0]-r, ZButtons.center[1]-kpos[1]-r, r*2, r*2)
gc.DrawEllipse(ZButtons.center[0] - kpos[0] - r, ZButtons.center[1] - kpos[1] - r, r * 2, r * 2)
# Top 'layer' is the mouse-over highlights
gc.SetPen(wx.Pen(wx.Colour(100, 100, 100, 172), 4))
gc.SetBrush(wx.Brush(wx.Colour(0, 0, 0, 128)))
if self.range != None and self.direction != None:
if self.range is not None and self.direction is not None:
self.highlight(gc, self.range, self.direction)
else:
gc.SetPen(wx.Pen(self.bgcolor, 0))
......
......@@ -13,44 +13,39 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import wx, math
from stltool import *
import wx
from stltool import stl, genfacet, emitstl
a = wx.App()
def genscape(data = [[0, 1, 0, 0],[1, 0, 2, 0],[1, 0, 0, 0],[0, 1, 0, 1]], pscale = 1.0, bheight = 1.0, zscale = 1.0):
def genscape(data = [[0, 1, 0, 0], [1, 0, 2, 0], [1, 0, 0, 0], [0, 1, 0, 1]],
pscale = 1.0, bheight = 1.0, zscale = 1.0):
o = stl(None)
datal = len(data)
datah = len(data[0])
#create bottom:
bmidpoint = (pscale*(datal-1)/2.0, pscale*(datah-1)/2.0)
bmidpoint = (pscale * (datal - 1) / 2.0, pscale * (datah - 1) / 2.0)
#print range(datal), bmidpoint
for i in zip(range(datal+1)[:-1], range(datal+1)[1:])[:-1]:
for i in zip(range(datal + 1)[:-1], range(datal + 1)[1:])[:-1]:
#print (pscale*i[0], pscale*i[1])
o.facets+=[[[0, 0,-1],[[0.0, pscale*i[0], 0.0],[0.0, pscale*i[1], 0.0],[bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets+=[[[0, 0,-1],[[2.0*bmidpoint[1], pscale*i[1], 0.0],[2.0*bmidpoint[1], pscale*i[0], 0.0],[bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets+=[genfacet([[0.0, pscale*i[0], data[i[0]][0]*zscale+bheight],[0.0, pscale*i[1], data[i[1]][0]*zscale+bheight],[0.0, pscale*i[1], 0.0]])]
o.facets+=[genfacet([[2.0*bmidpoint[1], pscale*i[1], data[i[1]][datah-1]*zscale+bheight],[2.0*bmidpoint[1], pscale*i[0], data[i[0]][datah-1]*zscale+bheight],[2.0*bmidpoint[1], pscale*i[1], 0.0]])]
o.facets+=[genfacet([[0.0, pscale*i[0], data[i[0]][0]*zscale+bheight],[0.0, pscale*i[1], 0.0],[0.0, pscale*i[0], 0.0]])]
o.facets+=[genfacet([[2.0*bmidpoint[1], pscale*i[1], 0.0],[2.0*bmidpoint[1], pscale*i[0], data[i[0]][datah-1]*zscale+bheight],[2.0*bmidpoint[1], pscale*i[0], 0.0]])]
#print o.facets[-1]
pass
#print o.facets[-4:]
for i in zip(range(datah+1)[:-1], range(datah+1)[1:])[:-1]:
#print (pscale*i[0], pscale*i[1])
o.facets+=[[[0, 0,-1],[[pscale*i[1], 0.0, 0.0],[pscale*i[0], 0.0, 0.0],[bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets+=[[[0, 0,-1],[[pscale*i[0], 2.0*bmidpoint[0], 0.0],[pscale*i[1], 2.0*bmidpoint[0], 0.0],[bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets+=[genfacet([[pscale*i[1], 0.0, data[0][i[1]]*zscale+bheight],[pscale*i[0], 0.0, data[0][i[0]]*zscale+bheight],[pscale*i[1], 0.0, 0.0]])]
#break
o.facets+=[genfacet([[pscale*i[0], 2.0*bmidpoint[0], data[datal-1][i[0]]*zscale+bheight],[pscale*i[1], 2.0*bmidpoint[0], data[datal-1][i[1]]*zscale+bheight],[pscale*i[1], 2.0*bmidpoint[0], 0.0]])]
o.facets+=[genfacet([[pscale*i[1], 0.0, 0.0],[pscale*i[0], 0.0, data[0][i[0]]*zscale+bheight],[pscale*i[0], 0.0, 0.0]])]
o.facets+=[genfacet([[pscale*i[0], 2.0*bmidpoint[0], data[datal-1][i[0]]*zscale+bheight],[pscale*i[1], 2.0*bmidpoint[0], 0.0],[pscale*i[0], 2.0*bmidpoint[0], 0.0]])]
pass
for i in xrange(datah-1):
for j in xrange(datal-1):
o.facets+=[genfacet([[pscale*i, pscale*j, data[j][i]*zscale+bheight],[pscale*(i+1), pscale*(j), data[j][i+1]*zscale+bheight],[pscale*(i+1), pscale*(j+1), data[j+1][i+1]*zscale+bheight]])]
o.facets+=[genfacet([[pscale*(i), pscale*(j+1), data[j+1][i]*zscale+bheight],[pscale*i, pscale*j, data[j][i]*zscale+bheight],[pscale*(i+1), pscale*(j+1), data[j+1][i+1]*zscale+bheight]])]
o.facets += [[[0, 0, -1], [[0.0, pscale * i[0], 0.0], [0.0, pscale * i[1], 0.0], [bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets += [[[0, 0, -1], [[2.0 * bmidpoint[1], pscale * i[1], 0.0], [2.0 * bmidpoint[1], pscale * i[0], 0.0], [bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets += [genfacet([[0.0, pscale * i[0], data[i[0]][0] * zscale + bheight], [0.0, pscale * i[1], data[i[1]][0] * zscale + bheight], [0.0, pscale * i[1], 0.0]])]
o.facets += [genfacet([[2.0 * bmidpoint[1], pscale * i[1], data[i[1]][datah - 1] * zscale + bheight], [2.0 * bmidpoint[1], pscale * i[0], data[i[0]][datah - 1] * zscale + bheight], [2.0 * bmidpoint[1], pscale * i[1], 0.0]])]
o.facets += [genfacet([[0.0, pscale * i[0], data[i[0]][0] * zscale + bheight], [0.0, pscale * i[1], 0.0], [0.0, pscale * i[0], 0.0]])]
o.facets += [genfacet([[2.0 * bmidpoint[1], pscale * i[1], 0.0], [2.0 * bmidpoint[1], pscale * i[0], data[i[0]][datah - 1] * zscale + bheight], [2.0 * bmidpoint[1], pscale * i[0], 0.0]])]
for i in zip(range(datah + 1)[: - 1], range(datah + 1)[1:])[: - 1]:
#print (pscale * i[0], pscale * i[1])
o.facets += [[[0, 0, -1], [[pscale * i[1], 0.0, 0.0], [pscale * i[0], 0.0, 0.0], [bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets += [[[0, 0, -1], [[pscale * i[0], 2.0 * bmidpoint[0], 0.0], [pscale * i[1], 2.0 * bmidpoint[0], 0.0], [bmidpoint[0], bmidpoint[1], 0.0]]]]
o.facets += [genfacet([[pscale * i[1], 0.0, data[0][i[1]] * zscale + bheight], [pscale * i[0], 0.0, data[0][i[0]] * zscale + bheight], [pscale * i[1], 0.0, 0.0]])]
o.facets += [genfacet([[pscale * i[0], 2.0 * bmidpoint[0], data[datal - 1][i[0]] * zscale + bheight], [pscale * i[1], 2.0 * bmidpoint[0], data[datal - 1][i[1]] * zscale + bheight], [pscale * i[1], 2.0 * bmidpoint[0], 0.0]])]
o.facets += [genfacet([[pscale * i[1], 0.0, 0.0], [pscale * i[0], 0.0, data[0][i[0]] * zscale + bheight], [pscale * i[0], 0.0, 0.0]])]
o.facets += [genfacet([[pscale * i[0], 2.0 * bmidpoint[0], data[datal - 1][i[0]] * zscale + bheight], [pscale * i[1], 2.0 * bmidpoint[0], 0.0], [pscale * i[0], 2.0 * bmidpoint[0], 0.0]])]
for i in xrange(datah - 1):
for j in xrange(datal - 1):
o.facets += [genfacet([[pscale * i, pscale * j, data[j][i] * zscale + bheight], [pscale * (i + 1), pscale * (j), data[j][i + 1] * zscale + bheight], [pscale * (i + 1), pscale * (j + 1), data[j + 1][i + 1] * zscale + bheight]])]
o.facets += [genfacet([[pscale * (i), pscale * (j + 1), data[j + 1][i] * zscale + bheight], [pscale * i, pscale * j, data[j][i] * zscale + bheight], [pscale * (i + 1), pscale * (j + 1), data[j + 1][i + 1] * zscale + bheight]])]
#print o.facets[-1]
facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]]
return o
def zimage(name, out):
i = wx.Image(name)
......@@ -59,14 +54,15 @@ def zimage(name, out):
b = map(ord, i.GetData()[::3])
data = []
for i in xrange(s[0]):
data+=[b[i*s[1]:(i+1)*s[1]]]
data += [b[i * s[1]:(i + 1) * s[1]]]
#data = [i[::5] for i in data[::5]]
emitstl(out, genscape(data, zscale = 0.1).facets, name)
"""
class scapewin(wx.Frame):
def __init__(self, size = (400, 530)):
wx.Frame.__init__(self, None, title = "Right-click to load an image", size = size)
wx.Frame.__init__(self, None,
title = "Right-click to load an image", size = size)
self.SetIcon(wx.Icon("plater.ico", wx.BITMAP_TYPE_ICO))
self.SetClientSize(size)
self.panel = wx.Panel(self, size = size)
......
......@@ -15,19 +15,22 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import cmd, sys
import glob, os, time, datetime
import sys, subprocess, traceback
import math, codecs
import cmd
import glob
import os
import time
import sys
import subprocess
import traceback
import codecs
import shlex
from math import sqrt
import argparse
import locale
import printcore
from printrun.printrun_utils import install_locale
from printrun import gcoder
install_locale('pronterface')
from printrun import gcoder
from functools import wraps
......@@ -40,21 +43,21 @@ READLINE = True
try:
import readline
try:
readline.rl.mode.show_all_if_ambiguous = "on" #config pyreadline on windows
readline.rl.mode.show_all_if_ambiguous = "on" # config pyreadline on windows
except:
pass
except:
READLINE = False #neither readline module is available
READLINE = False # neither readline module is available
def dosify(name):
return os.path.split(name)[1].split(".")[0][:8]+".g"
return os.path.split(name)[1].split(".")[0][:8] + ".g"
def setting_add_tooltip(func):
@wraps(func)
def decorator(self, *args, **kwargs):
widget = func(self, *args, **kwargs)
helptxt = self.help or ""
sep,deftxt = "",""
sep, deftxt = "", ""
if len(helptxt):
sep = "\n"
if helptxt.find("\n") >= 0:
......@@ -88,6 +91,7 @@ class Setting(object):
def _get_value(self):
return self._value
def _set_value(self, value):
raise NotImplementedError
value = property(_get_value, _set_value)
......@@ -95,7 +99,7 @@ class Setting(object):
def set_default(self, e):
import wx
if e.CmdDown() and e.ButtonDClick() and self.default is not "":
confirmation = wx.MessageDialog(None,_("Are you sure you want to reset the setting to the default value: {0!r} ?").format(self.default),_("Confirm set default"),wx.ICON_EXCLAMATION|wx.YES_NO|wx.NO_DEFAULT)
confirmation = wx.MessageDialog(None, _("Are you sure you want to reset the setting to the default value: {0!r} ?").format(self.default), _("Confirm set default"), wx.ICON_EXCLAMATION | wx.YES_NO | wx.NO_DEFAULT)
if confirmation.ShowModal() == wx.ID_YES:
self._set_value(self.default)
else:
......@@ -117,7 +121,7 @@ class Setting(object):
def update(self):
raise NotImplementedError
def __str__(self):
return self.name
......@@ -125,7 +129,7 @@ class Setting(object):
return self.name
class HiddenSetting(Setting):
hidden = True
def _set_value(self, value):
......@@ -133,7 +137,7 @@ class HiddenSetting(Setting):
value = property(Setting._get_value, _set_value)
class wxSetting(Setting):
widget = None
def _set_value(self, value):
......@@ -153,7 +157,7 @@ class StringSetting(wxSetting):
return self.widget
class ComboSetting(wxSetting):
def __init__(self, name, default, choices, label = None, help = None, group = None):
super(ComboSetting, self).__init__(name, default, label, help, group)
self.choices = choices
......@@ -164,7 +168,7 @@ class ComboSetting(wxSetting):
return self.widget
class SpinSetting(wxSetting):
def __init__(self, name, default, min, max, label = None, help = None, group = None):
super(SpinSetting, self).__init__(name, default, label, help, group)
self.min = min
......@@ -187,6 +191,7 @@ class BooleanSetting(wxSetting):
def _get_value(self):
return bool(self._value)
def _set_value(self, value):
self._value = value
if self.widget:
......@@ -208,10 +213,13 @@ class StaticTextSetting(wxSetting):
def update(self):
pass
def _get_value(self):
return ""
def _set_value(self, value):
pass
def get_specific_widget(self, parent):
import wx
self.widget = wx.StaticText(parent, -1, self.text)
......@@ -223,6 +231,7 @@ class Settings(object):
# if v < 0: raise ValueError("You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0.")
#def _bedtemperature_alias(self): return {"pla":60, "abs":110, "off":0}
def _baudrate_list(self): return ["2400", "9600", "19200", "38400", "57600", "115200", "250000"]
def __init__(self):
# defaults here.
# the initial value determines the type
......@@ -256,6 +265,7 @@ class Settings(object):
self._add(HiddenSetting("pause_between_prints", True))
_settings = []
def __setattr__(self, name, value):
if name.startswith("_"):
return object.__setattr__(self, name, value)
......@@ -280,31 +290,31 @@ class Settings(object):
def _set(self, key, value):
try:
value = getattr(self, "_%s_alias"%key)()[value]
value = getattr(self, "_%s_alias" % key)()[value]
except KeyError:
pass
except AttributeError:
pass
try:
getattr(self, "_%s_validate"%key)(value)
getattr(self, "_%s_validate" % key)(value)
except AttributeError:
pass
t = type(getattr(self, key))
if t == bool and value == "False": setattr(self, key, False)
else: setattr(self, key, t(value))
try:
getattr(self, "_%s_cb"%key)(key, value)
getattr(self, "_%s_cb" % key)(key, value)
except AttributeError:
pass
return value
def _tabcomplete(self, key):
try:
return getattr(self, "_%s_list"%key)()
return getattr(self, "_%s_list" % key)()
except AttributeError:
pass
try:
return getattr(self, "_%s_alias"%key)().keys()
return getattr(self, "_%s_alias" % key)().keys()
except AttributeError:
pass
return []
......@@ -315,21 +325,21 @@ class Settings(object):
class Status:
def __init__(self):
self.extruder_temp = 0
self.extruder_temp = 0
self.extruder_temp_target = 0
self.bed_temp = 0
self.bed_temp_target = 0
self.print_job = None
self.print_job_progress = 1.0
self.bed_temp = 0
self.bed_temp_target = 0
self.print_job = None
self.print_job_progress = 1.0
def update_tempreading(self, tempstr):
r = tempstr.split()
# eg. r = ["ok", "T:20.5", "/0.0", "B:0.0", "/0.0", "@:0"]
if len(r) == 6:
self.extruder_temp = float(r[1][2:])
self.extruder_temp = float(r[1][2:])
self.extruder_temp_target = float(r[2][1:])
self.bed_temp = float(r[3][2:])
self.bed_temp_target = float(r[4][1:])
self.bed_temp = float(r[3][2:])
self.bed_temp_target = float(r[4][1:])
@property
def bed_enabled(self):
......@@ -340,7 +350,6 @@ class Status:
return self.extruder_temp != 0
class pronsole(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
......@@ -358,8 +367,8 @@ class pronsole(cmd.Cmd):
self.sdfiles = []
self.paused = False
self.sdprinting = 0
self.temps = {"pla":"185", "abs":"230", "off":"0"}
self.bedtemps = {"pla":"60", "abs":"110", "off":"0"}
self.temps = {"pla": "185", "abs": "230", "off": "0"}
self.bedtemps = {"pla": "60", "abs": "110", "off": "0"}
self.percentdone = 0
self.tempreadings = ""
self.macros = {}
......@@ -374,19 +383,19 @@ class pronsole(cmd.Cmd):
self.settings._bedtemp_pla_cb = self.set_temp_preset
self.monitoring = 0
self.silent = False
self.commandprefixes='MGT$'
self.promptstrs = {"offline" : "%(bold)suninitialized>%(normal)s ",
"fallback" : "%(bold)sPC>%(normal)s ",
"macro" : "%(bold)s..>%(normal)s ",
"online" : "%(bold)sT:%(extruder_temp_fancy)s %(progress_fancy)s >%(normal)s "}
self.commandprefixes = 'MGT$'
self.promptstrs = {"offline": "%(bold)suninitialized>%(normal)s ",
"fallback": "%(bold)sPC>%(normal)s ",
"macro": "%(bold)s..>%(normal)s ",
"online": "%(bold)sT:%(extruder_temp_fancy)s %(progress_fancy)s >%(normal)s "}
def confirm(self):
y_or_n = raw_input("y/n: ")
if y_or_n == "y":
return True
elif y_or_n != "n":
return self.confirm()
return False
y_or_n = raw_input("y/n: ")
if y_or_n == "y":
return True
elif y_or_n != "n":
return self.confirm()
return False
def log(self, *msg):
print u"".join(unicode(i) for i in msg)
......@@ -408,31 +417,31 @@ class pronsole(cmd.Cmd):
return promptstr
else:
specials = {}
specials["extruder_temp"] = str(int(self.status.extruder_temp))
specials["extruder_temp"] = str(int(self.status.extruder_temp))
specials["extruder_temp_target"] = str(int(self.status.extruder_temp_target))
if self.status.extruder_temp_target == 0:
specials["extruder_temp_fancy"] = str(int(self.status.extruder_temp))
else:
specials["extruder_temp_fancy"] = "%s/%s" % (str(int(self.status.extruder_temp)), str(int(self.status.extruder_temp_target)))
if self.p.printing:
progress = int(1000*float(self.p.queueindex)/len(self.p.mainqueue)) / 10
progress = int(1000 * float(self.p.queueindex) / len(self.p.mainqueue)) / 10
elif self.sdprinting:
progress = self.percentdone
else:
progress = 0.0
specials["progress"] = str(progress)
if self.p.printing or self.sdprinting:
specials["progress_fancy"] = str(progress) +"%"
specials["progress_fancy"] = str(progress) + "%"
else:
specials["progress_fancy"] = "?%"
specials["bold"] = "\033[01m"
specials["bold"] = "\033[01m"
specials["normal"] = "\033[00m"
return promptstr % specials
def postcmd(self, stop, line):
""" A hook we override to generate prompts after
""" A hook we override to generate prompts after
each command is executed, for the next prompt.
We also use it to send M105 commands so that
We also use it to send M105 commands so that
temp info gets updated for the prompt."""
if self.p.online and self.dynamic_temp:
self.p.send_now("M105")
......@@ -457,8 +466,8 @@ class pronsole(cmd.Cmd):
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM")
i = 0
while(1):
baselist+=[_winreg.EnumValue(key, i)[1]]
i+=1
baselist += [_winreg.EnumValue(key, i)[1]]
i += 1
except:
pass
......@@ -487,9 +496,9 @@ class pronsole(cmd.Cmd):
self.log("Gcodes are passed through to the printer as they are")
def complete_macro(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in self.macros.keys() if i.startswith(text)]
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1]==" ")):
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1] == " ")):
return [i for i in ["/D", "/S"] + self.completenames(text) if i.startswith(text)]
else:
return []
......@@ -497,7 +506,7 @@ class pronsole(cmd.Cmd):
def hook_macro(self, l):
l = l.rstrip()
ls = l.lstrip()
ws = l[:len(l)-len(ls)] # just leading whitespace
ws = l[:len(l) - len(ls)] # just leading whitespace
if len(ws) == 0:
self.end_macro()
# pass the unprocessed line to regular command processor to not require empty line in .pronsolerc
......@@ -505,19 +514,19 @@ class pronsole(cmd.Cmd):
self.cur_macro_def += l + "\n"
def end_macro(self):
if self.__dict__.has_key("onecmd"): del self.onecmd # remove override
if "onecmd" in self.__dict__: del self.onecmd # remove override
self.in_macro = False
self.prompt = self.promptf()
if self.cur_macro_def!="":
if self.cur_macro_def != "":
self.macros[self.cur_macro_name] = self.cur_macro_def
macro = self.compile_macro(self.cur_macro_name, self.cur_macro_def)
setattr(self.__class__, "do_"+self.cur_macro_name, lambda self, largs, macro = macro:macro(self,*largs.split()))
setattr(self.__class__, "help_"+self.cur_macro_name, lambda self, macro_name = self.cur_macro_name: self.subhelp_macro(macro_name))
setattr(self.__class__, "do_" + self.cur_macro_name, lambda self, largs, macro = macro: macro(self, *largs.split()))
setattr(self.__class__, "help_" + self.cur_macro_name, lambda self, macro_name = self.cur_macro_name: self.subhelp_macro(macro_name))
if not self.processing_rc:
self.log("Macro '"+self.cur_macro_name+"' defined")
self.log("Macro '" + self.cur_macro_name + "' defined")
# save it
if not self.processing_args:
macro_key = "macro "+self.cur_macro_name
macro_key = "macro " + self.cur_macro_name
macro_def = macro_key
if "\n" in self.cur_macro_def:
macro_def += "\n"
......@@ -535,14 +544,14 @@ class pronsole(cmd.Cmd):
def compile_macro_line(self, line):
line = line.rstrip()
ls = line.lstrip()
ws = line[:len(line)-len(ls)] # just leading whitespace
if ls == "" or ls.startswith('#'): return "" # no code
ws = line[:len(line) - len(ls)] # just leading whitespace
if ls == "" or ls.startswith('#'): return "" # no code
if ls.startswith('!'):
return ws + ls[1:] + "\n" # python mode
return ws + ls[1:] + "\n" # python mode
else:
ls = ls.replace('"','\\"') # need to escape double quotes
ret = ws + 'self.parseusercmd("'+ls+'".format(*arg))\n' # parametric command mode
return ret + ws + 'self.onecmd("'+ls+'".format(*arg))\n'
ls = ls.replace('"', '\\"') # need to escape double quotes
ret = ws + 'self.parseusercmd("' + ls + '".format(*arg))\n' # parametric command mode
return ret + ws + 'self.onecmd("' + ls + '".format(*arg))\n'
def compile_macro(self, macro_name, macro_def):
if macro_def.strip() == "":
......@@ -550,7 +559,7 @@ class pronsole(cmd.Cmd):
return
pycode = "def macro(self,*arg):\n"
if "\n" not in macro_def.strip():
pycode += self.compile_macro_line(" "+macro_def.strip())
pycode += self.compile_macro_line(" " + macro_def.strip())
else:
lines = macro_def.split("\n")
for l in lines:
......@@ -563,27 +572,28 @@ class pronsole(cmd.Cmd):
self.logError("Enter macro using indented lines, end with empty line")
self.cur_macro_name = macro_name
self.cur_macro_def = ""
self.onecmd = self.hook_macro # override onecmd temporarily
self.onecmd = self.hook_macro # override onecmd temporarily
self.in_macro = False
self.prompt = self.promptf()
def delete_macro(self, macro_name):
if macro_name in self.macros.keys():
delattr(self.__class__, "do_"+macro_name)
delattr(self.__class__, "do_" + macro_name)
del self.macros[macro_name]
self.log("Macro '"+macro_name+"' removed")
self.log("Macro '" + macro_name + "' removed")
if not self.processing_rc and not self.processing_args:
self.save_in_rc("macro "+macro_name, "")
self.save_in_rc("macro " + macro_name, "")
else:
self.logError("Macro '"+macro_name+"' is not defined")
self.logError("Macro '" + macro_name + "' is not defined")
def do_macro(self, args):
if args.strip()=="":
self.print_topics("User-defined macros", map(str,self.macros.keys()), 15, 80)
if args.strip() == "":
self.print_topics("User-defined macros", map(str, self.macros.keys()), 15, 80)
return
arglist = args.split(None, 1)
macro_name = arglist[0]
if macro_name not in self.macros and hasattr(self.__class__, "do_"+macro_name):
self.logError("Name '"+macro_name+"' is being used by built-in command")
if macro_name not in self.macros and hasattr(self.__class__, "do_" + macro_name):
self.logError("Name '" + macro_name + "' is being used by built-in command")
return
if len(arglist) == 2:
macro_def = arglist[1]
......@@ -597,7 +607,7 @@ class pronsole(cmd.Cmd):
self.cur_macro_name = macro_name
self.end_macro()
return
if self.macros.has_key(macro_name):
if macro_name in self.macros:
self.start_macro(macro_name, self.macros[macro_name])
else:
self.start_macro(macro_name)
......@@ -615,19 +625,19 @@ class pronsole(cmd.Cmd):
if macro_name in self.macros.keys():
macro_def = self.macros[macro_name]
if "\n" in macro_def:
self.log("Macro '"+macro_name+"' defined as:")
self.log(self.macros[macro_name]+"----------------")
self.log("Macro '" + macro_name + "' defined as:")
self.log(self.macros[macro_name] + "----------------")
else:
self.log("Macro '"+macro_name+"' defined as: '"+macro_def+"'")
self.log("Macro '" + macro_name + "' defined as: '" + macro_def + "'")
else:
self.logError("Macro '"+macro_name+"' is not defined")
self.logError("Macro '" + macro_name + "' is not defined")
def set(self, var, str):
try:
t = type(getattr(self.settings, var))
value = self.settings._set(var, str)
if not self.processing_rc and not self.processing_args:
self.save_in_rc("set "+var, "set %s %s" % (var, value))
self.save_in_rc("set " + var, "set %s %s" % (var, value))
except AttributeError:
self.logError("Unknown variable '%s'" % var)
except ValueError, ve:
......@@ -639,7 +649,6 @@ class pronsole(cmd.Cmd):
for k in [kk for kk in dir(self.settings) if not kk.startswith("_")]:
self.log("%s = %s" % (k, str(getattr(self.settings, k))))
return
value = getattr(self.settings, args[0])
if len(args) < 2:
try:
self.log("%s = %s" % (args[0], getattr(self.settings, args[0])))
......@@ -654,9 +663,9 @@ class pronsole(cmd.Cmd):
self.log("'set' without arguments displays all variables")
def complete_set(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in dir(self.settings) if not i.startswith("_") and i.startswith(text)]
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1]==" ")):
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1] == " ")):
return [i for i in self.settings._tabcomplete(line.split()[1]) if i.startswith(text)]
else:
return []
......@@ -681,8 +690,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"
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))
......@@ -711,18 +720,18 @@ class pronsole(cmd.Cmd):
written = False
if os.path.exists(self.rc_filename):
import shutil
shutil.copy(self.rc_filename, self.rc_filename+"~bak")
rci = codecs.open(self.rc_filename+"~bak", "r", "utf-8")
shutil.copy(self.rc_filename, self.rc_filename + "~bak")
rci = codecs.open(self.rc_filename + "~bak", "r", "utf-8")
rco = codecs.open(self.rc_filename, "w", "utf-8")
if rci is not None:
overwriting = False
for rc_cmd in rci:
l = rc_cmd.rstrip()
ls = l.lstrip()
ws = l[:len(l)-len(ls)] # just leading whitespace
ws = l[:len(l) - len(ls)] # just leading whitespace
if overwriting and len(ws) == 0:
overwriting = False
if not written and key != "" and rc_cmd.startswith(key) and (rc_cmd+"\n")[len(key)].isspace():
if not written and key != "" and rc_cmd.startswith(key) and (rc_cmd + "\n")[len(key)].isspace():
overwriting = True
written = True
rco.write(definition)
......@@ -739,7 +748,7 @@ class pronsole(cmd.Cmd):
#else:
# self.log("Removed '"+key+"' from '"+self.rc_filename+"'")
except Exception, e:
self.logError("Saving failed for ", key+":", str(e))
self.logError("Saving failed for ", key + ":", str(e))
finally:
del rci, rco
......@@ -752,16 +761,16 @@ class pronsole(cmd.Cmd):
a = l.split()
p = self.scanserial()
port = self.settings.port
if (port == "" or port not in p) and len(p)>0:
if (port == "" or port not in p) and len(p) > 0:
port = p[0]
baud = self.settings.baudrate or 115200
if(len(a)>0):
if len(a) > 0:
port = a[0]
if(len(a)>1):
if len(a) > 1:
try:
baud = int(a[1])
except:
self.log("Bad baud value '"+a[1]+"' ignored")
self.log("Bad baud value '" + a[1] + "' ignored")
if len(p) == 0 and not port:
self.log("No serial ports detected - please specify a port")
return
......@@ -786,9 +795,9 @@ class pronsole(cmd.Cmd):
self.log("No serial ports were automatically found.")
def complete_connect(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in self.scanserial() if i.startswith(text)]
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1]==" ")):
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1] == " ")):
return [i for i in ["2400", "9600", "19200", "38400", "57600", "115200"] if i.startswith(text)]
else:
return []
......@@ -816,13 +825,13 @@ class pronsole(cmd.Cmd):
def complete_load(self, text, line, begidx, endidx):
s = line.split()
if len(s)>2:
if len(s) > 2:
return []
if (len(s) == 1 and line[-1]==" ") or (len(s) == 2 and line[-1]!=" "):
if len(s)>1:
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.g*")]
if (len(s) == 1 and line[-1] == " ") or (len(s) == 2 and line[-1] != " "):
if len(s) > 1:
return [i[len(s[1]) - len(text):] for i in glob.glob(s[1] + "*/") + glob.glob(s[1] + "*.g*")]
else:
return glob.glob("*/")+glob.glob("*.g*")
return glob.glob("*/") + glob.glob("*.g*")
def help_load(self):
self.log("Loads a gcode file (with tab-completion)")
......@@ -850,9 +859,9 @@ class pronsole(cmd.Cmd):
time.sleep(1)
while self.p.printing:
time.sleep(1)
sys.stdout.write("\b\b\b\b\b%04.1f%%" % (100*float(self.p.queueindex)/len(self.p.mainqueue),))
sys.stdout.write("\b\b\b\b\b%04.1f%%" % (100 * float(self.p.queueindex) / len(self.p.mainqueue),))
sys.stdout.flush()
self.p.send_now("M29 "+tname)
self.p.send_now("M29 " + targetname)
self.sleep(0.2)
self.p.clear = 1
self._do_ls(False)
......@@ -862,7 +871,7 @@ class pronsole(cmd.Cmd):
except:
self.logError(_("...interrupted!"))
self.p.pause()
self.p.send_now("M29 "+targetname)
self.p.send_now("M29 " + targetname)
time.sleep(0.2)
self.p.clear = 1
self.p.startprint(None)
......@@ -870,13 +879,13 @@ class pronsole(cmd.Cmd):
def complete_upload(self, text, line, begidx, endidx):
s = line.split()
if len(s)>2:
if len(s) > 2:
return []
if (len(s) == 1 and line[-1]==" ") or (len(s) == 2 and line[-1]!=" "):
if len(s)>1:
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.g*")]
if (len(s) == 1 and line[-1] == " ") or (len(s) == 2 and line[-1] != " "):
if len(s) > 1:
return [i[len(s[1]) - len(text):] for i in glob.glob(s[1] + "*/") + glob.glob(s[1] + "*.g*")]
else:
return glob.glob("*/")+glob.glob("*.g*")
return glob.glob("*/") + glob.glob("*.g*")
def help_upload(self):
self.log("Uploads a gcode file to the sd card")
......@@ -985,7 +994,7 @@ class pronsole(cmd.Cmd):
try:
resp = l.split()
vals = resp[-1].split("/")
self.percentdone = 100.0*int(vals[0])/int(vals[1])
self.percentdone = 100.0 * int(vals[0]) / int(vals[1])
except:
pass
......@@ -1020,7 +1029,7 @@ class pronsole(cmd.Cmd):
self._do_ls(False)
while self.listfiles in self.recvlisteners:
time.sleep(0.1)
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in self.sdfiles if i.startswith(text)]
def recvcb(self, l):
......@@ -1031,7 +1040,7 @@ class pronsole(cmd.Cmd):
if tstring != "ok" and not self.listing and not self.monitoring:
if tstring[:5] == "echo:":
tstring = tstring[5:].lstrip()
if self.silent == False: print "\r" + tstring.ljust(15)
if self.silent is False: print "\r" + tstring.ljust(15)
sys.stdout.write(self.promptf())
sys.stdout.flush()
for i in self.recvlisteners:
......@@ -1045,7 +1054,7 @@ class pronsole(cmd.Cmd):
if l[0] in self.commandprefixes.upper():
if self.p and self.p.online:
if not self.p.loud:
self.log("SENDING:"+l)
self.log("SENDING:" + l)
self.p.send_now(l)
else:
self.logError(_("Printer is not online."))
......@@ -1053,7 +1062,7 @@ class pronsole(cmd.Cmd):
elif l[0] in self.commandprefixes.lower():
if self.p and self.p.online:
if not self.p.loud:
self.log("SENDING:"+l.upper())
self.log("SENDING:" + l.upper())
self.p.send_now(l.upper())
else:
self.logError(_("Printer is not online."))
......@@ -1061,17 +1070,14 @@ class pronsole(cmd.Cmd):
elif l[0] == "@":
if self.p and self.p.online:
if not self.p.loud:
self.log("SENDING:"+l[1:])
self.log("SENDING:" + l[1:])
self.p.send_now(l[1:])
else:
self.logError("printer is not online.")
self.logError(_("Printer is not online."))
return
else:
cmd.Cmd.default(self, l)
def help_help(self):
self.do_help("")
def tempcb(self, l):
if "T:" in l:
self.log(l.strip().replace("T", "Hotend").replace("B", "Bed").replace("ok ", ""))
......@@ -1092,22 +1098,22 @@ class pronsole(cmd.Cmd):
self.log(_("Read the extruder and bed temperature."))
def do_settemp(self, l):
l = l.lower().replace(", ",".")
l = l.lower().replace(", ", ".")
for i in self.temps.keys():
l = l.replace(i, self.temps[i])
try:
f = float(l)
f = float(l)
except:
self.logError(_("You must enter a temperature."))
return
if f>=0:
if f >= 0:
if f > 250:
print _("%s is a high temperature to set your extruder to. Are you sure you want to do that?") % f
if not self.confirm():
return
print _("%s is a high temperature to set your extruder to. Are you sure you want to do that?") % f
if not self.confirm():
return
if self.p.online:
self.p.send_now("M104 S"+l)
self.p.send_now("M104 S" + l)
self.log(_("Setting hotend temperature to %s degrees Celsius.") % f)
else:
self.logError(_("Printer is not online."))
......@@ -1117,16 +1123,16 @@ class pronsole(cmd.Cmd):
def help_settemp(self):
self.log(_("Sets the hotend temperature to the value entered."))
self.log(_("Enter either a temperature in celsius or one of the following keywords"))
self.log(", ".join([i+"("+self.temps[i]+")" for i in self.temps.keys()]))
self.log(", ".join([i + "(" + self.temps[i] + ")" for i in self.temps.keys()]))
def complete_settemp(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in self.temps.keys() if i.startswith(text)]
def do_bedtemp(self, l):
f = None
try:
l = l.lower().replace(", ",".")
l = l.lower().replace(", ", ".")
for i in self.bedtemps.keys():
l = l.replace(i, self.bedtemps[i])
f = float(l)
......@@ -1144,14 +1150,14 @@ class pronsole(cmd.Cmd):
def help_bedtemp(self):
self.log(_("Sets the bed temperature to the value entered."))
self.log(_("Enter either a temperature in celsius or one of the following keywords"))
self.log(", ".join([i+"("+self.bedtemps[i]+")" for i in self.bedtemps.keys()]))
self.log(", ".join([i + "(" + self.bedtemps[i] + ")" for i in self.bedtemps.keys()]))
def complete_bedtemp(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in self.bedtemps.keys() if i.startswith(text)]
def do_move(self, l):
if(len(l.split())<2):
if(len(l.split()) < 2):
self.logError(_("No move specified."))
return
if self.p.printing:
......@@ -1161,24 +1167,23 @@ class pronsole(cmd.Cmd):
self.logError(_("Printer is not online. Unable to move."))
return
l = l.split()
if(l[0].lower()=="x"):
if(l[0].lower() == "x"):
feed = self.settings.xy_feedrate
axis = "X"
elif(l[0].lower()=="y"):
elif(l[0].lower() == "y"):
feed = self.settings.xy_feedrate
axis = "Y"
elif(l[0].lower()=="z"):
elif(l[0].lower() == "z"):
feed = self.settings.z_feedrate
axis = "Z"
elif(l[0].lower()=="e"):
elif(l[0].lower() == "e"):
feed = self.settings.e_feedrate
axis = "E"
else:
self.logError(_("Unknown axis."))
return
dist = 0
try:
dist = float(l[1])
float(l[1]) # check if distance can be a float
except:
self.logError(_("Invalid distance"))
return
......@@ -1187,33 +1192,33 @@ class pronsole(cmd.Cmd):
except:
pass
self.p.send_now("G91")
self.p.send_now("G1 "+axis+str(l[1])+" F"+str(feed))
self.p.send_now("G1 " + axis + str(l[1]) + " F" + str(feed))
self.p.send_now("G90")
def help_move(self):
self.log(_("Move an axis. Specify the name of the axis and the amount. "))
self.log(_("move X 10 will move the X axis forward by 10mm at %s mm/min (default XY speed)") % self.settings.xy_feedrate)
self.log(_("move Y 10 5000 will move the Y axis forward by 10mm at 5000mm/min"))
self.log(_("move Z -1 will move the Z axis down by 1mm at %s mm/min (default Z speed)") % self.settings.z_feedrate)
self.log(_("move Z -1 will move the Z axis down by 1mm at %s mm/min (default Z speed)") % self.settings.z_feedrate)
self.log(_("Common amounts are in the tabcomplete list."))
def complete_move(self, text, line, begidx, endidx):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1]==" "):
if (len(line.split()) == 2 and line[-1] != " ") or (len(line.split()) == 1 and line[-1] == " "):
return [i for i in ["X ", "Y ", "Z ", "E "] if i.lower().startswith(text)]
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1]==" ")):
elif(len(line.split()) == 3 or (len(line.split()) == 2 and line[-1] == " ")):
base = line.split()[-1]
rlen = 0
if base.startswith("-"):
rlen = 1
if line[-1]==" ":
if line[-1] == " ":
base = ""
return [i[rlen:] for i in ["-100", "-10", "-1", "-0.1", "100", "10", "1", "0.1", "-50", "-5", "-0.5", "50", "5", "0.5", "-200", "-20", "-2", "-0.2", "200", "20", "2", "0.2"] if i.startswith(base)]
else:
return []
def do_extrude(self, l, override = None, overridefeed = 300):
length = 5#default extrusion length
feed = self.settings.e_feedrate#default speed
length = 5 # default extrusion length
feed = self.settings.e_feedrate # default speed
if not self.p.online:
self.logError("Printer is not online. Unable to extrude.")
return
......@@ -1226,7 +1231,7 @@ class pronsole(cmd.Cmd):
length = float(ls[0])
except:
self.logError(_("Invalid length given."))
if len(ls)>1:
if len(ls) > 1:
try:
feed = int(ls[1])
except:
......@@ -1237,11 +1242,11 @@ class pronsole(cmd.Cmd):
if length > 0:
self.log(_("Extruding %fmm of filament.") % (length,))
elif length < 0:
self.log(_("Reversing %fmm of filament.") % (-1*length,))
self.log(_("Reversing %fmm of filament.") % (-length,))
else:
self.log(_("Length is 0, not doing anything."))
self.p.send_now("G91")
self.p.send_now("G1 E"+str(length)+" F"+str(feed))
self.p.send_now("G1 E" + str(length) + " F" + str(feed))
self.p.send_now("G90")
def help_extrude(self):
......@@ -1252,8 +1257,8 @@ class pronsole(cmd.Cmd):
self.log(_("extrude 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)"))
def do_reverse(self, l):
length = 5#default extrusion length
feed = self.settings.e_feedrate#default speed
length = 5 # default extrusion length
feed = self.settings.e_feedrate # default speed
if not self.p.online:
self.logError(_("Printer is not online. Unable to reverse."))
return
......@@ -1266,12 +1271,12 @@ class pronsole(cmd.Cmd):
length = float(ls[0])
except:
self.logError(_("Invalid length given."))
if len(ls)>1:
if len(ls) > 1:
try:
feed = int(ls[1])
except:
self.logError(_("Invalid speed given."))
self.do_extrude("", length*-1.0, feed)
self.do_extrude("", -length, feed)
def help_reverse(self):
self.log(_("Reverses the extruder, 5mm by default, or the number of mm given as a parameter"))
......@@ -1326,19 +1331,18 @@ class pronsole(cmd.Cmd):
time.sleep(interval)
#print (self.tempreadings.replace("\r", "").replace("T", "Hotend").replace("B", "Bed").replace("\n", "").replace("ok ", ""))
if self.p.printing:
preface = _("Print progress: ")
progress = 100*float(self.p.queueindex)/len(self.p.mainqueue)
preface = _("Print progress: ")
progress = 100 * float(self.p.queueindex) / len(self.p.mainqueue)
elif self.sdprinting:
preface = _("Print progress: ")
preface = _("Print progress: ")
progress = self.percentdone
progress = int(progress*10)/10.0 #limit precision
prev_msg = preface + str(progress) + "%"
if self.silent == False:
prev_msg = preface + "%.1f%%" % progress
if self.silent is False:
sys.stdout.write("\r" + prev_msg.ljust(prev_msg_len))
sys.stdout.flush()
prev_msg_len = len(prev_msg)
except KeyboardInterrupt:
if self.silent == False: print _("Done monitoring.")
if self.silent is False: print _("Done monitoring.")
self.monitoring = 0
def help_monitor(self):
......@@ -1355,7 +1359,7 @@ class pronsole(cmd.Cmd):
self.logError(_("No file name given."))
return
settings = 0
if(l[0]=="set"):
if l[0] == "set":
settings = 1
else:
self.log(_("Skeining file: %s") % l[0])
......@@ -1379,13 +1383,13 @@ class pronsole(cmd.Cmd):
def complete_skein(self, text, line, begidx, endidx):
s = line.split()
if len(s)>2:
if len(s) > 2:
return []
if (len(s) == 1 and line[-1]==" ") or (len(s) == 2 and line[-1]!=" "):
if len(s)>1:
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.stl")]
if (len(s) == 1 and line[-1] == " ") or (len(s) == 2 and line[-1] != " "):
if len(s) > 1:
return [i[len(s[1]) - len(text):] for i in glob.glob(s[1] + "*/") + glob.glob(s[1] + "*.stl")]
else:
return glob.glob("*/")+glob.glob("*.stl")
return glob.glob("*/") + glob.glob("*.stl")
def help_skein(self):
self.log(_("Creates a gcode file from an stl model using the slicer (with tab-completion)"))
......@@ -1443,8 +1447,8 @@ class pronsole(cmd.Cmd):
self.log(_("Turns off everything on the printer"))
def add_cmdline_arguments(self, parser):
parser.add_argument('-c','--conf','--config', help = _("load this file on startup instead of .pronsolerc ; you may chain config files, if so settings auto-save will use the last specified file"), action = "append", default = [])
parser.add_argument('-e','--execute', help = _("executes command after configuration/.pronsolerc is loaded ; macros/settings from these commands are not autosaved"), action = "append", default = [])
parser.add_argument('-c', '--conf', '--config', help = _("load this file on startup instead of .pronsolerc ; you may chain config files, if so settings auto-save will use the last specified file"), action = "append", default = [])
parser.add_argument('-e', '--execute', help = _("executes command after configuration/.pronsolerc is loaded ; macros/settings from these commands are not autosaved"), action = "append", default = [])
parser.add_argument('filename', nargs='?', help = _("file to load"))
def process_cmdline_arguments(self, args):
......@@ -1487,14 +1491,14 @@ class pronsole(cmd.Cmd):
import readline
self.old_completer = readline.get_completer()
readline.set_completer(self.complete)
readline.parse_and_bind(self.completekey+": complete")
readline.parse_and_bind(self.completekey + ": complete")
except ImportError:
pass
try:
if intro is not None:
self.intro = intro
if self.intro:
self.stdout.write(str(self.intro)+"\n")
self.stdout.write(str(self.intro) + "\n")
stop = None
while not stop:
if self.cmdqueue:
......
......@@ -15,7 +15,17 @@
# 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, Queue, re
import os
import Queue
import re
import sys
import time
import datetime
import threading
import traceback
import cStringIO as StringIO
import subprocess
import shlex
from printrun.printrun_utils import install_locale, RemainingTimeEstimator
install_locale('pronterface')
......@@ -25,24 +35,16 @@ try:
except:
print _("WX is not installed. This program requires WX to run.")
raise
import sys, glob, time, datetime, threading, traceback, cStringIO, subprocess
import shlex
from printrun.pronterface_widgets import *
from printrun.pronterface_widgets import SpecialButton, MacroEditor, \
PronterOptions, ButtonEdit
from serial import SerialException
StringIO = cStringIO
winsize = (800, 500)
layerindex = 0
if os.name == "nt":
winsize = (800, 530)
try:
import _winreg
except:
pass
import printcore
from printrun.printrun_utils import pixmapfile, configfile
from printrun.gui import MainWindow
from printrun.excluder import Excluder
......@@ -67,8 +69,10 @@ class Tee(object):
self.stdout = sys.stdout
sys.stdout = self
self.target = target
def __del__(self):
sys.stdout = self.stdout
def write(self, data):
try:
self.target(data)
......@@ -79,6 +83,7 @@ class Tee(object):
except:
pass
self.stdout.write(data)
def flush(self):
self.stdout.flush()
......@@ -96,7 +101,7 @@ def parse_build_dimensions(bdim):
bdl_float = [float(value) if value else defaults[i] for i, value in enumerate(bdl)]
if len(bdl_float) < len(defaults):
bdl_float += [defaults[i] for i in range(len(bdl_float), len(defaults))]
for i in range(3): # Check for nonpositive dimensions for build volume
for i in range(3): # Check for nonpositive dimensions for build volume
if bdl_float[i] <= 0: bdl_float[i] = 1
return bdl_float
......@@ -113,7 +118,7 @@ class BuildDimensionsSetting(wxSetting):
def _set_widgets_values(self, value):
build_dimensions_list = parse_build_dimensions(value)
for i in range(len(self.widgets)):
self.widgets[i].SetValue(build_dimensions_list[i])
self.widgets[i].SetValue(build_dimensions_list[i])
def get_widget(self, parent):
from wx.lib.agw.floatspin import FloatSpin
......@@ -157,15 +162,8 @@ class BuildDimensionsSetting(wxSetting):
values = [float(w.GetValue()) for w in self.widgets]
self.value = "%.02fx%.02fx%.02f%+.02f%+.02f%+.02f%+.02f%+.02f%+.02f" % tuple(values)
class StringSetting(wxSetting):
def get_specific_widget(self, parent):
import wx
self.widget = wx.TextCtrl(parent, -1, str(self.value))
return self.widget
class ComboSetting(wxSetting):
def __init__(self, name, default, choices, label = None, help = None, group = None):
super(ComboSetting, self).__init__(name, default, label, help, group)
self.choices = choices
......@@ -178,8 +176,10 @@ class ComboSetting(wxSetting):
class PronterWindow(MainWindow, pronsole.pronsole):
_fgcode = None
def _get_fgcode(self):
return self._fgcode
def _set_fgcode(self, value):
self._fgcode = value
self.excluder = None
......@@ -211,14 +211,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.settings._add(SpinSetting("preview_grid_step1", 10., 0, 200, _("Fine grid spacing"), _("Fine Grid Spacing"), "UI"), self.update_gviz_params)
self.settings._add(SpinSetting("preview_grid_step2", 50., 0, 200, _("Coarse grid spacing"), _("Coarse Grid Spacing"), "UI"), self.update_gviz_params)
self.settings._add(StaticTextSetting("note1", _("Note:"), _("Changing most settings here will require restart to get effect"), group = "UI"))
self.pauseScript = "pause.gcode"
self.endScript = "end.gcode"
self.filename = filename
os.putenv("UBUNTU_MENUPROXY", "0")
MainWindow.__init__(self, None, title = _("Pronterface"), size = size);
if hasattr(sys,"frozen") and sys.frozen=="windows_exe":
MainWindow.__init__(self, None, title = _("Pronterface"), size = size)
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))
......@@ -252,30 +252,30 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.build_dimensions_list = parse_build_dimensions(self.settings.build_dimensions)
self.display_graph = self.settings.tempgraph
self.display_gauges = self.settings.tempgauges
#initialize the code analyzer with the correct sizes. There must be a more general way to do so
# minimum = offset
self.p.analyzer.minX = self.build_dimensions_list[3]
self.p.analyzer.minY = self.build_dimensions_list[4]
self.p.analyzer.minZ = self.build_dimensions_list[5]
#max = offset + bedsize
self.p.analyzer.maxX = self.build_dimensions_list[3] + self.build_dimensions_list[0]
self.p.analyzer.maxY = self.build_dimensions_list[4] + self.build_dimensions_list[1]
self.p.analyzer.maxZ = self.build_dimensions_list[5] + self.build_dimensions_list[2]
self.p.analyzer.homeX = self.build_dimensions_list[6]
self.p.analyzer.homeY = self.build_dimensions_list[7]
self.p.analyzer.homeZ = self.build_dimensions_list[8]
#set feedrates in printcore for pause/resume
self.p.xy_feedrate = self.settings.xy_feedrate
self.p.z_feedrate = self.settings.z_feedrate
#make printcore aware of me
self.p.pronterface = self
self.panel.SetBackgroundColour(self.settings.bgcolor)
customdict = {}
try:
......@@ -332,7 +332,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def add_cmdline_arguments(self, parser):
pronsole.pronsole.add_cmdline_arguments(self, parser)
parser.add_argument('-a','--autoconnect', help = _("automatically try to connect to printer on startup"), action = "store_true")
parser.add_argument('-a', '--autoconnect', help = _("automatically try to connect to printer on startup"), action = "store_true")
def process_cmdline_arguments(self, args):
pronsole.pronsole.process_cmdline_arguments(self, args)
......@@ -350,14 +350,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def endcb(self):
if self.p.queueindex == 0:
print_duration = int(time.time () - self.starttime + self.extra_print_time)
print_duration = int(time.time() - self.starttime + self.extra_print_time)
print _("Print ended at: %(end_time)s and took %(duration)s") % {"end_time": format_time(time.time()),
"duration": format_duration(print_duration)}
wx.CallAfter(self.pausebtn.Disable)
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
self.p.runSmallScript(self.endScript)
param = self.settings.final_command
if not param:
return
......@@ -393,7 +393,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
split_raw = gcoder.split(gline)
gcoder.parse_coordinates(gline, split_raw, imperial = False)
if gline.is_move:
if gline.z != None:
if gline.z is not None:
layer = gline.z
if layer != self.curlayer:
self.curlayer = layer
......@@ -402,14 +402,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
elif gline.command in ["M104", "M109"]:
gcoder.parse_coordinates(gline, split_raw, imperial = False, force = True)
gline_s = gcoder.S(gline)
if gline_s != None:
if gline_s is not None:
temp = gline_s
if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp)
if self.display_graph: wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp)
elif gline.command == "M140":
gline.parse_coordinates(gline, split_raw, imperial = False, force = True)
gline_s = gcoder.S(gline)
if gline_s != None:
if gline_s is not None:
temp = gline_s
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp)
if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, temp)
......@@ -429,32 +429,32 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if not self.is_excluded_move(gline):
return gline
else:
if gline.z != None:
if gline.z is not None:
if gline.relative:
if self.excluder_z_abs != None:
if self.excluder_z_abs is not None:
self.excluder_z_abs += gline.z
elif self.excluder_z_rel != None:
elif self.excluder_z_rel is not None:
self.excluder_z_rel += gline.z
else:
self.excluder_z_rel = gline.z
else:
self.excluder_z_rel = None
self.excluder_z_abs = gline.z
if gline.e != None and not gline.relative_e:
if gline.e is not None and not gline.relative_e:
self.excluder_e = gline.e
# If next move won't be excluded, push the changes we have to do
if next_gline != None and not self.is_excluded_move(next_gline):
if self.excluder_e != None:
if next_gline is not None and not self.is_excluded_move(next_gline):
if self.excluder_e is not None:
self.p.send_now("G92 E%.5f" % self.excluder_e)
self.excluder_e = None
if self.excluder_z_abs != None:
if self.excluder_z_abs is not None:
if gline.relative:
self.p.send_now("G90")
self.p.send_now("G1 Z%.5f" % self.excluder_z_abs)
self.excluder_z_abs = None
if gline.relative:
self.p.send_now("G91")
if self.excluder_z_rel != None:
if self.excluder_z_rel is not None:
if not gline.relative:
self.p.send_now("G91")
self.p.send_now("G1 Z%.5f" % self.excluder_z_rel)
......@@ -489,7 +489,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.bsetpoint = f
if self.display_gauges: self.bedtgauge.SetTarget(int(f))
if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, int(f))
if f>0:
if f > 0:
wx.CallAfter(self.btemp.SetValue, str(f))
self.set("last_bed_temperature", str(f))
wx.CallAfter(self.setboff.SetBackgroundColour, None)
......@@ -535,7 +535,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
f = float(l)
if f >= 0:
if self.p.online:
self.p.send_now("M104 S"+l)
self.p.send_now("M104 S" + l)
print _("Setting hotend temperature to %f degrees Celsius.") % f
self.sethotendgui(f)
else:
......@@ -555,7 +555,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
f = float(l)
if f >= 0:
if self.p.online:
self.p.send_now("M140 S"+l)
self.p.send_now("M140 S" + l)
print _("Setting bed temperature to %f degrees Celsius.") % f
self.setbedgui(f)
else:
......@@ -578,7 +578,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def cb(definition):
if len(definition.strip()) == 0:
if old_macro_definition != "":
dialog = wx.MessageDialog(self, _("Do you want to erase the macro?"), style = wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
dialog = wx.MessageDialog(self, _("Do you want to erase the macro?"), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
if dialog.ShowModal() == wx.ID_YES:
self.delete_macro(macro_name)
return
......@@ -594,14 +594,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def catchprint(self, l):
wx.CallAfter(self.addtexttolog, l)
def project(self,event):
def project(self, event):
from printrun import projectlayer
projectlayer.SettingsFrame(self, self.p).Show()
def exclude(self, event):
if not self.fgcode:
wx.CallAfter(self.statusbar.SetStatusText, _("No file loaded. Please use load first."))
return
return
if not self.excluder:
self.excluder = Excluder()
self.excluder.pop_window(self.fgcode, bgcolor = self.settings.bgcolor)
......@@ -614,14 +614,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.Bind(wx.EVT_MENU, self.clearOutput, m.Append(-1, _("Clear console"), _(" Clear output console")))
self.Bind(wx.EVT_MENU, self.OnExit, m.Append(wx.ID_EXIT, _("E&xit"), _(" Closes the Window")))
self.menustrip.Append(m, _("&File"))
m = wx.Menu()
self.Bind(wx.EVT_MENU, self.do_editgcode, m.Append(-1, _("&Edit..."), _(" Edit open file")))
self.Bind(wx.EVT_MENU, self.plate, m.Append(-1, _("Plater"), _(" Compose 3D models into a single plate")))
self.Bind(wx.EVT_MENU, self.exclude, m.Append(-1, _("Excluder"), _(" Exclude parts of the bed from being printed")))
self.Bind(wx.EVT_MENU, self.project, m.Append(-1, _("Projector"), _(" Project slices")))
self.menustrip.Append(m, _("&Tools"))
m = wx.Menu()
self.recoverbtn = m.Append(-1, _("Recover"), _(" Recover previous print after a disconnect (homes X, Y, restores Z and E status)"))
self.recoverbtn.Disable = lambda *a: self.recoverbtn.Enable(False)
......@@ -635,10 +635,10 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.Bind(wx.EVT_MENU, self.new_macro, self.macros_menu.Append(-1, _("<&New...>")))
self.Bind(wx.EVT_MENU, lambda *e: PronterOptions(self), m.Append(-1, _("&Options"), _(" Options dialog")))
self.Bind(wx.EVT_MENU, lambda x: threading.Thread(target = lambda:self.do_skein("set")).start(), m.Append(-1, _("Slicing Settings"), _(" Adjust slicing settings")))
self.Bind(wx.EVT_MENU, lambda x: threading.Thread(target = lambda: self.do_skein("set")).start(), m.Append(-1, _("Slicing Settings"), _(" Adjust slicing settings")))
mItem = m.AppendCheckItem(-1, _("Debug G-code"),
_("Print all G-code sent to and received from the printer."))
_("Print all G-code sent to and received from the printer."))
m.Check(mItem.GetId(), self.p.loud)
self.Bind(wx.EVT_MENU, self.setloud, mItem)
......@@ -668,12 +668,12 @@ class PronterWindow(MainWindow, pronsole.pronsole):
dialog.namectrl = wx.TextCtrl(panel, -1, '', (110, 8), size = (130, 24), style = wx.TE_PROCESS_ENTER)
hbox = wx.BoxSizer(wx.HORIZONTAL)
okb = wx.Button(dialog, wx.ID_OK, _("Ok"), size = (60, 24))
dialog.Bind(wx.EVT_TEXT_ENTER, lambda e:dialog.EndModal(wx.ID_OK), dialog.namectrl)
dialog.Bind(wx.EVT_TEXT_ENTER, lambda e: dialog.EndModal(wx.ID_OK), dialog.namectrl)
#dialog.Bind(wx.EVT_BUTTON, lambda e:self.new_macro_named(dialog, e), okb)
hbox.Add(okb)
hbox.Add(wx.Button(dialog, wx.ID_CANCEL, _("Cancel"), size = (60, 24)))
vbox.Add(panel)
vbox.Add(hbox, 1, wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, 10)
vbox.Add(hbox, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10)
dialog.SetSizer(vbox)
dialog.Centre()
macro = ""
......@@ -686,12 +686,12 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def edit_macro(self, macro):
if macro == "": return self.new_macro()
if self.macros.has_key(macro):
if macro in self.macros:
old_def = self.macros[macro]
elif len([c for c in macro.encode("ascii", "replace") if not c.isalnum() and c != "_"]):
print _("Macro name may contain only ASCII alphanumeric symbols and underscores")
return
elif hasattr(self.__class__, "do_"+macro):
elif hasattr(self.__class__, "do_" + macro):
print _("Name '%s' is being used by built-in command") % macro
return
else:
......@@ -701,7 +701,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def update_macros_menu(self):
if not hasattr(self, "macros_menu"):
return # too early, menu not yet built
return # too early, menu not yet built
try:
while True:
item = self.macros_menu.FindItemByPosition(1)
......@@ -730,16 +730,16 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def cbkey(self, e):
if e.GetKeyCode() == wx.WXK_UP:
if self.commandbox.histindex == len(self.commandbox.history):
self.commandbox.history+=[self.commandbox.GetValue()] #save current command
self.commandbox.history.append(self.commandbox.GetValue()) # save current command
if len(self.commandbox.history):
self.commandbox.histindex = (self.commandbox.histindex-1)%len(self.commandbox.history)
self.commandbox.histindex = (self.commandbox.histindex - 1) % len(self.commandbox.history)
self.commandbox.SetValue(self.commandbox.history[self.commandbox.histindex])
self.commandbox.SetSelection(0, len(self.commandbox.history[self.commandbox.histindex]))
elif e.GetKeyCode() == wx.WXK_DOWN:
if self.commandbox.histindex == len(self.commandbox.history):
self.commandbox.history+=[self.commandbox.GetValue()] #save current command
self.commandbox.history.append(self.commandbox.GetValue()) # save current command
if len(self.commandbox.history):
self.commandbox.histindex = (self.commandbox.histindex+1)%len(self.commandbox.history)
self.commandbox.histindex = (self.commandbox.histindex + 1) % len(self.commandbox.history)
self.commandbox.SetValue(self.commandbox.history[self.commandbox.histindex])
self.commandbox.SetSelection(0, len(self.commandbox.history[self.commandbox.histindex]))
else:
......@@ -784,7 +784,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def update_gviz_params(self, param, value):
params_map = {"preview_extrusion_width": "extrusion_width",
"preview_grid_step1": "grid",
"preview_grid_step2": "grid",}
"preview_grid_step2": "grid"}
if param not in params_map:
return
trueparam = params_map[param]
......@@ -796,7 +796,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
return
if trueparam == "grid":
try:
item = int(param[-1]) # extract list item position
item = int(param[-1]) # extract list item position
grid = list(gviz.grid)
grid[item - 1] = value
value = tuple(grid)
......@@ -837,11 +837,11 @@ class PronterWindow(MainWindow, pronsole.pronsole):
for i, btndef in enumerate(custombuttons):
try:
b = wx.Button(self.centerpanel, -1, btndef.label, style = wx.BU_EXACTFIT)
b.SetToolTip(wx.ToolTip(_("Execute command: ")+btndef.command))
b.SetToolTip(wx.ToolTip(_("Execute command: ") + btndef.command))
if btndef.background:
b.SetBackgroundColour(btndef.background)
rr, gg, bb = b.GetBackgroundColour().Get()
if 0.3*rr+0.59*gg+0.11*bb < 60:
if 0.3 * rr + 0.59 * gg + 0.11 * bb < 60:
b.SetForegroundColour("#ffffff")
except:
if i == len(custombuttons) - 1:
......@@ -851,7 +851,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
b.SetToolTip(wx.ToolTip(_("click to add new custom button")))
b.Bind(wx.EVT_BUTTON, self.cbutton_edit)
else:
b = wx.Button(self.centerpanel,-1, ".", size = (1, 1))
b = wx.Button(self.centerpanel, -1, ".", size = (1, 1))
#b = wx.StaticText(self.panel,-1, "", size = (72, 22), style = wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE) #+wx.SIMPLE_BORDER
b.Disable()
#continue
......@@ -871,7 +871,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def nextarg(rest):
rest = rest.lstrip()
if rest.startswith('"'):
return rest[1:].split('"',1)
return rest[1:].split('"', 1)
else:
return rest.split(None, 1)
#try:
......@@ -886,7 +886,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
except:
pass
command = argstr.strip()
if num<0 or num>=64:
if num < 0 or num >= 64:
print _("Custom button number should be between 0 and 63")
return
while num >= len(self.custombuttons):
......@@ -903,19 +903,19 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def cbutton_save(self, n, bdef, new_n = None):
if new_n is None: new_n = n
if bdef is None or bdef == "":
self.save_in_rc(("button %d" % n),'')
self.save_in_rc(("button %d" % n), '')
elif bdef.background:
colour = bdef.background
if type(colour) not in (str, unicode):
#print type(colour), map(type, colour)
if type(colour) == tuple and tuple(map(type, colour)) == (int, int, int):
colour = map(lambda x:x%256, colour)
colour = wx.Colour(*colour).GetAsString(wx.C2S_NAME|wx.C2S_HTML_SYNTAX)
colour = map(lambda x: x % 256, colour)
colour = wx.Colour(*colour).GetAsString(wx.C2S_NAME | wx.C2S_HTML_SYNTAX)
else:
colour = wx.Colour(colour).GetAsString(wx.C2S_NAME|wx.C2S_HTML_SYNTAX)
self.save_in_rc(("button %d" % n),'button %d "%s" /c "%s" %s' % (new_n, bdef.label, colour, bdef.command))
colour = wx.Colour(colour).GetAsString(wx.C2S_NAME | wx.C2S_HTML_SYNTAX)
self.save_in_rc(("button %d" % n), 'button %d "%s" /c "%s" %s' % (new_n, bdef.label, colour, bdef.command))
else:
self.save_in_rc(("button %d" % n),'button %d "%s" %s' % (new_n, bdef.label, bdef.command))
self.save_in_rc(("button %d" % n), 'button %d "%s" %s' % (new_n, bdef.label, bdef.command))
def cbutton_edit(self, e, button = None):
bedit = ButtonEdit(self)
......@@ -928,20 +928,20 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if type(colour) not in (str, unicode):
#print type(colour)
if type(colour) == tuple and tuple(map(type, colour)) == (int, int, int):
colour = map(lambda x:x%256, colour)
colour = wx.Colour(*colour).GetAsString(wx.C2S_NAME|wx.C2S_HTML_SYNTAX)
colour = map(lambda x: x % 256, colour)
colour = wx.Colour(*colour).GetAsString(wx.C2S_NAME | wx.C2S_HTML_SYNTAX)
else:
colour = wx.Colour(colour).GetAsString(wx.C2S_NAME|wx.C2S_HTML_SYNTAX)
colour = wx.Colour(colour).GetAsString(wx.C2S_NAME | wx.C2S_HTML_SYNTAX)
bedit.color.SetValue(colour)
else:
n = len(self.custombuttons)
while n>0 and self.custombuttons[n-1] is None:
while n > 0 and self.custombuttons[n - 1] is None:
n -= 1
if bedit.ShowModal() == wx.ID_OK:
if n == len(self.custombuttons):
self.custombuttons+=[None]
self.custombuttons[n]=SpecialButton(bedit.name.GetValue().strip(), bedit.command.GetValue().strip(), custom = True)
if bedit.color.GetValue().strip()!="":
self.custombuttons.append(None)
self.custombuttons[n] = SpecialButton(bedit.name.GetValue().strip(), bedit.command.GetValue().strip(), custom = True)
if bedit.color.GetValue().strip() != "":
self.custombuttons[n].background = bedit.color.GetValue()
self.cbutton_save(n, self.custombuttons[n])
wx.CallAfter(bedit.Destroy)
......@@ -957,14 +957,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def cbutton_order(self, e, button, dir):
n = button.custombutton
if dir<0:
n = n-1
if n+1 >= len(self.custombuttons):
self.custombuttons+=[None] # pad
if dir < 0:
n = n - 1
if n + 1 >= len(self.custombuttons):
self.custombuttons.append(None) # pad
# swap
self.custombuttons[n], self.custombuttons[n+1] = self.custombuttons[n+1], self.custombuttons[n]
self.custombuttons[n], self.custombuttons[n + 1] = self.custombuttons[n + 1], self.custombuttons[n]
self.cbutton_save(n, self.custombuttons[n])
self.cbutton_save(n+1, self.custombuttons[n+1])
self.cbutton_save(n + 1, self.custombuttons[n + 1])
#if self.custombuttons[-1] is None:
# del self.custombuttons[-1]
wx.CallAfter(self.cbuttons_reload)
......@@ -979,16 +979,16 @@ class PronterWindow(MainWindow, pronsole.pronsole):
obj = e.GetEventObject()
if hasattr(obj, "custombutton"):
item = popupmenu.Append(-1, _("Edit custom button '%s'") % e.GetEventObject().GetLabelText())
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject():self.cbutton_edit(e, button), item)
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject(): self.cbutton_edit(e, button), item)
item = popupmenu.Append(-1, _("Move left <<"))
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject():self.cbutton_order(e, button,-1), item)
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject(): self.cbutton_order(e, button, -1), item)
if obj.custombutton == 0: item.Enable(False)
item = popupmenu.Append(-1, _("Move right >>"))
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject():self.cbutton_order(e, button, 1), item)
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject(): self.cbutton_order(e, button, 1), item)
if obj.custombutton == 63: item.Enable(False)
pos = self.panel.ScreenToClient(e.GetEventObject().ClientToScreen(pos))
item = popupmenu.Append(-1, _("Remove custom button '%s'") % e.GetEventObject().GetLabelText())
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject():self.cbutton_remove(e, button), item)
self.Bind(wx.EVT_MENU, lambda e, button = e.GetEventObject(): self.cbutton_remove(e, button), item)
else:
item = popupmenu.Append(-1, _("Add custom button"))
self.Bind(wx.EVT_MENU, self.cbutton_edit, item)
......@@ -1001,8 +1001,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
e.Skip()
return
else:
dx, dy = self.dragpos[0]-scrpos[0], self.dragpos[1]-scrpos[1]
if dx*dx+dy*dy < 5*5: # threshold to detect dragging for jittery mice
dx, dy = self.dragpos[0] - scrpos[0], self.dragpos[1] - scrpos[1]
if dx * dx + dy * dy < 5 * 5: # threshold to detect dragging for jittery mice
e.Skip()
return
if not hasattr(self, "dragging"):
......@@ -1027,7 +1027,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.uppersizer.SetItemMinSize(b, obj.GetSize())
self.mainsizer.Layout()
# b.SetStyle(wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE+wx.SIMPLE_BORDER)
self.dragging = wx.Button(self.panel,-1, obj.GetLabel(), style = wx.BU_EXACTFIT)
self.dragging = wx.Button(self.panel, -1, obj.GetLabel(), style = wx.BU_EXACTFIT)
self.dragging.SetBackgroundColour(obj.GetBackgroundColour())
self.dragging.SetForegroundColour(obj.GetForegroundColour())
self.dragging.sourcebutton = obj
......@@ -1042,7 +1042,6 @@ class PronterWindow(MainWindow, pronsole.pronsole):
# dragging in progress
self.dragging.SetPosition(self.panel.ScreenToClient(scrpos))
wx.CallAfter(self.dragging.Refresh)
btns = self.custombuttonbuttons
dst = None
src = self.dragging.sourcebutton
drg = self.dragging
......@@ -1116,13 +1115,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def homeButtonClicked(self, corner):
# When user clicks on the XY control, the Z control no longer gets spacebar/repeat signals
self.zb.clearRepeat()
if corner == 0: # upper-left
if corner == 0: # upper-left
self.onecmd('home X')
elif corner == 1: # upper-right
elif corner == 1: # upper-right
self.onecmd('home Y')
elif corner == 2: # lower-right
elif corner == 2: # lower-right
self.onecmd('home Z')
elif corner == 3: # lower-left
elif corner == 3: # lower-left
self.onecmd('home')
else:
return
......@@ -1176,7 +1175,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def procbutton(self, e):
try:
if hasattr(e.GetEventObject(),"custombutton"):
if hasattr(e.GetEventObject(), "custombutton"):
if wx.GetKeyState(wx.WXK_CONTROL) or wx.GetKeyState(wx.WXK_ALT):
return self.editbutton(e)
self.cur_button = e.GetEventObject().custombutton
......@@ -1206,14 +1205,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
wx.CallAfter(self.Destroy)
def do_monitor(self, l = ""):
if l.strip()=="":
if l.strip() == "":
self.monitorbox.SetValue(not self.monitorbox.GetValue())
elif l.strip()=="off":
elif l.strip() == "off":
wx.CallAfter(self.monitorbox.SetValue, False)
else:
try:
self.monitor_interval = float(l)
wx.CallAfter(self.monitorbox.SetValue, self.monitor_interval>0)
wx.CallAfter(self.monitorbox.SetValue, self.monitor_interval > 0)
except:
print _("Invalid period given.")
self.setmonitor(None)
......@@ -1231,20 +1230,20 @@ class PronterWindow(MainWindow, pronsole.pronsole):
else:
wx.CallAfter(self.graph.StopPlotting)
def addtexttolog(self,text):
def addtexttolog(self, text):
try:
self.logbox.AppendText(text)
except:
print _("Attempted to write invalid text to console, which could be due to an invalid baudrate")
def setloud(self,e):
self.p.loud=e.IsChecked()
def setloud(self, e):
self.p.loud = e.IsChecked()
def sendline(self, e):
command = self.commandbox.GetValue()
if not len(command):
return
wx.CallAfter(self.addtexttolog, ">>>" + command + "\n");
wx.CallAfter(self.addtexttolog, ">>>" + command + "\n")
self.parseusercmd(str(command))
self.onecmd(str(command))
self.commandbox.SetSelection(0, len(command))
......@@ -1286,7 +1285,6 @@ class PronterWindow(MainWindow, pronsole.pronsole):
setpoint = float(setpoint)
if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, setpoint)
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, setpoint)
except:
traceback.print_exc()
......@@ -1314,8 +1312,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.sdprinting or self.uploading:
if self.uploading:
fractioncomplete = float(self.p.queueindex) / len(self.p.mainqueue)
string += _("SD upload: %04.2f%% |") % (100*fractioncomplete,)
string += _(" Line# %d of %d lines |" ) % (self.p.queueindex, len(self.p.mainqueue))
string += _("SD upload: %04.2f%% |") % (100 * fractioncomplete,)
string += _(" Line# %d of %d lines |") % (self.p.queueindex, len(self.p.mainqueue))
else:
fractioncomplete = float(self.percentdone / 100.0)
string += _("SD printing: %04.2f%% |") % (self.percentdone,)
......@@ -1328,8 +1326,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
string += _(" Z: %.3f mm") % self.curlayer
elif self.p.printing:
fractioncomplete = float(self.p.queueindex) / len(self.p.mainqueue)
string += _("Printing: %04.2f%% |") % (100*float(self.p.queueindex)/len(self.p.mainqueue),)
string += _(" Line# %d of %d lines |" ) % (self.p.queueindex, len(self.p.mainqueue))
string += _("Printing: %04.2f%% |") % (100 * float(self.p.queueindex) / len(self.p.mainqueue),)
string += _(" Line# %d of %d lines |") % (self.p.queueindex, len(self.p.mainqueue))
if self.p.queueindex > 0:
secondselapsed = int(time.time() - self.starttime + self.extra_print_time)
secondsremain, secondsestimate = self.compute_eta(self.p.queueindex, secondselapsed)
......@@ -1390,7 +1388,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
isreport = True
tstring = l.rstrip()
if not self.p.loud and (tstring not in ["ok", "wait"] and not isreport):
wx.CallAfter(self.addtexttolog, tstring + "\n");
wx.CallAfter(self.addtexttolog, tstring + "\n")
for listener in self.recvlisteners:
listener(l)
......@@ -1428,7 +1426,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
try:
resp = l.split()
vals = resp[-1].split("/")
self.percentdone = 100.0*int(vals[0])/int(vals[1])
self.percentdone = 100.0 * int(vals[0]) / int(vals[1])
except:
pass
......@@ -1437,8 +1435,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if(dlg.ShowModal() == wx.ID_OK):
target = dlg.GetStringSelection()
if len(target):
self.recvlisteners+=[self.waitforsdresponse]
self.p.send_now("M23 "+target.lower())
self.recvlisteners.append(self.waitforsdresponse)
self.p.send_now("M23 " + target.lower())
dlg.Destroy()
#print self.sdfiles
......@@ -1468,7 +1466,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.skeinp = subprocess.Popen(pararray, stderr = subprocess.STDOUT, stdout = subprocess.PIPE)
while True:
o = self.skeinp.stdout.read(1)
if o == '' and self.skeinp.poll() != None: break
if o == '' and self.skeinp.poll() is not None: break
sys.stdout.write(o)
self.skeinp.wait()
self.stopsf = 1
......@@ -1480,7 +1478,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def skein_monitor(self):
while not self.stopsf:
try:
wx.CallAfter(self.statusbar.SetStatusText, _("Slicing..."))#+self.cout.getvalue().split("\n")[-1])
wx.CallAfter(self.statusbar.SetStatusText, _("Slicing...")) # +self.cout.getvalue().split("\n")[-1])
except:
pass
time.sleep(0.1)
......@@ -1518,7 +1516,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
# handle it when everything has been prepared
self.filename = filename
def do_load(self,l):
def do_load(self, l):
if hasattr(self, 'skeining'):
self.loadfile(None, l)
else:
......@@ -1537,7 +1535,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
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 = 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:
......@@ -1631,7 +1629,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
return
if not self.p.online:
return
dlg = wx.TextEntryDialog(self, ("Enter a target filename in 8.3 format:"), _("Pick SD filename") ,dosify(self.filename))
dlg = wx.TextEntryDialog(self, ("Enter a target filename in 8.3 format:"), _("Pick SD filename"), dosify(self.filename))
if dlg.ShowModal() == wx.ID_OK:
self.p.send_now("M21")
self.p.send_now("M28 " + str(dlg.GetValue()))
......@@ -1764,7 +1762,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def reset(self, event):
print _("Reset.")
dlg = wx.MessageDialog(self, _("Are you sure you want to reset the printer?"), _("Reset?"), wx.YES|wx.NO)
dlg = wx.MessageDialog(self, _("Are you sure you want to reset the printer?"), _("Reset?"), wx.YES | wx.NO)
if dlg.ShowModal() == wx.ID_YES:
self.p.reset()
self.sethotendgui(0)
......@@ -1778,7 +1776,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
dlg.Destroy()
def lock(self, event = None, force = None):
if force != None:
if force is not None:
self.locker.SetValue(force)
if self.locker.GetValue():
print _("Locking interface.")
......
......@@ -15,9 +15,9 @@
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import sys, os, glob
import subprocess
from stat import *
import sys
import os
from stat import S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH
from distutils.core import setup
from distutils.command.install import install as _install
from distutils.command.install_data import install_data as _install_data
......@@ -33,93 +33,93 @@ INSTALLED_FILES = "installed_files"
class install (_install):
def run (self):
_install.run (self)
outputs = self.get_outputs ()
def run(self):
_install.run(self)
outputs = self.get_outputs()
length = 0
if self.root:
length += len (self.root)
length += len(self.root)
if self.prefix:
length += len (self.prefix)
length += len(self.prefix)
if length:
for counter in xrange (len (outputs)):
for counter in xrange(len(outputs)):
outputs[counter] = outputs[counter][length:]
data = "\n".join (outputs)
data = "\n".join(outputs)
try:
file = open (INSTALLED_FILES, "w")
file = open(INSTALLED_FILES, "w")
except:
self.warn ("Could not write installed files list %s" % \
INSTALLED_FILES)
self.warn("Could not write installed files list %s" %
INSTALLED_FILES)
return
file.write (data)
file.close ()
file.write(data)
file.close()
class install_data (_install_data):
class install_data(_install_data):
def run (self):
def chmod_data_file (file):
def run(self):
def chmod_data_file(file):
try:
os.chmod (file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
os.chmod(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
except:
self.warn ("Could not chmod data file %s" % file)
_install_data.run (self)
map (chmod_data_file, self.get_outputs ())
self.warn("Could not chmod data file %s" % file)
_install_data.run(self)
map(chmod_data_file, self.get_outputs())
class uninstall (_install):
class uninstall(_install):
def run (self):
def run(self):
try:
file = open (INSTALLED_FILES, "r")
file = open(INSTALLED_FILES, "r")
except:
self.warn ("Could not read installed files list %s" % \
INSTALLED_FILES)
self.warn("Could not read installed files list %s" %
INSTALLED_FILES)
return
files = file.readlines ()
file.close ()
files = file.readlines()
file.close()
prepend = ""
if self.root:
prepend += self.root
if self.prefix:
prepend += self.prefix
if len (prepend):
for counter in xrange (len (files)):
files[counter] = prepend + files[counter].rstrip ()
if len(prepend):
for counter in xrange(len(files)):
files[counter] = prepend + files[counter].rstrip()
for file in files:
print "Uninstalling %s" % file
print "Uninstalling", file
try:
os.unlink (file)
os.unlink(file)
except:
self.warn ("Could not remove file %s" % file)
self.warn("Could not remove file %s" % file)
ops = ("install", "build", "sdist", "uninstall", "clean", "build_ext")
if len (sys.argv) < 2 or sys.argv[1] not in ops:
print "Please specify operation : %s" % " | ".join (ops)
if len(sys.argv) < 2 or sys.argv[1] not in ops:
print "Please specify operation : %s" % " | ".join(ops)
raise SystemExit
prefix = None
if len (sys.argv) > 2:
if len(sys.argv) > 2:
i = 0
for o in sys.argv:
if o.startswith ("--prefix"):
if o.startswith("--prefix"):
if o == "--prefix":
if len (sys.argv) >= i:
if len(sys.argv) >= i:
prefix = sys.argv[i + 1]
sys.argv.remove (prefix)
elif o.startswith ("--prefix=") and len (o[9:]):
sys.argv.remove(prefix)
elif o.startswith("--prefix=") and len(o[9:]):
prefix = o[9:]
sys.argv.remove (o)
sys.argv.remove(o)
i += 1
if not prefix and "PREFIX" in os.environ:
prefix = os.environ["PREFIX"]
if not prefix or not len (prefix):
if not prefix or not len(prefix):
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]
target_images_path = "share/pronterface/images/"
data_files = [('share/pixmaps/', ['P-face.ico','plater.ico','pronsole.ico'])]
data_files = [('share/pixmaps/', ['P-face.ico', 'plater.ico', 'pronsole.ico'])]
for basedir, subdirs, files in os.walk("images"):
images = []
......@@ -135,30 +135,29 @@ for basedir, subdirs, files in os.walk("locale"):
destpath = os.path.join("share", "pronterface", basedir)
files = filter(lambda x: x.endswith(".mo"), files)
files = map(lambda x: os.path.join(basedir, x), files)
data_files.append ((destpath, files))
data_files.append((destpath, files))
extra_data_dirs = ["css"]
for extra_data_dir in extra_data_dirs:
for basedir, subdirs, files in os.walk(extra_data_dir):
files = map(lambda x: os.path.join(basedir, x), files)
destpath = os.path.join("share", "pronterface", basedir)
data_files.append ((destpath, files))
data_files.append((destpath, files))
cmdclass = {"uninstall" : uninstall,
"install" : install,
"install_data" : install_data}
cmdclass = {"uninstall": uninstall,
"install": install,
"install_data": install_data}
if build_ext:
cmdclass['build_ext'] = build_ext
setup (
name = "Printrun",
description = "Host software for 3D printers",
author = "Kliment Yanev",
url = "http://github.com/kliment/Printrun/",
license = "GPLv3",
data_files = data_files,
packages = ["printrun", "printrun.cairosvg", "printrun.server", "printrun.gl", "printrun.gl.libtatlin"],
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = cmdclass,
ext_modules = extensions,
)
setup(name = "Printrun",
description = "Host software for 3D printers",
author = "Kliment Yanev",
url = "http://github.com/kliment/Printrun/",
license = "GPLv3",
data_files = data_files,
packages = ["printrun", "printrun.cairosvg", "printrun.server", "printrun.gl", "printrun.gl.libtatlin"],
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = cmdclass,
ext_modules = extensions,
)
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