Run reindent.py on the whole repository
parent
ec596c5ab6
commit
8cc134955f
28
plater.py
28
plater.py
|
@ -1,17 +1,17 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -336,25 +336,25 @@ class stlwin(wx.Frame):
|
||||||
def center(self, event):
|
def center(self, event):
|
||||||
i = self.l.GetSelection()
|
i = self.l.GetSelection()
|
||||||
if i != -1:
|
if i != -1:
|
||||||
m = self.models[self.l.GetString(i)]
|
m = self.models[self.l.GetString(i)]
|
||||||
m.offsets = [100, 100, m.offsets[2]]
|
m.offsets = [100, 100, m.offsets[2]]
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def snap(self, event):
|
def snap(self, event):
|
||||||
i = self.l.GetSelection()
|
i = self.l.GetSelection()
|
||||||
if i != -1:
|
if i != -1:
|
||||||
m = self.models[self.l.GetString(i)]
|
m = self.models[self.l.GetString(i)]
|
||||||
m.offsets[2] = -1.0 * min(m.facetsminz)[0]
|
m.offsets[2] = -1.0 * min(m.facetsminz)[0]
|
||||||
#print m.offsets[2]
|
#print m.offsets[2]
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def delete(self, event):
|
def delete(self, event):
|
||||||
i = self.l.GetSelection()
|
i = self.l.GetSelection()
|
||||||
if i != -1:
|
if i != -1:
|
||||||
del self.models[self.l.GetString(i)]
|
del self.models[self.l.GetString(i)]
|
||||||
self.l.Delete(i)
|
self.l.Delete(i)
|
||||||
self.l.Select(self.l.GetCount() - 1)
|
self.l.Select(self.l.GetCount() - 1)
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def done(self, event, cb):
|
def done(self, event, cb):
|
||||||
try:
|
try:
|
||||||
|
|
42
printcore.py
42
printcore.py
|
@ -1,17 +1,17 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class printcore():
|
||||||
self.clear = 0 #clear to send, enabled after responses
|
self.clear = 0 #clear to send, enabled after responses
|
||||||
self.online = False #The printer has responded to the initial command and is active
|
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.printing = False #is a print currently running, true if printing, false if paused
|
||||||
self.mainqueue = []
|
self.mainqueue = []
|
||||||
self.priqueue = []
|
self.priqueue = []
|
||||||
self.queueindex = 0
|
self.queueindex = 0
|
||||||
self.lineno = 0
|
self.lineno = 0
|
||||||
|
@ -69,7 +69,7 @@ class printcore():
|
||||||
self.print_thread = None
|
self.print_thread = None
|
||||||
if port is not None and baud is not None:
|
if port is not None and baud is not None:
|
||||||
self.connect(port, baud)
|
self.connect(port, baud)
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
"""Disconnects from printer and pauses the print
|
"""Disconnects from printer and pauses the print
|
||||||
"""
|
"""
|
||||||
|
@ -82,7 +82,7 @@ class printcore():
|
||||||
self.printer = None
|
self.printer = None
|
||||||
self.online = False
|
self.online = False
|
||||||
self.printing = False
|
self.printing = False
|
||||||
|
|
||||||
def connect(self,port=None,baud=None):
|
def connect(self,port=None,baud=None):
|
||||||
"""Set port and baudrate if given, then connect to printer
|
"""Set port and baudrate if given, then connect to printer
|
||||||
"""
|
"""
|
||||||
|
@ -98,7 +98,7 @@ class printcore():
|
||||||
self.stop_read_thread = False
|
self.stop_read_thread = False
|
||||||
self.read_thread = Thread(target=self._listen)
|
self.read_thread = Thread(target=self._listen)
|
||||||
self.read_thread.start()
|
self.read_thread.start()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset the printer
|
"""Reset the printer
|
||||||
"""
|
"""
|
||||||
|
@ -106,7 +106,7 @@ class printcore():
|
||||||
self.printer.setDTR(1)
|
self.printer.setDTR(1)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
self.printer.setDTR(0)
|
self.printer.setDTR(0)
|
||||||
|
|
||||||
def _readline(self):
|
def _readline(self):
|
||||||
try:
|
try:
|
||||||
line = self.printer.readline()
|
line = self.printer.readline()
|
||||||
|
@ -164,11 +164,11 @@ class printcore():
|
||||||
self.clear = True
|
self.clear = True
|
||||||
if line.startswith('ok') and "T:" in line and self.tempcb:
|
if line.startswith('ok') and "T:" in line and self.tempcb:
|
||||||
#callback for temp, status, whatever
|
#callback for temp, status, whatever
|
||||||
try: self.tempcb(line)
|
try: self.tempcb(line)
|
||||||
except: pass
|
except: pass
|
||||||
elif line.startswith('Error'):
|
elif line.startswith('Error'):
|
||||||
if self.errorcb:
|
if self.errorcb:
|
||||||
#callback for errors
|
#callback for errors
|
||||||
try: self.errorcb(line)
|
try: self.errorcb(line)
|
||||||
except: pass
|
except: pass
|
||||||
if line.lower().startswith("resend") or line.startswith("rs"):
|
if line.lower().startswith("resend") or line.startswith("rs"):
|
||||||
|
@ -181,10 +181,10 @@ class printcore():
|
||||||
self.resendfrom = toresend
|
self.resendfrom = toresend
|
||||||
self.clear = True
|
self.clear = True
|
||||||
self.clear = True
|
self.clear = True
|
||||||
|
|
||||||
def _checksum(self, command):
|
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, data, startindex = 0):
|
def startprint(self, data, startindex = 0):
|
||||||
"""Start a print, data is an array of gcode commands.
|
"""Start a print, data is an array of gcode commands.
|
||||||
returns True on success, False if already printing.
|
returns True on success, False if already printing.
|
||||||
|
@ -205,7 +205,7 @@ class printcore():
|
||||||
self.print_thread = Thread(target = self._print)
|
self.print_thread = Thread(target = self._print)
|
||||||
self.print_thread.start()
|
self.print_thread.start()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
"""Pauses the print, saving the current position.
|
"""Pauses the print, saving the current position.
|
||||||
"""
|
"""
|
||||||
|
@ -213,7 +213,7 @@ class printcore():
|
||||||
self.printing = False
|
self.printing = False
|
||||||
self.print_thread.join()
|
self.print_thread.join()
|
||||||
self.print_thread = None
|
self.print_thread = None
|
||||||
|
|
||||||
def resume(self):
|
def resume(self):
|
||||||
"""Resumes a paused print.
|
"""Resumes a paused print.
|
||||||
"""
|
"""
|
||||||
|
@ -221,11 +221,11 @@ class printcore():
|
||||||
self.printing = True
|
self.printing = True
|
||||||
self.print_thread = Thread(target = self._print)
|
self.print_thread = Thread(target = self._print)
|
||||||
self.print_thread.start()
|
self.print_thread.start()
|
||||||
|
|
||||||
def send(self, command, wait = 0):
|
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.online:
|
||||||
if self.printing:
|
if self.printing:
|
||||||
self.mainqueue.append(command)
|
self.mainqueue.append(command)
|
||||||
|
@ -243,7 +243,7 @@ class printcore():
|
||||||
wait -= 1
|
wait -= 1
|
||||||
else:
|
else:
|
||||||
print "Not connected to printer."
|
print "Not connected to printer."
|
||||||
|
|
||||||
def send_now(self, command, wait = 0):
|
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
|
||||||
"""
|
"""
|
||||||
|
@ -263,7 +263,7 @@ class printcore():
|
||||||
wait -= 1
|
wait -= 1
|
||||||
else:
|
else:
|
||||||
print "Not connected to printer."
|
print "Not connected to printer."
|
||||||
|
|
||||||
def _print(self):
|
def _print(self):
|
||||||
if self.startcb:
|
if self.startcb:
|
||||||
#callback for printing started
|
#callback for printing started
|
||||||
|
@ -278,7 +278,7 @@ class printcore():
|
||||||
#callback for printing done
|
#callback for printing done
|
||||||
try: self.endcb()
|
try: self.endcb()
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
def _sendnext(self):
|
def _sendnext(self):
|
||||||
if not self.printer:
|
if not self.printer:
|
||||||
return
|
return
|
||||||
|
@ -313,7 +313,7 @@ class printcore():
|
||||||
self.queueindex = 0
|
self.queueindex = 0
|
||||||
self.lineno = 0
|
self.lineno = 0
|
||||||
self._send("M110", -1, True)
|
self._send("M110", -1, True)
|
||||||
|
|
||||||
def _send(self, command, lineno = 0, calcchecksum = False):
|
def _send(self, command, lineno = 0, calcchecksum = False):
|
||||||
if calcchecksum:
|
if calcchecksum:
|
||||||
prefix = "N" + str(lineno) + " " + command
|
prefix = "N" + str(lineno) + " " + command
|
||||||
|
|
|
@ -16,13 +16,13 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
|
||||||
self.cancelButton = wx.Button(self, wx.ID_CANCEL, "")
|
self.cancelButton = wx.Button(self, wx.ID_CANCEL, "")
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnExit, self.cancelButton)
|
self.Bind(wx.EVT_BUTTON, self.OnExit, self.cancelButton)
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnSave, self.okButton)
|
self.Bind(wx.EVT_BUTTON, self.OnSave, self.okButton)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The following list determines which settings are shown.
|
The following list determines which settings are shown.
|
||||||
The dictionary key is the plugin name and the value is a list of setting names as found in the corresponding .csv file for that plugin.
|
The dictionary key is the plugin name and the value is a list of setting names as found in the corresponding .csv file for that plugin.
|
||||||
|
|
||||||
NOTE: Skeinforge is tightly integrated with Tkinter and there appears to be a dependency which stops radio-button values from being saved.
|
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.
|
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 = {
|
self.moduleSettingsMap = {
|
||||||
'dimension':['Filament Diameter (mm):','Retraction Distance (millimeters):', 'Retraction Distance (millimeters):','Extruder Retraction Speed (mm/s):'],
|
'dimension':['Filament Diameter (mm):','Retraction Distance (millimeters):', 'Retraction Distance (millimeters):','Extruder Retraction Speed (mm/s):'],
|
||||||
|
@ -34,28 +34,28 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
|
||||||
'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):',],
|
'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):']
|
'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.scrollbarPanel = wx.ScrolledWindow(self, -1, style=wx.TAB_TRAVERSAL)
|
||||||
self.settingsSizer = self.getProfileSettings()
|
self.settingsSizer = self.getProfileSettings()
|
||||||
self.scrollbarPanel.SetSizer(self.settingsSizer)
|
self.scrollbarPanel.SetSizer(self.settingsSizer)
|
||||||
|
|
||||||
self.__set_properties()
|
self.__set_properties()
|
||||||
self.__do_layout()
|
self.__do_layout()
|
||||||
self.Show()
|
self.Show()
|
||||||
|
|
||||||
def __set_properties(self):
|
def __set_properties(self):
|
||||||
self.profileName = skeinforge_profile.getProfileName(skeinforge_profile.getCraftTypeName())
|
self.profileName = skeinforge_profile.getProfileName(skeinforge_profile.getCraftTypeName())
|
||||||
self.SetTitle("Skeinforge Quick Edit Profile: " + self.profileName)
|
self.SetTitle("Skeinforge Quick Edit Profile: " + self.profileName)
|
||||||
|
|
||||||
# For some reason the dialog size is not consistent between Windows and Linux - this is a hack to get it working
|
# For some reason the dialog size is not consistent between Windows and Linux - this is a hack to get it working
|
||||||
if (os.name == 'nt'):
|
if (os.name == 'nt'):
|
||||||
self.SetMinSize(wx.DLG_SZE(self, (465, 370)))
|
self.SetMinSize(wx.DLG_SZE(self, (465, 370)))
|
||||||
else:
|
else:
|
||||||
self.SetSize(wx.DLG_SZE(self, (465, 325)))
|
self.SetSize(wx.DLG_SZE(self, (465, 325)))
|
||||||
|
|
||||||
self.SetPosition((0, 0))
|
self.SetPosition((0, 0))
|
||||||
self.scrollbarPanel.SetScrollRate(10, 10)
|
self.scrollbarPanel.SetScrollRate(10, 10)
|
||||||
|
|
||||||
def __do_layout(self):
|
def __do_layout(self):
|
||||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
actionsSizer = wx.BoxSizer(wx.HORIZONTAL)
|
actionsSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
@ -65,34 +65,34 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
|
||||||
mainSizer.Add(actionsSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 5)
|
mainSizer.Add(actionsSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 5)
|
||||||
self.SetSizer(mainSizer)
|
self.SetSizer(mainSizer)
|
||||||
self.Layout()
|
self.Layout()
|
||||||
|
|
||||||
def getProfileSettings(self):
|
def getProfileSettings(self):
|
||||||
settingsSizer = wx.GridBagSizer(hgap=2, vgap=1)
|
settingsSizer = wx.GridBagSizer(hgap=2, vgap=1)
|
||||||
settingsRow = 0
|
settingsRow = 0
|
||||||
|
|
||||||
for craftName in sorted(self.moduleSettingsMap.keys()):
|
for craftName in sorted(self.moduleSettingsMap.keys()):
|
||||||
|
|
||||||
craftStaticBox = wx.StaticBox(self.scrollbarPanel, -1, craftName.capitalize())
|
craftStaticBox = wx.StaticBox(self.scrollbarPanel, -1, craftName.capitalize())
|
||||||
craftStaticBoxSizer = wx.StaticBoxSizer(craftStaticBox, wx.VERTICAL)
|
craftStaticBoxSizer = wx.StaticBoxSizer(craftStaticBox, wx.VERTICAL)
|
||||||
|
|
||||||
# For some reason the dialog size is not consistent between Windows and Linux - this is a hack to get it working
|
# For some reason the dialog size is not consistent between Windows and Linux - this is a hack to get it working
|
||||||
if (os.name == 'nt'):
|
if (os.name == 'nt'):
|
||||||
craftStaticBoxSizer.SetMinSize((320, -1))
|
craftStaticBoxSizer.SetMinSize((320, -1))
|
||||||
else:
|
else:
|
||||||
craftStaticBoxSizer.SetMinSize((450, -1))
|
craftStaticBoxSizer.SetMinSize((450, -1))
|
||||||
pluginModule = archive.getModuleWithPath(os.path.join(skeinforge_craft.getPluginsDirectoryPath(), craftName))
|
pluginModule = archive.getModuleWithPath(os.path.join(skeinforge_craft.getPluginsDirectoryPath(), craftName))
|
||||||
repo = pluginModule.getNewRepository()
|
repo = pluginModule.getNewRepository()
|
||||||
|
|
||||||
for setting in settings.getReadRepository(repo).preferences:
|
for setting in settings.getReadRepository(repo).preferences:
|
||||||
if setting.name in self.moduleSettingsMap[craftName]:
|
if setting.name in self.moduleSettingsMap[craftName]:
|
||||||
|
|
||||||
settingSizer = wx.GridBagSizer(hgap=2, vgap=2)
|
settingSizer = wx.GridBagSizer(hgap=2, vgap=2)
|
||||||
settingSizer.AddGrowableCol(0)
|
settingSizer.AddGrowableCol(0)
|
||||||
settingRow = 0
|
settingRow = 0
|
||||||
settingLabel = wx.StaticText(self.scrollbarPanel, -1, setting.name)
|
settingLabel = wx.StaticText(self.scrollbarPanel, -1, setting.name)
|
||||||
settingLabel.Wrap(400)
|
settingLabel.Wrap(400)
|
||||||
settingSizer.Add(settingLabel, pos=(settingRow, 0))
|
settingSizer.Add(settingLabel, pos=(settingRow, 0))
|
||||||
|
|
||||||
if (isinstance(setting.value, bool)):
|
if (isinstance(setting.value, bool)):
|
||||||
checkbox = wx.CheckBox(self.scrollbarPanel)
|
checkbox = wx.CheckBox(self.scrollbarPanel)
|
||||||
checkbox.SetName(craftName + '.' + setting.name)
|
checkbox.SetName(craftName + '.' + setting.name)
|
||||||
|
@ -103,7 +103,7 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
|
||||||
textCtrl = wx.TextCtrl(self.scrollbarPanel, value=str(setting.value), size=(50, -1))
|
textCtrl = wx.TextCtrl(self.scrollbarPanel, value=str(setting.value), size=(50, -1))
|
||||||
textCtrl.SetName(craftName + '.' + setting.name)
|
textCtrl.SetName(craftName + '.' + setting.name)
|
||||||
settingSizer.Add(textCtrl, pos=(settingRow, 1))
|
settingSizer.Add(textCtrl, pos=(settingRow, 1))
|
||||||
|
|
||||||
craftStaticBoxSizer.Add(settingSizer, 1, wx.EXPAND, 0)
|
craftStaticBoxSizer.Add(settingSizer, 1, wx.EXPAND, 0)
|
||||||
settingRow += 1
|
settingRow += 1
|
||||||
col = settingsRow % 2
|
col = settingsRow % 2
|
||||||
|
@ -114,7 +114,7 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
|
||||||
|
|
||||||
def OnExit(self, e):
|
def OnExit(self, e):
|
||||||
self.Destroy()
|
self.Destroy()
|
||||||
|
|
||||||
def OnSave(self, e):
|
def OnSave(self, e):
|
||||||
for x in self.scrollbarPanel.GetChildren():
|
for x in self.scrollbarPanel.GetChildren():
|
||||||
if (isinstance(x, (wx.CheckBox, wx.TextCtrl))):
|
if (isinstance(x, (wx.CheckBox, wx.TextCtrl))):
|
||||||
|
|
|
@ -13,7 +13,7 @@ class MyFrame(wx.Frame):
|
||||||
def __init__(self, parent, mysize):
|
def __init__(self, parent, mysize):
|
||||||
wx.Frame.__init__(self, parent, wx.ID_ANY, size=mysize)
|
wx.Frame.__init__(self, parent, wx.ID_ANY, size=mysize)
|
||||||
self.SetBackgroundColour('black')
|
self.SetBackgroundColour('black')
|
||||||
|
|
||||||
# milliseconds per frame
|
# milliseconds per frame
|
||||||
self.delay = 60
|
self.delay = 60
|
||||||
# number of loops
|
# number of loops
|
||||||
|
@ -41,7 +41,7 @@ class MyFrame(wx.Frame):
|
||||||
self.image_list = []
|
self.image_list = []
|
||||||
for image_file in file_list:
|
for image_file in file_list:
|
||||||
self.image_list.append(wx.Bitmap(image_file))
|
self.image_list.append(wx.Bitmap(image_file))
|
||||||
|
|
||||||
# bind the panel to the paint event
|
# bind the panel to the paint event
|
||||||
wx.EVT_PAINT(self, self.onPaint)
|
wx.EVT_PAINT(self, self.onPaint)
|
||||||
|
|
||||||
|
@ -73,4 +73,4 @@ width = 800
|
||||||
frameoffset = 35
|
frameoffset = 35
|
||||||
height = 600 + frameoffset
|
height = 600 + frameoffset
|
||||||
MyFrame(None, (width, height)).Show()
|
MyFrame(None, (width, height)).Show()
|
||||||
app.MainLoop()
|
app.MainLoop()
|
||||||
|
|
|
@ -23,9 +23,9 @@ modify it under the terms of the GNU Lesser General Public License as
|
||||||
published by the Free Software Foundation; either version 2.1 of the
|
published by the Free Software Foundation; either version 2.1 of the
|
||||||
License, or (at your option) any later version.
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
As a special exception, the copyright holders of this library
|
As a special exception, the copyright holders of this library
|
||||||
hereby recind Section 3 of the GNU Lesser General Public License. This
|
hereby recind Section 3 of the GNU Lesser General Public License. This
|
||||||
means that you MAY NOT apply the terms of the ordinary GNU General
|
means that you MAY NOT apply the terms of the ordinary GNU General
|
||||||
Public License instead of this License to any given copy of the
|
Public License instead of this License to any given copy of the
|
||||||
Library. This has been done to prevent users of the Library from being
|
Library. This has been done to prevent users of the Library from being
|
||||||
denied access or the ability to use future improvements.
|
denied access or the ability to use future improvements.
|
||||||
|
@ -94,7 +94,7 @@ class BufferedCanvas(wx.Panel):
|
||||||
Causes the canvas to be updated.
|
Causes the canvas to be updated.
|
||||||
"""
|
"""
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def getWidthHeight(self):
|
def getWidthHeight(self):
|
||||||
width,height = self.GetClientSizeTuple()
|
width,height = self.GetClientSizeTuple()
|
||||||
if width == 0:
|
if width == 0:
|
||||||
|
|
|
@ -2,150 +2,150 @@
|
||||||
#Interactive RepRap e axis calibration program
|
#Interactive RepRap e axis calibration program
|
||||||
#(C) Nathan Zadoks 2011
|
#(C) Nathan Zadoks 2011
|
||||||
#Licensed under CC-BY-SA or GPLv2 and higher - Pick your poison.
|
#Licensed under CC-BY-SA or GPLv2 and higher - Pick your poison.
|
||||||
s=300 #Extrusion speed (mm/min)
|
s=300 #Extrusion speed (mm/min)
|
||||||
n=100 #Default length to extrude
|
n=100 #Default length to extrude
|
||||||
m= 0 #User-entered measured extrusion length
|
m= 0 #User-entered measured extrusion length
|
||||||
k=300 #Default amount of steps per mm
|
k=300 #Default amount of steps per mm
|
||||||
port='/dev/ttyUSB0' #Default serial port to connect to printer
|
port='/dev/ttyUSB0' #Default serial port to connect to printer
|
||||||
temp=210 #Default extrusion temperature
|
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:
|
try:
|
||||||
from printdummy import printcore
|
from printdummy import printcore
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from printcore import printcore
|
from printcore import printcore
|
||||||
import time,getopt,sys,os
|
import time,getopt,sys,os
|
||||||
|
|
||||||
def float_input(prompt=''):
|
def float_input(prompt=''):
|
||||||
import sys
|
import sys
|
||||||
f=None
|
f=None
|
||||||
while f==None:
|
while f==None:
|
||||||
s=raw_input(prompt)
|
s=raw_input(prompt)
|
||||||
try:
|
try:
|
||||||
f=float(s)
|
f=float(s)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
sys.stderr.write("Not a valid floating-point number.\n")
|
sys.stderr.write("Not a valid floating-point number.\n")
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
return f
|
return f
|
||||||
def wait(t,m=''):
|
def wait(t,m=''):
|
||||||
import time,sys
|
import time,sys
|
||||||
sys.stdout.write(m+'['+(' '*t)+']\r'+m+'[')
|
sys.stdout.write(m+'['+(' '*t)+']\r'+m+'[')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
for i in range(t):
|
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.write(s)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
time.sleep(1.0/5)
|
time.sleep(1.0/5)
|
||||||
print
|
print
|
||||||
def w(s):
|
def w(s):
|
||||||
sys.stdout.write(s)
|
sys.stdout.write(s)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
def heatup(p,temp,s=0):
|
def heatup(p,temp,s=0):
|
||||||
curtemp=gettemp(p)
|
curtemp=gettemp(p)
|
||||||
p.send_now('M109 S%03d'%temp)
|
p.send_now('M109 S%03d'%temp)
|
||||||
p.temp=0
|
p.temp=0
|
||||||
if not s: w("Heating extruder up..")
|
if not s: w("Heating extruder up..")
|
||||||
f=False
|
f=False
|
||||||
while curtemp<=(temp-1):
|
while curtemp<=(temp-1):
|
||||||
p.send_now('M105')
|
p.send_now('M105')
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if not f:
|
if not f:
|
||||||
time.sleep(1.5)
|
time.sleep(1.5)
|
||||||
f=True
|
f=True
|
||||||
curtemp=gettemp(p)
|
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
|
if s: print
|
||||||
else: print "\nReady."
|
else: print "\nReady."
|
||||||
|
|
||||||
def gettemp(p):
|
def gettemp(p):
|
||||||
try: p.logl
|
try: p.logl
|
||||||
except: setattr(p,'logl',0)
|
except: setattr(p,'logl',0)
|
||||||
try: p.temp
|
try: p.temp
|
||||||
except: setattr(p,'temp',0)
|
except: setattr(p,'temp',0)
|
||||||
for n in range(p.logl,len(p.log)):
|
for n in range(p.logl,len(p.log)):
|
||||||
line=p.log[n]
|
line=p.log[n]
|
||||||
if 'T:' in line:
|
if 'T:' in line:
|
||||||
try:
|
try:
|
||||||
setattr(p,'temp',int(line.split('T:')[1].split()[0]))
|
setattr(p,'temp',int(line.split('T:')[1].split()[0]))
|
||||||
except: print line
|
except: print line
|
||||||
p.logl=len(p.log)
|
p.logl=len(p.log)
|
||||||
return p.temp
|
return p.temp
|
||||||
if not os.path.exists(port):
|
if not os.path.exists(port):
|
||||||
port=0
|
port=0
|
||||||
|
|
||||||
#Parse options
|
#Parse options
|
||||||
help=u"""
|
help=u"""
|
||||||
%s [ -l DISTANCE ] [ -s STEPS ] [ -t TEMP ] [ -p PORT ]
|
%s [ -l DISTANCE ] [ -s STEPS ] [ -t TEMP ] [ -p PORT ]
|
||||||
-l --length Length of filament to extrude for each calibration step (default: %d mm)
|
-l --length Length of filament to extrude for each calibration step (default: %d mm)
|
||||||
-s --steps Initial amount of steps to use (default: %d steps)
|
-s --steps Initial amount of steps to use (default: %d steps)
|
||||||
-t --temp Extrusion temperature in degrees Celsius (default: %d \xb0C, max %d \xb0C)
|
-t --temp Extrusion temperature in degrees Celsius (default: %d \xb0C, max %d \xb0C)
|
||||||
-p --port Serial port the printer is connected to (default: %s)
|
-p --port Serial port the printer is connected to (default: %s)
|
||||||
-h --help This cruft.
|
-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:
|
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:
|
except getopt.GetoptError,err:
|
||||||
print str(err)
|
print str(err)
|
||||||
print help
|
print help
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
for o,a in opts:
|
for o,a in opts:
|
||||||
if o in ('-h','--help'):
|
if o in ('-h','--help'):
|
||||||
print help
|
print help
|
||||||
sys.exit()
|
sys.exit()
|
||||||
elif o in ('-l','--length'):
|
elif o in ('-l','--length'):
|
||||||
n=float(a)
|
n=float(a)
|
||||||
elif o in ('-s','--steps'):
|
elif o in ('-s','--steps'):
|
||||||
k=int(a)
|
k=int(a)
|
||||||
elif o in ('-t','--temp'):
|
elif o in ('-t','--temp'):
|
||||||
temp=int(a)
|
temp=int(a)
|
||||||
if temp>=tempmax:
|
if temp>=tempmax:
|
||||||
print (u'%d \xb0C? Are you insane?'.encode('utf-8')%temp)+(" That's over nine thousand!" if temp>9000 else '')
|
print (u'%d \xb0C? Are you insane?'.encode('utf-8')%temp)+(" That's over nine thousand!" if temp>9000 else '')
|
||||||
sys.exit(255)
|
sys.exit(255)
|
||||||
elif o in ('-p','--port'):
|
elif o in ('-p','--port'):
|
||||||
port=a
|
port=a
|
||||||
|
|
||||||
#Show initial parameters
|
#Show initial parameters
|
||||||
print "Initial parameters"
|
print "Initial parameters"
|
||||||
print "Steps per mm: %3d steps"%k
|
print "Steps per mm: %3d steps"%k
|
||||||
print "Length extruded: %3d mm"%n
|
print "Length extruded: %3d mm"%n
|
||||||
print
|
print
|
||||||
print "Serial port: %s"%(port if port else 'auto')
|
print "Serial port: %s"%(port if port else 'auto')
|
||||||
|
|
||||||
p=None
|
p=None
|
||||||
try:
|
try:
|
||||||
#Connect to printer
|
#Connect to printer
|
||||||
w("Connecting to printer..")
|
w("Connecting to printer..")
|
||||||
try:
|
try:
|
||||||
p=printcore(port,115200)
|
p=printcore(port,115200)
|
||||||
except:
|
except:
|
||||||
print 'Error.'
|
print 'Error.'
|
||||||
raise
|
raise
|
||||||
while not p.online:
|
while not p.online:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
w('.')
|
w('.')
|
||||||
print " connected."
|
print " connected."
|
||||||
|
|
||||||
heatup(p,temp)
|
heatup(p,temp)
|
||||||
|
|
||||||
#Calibration loop
|
#Calibration loop
|
||||||
while n!=m:
|
while n!=m:
|
||||||
heatup(p,temp,True)
|
heatup(p,temp,True)
|
||||||
p.send_now("G92 E0") #Reset e axis
|
p.send_now("G92 E0") #Reset e axis
|
||||||
p.send_now("G1 E%d F%d"%(n,s)) #Extrude length of filament
|
p.send_now("G1 E%d F%d"%(n,s)) #Extrude length of filament
|
||||||
wait(t,'Extruding.. ')
|
wait(t,'Extruding.. ')
|
||||||
m=float_input("How many millimeters of filament were extruded? ")
|
m=float_input("How many millimeters of filament were extruded? ")
|
||||||
if m==0: continue
|
if m==0: continue
|
||||||
if n!=m:
|
if n!=m:
|
||||||
k=(n/m)*k
|
k=(n/m)*k
|
||||||
p.send_now("M92 E%d"%int(round(k))) #Set new step count
|
p.send_now("M92 E%d"%int(round(k))) #Set new step count
|
||||||
print "Steps per mm: %3d steps"%k #Tell user
|
print "Steps per mm: %3d steps"%k #Tell user
|
||||||
print 'Calibration completed.' #Yay!
|
print 'Calibration completed.' #Yay!
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
if p: p.disconnect()
|
if p: p.disconnect()
|
||||||
|
|
|
@ -263,5 +263,3 @@ class Graph(BufferedCanvas):
|
||||||
self.drawextruder0temp(dc, gc)
|
self.drawextruder0temp(dc, gc)
|
||||||
self.drawextruder1targettemp(dc, gc)
|
self.drawextruder1targettemp(dc, gc)
|
||||||
self.drawextruder1temp(dc, gc)
|
self.drawextruder1temp(dc, gc)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import wx,time
|
import wx,time
|
||||||
|
@ -20,9 +20,9 @@ ID_ABOUT = 101
|
||||||
ID_EXIT = 110
|
ID_EXIT = 110
|
||||||
class window(wx.Frame):
|
class window(wx.Frame):
|
||||||
def __init__(self,f,size=(600,600),build_dimensions=[200,200,100,0,0,0],grid=(10,50),extrusion_width=0.5):
|
def __init__(self,f,size=(600,600),build_dimensions=[200,200,100,0,0,0],grid=(10,50),extrusion_width=0.5):
|
||||||
wx.Frame.__init__(self,None,title="Gcode view, shift to move view, mousewheel to set layer",size=(size[0],size[1]))
|
wx.Frame.__init__(self,None,title="Gcode view, shift to move view, mousewheel to set layer",size=(size[0],size[1]))
|
||||||
self.p=gviz(self,size=size,build_dimensions=build_dimensions,grid=grid,extrusion_width=extrusion_width)
|
self.p=gviz(self,size=size,build_dimensions=build_dimensions,grid=grid,extrusion_width=extrusion_width)
|
||||||
|
|
||||||
vbox = wx.BoxSizer(wx.VERTICAL)
|
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||||
toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
|
toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
|
||||||
toolbar.AddSimpleTool(1, wx.Image(imagefile('zoom_in.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Zoom In [+]', '')
|
toolbar.AddSimpleTool(1, wx.Image(imagefile('zoom_in.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Zoom In [+]', '')
|
||||||
|
@ -42,8 +42,8 @@ class window(wx.Frame):
|
||||||
self.Bind(wx.EVT_TOOL, lambda x:self.p.layerdown(), id=4)
|
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, self.resetview, id=5)
|
||||||
#self.Bind(wx.EVT_TOOL, lambda x:self.p.inject(), id=5)
|
#self.Bind(wx.EVT_TOOL, lambda x:self.p.inject(), id=5)
|
||||||
|
|
||||||
|
|
||||||
self.CreateStatusBar(1);
|
self.CreateStatusBar(1);
|
||||||
self.SetStatusText("Layer number and Z position show here when you scroll");
|
self.SetStatusText("Layer number and Z position show here when you scroll");
|
||||||
#self.bu=wx.Button(self.p,-1,"U",pos=(0,100),size=(40,140))
|
#self.bu=wx.Button(self.p,-1,"U",pos=(0,100),size=(40,140))
|
||||||
|
@ -51,19 +51,19 @@ class window(wx.Frame):
|
||||||
#self.bi=wx.Button(self.p,-1,"+",pos=(40,100),size=(40,140))
|
#self.bi=wx.Button(self.p,-1,"+",pos=(40,100),size=(40,140))
|
||||||
#self.bo=wx.Button(self.p,-1,"-",pos=(40,140),size=(40,140))
|
#self.bo=wx.Button(self.p,-1,"-",pos=(40,140),size=(40,140))
|
||||||
#self.bs=wx.Button(self.p, -1, "Inject", pos=(85, 103), size=(50, 20))
|
#self.bs=wx.Button(self.p, -1, "Inject", pos=(85, 103), size=(50, 20))
|
||||||
|
|
||||||
#self.bu.SetToolTip(wx.ToolTip("Move up one layer"))
|
#self.bu.SetToolTip(wx.ToolTip("Move up one layer"))
|
||||||
#self.bd.SetToolTip(wx.ToolTip("Move down one layer"))
|
#self.bd.SetToolTip(wx.ToolTip("Move down one layer"))
|
||||||
#self.bi.SetToolTip(wx.ToolTip("Zoom view in"))
|
#self.bi.SetToolTip(wx.ToolTip("Zoom view in"))
|
||||||
#self.bo.SetToolTip(wx.ToolTip("Zoom view out"))
|
#self.bo.SetToolTip(wx.ToolTip("Zoom view out"))
|
||||||
#self.bs.SetToolTip(wx.ToolTip("Insert Code at start of this layer"))
|
#self.bs.SetToolTip(wx.ToolTip("Insert Code at start of this layer"))
|
||||||
|
|
||||||
#self.bu.Bind(wx.EVT_BUTTON,lambda x:self.p.layerup())
|
#self.bu.Bind(wx.EVT_BUTTON,lambda x:self.p.layerup())
|
||||||
#self.bd.Bind(wx.EVT_BUTTON,lambda x:self.p.layerdown())
|
#self.bd.Bind(wx.EVT_BUTTON,lambda x:self.p.layerdown())
|
||||||
#self.bi.Bind(wx.EVT_BUTTON,lambda x:self.p.zoom(200,200,1.2))
|
#self.bi.Bind(wx.EVT_BUTTON,lambda x:self.p.zoom(200,200,1.2))
|
||||||
#self.bo.Bind(wx.EVT_BUTTON,lambda x:self.p.zoom(200,200,1/1.2))
|
#self.bo.Bind(wx.EVT_BUTTON,lambda x:self.p.zoom(200,200,1/1.2))
|
||||||
#self.bs.Bind(wx.EVT_BUTTON,lambda x:self.p.inject())
|
#self.bs.Bind(wx.EVT_BUTTON,lambda x:self.p.inject())
|
||||||
|
|
||||||
s=time.time()
|
s=time.time()
|
||||||
#print time.time()-s
|
#print time.time()-s
|
||||||
self.initpos=[0,0]
|
self.initpos=[0,0]
|
||||||
|
@ -77,12 +77,12 @@ class window(wx.Frame):
|
||||||
self.Bind(wx.EVT_MOUSEWHEEL,self.zoom)
|
self.Bind(wx.EVT_MOUSEWHEEL,self.zoom)
|
||||||
self.p.Bind(wx.EVT_MOUSE_EVENTS,self.mouse)
|
self.p.Bind(wx.EVT_MOUSE_EVENTS,self.mouse)
|
||||||
self.Bind(wx.EVT_MOUSE_EVENTS,self.mouse)
|
self.Bind(wx.EVT_MOUSE_EVENTS,self.mouse)
|
||||||
|
|
||||||
def resetview(self,event):
|
def resetview(self,event):
|
||||||
self.p.translate=[0.0,0.0]
|
self.p.translate=[0.0,0.0]
|
||||||
self.p.scale=self.p.basescale
|
self.p.scale=self.p.basescale
|
||||||
self.p.zoom(0,0,1.0)
|
self.p.zoom(0,0,1.0)
|
||||||
|
|
||||||
def mouse(self,event):
|
def mouse(self,event):
|
||||||
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
|
if event.ButtonUp(wx.MOUSE_BTN_LEFT):
|
||||||
if(self.initpos is not None):
|
if(self.initpos is not None):
|
||||||
|
@ -97,14 +97,14 @@ class window(wx.Frame):
|
||||||
self.basetrans[1]+(e[1]-self.initpos[1]) ]
|
self.basetrans[1]+(e[1]-self.initpos[1]) ]
|
||||||
self.p.repaint()
|
self.p.repaint()
|
||||||
self.p.Refresh()
|
self.p.Refresh()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def key(self, event):
|
def key(self, event):
|
||||||
# Keycode definitions
|
# Keycode definitions
|
||||||
kup=[85, 315] # Up keys
|
kup=[85, 315] # Up keys
|
||||||
kdo=[68, 317] # Down Keys
|
kdo=[68, 317] # Down Keys
|
||||||
kzi=[388, 316, 61] # Zoom In Keys
|
kzi=[388, 316, 61] # Zoom In Keys
|
||||||
kzo=[390, 314, 45] # Zoom Out Keys
|
kzo=[390, 314, 45] # Zoom Out Keys
|
||||||
x=event.GetKeyCode()
|
x=event.GetKeyCode()
|
||||||
|
@ -118,7 +118,7 @@ class window(wx.Frame):
|
||||||
#else:
|
#else:
|
||||||
# if x==wx.WXK_UP:
|
# if x==wx.WXK_UP:
|
||||||
# self.p.layerup()
|
# self.p.layerup()
|
||||||
# if x==wx.WXK_DOWN:
|
# if x==wx.WXK_DOWN:
|
||||||
# self.p.layerdown()
|
# self.p.layerdown()
|
||||||
if x in kup:
|
if x in kup:
|
||||||
self.p.layerup()
|
self.p.layerup()
|
||||||
|
@ -128,7 +128,7 @@ class window(wx.Frame):
|
||||||
self.p.zoom(cx,cy,1.2)
|
self.p.zoom(cx,cy,1.2)
|
||||||
if x in kzo:
|
if x in kzo:
|
||||||
self.p.zoom(cx, cy, 1/1.2)
|
self.p.zoom(cx, cy, 1/1.2)
|
||||||
|
|
||||||
#print p.lines.keys()
|
#print p.lines.keys()
|
||||||
def zoom(self, event):
|
def zoom(self, event):
|
||||||
z=event.GetWheelRotation()
|
z=event.GetWheelRotation()
|
||||||
|
@ -138,7 +138,7 @@ class window(wx.Frame):
|
||||||
else:
|
else:
|
||||||
if z > 0: self.p.zoom(event.GetX(),event.GetY(),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)
|
elif z < 0: self.p.zoom(event.GetX(),event.GetY(),1/1.2)
|
||||||
|
|
||||||
class gviz(wx.Panel):
|
class gviz(wx.Panel):
|
||||||
def __init__(self,parent,size=(200,200),build_dimensions=[200,200,100,0,0,0],grid=(10,50),extrusion_width=0.5):
|
def __init__(self,parent,size=(200,200),build_dimensions=[200,200,100,0,0,0],grid=(10,50),extrusion_width=0.5):
|
||||||
wx.Panel.__init__(self,parent,-1,size=(size[0],size[1]))
|
wx.Panel.__init__(self,parent,-1,size=(size[0],size[1]))
|
||||||
|
@ -172,12 +172,12 @@ class gviz(wx.Panel):
|
||||||
self.hilightarcs=[]
|
self.hilightarcs=[]
|
||||||
self.dirty=1
|
self.dirty=1
|
||||||
self.blitmap=wx.EmptyBitmap(self.GetClientSize()[0],self.GetClientSize()[1],-1)
|
self.blitmap=wx.EmptyBitmap(self.GetClientSize()[0],self.GetClientSize()[1],-1)
|
||||||
|
|
||||||
def inject(self):
|
def inject(self):
|
||||||
#import pdb; pdb.set_trace()
|
#import pdb; pdb.set_trace()
|
||||||
print"Inject code here..."
|
print"Inject code here..."
|
||||||
print "Layer "+str(self.layerindex +1)+" - Z = "+str(self.layers[self.layerindex])+" mm"
|
print "Layer "+str(self.layerindex +1)+" - Z = "+str(self.layers[self.layerindex])+" mm"
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.lastpos=[0,0,0,0,0,0,0]
|
self.lastpos=[0,0,0,0,0,0,0]
|
||||||
self.lines={}
|
self.lines={}
|
||||||
|
@ -190,7 +190,7 @@ class gviz(wx.Panel):
|
||||||
self.layerindex=0
|
self.layerindex=0
|
||||||
self.showall=0
|
self.showall=0
|
||||||
self.dirty=1
|
self.dirty=1
|
||||||
#self.repaint()
|
#self.repaint()
|
||||||
def layerup(self):
|
def layerup(self):
|
||||||
if(self.layerindex+1<len(self.layers)):
|
if(self.layerindex+1<len(self.layers)):
|
||||||
self.layerindex+=1
|
self.layerindex+=1
|
||||||
|
@ -198,15 +198,15 @@ class gviz(wx.Panel):
|
||||||
self.parent.SetStatusText("Layer "+str(self.layerindex +1)+" - Going Up - Z = "+str(self.layers[self.layerindex])+" mm",0)
|
self.parent.SetStatusText("Layer "+str(self.layerindex +1)+" - Going Up - Z = "+str(self.layers[self.layerindex])+" mm",0)
|
||||||
self.repaint()
|
self.repaint()
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def layerdown(self):
|
def layerdown(self):
|
||||||
if(self.layerindex>0):
|
if(self.layerindex>0):
|
||||||
self.layerindex-=1
|
self.layerindex-=1
|
||||||
# Display layer info on statusbar (Jezmy)
|
# Display layer info on statusbar (Jezmy)
|
||||||
self.parent.SetStatusText("Layer "+str(self.layerindex + 1)+" - Going Down - Z = "+str(self.layers[self.layerindex])+ " mm",0)
|
self.parent.SetStatusText("Layer "+str(self.layerindex + 1)+" - Going Down - Z = "+str(self.layers[self.layerindex])+ " mm",0)
|
||||||
self.repaint()
|
self.repaint()
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
def setlayer(self,layer):
|
def setlayer(self,layer):
|
||||||
try:
|
try:
|
||||||
self.layerindex=self.layers.index(layer)
|
self.layerindex=self.layers.index(layer)
|
||||||
|
@ -215,17 +215,17 @@ class gviz(wx.Panel):
|
||||||
self.showall=0
|
self.showall=0
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def resize(self,event):
|
def resize(self,event):
|
||||||
size=self.GetClientSize()
|
size=self.GetClientSize()
|
||||||
newsize=min(float(size[0])/self.size[0],float(size[1])/self.size[1])
|
newsize=min(float(size[0])/self.size[0],float(size[1])/self.size[1])
|
||||||
self.size=self.GetClientSize()
|
self.size=self.GetClientSize()
|
||||||
wx.CallAfter(self.zoom,0,0,newsize)
|
wx.CallAfter(self.zoom,0,0,newsize)
|
||||||
|
|
||||||
|
|
||||||
def zoom(self,x,y,factor):
|
def zoom(self,x,y,factor):
|
||||||
self.scale = [s * factor for s in self.scale]
|
self.scale = [s * factor for s in self.scale]
|
||||||
|
|
||||||
self.translate = [ x - (x-self.translate[0]) * factor,
|
self.translate = [ x - (x-self.translate[0]) * factor,
|
||||||
y - (y-self.translate[1]) * 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))
|
||||||
|
@ -234,8 +234,8 @@ class gviz(wx.Panel):
|
||||||
#self.dirty=1
|
#self.dirty=1
|
||||||
self.repaint()
|
self.repaint()
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
|
|
||||||
def repaint(self):
|
def repaint(self):
|
||||||
self.blitmap=wx.EmptyBitmap(self.GetClientSize()[0],self.GetClientSize()[1],-1)
|
self.blitmap=wx.EmptyBitmap(self.GetClientSize()[0],self.GetClientSize()[1],-1)
|
||||||
dc=wx.MemoryDC()
|
dc=wx.MemoryDC()
|
||||||
|
@ -257,7 +257,7 @@ class gviz(wx.Panel):
|
||||||
dc.SetBrush(wx.Brush((0,255,0)))
|
dc.SetBrush(wx.Brush((0,255,0)))
|
||||||
if len(self.layers):
|
if len(self.layers):
|
||||||
dc.DrawRectangle(self.size[0]-14,(1.0-(1.0*(self.layerindex+1))/len(self.layers))*self.size[1],13,self.size[1]-1)
|
dc.DrawRectangle(self.size[0]-14,(1.0-(1.0*(self.layerindex+1))/len(self.layers))*self.size[1],13,self.size[1]-1)
|
||||||
|
|
||||||
def _drawlines(lines,pens):
|
def _drawlines(lines,pens):
|
||||||
def _scaler(x):
|
def _scaler(x):
|
||||||
return (self.scale[0]*x[0]+self.translate[0],
|
return (self.scale[0]*x[0]+self.translate[0],
|
||||||
|
@ -266,7 +266,7 @@ class gviz(wx.Panel):
|
||||||
self.scale[1]*x[3]+self.translate[1],)
|
self.scale[1]*x[3]+self.translate[1],)
|
||||||
scaled_lines = map(_scaler,lines)
|
scaled_lines = map(_scaler,lines)
|
||||||
dc.DrawLineList(scaled_lines, pens)
|
dc.DrawLineList(scaled_lines, pens)
|
||||||
|
|
||||||
def _drawarcs(arcs,pens):
|
def _drawarcs(arcs,pens):
|
||||||
def _scaler(x):
|
def _scaler(x):
|
||||||
return (self.scale[0]*x[0]+self.translate[0],
|
return (self.scale[0]*x[0]+self.translate[0],
|
||||||
|
@ -280,7 +280,7 @@ class gviz(wx.Panel):
|
||||||
dc.SetPen(pens[i] if type(pens).__name__ == 'list' else pens)
|
dc.SetPen(pens[i] if type(pens).__name__ == 'list' else pens)
|
||||||
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
dc.DrawArc(*scaled_arcs[i])
|
dc.DrawArc(*scaled_arcs[i])
|
||||||
|
|
||||||
if self.showall:
|
if self.showall:
|
||||||
l=[]
|
l=[]
|
||||||
for i in self.layers:
|
for i in self.layers:
|
||||||
|
@ -295,12 +295,12 @@ class gviz(wx.Panel):
|
||||||
_drawarcs(self.arcs[self.layers[layer_i]], self.fades[self.layerindex-layer_i-1])
|
_drawarcs(self.arcs[self.layers[layer_i]], self.fades[self.layerindex-layer_i-1])
|
||||||
_drawlines(self.lines[self.layers[self.layerindex]], self.pens[self.layers[self.layerindex]])
|
_drawlines(self.lines[self.layers[self.layerindex]], self.pens[self.layers[self.layerindex]])
|
||||||
_drawarcs(self.arcs[self.layers[self.layerindex]], self.arcpens[self.layers[self.layerindex]])
|
_drawarcs(self.arcs[self.layers[self.layerindex]], self.arcpens[self.layers[self.layerindex]])
|
||||||
|
|
||||||
_drawlines(self.hilight, self.hlpen)
|
_drawlines(self.hilight, self.hlpen)
|
||||||
_drawarcs(self.hilightarcs, self.hlpen)
|
_drawarcs(self.hilightarcs, self.hlpen)
|
||||||
|
|
||||||
dc.SelectObject(wx.NullBitmap)
|
dc.SelectObject(wx.NullBitmap)
|
||||||
|
|
||||||
def paint(self,event):
|
def paint(self,event):
|
||||||
dc=wx.PaintDC(self)
|
dc=wx.PaintDC(self)
|
||||||
if(self.dirty):
|
if(self.dirty):
|
||||||
|
@ -309,12 +309,12 @@ class gviz(wx.Panel):
|
||||||
sz=self.GetClientSize()
|
sz=self.GetClientSize()
|
||||||
dc.DrawBitmap(self.blitmap,0,0)
|
dc.DrawBitmap(self.blitmap,0,0)
|
||||||
del dc
|
del dc
|
||||||
|
|
||||||
def addfile(self,gcodes=[]):
|
def addfile(self,gcodes=[]):
|
||||||
self.clear()
|
self.clear()
|
||||||
for i in gcodes:
|
for i in gcodes:
|
||||||
self.addgcode(i)
|
self.addgcode(i)
|
||||||
|
|
||||||
def addgcode(self,gcode="M105",hilight=0):
|
def addgcode(self,gcode="M105",hilight=0):
|
||||||
gcode=gcode.split("*")[0]
|
gcode=gcode.split("*")[0]
|
||||||
gcode=gcode.split(";")[0]
|
gcode=gcode.split(";")[0]
|
||||||
|
@ -323,7 +323,7 @@ class gviz(wx.Panel):
|
||||||
return
|
return
|
||||||
if gcode[0][0] == 'n':
|
if gcode[0][0] == 'n':
|
||||||
gcode.pop(0)
|
gcode.pop(0)
|
||||||
|
|
||||||
def _readgcode():
|
def _readgcode():
|
||||||
target=self.lastpos[:]
|
target=self.lastpos[:]
|
||||||
target[5]=0.0
|
target[5]=0.0
|
||||||
|
@ -353,14 +353,14 @@ class gviz(wx.Panel):
|
||||||
self.arcpens[target[2]]=[]
|
self.arcpens[target[2]]=[]
|
||||||
self.layers+=[target[2]]
|
self.layers+=[target[2]]
|
||||||
return target
|
return target
|
||||||
|
|
||||||
def _y(y):
|
def _y(y):
|
||||||
return self.build_dimensions[1]-(y-self.build_dimensions[4])
|
return self.build_dimensions[1]-(y-self.build_dimensions[4])
|
||||||
def _x(x):
|
def _x(x):
|
||||||
return x-self.build_dimensions[3]
|
return x-self.build_dimensions[3]
|
||||||
|
|
||||||
start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
|
start_pos = self.hilightpos[:] if hilight else self.lastpos[:]
|
||||||
|
|
||||||
if gcode[0] in [ "g0", "g1" ]:
|
if gcode[0] in [ "g0", "g1" ]:
|
||||||
target = _readgcode()
|
target = _readgcode()
|
||||||
line = [ _x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1]) ]
|
line = [ _x(start_pos[0]), _y(start_pos[1]), _x(target[0]), _y(target[1]) ]
|
||||||
|
@ -372,7 +372,7 @@ class gviz(wx.Panel):
|
||||||
self.hilight += [line]
|
self.hilight += [line]
|
||||||
self.hilightpos = target
|
self.hilightpos = target
|
||||||
self.dirty = 1
|
self.dirty = 1
|
||||||
|
|
||||||
if gcode[0] in [ "g2", "g3" ]:
|
if gcode[0] in [ "g2", "g3" ]:
|
||||||
target = _readgcode()
|
target = _readgcode()
|
||||||
arc = []
|
arc = []
|
||||||
|
@ -381,7 +381,7 @@ class gviz(wx.Panel):
|
||||||
arc += [ _x(start_pos[0] + target[5]), _y(start_pos[1] + target[6]) ] # center
|
arc += [ _x(start_pos[0] + target[5]), _y(start_pos[1] + target[6]) ] # center
|
||||||
if gcode[0] == "g2": # clockwise, reverse endpoints
|
if gcode[0] == "g2": # clockwise, reverse endpoints
|
||||||
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
|
arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1]
|
||||||
|
|
||||||
if not hilight:
|
if not hilight:
|
||||||
self.arcs[ target[2] ] += [arc]
|
self.arcs[ target[2] ] += [arc]
|
||||||
self.arcpens[ target[2] ] += [self.arcpen]
|
self.arcpens[ target[2] ] += [self.arcpen]
|
||||||
|
@ -390,11 +390,10 @@ class gviz(wx.Panel):
|
||||||
self.hilightarcs += [arc]
|
self.hilightarcs += [arc]
|
||||||
self.hilightpos = target
|
self.hilightpos = target
|
||||||
self.dirty = 1
|
self.dirty = 1
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = wx.App(False)
|
app = wx.App(False)
|
||||||
#main = window(open("/home/kliment/designs/spinner/arm_export.gcode"))
|
#main = window(open("/home/kliment/designs/spinner/arm_export.gcode"))
|
||||||
main = window(open("jam.gcode"))
|
main = window(open("jam.gcode"))
|
||||||
main.Show()
|
main.Show()
|
||||||
app.MainLoop()
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,14 @@ def install_locale(domain):
|
||||||
gettext.install(domain, '/usr/share/pronterface/locale', unicode=1)
|
gettext.install(domain, '/usr/share/pronterface/locale', unicode=1)
|
||||||
elif os.path.exists('/usr/local/share/pronterface/locale'):
|
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:
|
else:
|
||||||
gettext.install(domain, './locale', unicode=1)
|
gettext.install(domain, './locale', unicode=1)
|
||||||
|
|
||||||
def imagefile(filename):
|
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)
|
candidate = os.path.join(prefix, filename)
|
||||||
if os.path.exists(candidate):
|
if os.path.exists(candidate):
|
||||||
return candidate
|
return candidate
|
||||||
local_candidate = os.path.join(os.path.dirname(__file__), "images", filename)
|
local_candidate = os.path.join(os.path.dirname(__file__), "images", filename)
|
||||||
if os.path.exists(local_candidate):
|
if os.path.exists(local_candidate):
|
||||||
return local_candidate
|
return local_candidate
|
||||||
|
@ -24,9 +24,9 @@ def imagefile(filename):
|
||||||
|
|
||||||
def lookup_file(filename, prefixes):
|
def lookup_file(filename, prefixes):
|
||||||
for prefix in prefixes:
|
for prefix in prefixes:
|
||||||
candidate = os.path.join(prefix, filename)
|
candidate = os.path.join(prefix, filename)
|
||||||
if os.path.exists(candidate):
|
if os.path.exists(candidate):
|
||||||
return candidate
|
return candidate
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def pixmapfile(filename):
|
def pixmapfile(filename):
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import tempfile
|
||||||
import shutil
|
import shutil
|
||||||
import svg.document as wxpsvgdocument
|
import svg.document as wxpsvgdocument
|
||||||
import imghdr
|
import imghdr
|
||||||
|
|
||||||
class dispframe(wx.Frame):
|
class dispframe(wx.Frame):
|
||||||
def __init__(self, parent, title, res=(800, 600), printer=None):
|
def __init__(self, parent, title, res=(800, 600), printer=None):
|
||||||
wx.Frame.__init__(self, parent=parent, title=title)
|
wx.Frame.__init__(self, parent=parent, title=title)
|
||||||
|
@ -58,7 +58,7 @@ class dispframe(wx.Frame):
|
||||||
points = [wx.Point(*map(lambda x:int(round(float(x) * self.scale)), j.strip().split())) for j in i.strip().split("M")[1].split("L")]
|
points = [wx.Point(*map(lambda x:int(round(float(x) * self.scale)), j.strip().split())) for j in i.strip().split("M")[1].split("L")]
|
||||||
dc.DrawPolygon(points, self.size[0] / 2, self.size[1] / 2)
|
dc.DrawPolygon(points, self.size[0] / 2, self.size[1] / 2)
|
||||||
elif self.slicer == 'Slic3r':
|
elif self.slicer == 'Slic3r':
|
||||||
gc = wx.GraphicsContext_Create(dc)
|
gc = wx.GraphicsContext_Create(dc)
|
||||||
gc.Translate(*self.offset)
|
gc.Translate(*self.offset)
|
||||||
gc.Scale(self.scale, self.scale)
|
gc.Scale(self.scale, self.scale)
|
||||||
wxpsvgdocument.SVGDocument(image).render(gc)
|
wxpsvgdocument.SVGDocument(image).render(gc)
|
||||||
|
@ -69,12 +69,12 @@ class dispframe(wx.Frame):
|
||||||
self.pic.SetBitmap(self.bitmap)
|
self.pic.SetBitmap(self.bitmap)
|
||||||
self.pic.Show()
|
self.pic.Show()
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def showimgdelay(self, image):
|
def showimgdelay(self, image):
|
||||||
self.drawlayer(image)
|
self.drawlayer(image)
|
||||||
self.pic.Show()
|
self.pic.Show()
|
||||||
|
@ -82,10 +82,10 @@ class dispframe(wx.Frame):
|
||||||
|
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
if self.p != None and self.p.online:
|
if self.p != None and self.p.online:
|
||||||
self.p.send_now("G91")
|
self.p.send_now("G91")
|
||||||
self.p.send_now("G1 Z%f F300" % (self.thickness,))
|
self.p.send_now("G1 Z%f F300" % (self.thickness,))
|
||||||
self.p.send_now("G90")
|
self.p.send_now("G90")
|
||||||
|
|
||||||
def nextimg(self, event):
|
def nextimg(self, event):
|
||||||
if self.index < len(self.layers):
|
if self.index < len(self.layers):
|
||||||
i = self.index
|
i = self.index
|
||||||
|
@ -99,8 +99,8 @@ class dispframe(wx.Frame):
|
||||||
wx.CallAfter(self.pic.Hide)
|
wx.CallAfter(self.pic.Hide)
|
||||||
wx.CallAfter(self.Refresh)
|
wx.CallAfter(self.Refresh)
|
||||||
wx.CallAfter(self.ShowFullScreen, 0)
|
wx.CallAfter(self.ShowFullScreen, 0)
|
||||||
wx.CallAfter(self.timer.Stop)
|
wx.CallAfter(self.timer.Stop)
|
||||||
|
|
||||||
def present(self, layers, interval=0.5, pause=0.2, thickness=0.4, scale=20, size=(800, 600), offset=(0, 0)):
|
def present(self, layers, interval=0.5, pause=0.2, thickness=0.4, scale=20, size=(800, 600), offset=(0, 0)):
|
||||||
wx.CallAfter(self.pic.Hide)
|
wx.CallAfter(self.pic.Hide)
|
||||||
wx.CallAfter(self.Refresh)
|
wx.CallAfter(self.Refresh)
|
||||||
|
@ -117,7 +117,7 @@ class dispframe(wx.Frame):
|
||||||
self.timer.Start(1000 * interval + 1000 * pause)
|
self.timer.Start(1000 * interval + 1000 * pause)
|
||||||
|
|
||||||
class setframe(wx.Frame):
|
class setframe(wx.Frame):
|
||||||
|
|
||||||
def __init__(self, parent, printer=None):
|
def __init__(self, parent, printer=None):
|
||||||
wx.Frame.__init__(self, parent, title="Projector setup")
|
wx.Frame.__init__(self, parent, title="Projector setup")
|
||||||
self.f = dispframe(None, "", printer=printer)
|
self.f = dispframe(None, "", printer=printer)
|
||||||
|
@ -147,26 +147,26 @@ class setframe(wx.Frame):
|
||||||
|
|
||||||
wx.StaticText(self.panel, -1, "Y:", pos=(160, 60))
|
wx.StaticText(self.panel, -1, "Y:", pos=(160, 60))
|
||||||
self.Y = wx.TextCtrl(self.panel, -1, "768", pos=(210, 60))
|
self.Y = wx.TextCtrl(self.panel, -1, "768", pos=(210, 60))
|
||||||
|
|
||||||
wx.StaticText(self.panel, -1, "OffsetX:", pos=(160, 90))
|
wx.StaticText(self.panel, -1, "OffsetX:", pos=(160, 90))
|
||||||
self.offsetX = wx.TextCtrl(self.panel, -1, "50", pos=(210, 90))
|
self.offsetX = wx.TextCtrl(self.panel, -1, "50", pos=(210, 90))
|
||||||
|
|
||||||
wx.StaticText(self.panel, -1, "OffsetY:", pos=(160, 120))
|
wx.StaticText(self.panel, -1, "OffsetY:", pos=(160, 120))
|
||||||
self.offsetY = wx.TextCtrl(self.panel, -1, "50", pos=(210, 120))
|
self.offsetY = wx.TextCtrl(self.panel, -1, "50", pos=(210, 120))
|
||||||
|
|
||||||
self.bload = wx.Button(self.panel, -1, "Present", pos=(0, 150))
|
self.bload = wx.Button(self.panel, -1, "Present", pos=(0, 150))
|
||||||
self.bload.Bind(wx.EVT_BUTTON, self.startdisplay)
|
self.bload.Bind(wx.EVT_BUTTON, self.startdisplay)
|
||||||
|
|
||||||
wx.StaticText(self.panel, -1, "Fullscreen:", pos=(160, 150))
|
wx.StaticText(self.panel, -1, "Fullscreen:", pos=(160, 150))
|
||||||
self.fullscreen = wx.CheckBox(self.panel, -1, pos=(220, 150))
|
self.fullscreen = wx.CheckBox(self.panel, -1, pos=(220, 150))
|
||||||
self.fullscreen.SetValue(True)
|
self.fullscreen.SetValue(True)
|
||||||
|
|
||||||
self.Show()
|
self.Show()
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if hasattr(self, 'image_dir') and self.image_dir != '':
|
if hasattr(self, 'image_dir') and self.image_dir != '':
|
||||||
shutil.rmtree(self.image_dir)
|
shutil.rmtree(self.image_dir)
|
||||||
|
|
||||||
def parsesvg(self, name):
|
def parsesvg(self, name):
|
||||||
et = xml.etree.ElementTree.ElementTree(file=name)
|
et = xml.etree.ElementTree.ElementTree(file=name)
|
||||||
#xml.etree.ElementTree.dump(et)
|
#xml.etree.ElementTree.dump(et)
|
||||||
|
@ -177,18 +177,18 @@ class setframe(wx.Frame):
|
||||||
if (slicer == 'Slic3r'):
|
if (slicer == 'Slic3r'):
|
||||||
height = et.getroot().get('height')
|
height = et.getroot().get('height')
|
||||||
width = et.getroot().get('width')
|
width = et.getroot().get('width')
|
||||||
|
|
||||||
for i in et.findall("{http://www.w3.org/2000/svg}g"):
|
for i in et.findall("{http://www.w3.org/2000/svg}g"):
|
||||||
z = float(i.get('{http://slic3r.org/namespaces/slic3r}z'))
|
z = float(i.get('{http://slic3r.org/namespaces/slic3r}z'))
|
||||||
zdiff = z - zlast
|
zdiff = z - zlast
|
||||||
zlast = z
|
zlast = z
|
||||||
|
|
||||||
svgSnippet = xml.etree.ElementTree.Element('{http://www.w3.org/2000/svg}svg')
|
svgSnippet = xml.etree.ElementTree.Element('{http://www.w3.org/2000/svg}svg')
|
||||||
svgSnippet.set('height', height + 'mm')
|
svgSnippet.set('height', height + 'mm')
|
||||||
svgSnippet.set('width', width + 'mm')
|
svgSnippet.set('width', width + 'mm')
|
||||||
svgSnippet.set('viewBox', '0 0 ' + height + ' ' + width)
|
svgSnippet.set('viewBox', '0 0 ' + height + ' ' + width)
|
||||||
svgSnippet.append(i)
|
svgSnippet.append(i)
|
||||||
|
|
||||||
ol += [svgSnippet]
|
ol += [svgSnippet]
|
||||||
else :
|
else :
|
||||||
for i in et.findall("{http://www.w3.org/2000/svg}g")[0].findall("{http://www.w3.org/2000/svg}g"):
|
for i in et.findall("{http://www.w3.org/2000/svg}g")[0].findall("{http://www.w3.org/2000/svg}g"):
|
||||||
|
@ -198,7 +198,7 @@ class setframe(wx.Frame):
|
||||||
path = i.find('{http://www.w3.org/2000/svg}path')
|
path = i.find('{http://www.w3.org/2000/svg}path')
|
||||||
ol += [(path.get("d").split("z"))[:-1]]
|
ol += [(path.get("d").split("z"))[:-1]]
|
||||||
return ol, zdiff, slicer
|
return ol, zdiff, slicer
|
||||||
|
|
||||||
def parse3DLPzip(self, name):
|
def parse3DLPzip(self, name):
|
||||||
if not zipfile.is_zipfile(name):
|
if not zipfile.is_zipfile(name):
|
||||||
raise Exception(name + " is not a zip file!")
|
raise Exception(name + " is not a zip file!")
|
||||||
|
@ -212,7 +212,7 @@ class setframe(wx.Frame):
|
||||||
if os.path.isfile(path) and imghdr.what(path) in acceptedImageTypes:
|
if os.path.isfile(path) and imghdr.what(path) in acceptedImageTypes:
|
||||||
ol.append(wx.Bitmap(path))
|
ol.append(wx.Bitmap(path))
|
||||||
return ol, -1, "bitmap"
|
return ol, -1, "bitmap"
|
||||||
|
|
||||||
def loadfile(self, event):
|
def loadfile(self, event):
|
||||||
dlg = wx.FileDialog(self, ("Open file to print"), style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
dlg = wx.FileDialog(self, ("Open file to print"), style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
||||||
dlg.SetWildcard(("Slic3r or Skeinforge svg files (;*.svg;*.SVG;);3DLP Zip (;*.3dlp.zip;)"))
|
dlg.SetWildcard(("Slic3r or Skeinforge svg files (;*.svg;*.SVG;);3DLP Zip (;*.3dlp.zip;)"))
|
||||||
|
|
|
@ -17,7 +17,7 @@ import wx
|
||||||
|
|
||||||
class macroed(wx.Dialog):
|
class macroed(wx.Dialog):
|
||||||
"""Really simple editor to edit macro definitions"""
|
"""Really simple editor to edit macro definitions"""
|
||||||
|
|
||||||
def __init__(self,macro_name,definition,callback,gcode=False):
|
def __init__(self,macro_name,definition,callback,gcode=False):
|
||||||
self.indent_chars = " "
|
self.indent_chars = " "
|
||||||
title=" macro %s"
|
title=" macro %s"
|
||||||
|
@ -54,7 +54,7 @@ class macroed(wx.Dialog):
|
||||||
topsizer.Fit(self)
|
topsizer.Fit(self)
|
||||||
self.Show()
|
self.Show()
|
||||||
self.e.SetFocus()
|
self.e.SetFocus()
|
||||||
|
|
||||||
def find(self,ev):
|
def find(self,ev):
|
||||||
# Ask user what to look for, find it and point at it ... (Jezmy)
|
# Ask user what to look for, find it and point at it ... (Jezmy)
|
||||||
S = self.e.GetStringSelection()
|
S = self.e.GetStringSelection()
|
||||||
|
@ -63,27 +63,27 @@ class macroed(wx.Dialog):
|
||||||
FindValue = wx.GetTextFromUser('Please enter a search string:', caption="Search", default_value=S, parent=None)
|
FindValue = wx.GetTextFromUser('Please enter a search string:', caption="Search", default_value=S, parent=None)
|
||||||
somecode = self.e.GetValue()
|
somecode = self.e.GetValue()
|
||||||
numLines = len(somecode)
|
numLines = len(somecode)
|
||||||
position = somecode.find(FindValue, self.e.GetInsertionPoint())
|
position = somecode.find(FindValue, self.e.GetInsertionPoint())
|
||||||
if position == -1 :
|
if position == -1 :
|
||||||
# ShowMessage(self,-1, "Not found!")
|
# ShowMessage(self,-1, "Not found!")
|
||||||
titletext = wx.TextCtrl(self.panel,-1,"Not Found!")
|
titletext = wx.TextCtrl(self.panel,-1,"Not Found!")
|
||||||
else:
|
else:
|
||||||
# self.title.SetValue("Position : "+str(position))
|
# self.title.SetValue("Position : "+str(position))
|
||||||
|
|
||||||
titletext = wx.TextCtrl(self.panel,-1,str(position))
|
titletext = wx.TextCtrl(self.panel,-1,str(position))
|
||||||
|
|
||||||
# ananswer = wx.MessageBox(str(numLines)+" Lines detected in file\n"+str(position), "OK")
|
# ananswer = wx.MessageBox(str(numLines)+" Lines detected in file\n"+str(position), "OK")
|
||||||
self.e.SetFocus()
|
self.e.SetFocus()
|
||||||
self.e.SetInsertionPoint(position)
|
self.e.SetInsertionPoint(position)
|
||||||
self.e.SetSelection(position, position + len(FindValue))
|
self.e.SetSelection(position, position + len(FindValue))
|
||||||
self.e.ShowPosition(position)
|
self.e.ShowPosition(position)
|
||||||
|
|
||||||
def ShowMessage(self, ev , message):
|
def ShowMessage(self, ev , message):
|
||||||
dlg = wxMessageDialog(self, message,
|
dlg = wxMessageDialog(self, message,
|
||||||
"Info!", wxOK | wxICON_INFORMATION)
|
"Info!", wxOK | wxICON_INFORMATION)
|
||||||
dlg.ShowModal()
|
dlg.ShowModal()
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def save(self,ev):
|
def save(self,ev):
|
||||||
self.Destroy()
|
self.Destroy()
|
||||||
if not self.gcode:
|
if not self.gcode:
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -38,15 +38,15 @@ I=[
|
||||||
def transpose(matrix):
|
def transpose(matrix):
|
||||||
return zip(*matrix)
|
return zip(*matrix)
|
||||||
#return [[v[i] for v in matrix] for i in xrange(len(matrix[0]))]
|
#return [[v[i] for v in matrix] for i in xrange(len(matrix[0]))]
|
||||||
|
|
||||||
def multmatrix(vector,matrix):
|
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):
|
def applymatrix(facet,matrix=I):
|
||||||
#return facet
|
#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 [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=[
|
m=[
|
||||||
[1,0,0,0],
|
[1,0,0,0],
|
||||||
|
@ -73,7 +73,7 @@ def emitstl(filename,facets=[],objname="stltool_export",binary=1):
|
||||||
f.write(buf)
|
f.write(buf)
|
||||||
f.close()
|
f.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
f=open(filename,"w")
|
f=open(filename,"w")
|
||||||
f.write("solid "+objname+"\n")
|
f.write("solid "+objname+"\n")
|
||||||
|
@ -85,8 +85,8 @@ def emitstl(filename,facets=[],objname="stltool_export",binary=1):
|
||||||
f.write(" endfacet"+"\n")
|
f.write(" endfacet"+"\n")
|
||||||
f.write("endsolid "+objname+"\n")
|
f.write("endsolid "+objname+"\n")
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class stl:
|
class stl:
|
||||||
def __init__(self, filename=None):
|
def __init__(self, filename=None):
|
||||||
|
@ -94,7 +94,7 @@ class stl:
|
||||||
self.facets=[]
|
self.facets=[]
|
||||||
self.facetsminz=[]
|
self.facetsminz=[]
|
||||||
self.facetsmaxz=[]
|
self.facetsmaxz=[]
|
||||||
|
|
||||||
self.name=""
|
self.name=""
|
||||||
self.insolid=0
|
self.insolid=0
|
||||||
self.infacet=0
|
self.infacet=0
|
||||||
|
@ -133,7 +133,7 @@ class stl:
|
||||||
for i in self.f:
|
for i in self.f:
|
||||||
if not self.parseline(i):
|
if not self.parseline(i):
|
||||||
return
|
return
|
||||||
|
|
||||||
def translate(self,v=[0,0,0]):
|
def translate(self,v=[0,0,0]):
|
||||||
matrix=[
|
matrix=[
|
||||||
[1,0,0,v[0]],
|
[1,0,0,v[0]],
|
||||||
|
@ -142,7 +142,7 @@ class stl:
|
||||||
[0,0,0,1]
|
[0,0,0,1]
|
||||||
]
|
]
|
||||||
return self.transform(matrix)
|
return self.transform(matrix)
|
||||||
|
|
||||||
def rotate(self,v=[0,0,0]):
|
def rotate(self,v=[0,0,0]):
|
||||||
import math
|
import math
|
||||||
z=v[2]
|
z=v[2]
|
||||||
|
@ -167,7 +167,7 @@ class stl:
|
||||||
[0,0,0,1]
|
[0,0,0,1]
|
||||||
]
|
]
|
||||||
return self.transform(matrix1).transform(matrix2).transform(matrix3)
|
return self.transform(matrix1).transform(matrix2).transform(matrix3)
|
||||||
|
|
||||||
def scale(self,v=[0,0,0]):
|
def scale(self,v=[0,0,0]):
|
||||||
matrix=[
|
matrix=[
|
||||||
[v[0],0,0,0],
|
[v[0],0,0,0],
|
||||||
|
@ -176,8 +176,8 @@ class stl:
|
||||||
[0,0,0,1]
|
[0,0,0,1]
|
||||||
]
|
]
|
||||||
return self.transform(matrix)
|
return self.transform(matrix)
|
||||||
|
|
||||||
|
|
||||||
def transform(self,m=I):
|
def transform(self,m=I):
|
||||||
s=stl()
|
s=stl()
|
||||||
s.facets=[applymatrix(i,m) for i in self.facets]
|
s.facets=[applymatrix(i,m) for i in self.facets]
|
||||||
|
@ -190,7 +190,7 @@ class stl:
|
||||||
s.facetsminz+=[(min(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)]
|
s.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])),facet)]
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def export(self,f=sys.stdout):
|
def export(self,f=sys.stdout):
|
||||||
f.write("solid "+self.name+"\n")
|
f.write("solid "+self.name+"\n")
|
||||||
for i in self.facets:
|
for i in self.facets:
|
||||||
|
@ -202,14 +202,14 @@ class stl:
|
||||||
f.write(" endfacet"+"\n")
|
f.write(" endfacet"+"\n")
|
||||||
f.write("endsolid "+self.name+"\n")
|
f.write("endsolid "+self.name+"\n")
|
||||||
f.flush()
|
f.flush()
|
||||||
|
|
||||||
def parseline(self,l):
|
def parseline(self,l):
|
||||||
l=l.strip()
|
l=l.strip()
|
||||||
if l.startswith("solid"):
|
if l.startswith("solid"):
|
||||||
self.insolid=1
|
self.insolid=1
|
||||||
self.name=l[6:]
|
self.name=l[6:]
|
||||||
#print self.name
|
#print self.name
|
||||||
|
|
||||||
elif l.startswith("endsolid"):
|
elif l.startswith("endsolid"):
|
||||||
self.insolid=0
|
self.insolid=0
|
||||||
return 0
|
return 0
|
||||||
|
@ -244,7 +244,7 @@ if __name__=="__main__":
|
||||||
working.remove(j[1])
|
working.remove(j[1])
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
print i,len(working)
|
print i,len(working)
|
||||||
emitstl("../../Downloads/frame-vertex-neo-foot-x4-a.stl",s.facets,"emitted_object")
|
emitstl("../../Downloads/frame-vertex-neo-foot-x4-a.stl",s.facets,"emitted_object")
|
||||||
#stl("../prusamendel/stl/mendelplate.stl")
|
#stl("../prusamendel/stl/mendelplate.stl")
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -304,14 +304,14 @@ class gcview(object):
|
||||||
('v3f/static', vertices),
|
('v3f/static', vertices),
|
||||||
('n3f/static', normals)))
|
('n3f/static', normals)))
|
||||||
if lasth is not None:
|
if lasth is not None:
|
||||||
self.layers[lasth] = pyglet.graphics.Batch()
|
self.layers[lasth] = pyglet.graphics.Batch()
|
||||||
indices = range(len(layertemp[lasth][0])) # [[3*i,3*i+1,3*i+2] for i in xrange(len(facets))]
|
indices = range(len(layertemp[lasth][0])) # [[3*i,3*i+1,3*i+2] for i in xrange(len(facets))]
|
||||||
self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0]) // 3,
|
self.vlists.append(self.layers[lasth].add_indexed(len(layertemp[lasth][0]) // 3,
|
||||||
GL_TRIANGLES,
|
GL_TRIANGLES,
|
||||||
None, # group,
|
None, # group,
|
||||||
indices,
|
indices,
|
||||||
('v3f/static', layertemp[lasth][0]),
|
('v3f/static', layertemp[lasth][0]),
|
||||||
('n3f/static', layertemp[lasth][1])))
|
('n3f/static', layertemp[lasth][1])))
|
||||||
|
|
||||||
def genline(self, i, h, w):
|
def genline(self, i, h, w):
|
||||||
S = i[0][:3]
|
S = i[0][:3]
|
||||||
|
@ -356,28 +356,28 @@ class gcview(object):
|
||||||
return spoints, epoints, S, E
|
return spoints, epoints, S, E
|
||||||
|
|
||||||
def transform(self, line):
|
def transform(self, line):
|
||||||
line = line.split(";")[0]
|
line = line.split(";")[0]
|
||||||
cur = self.prev[:]
|
cur = self.prev[:]
|
||||||
if len(line) > 0:
|
if len(line) > 0:
|
||||||
if "G1" in line or "G0" in line or "G92" in line:
|
if "G1" in line or "G0" in line or "G92" in line:
|
||||||
if("X" in line):
|
if("X" in line):
|
||||||
cur[0] = float(line.split("X")[1].split(" ")[0])
|
cur[0] = float(line.split("X")[1].split(" ")[0])
|
||||||
if("Y" in line):
|
if("Y" in line):
|
||||||
cur[1] = float(line.split("Y")[1].split(" ")[0])
|
cur[1] = float(line.split("Y")[1].split(" ")[0])
|
||||||
if("Z" in line):
|
if("Z" in line):
|
||||||
cur[2] = float(line.split("Z")[1].split(" ")[0])
|
cur[2] = float(line.split("Z")[1].split(" ")[0])
|
||||||
if("E" in line):
|
if("E" in line):
|
||||||
cur[3] = float(line.split("E")[1].split(" ")[0])
|
cur[3] = float(line.split("E")[1].split(" ")[0])
|
||||||
if self.prev == cur:
|
if self.prev == cur:
|
||||||
return None
|
return None
|
||||||
if self.fline or "G92" in line:
|
if self.fline or "G92" in line:
|
||||||
self.prev = cur
|
self.prev = cur
|
||||||
self.fline = 0
|
self.fline = 0
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
r = [self.prev, cur]
|
r = [self.prev, cur]
|
||||||
self.prev = cur
|
self.prev = cur
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
for i in self.vlists:
|
for i in self.vlists:
|
||||||
|
@ -570,27 +570,27 @@ class TestGlPanel(GLPanel):
|
||||||
self.initpos = None
|
self.initpos = None
|
||||||
|
|
||||||
elif event.Dragging() and event.RightIsDown() and event.ShiftDown():
|
elif event.Dragging() and event.RightIsDown() and event.ShiftDown():
|
||||||
if self.initpos is None:
|
if self.initpos is None:
|
||||||
self.initpos = event.GetPositionTuple()
|
self.initpos = event.GetPositionTuple()
|
||||||
else:
|
else:
|
||||||
p1 = self.initpos
|
p1 = self.initpos
|
||||||
p2 = event.GetPositionTuple()
|
p2 = event.GetPositionTuple()
|
||||||
sz = self.GetClientSize()
|
sz = self.GetClientSize()
|
||||||
p1 = list(p1)
|
p1 = list(p1)
|
||||||
p2 = list(p2)
|
p2 = list(p2)
|
||||||
p1[1] *= -1
|
p1[1] *= -1
|
||||||
p2[1] *= -1
|
p2[1] *= -1
|
||||||
|
|
||||||
self.transv = map(lambda x, y, z, c: c - self.dist * (x - y) / z, list(p1) + [0], list(p2) + [0], list(sz) + [1], self.transv)
|
self.transv = map(lambda x, y, z, c: c - self.dist * (x - y) / z, list(p1) + [0], list(p2) + [0], list(sz) + [1], self.transv)
|
||||||
|
|
||||||
glLoadIdentity()
|
glLoadIdentity()
|
||||||
glTranslatef(self.transv[0], self.transv[1], 0)
|
glTranslatef(self.transv[0], self.transv[1], 0)
|
||||||
glTranslatef(0, 0, self.transv[2])
|
glTranslatef(0, 0, self.transv[2])
|
||||||
if(self.rot):
|
if(self.rot):
|
||||||
glMultMatrixd(build_rotmatrix(self.basequat))
|
glMultMatrixd(build_rotmatrix(self.basequat))
|
||||||
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
|
glGetDoublev(GL_MODELVIEW_MATRIX, self.mvmat)
|
||||||
self.rot = 1
|
self.rot = 1
|
||||||
self.initpos = None
|
self.initpos = None
|
||||||
else:
|
else:
|
||||||
#mouse is moving without a button press
|
#mouse is moving without a button press
|
||||||
p = event.GetPositionTuple()
|
p = event.GetPositionTuple()
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
import wx
|
import wx
|
||||||
|
|
||||||
def AddEllipticalArc(self, x, y, w, h, startAngle, endAngle, clockwise=False):
|
def AddEllipticalArc(self, x, y, w, h, startAngle, endAngle, clockwise=False):
|
||||||
""" Draws an arc of an ellipse within bounding rect (x,y,w,h)
|
""" Draws an arc of an ellipse within bounding rect (x,y,w,h)
|
||||||
from startArc to endArc (in radians, relative to the horizontal line of the eclipse)"""
|
from startArc to endArc (in radians, relative to the horizontal line of the eclipse)"""
|
||||||
|
|
||||||
if True:
|
if True:
|
||||||
import warnings
|
import warnings
|
||||||
warnings.warn("elliptical arcs are not supported")
|
warnings.warn("elliptical arcs are not supported")
|
||||||
|
@ -15,7 +15,7 @@ def AddEllipticalArc(self, x, y, w, h, startAngle, endAngle, clockwise=False):
|
||||||
h = h/2.0
|
h = h/2.0
|
||||||
self.AddArc(x+w, y+h, ((w+h)/2), startAngle, endAngle, clockwise)
|
self.AddArc(x+w, y+h, ((w+h)/2), startAngle, endAngle, clockwise)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
#implement in terms of AddArc by applying a transformation matrix
|
#implement in terms of AddArc by applying a transformation matrix
|
||||||
#Sigh this can't work, still need to patch wx to allow
|
#Sigh this can't work, still need to patch wx to allow
|
||||||
#either a) AddPath that's not a closed path or
|
#either a) AddPath that's not a closed path or
|
||||||
|
@ -25,19 +25,18 @@ def AddEllipticalArc(self, x, y, w, h, startAngle, endAngle, clockwise=False):
|
||||||
#possibly be simulated by combining the current transform with option a.
|
#possibly be simulated by combining the current transform with option a.
|
||||||
mtx = wx.GraphicsRenderer_GetDefaultRenderer().CreateMatrix()
|
mtx = wx.GraphicsRenderer_GetDefaultRenderer().CreateMatrix()
|
||||||
path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath()
|
path = wx.GraphicsRenderer_GetDefaultRenderer().CreatePath()
|
||||||
|
|
||||||
|
|
||||||
mtx.Translate(x+(w/2.0), y+(h/2.0))
|
mtx.Translate(x+(w/2.0), y+(h/2.0))
|
||||||
mtx.Scale(w/2.0, y/2.0)
|
mtx.Scale(w/2.0, y/2.0)
|
||||||
|
|
||||||
path.AddArc(0, 0, 1, startAngle, endAngle, clockwise)
|
path.AddArc(0, 0, 1, startAngle, endAngle, clockwise)
|
||||||
path.Transform(mtx)
|
path.Transform(mtx)
|
||||||
self.AddPath(path)
|
self.AddPath(path)
|
||||||
self.MoveToPoint(path.GetCurrentPoint())
|
self.MoveToPoint(path.GetCurrentPoint())
|
||||||
self.CloseSubpath()
|
self.CloseSubpath()
|
||||||
|
|
||||||
if not hasattr(wx.GraphicsPath, "AddEllipticalArc"):
|
if not hasattr(wx.GraphicsPath, "AddEllipticalArc"):
|
||||||
wx.GraphicsPath.AddEllipticalArc = AddEllipticalArc
|
wx.GraphicsPath.AddEllipticalArc = AddEllipticalArc
|
||||||
|
|
||||||
del AddEllipticalArc
|
del AddEllipticalArc
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Parsers for specific attributes
|
Parsers for specific attributes
|
||||||
"""
|
"""
|
||||||
import urlparse
|
import urlparse
|
||||||
from pyparsing import (Literal,
|
from pyparsing import (Literal,
|
||||||
Optional, oneOf, Group, StringEnd, Combine, Word, alphas, hexnums,
|
Optional, oneOf, Group, StringEnd, Combine, Word, alphas, hexnums,
|
||||||
CaselessLiteral, SkipTo
|
CaselessLiteral, SkipTo
|
||||||
)
|
)
|
||||||
|
@ -21,14 +21,14 @@ def parsePossibleURL(t):
|
||||||
colorDeclaration = none | currentColor | colourValue
|
colorDeclaration = none | currentColor | colourValue
|
||||||
|
|
||||||
urlEnd = (
|
urlEnd = (
|
||||||
Literal(")").suppress() +
|
Literal(")").suppress() +
|
||||||
Optional(Group(colorDeclaration), default=()) +
|
Optional(Group(colorDeclaration), default=()) +
|
||||||
StringEnd()
|
StringEnd()
|
||||||
)
|
)
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
CaselessLiteral("URL")
|
CaselessLiteral("URL")
|
||||||
+
|
+
|
||||||
Literal("(").suppress()+
|
Literal("(").suppress()+
|
||||||
Group(SkipTo(urlEnd, include=True).setParseAction(parsePossibleURL))
|
Group(SkipTo(urlEnd, include=True).setParseAction(parsePossibleURL))
|
||||||
)
|
)
|
||||||
|
@ -37,7 +37,7 @@ url = (
|
||||||
#For none and currentColor, the details tuple will be the empty tuple
|
#For none and currentColor, the details tuple will be the empty tuple
|
||||||
#for CSS color declarations, it will be (type, (R,G,B))
|
#for CSS color declarations, it will be (type, (R,G,B))
|
||||||
#for URLs, it will be ("URL", ((url tuple), fallback))
|
#for URLs, it will be ("URL", ((url tuple), fallback))
|
||||||
#The url tuple will be as returned by urlparse.urlsplit, and can be
|
#The url tuple will be as returned by urlparse.urlsplit, and can be
|
||||||
#an empty tuple if the parser has an error
|
#an empty tuple if the parser has an error
|
||||||
#The fallback will be another (type, details) tuple as a parsed
|
#The fallback will be another (type, details) tuple as a parsed
|
||||||
#colorDeclaration, but may be the empty tuple if it is not present
|
#colorDeclaration, but may be the empty tuple if it is not present
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
from pyparsing import Literal, Combine
|
from pyparsing import Literal, Combine
|
||||||
from .identifier import identifier
|
from .identifier import identifier
|
||||||
|
|
||||||
atkeyword = Combine(Literal("@") + identifier)
|
atkeyword = Combine(Literal("@") + identifier)
|
||||||
|
|
|
@ -5,4 +5,3 @@
|
||||||
from pyparsing import nestedExpr
|
from pyparsing import nestedExpr
|
||||||
|
|
||||||
block = nestedExpr(opener="{", closer="}")
|
block = nestedExpr(opener="{", closer="}")
|
||||||
|
|
||||||
|
|
|
@ -21,31 +21,31 @@ comma = Literal(",").suppress()
|
||||||
def clampColourByte(val):
|
def clampColourByte(val):
|
||||||
val = int(val)
|
val = int(val)
|
||||||
return min(max(0,val), 255)
|
return min(max(0,val), 255)
|
||||||
|
|
||||||
def clampColourPerc(val):
|
def clampColourPerc(val):
|
||||||
val = float(val)
|
val = float(val)
|
||||||
return min(max(0,val), 100)
|
return min(max(0,val), 100)
|
||||||
|
|
||||||
def parseColorPerc(token):
|
def parseColorPerc(token):
|
||||||
val = token[0]
|
val = token[0]
|
||||||
val = clampColourPerc(val)
|
val = clampColourPerc(val)
|
||||||
#normalize to bytes
|
#normalize to bytes
|
||||||
return int(255 * (val / 100.0))
|
return int(255 * (val / 100.0))
|
||||||
|
|
||||||
|
|
||||||
colorByte = Optional(sign) + integerConstant.setParseAction(lambda t: clampColourByte(t[0]))
|
colorByte = Optional(sign) + integerConstant.setParseAction(lambda t: clampColourByte(t[0]))
|
||||||
colorPerc = number.setParseAction(parseColorPerc) + Literal("%").suppress()
|
colorPerc = number.setParseAction(parseColorPerc) + Literal("%").suppress()
|
||||||
|
|
||||||
rgb = (
|
rgb = (
|
||||||
Literal("rgb(").setParseAction(lambda t: "RGB") +
|
Literal("rgb(").setParseAction(lambda t: "RGB") +
|
||||||
|
|
||||||
(
|
(
|
||||||
#integer constants, ie 255,255,255
|
#integer constants, ie 255,255,255
|
||||||
Group(colorByte + comma + colorByte + comma + colorByte) ^
|
Group(colorByte + comma + colorByte + comma + colorByte) ^
|
||||||
#percentage values, ie 100%, 50%
|
#percentage values, ie 100%, 50%
|
||||||
Group(colorPerc + comma + colorPerc + comma + colorPerc)
|
Group(colorPerc + comma + colorPerc + comma + colorPerc)
|
||||||
)
|
)
|
||||||
+
|
+
|
||||||
Literal(")").suppress() + StringEnd()
|
Literal(")").suppress() + StringEnd()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,10 +54,10 @@ def parseShortHex(t):
|
||||||
|
|
||||||
|
|
||||||
doubleHex = Word(hexnums, exact=2).setParseAction(lambda t: int(t[0], 16))
|
doubleHex = Word(hexnums, exact=2).setParseAction(lambda t: int(t[0], 16))
|
||||||
hexLiteral = (Literal("#").setParseAction(lambda t: "RGB") +
|
hexLiteral = (Literal("#").setParseAction(lambda t: "RGB") +
|
||||||
(
|
(
|
||||||
Group(doubleHex + doubleHex + doubleHex) |
|
Group(doubleHex + doubleHex + doubleHex) |
|
||||||
Word(hexnums, exact=3).setParseAction(parseShortHex)
|
Word(hexnums, exact=3).setParseAction(parseShortHex)
|
||||||
) + StringEnd()
|
) + StringEnd()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def parseNamedColour(t):
|
||||||
return ["RGB", NamedColours[t[0].lower()]]
|
return ["RGB", NamedColours[t[0].lower()]]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return ["RGB", (0,0,0)]
|
return ["RGB", (0,0,0)]
|
||||||
|
|
||||||
namedColour = Word(alphas).setParseAction(parseNamedColour)
|
namedColour = Word(alphas).setParseAction(parseNamedColour)
|
||||||
|
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ NamedColours = {
|
||||||
|
|
||||||
def fillCSS2SystemColours():
|
def fillCSS2SystemColours():
|
||||||
#The system colours require a wxApp to be present to retrieve,
|
#The system colours require a wxApp to be present to retrieve,
|
||||||
#so if you wnat support for them you'll need
|
#so if you wnat support for them you'll need
|
||||||
#to call this function after your wxApp instance starts
|
#to call this function after your wxApp instance starts
|
||||||
systemColors = {
|
systemColors = {
|
||||||
"ActiveBorder": wx.SYS_COLOUR_ACTIVEBORDER,
|
"ActiveBorder": wx.SYS_COLOUR_ACTIVEBORDER,
|
||||||
|
@ -280,4 +280,4 @@ def fillCSS2SystemColours():
|
||||||
NamedColours.update(
|
NamedColours.update(
|
||||||
#strip the alpha from the system colors. Is this really what we want to do?
|
#strip the alpha from the system colors. Is this really what we want to do?
|
||||||
(k.lower(), wx.SystemSettings.GetColour(v)[:3]) for (k,v) in systemColors.iteritems()
|
(k.lower(), wx.SystemSettings.GetColour(v)[:3]) for (k,v) in systemColors.iteritems()
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,7 +10,7 @@ class White(White):
|
||||||
super(White, self).__init__(ws, min, max, exact)
|
super(White, self).__init__(ws, min, max, exact)
|
||||||
|
|
||||||
escaped = (
|
escaped = (
|
||||||
Literal("\\").suppress() +
|
Literal("\\").suppress() +
|
||||||
#chr(20)-chr(126) + chr(128)-unichr(sys.maxunicode)
|
#chr(20)-chr(126) + chr(128)-unichr(sys.maxunicode)
|
||||||
Regex(u"[\u0020-\u007e\u0080-\uffff]", re.IGNORECASE)
|
Regex(u"[\u0020-\u007e\u0080-\uffff]", re.IGNORECASE)
|
||||||
)
|
)
|
||||||
|
@ -18,7 +18,7 @@ escaped = (
|
||||||
def convertToUnicode(t):
|
def convertToUnicode(t):
|
||||||
return unichr(int(t[0], 16))
|
return unichr(int(t[0], 16))
|
||||||
hex_unicode = (
|
hex_unicode = (
|
||||||
Literal("\\").suppress() +
|
Literal("\\").suppress() +
|
||||||
Regex("[0-9a-f]{1,6}", re.IGNORECASE) +
|
Regex("[0-9a-f]{1,6}", re.IGNORECASE) +
|
||||||
Optional(White(exact=1)).suppress()
|
Optional(White(exact=1)).suppress()
|
||||||
).setParseAction(convertToUnicode)
|
).setParseAction(convertToUnicode)
|
||||||
|
@ -29,9 +29,9 @@ escape = hex_unicode | escaped
|
||||||
#any unicode literal outside the 0-127 ascii range
|
#any unicode literal outside the 0-127 ascii range
|
||||||
nonascii = Regex(u"[^\u0000-\u007f]")
|
nonascii = Regex(u"[^\u0000-\u007f]")
|
||||||
|
|
||||||
#single character for starting an identifier.
|
#single character for starting an identifier.
|
||||||
nmstart = Regex(u"[A-Z]", re.IGNORECASE) | nonascii | escape
|
nmstart = Regex(u"[A-Z]", re.IGNORECASE) | nonascii | escape
|
||||||
|
|
||||||
nmchar = Regex(u"[0-9A-Z-]", re.IGNORECASE) | nonascii | escape
|
nmchar = Regex(u"[0-9A-Z-]", re.IGNORECASE) | nonascii | escape
|
||||||
|
|
||||||
identifier = Combine(nmstart + ZeroOrMore(nmchar))
|
identifier = Combine(nmstart + ZeroOrMore(nmchar))
|
||||||
|
|
|
@ -5,4 +5,4 @@ def inlineStyle(styleString):
|
||||||
return {}
|
return {}
|
||||||
styles = styleString.split(";")
|
styles = styleString.split(";")
|
||||||
rv = dict(style.split(":") for style in styles if len(style) != 0)
|
rv = dict(style.split(":") for style in styles if len(style) != 0)
|
||||||
return rv
|
return rv
|
||||||
|
|
|
@ -48,4 +48,4 @@ transformList = delimitedList(Group(transform), delim=maybeComma)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from tests.test_css import *
|
from tests.test_css import *
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -43,4 +43,4 @@ length = lengthValue + Optional(lengthUnit, default=None) + StringEnd()
|
||||||
length.leaveWhitespace()
|
length.leaveWhitespace()
|
||||||
|
|
||||||
#set the parse action aftward so it doesn't "infect" the parsers that build on it
|
#set the parse action aftward so it doesn't "infect" the parsers that build on it
|
||||||
number.setParseAction(asFloat)
|
number.setParseAction(asFloat)
|
||||||
|
|
|
@ -15,7 +15,7 @@ from svg.css import values
|
||||||
from attributes import paintValue
|
from attributes import paintValue
|
||||||
|
|
||||||
document = """<?xml version="1.0" standalone="no"?>
|
document = """<?xml version="1.0" standalone="no"?>
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
|
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
|
||||||
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||||
|
@ -38,7 +38,7 @@ def attrAsFloat(node, attr, defaultValue="0"):
|
||||||
return float(val)
|
return float(val)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return valueToPixels(val)
|
return valueToPixels(val)
|
||||||
|
|
||||||
def valueToPixels(val, defaultUnits="px"):
|
def valueToPixels(val, defaultUnits="px"):
|
||||||
#TODO manage default units
|
#TODO manage default units
|
||||||
from pyparsing import ParseException
|
from pyparsing import ParseException
|
||||||
|
@ -67,7 +67,7 @@ def pathHandler(func):
|
||||||
ops = self.generatePathOps(path)
|
ops = self.generatePathOps(path)
|
||||||
return path, ops
|
return path, ops
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
|
||||||
class SVGDocument(object):
|
class SVGDocument(object):
|
||||||
lastControl = None
|
lastControl = None
|
||||||
|
@ -102,12 +102,12 @@ class SVGDocument(object):
|
||||||
def state(self):
|
def state(self):
|
||||||
""" Retrieve the current state, without popping"""
|
""" Retrieve the current state, without popping"""
|
||||||
return self.stateStack[-1]
|
return self.stateStack[-1]
|
||||||
|
|
||||||
def processElement(self, element):
|
def processElement(self, element):
|
||||||
""" Process one element of the XML tree.
|
""" Process one element of the XML tree.
|
||||||
Returns the path representing the node,
|
Returns the path representing the node,
|
||||||
and an operation list for drawing the node.
|
and an operation list for drawing the node.
|
||||||
|
|
||||||
Parent nodes should return a path (for hittesting), but
|
Parent nodes should return a path (for hittesting), but
|
||||||
no draw operations
|
no draw operations
|
||||||
"""
|
"""
|
||||||
|
@ -126,7 +126,7 @@ class SVGDocument(object):
|
||||||
""" Returns an oplist for transformations.
|
""" Returns an oplist for transformations.
|
||||||
This applies to a node, not the current state because
|
This applies to a node, not the current state because
|
||||||
the transform stack is saved in the wxGraphicsContext.
|
the transform stack is saved in the wxGraphicsContext.
|
||||||
|
|
||||||
This oplist does *not* include the push/pop state commands
|
This oplist does *not* include the push/pop state commands
|
||||||
"""
|
"""
|
||||||
ops = []
|
ops = []
|
||||||
|
@ -188,8 +188,8 @@ class SVGDocument(object):
|
||||||
(wx.GraphicsContext.ConcatTransform, (matrix,))
|
(wx.GraphicsContext.ConcatTransform, (matrix,))
|
||||||
)
|
)
|
||||||
return ops
|
return ops
|
||||||
|
|
||||||
|
|
||||||
def addGroupToDocument(self, node):
|
def addGroupToDocument(self, node):
|
||||||
""" For parent elements: push on a state,
|
""" For parent elements: push on a state,
|
||||||
then process all child elements
|
then process all child elements
|
||||||
|
@ -197,7 +197,7 @@ class SVGDocument(object):
|
||||||
ops = [
|
ops = [
|
||||||
(wx.GraphicsContext.PushState, ())
|
(wx.GraphicsContext.PushState, ())
|
||||||
]
|
]
|
||||||
|
|
||||||
path = makePath()
|
path = makePath()
|
||||||
ops.extend(self.createTransformOpsFromNode(node))
|
ops.extend(self.createTransformOpsFromNode(node))
|
||||||
for child in node.getchildren():
|
for child in node.getchildren():
|
||||||
|
@ -210,7 +210,7 @@ class SVGDocument(object):
|
||||||
(wx.GraphicsContext.PopState, ())
|
(wx.GraphicsContext.PopState, ())
|
||||||
)
|
)
|
||||||
return path, ops
|
return path, ops
|
||||||
|
|
||||||
def getFontFromState(self):
|
def getFontFromState(self):
|
||||||
font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
||||||
family = self.state.get("font-family")
|
family = self.state.get("font-family")
|
||||||
|
@ -227,10 +227,10 @@ class SVGDocument(object):
|
||||||
else:
|
else:
|
||||||
font.SetPointSize(int(val))
|
font.SetPointSize(int(val))
|
||||||
return font
|
return font
|
||||||
|
|
||||||
def addTextToDocument(self, node):
|
def addTextToDocument(self, node):
|
||||||
x, y = [attrAsFloat(node, attr) for attr in ('x', 'y')]
|
x, y = [attrAsFloat(node, attr) for attr in ('x', 'y')]
|
||||||
|
|
||||||
def DoDrawText(context, text, x, y, brush=wx.NullGraphicsBrush):
|
def DoDrawText(context, text, x, y, brush=wx.NullGraphicsBrush):
|
||||||
#SVG spec appears to originate text from the bottom
|
#SVG spec appears to originate text from the bottom
|
||||||
#rather than the top as with our API. This function
|
#rather than the top as with our API. This function
|
||||||
|
@ -252,7 +252,7 @@ class SVGDocument(object):
|
||||||
(DoDrawText, (text, x, y))
|
(DoDrawText, (text, x, y))
|
||||||
]
|
]
|
||||||
return None, ops
|
return None, ops
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addRectToDocument(self, node, path):
|
def addRectToDocument(self, node, path):
|
||||||
x, y, w, h = (attrAsFloat(node, attr) for attr in ['x', 'y', 'width', 'height'])
|
x, y, w, h = (attrAsFloat(node, attr) for attr in ['x', 'y', 'width', 'height'])
|
||||||
|
@ -271,7 +271,7 @@ class SVGDocument(object):
|
||||||
#value clamping as per spec section 9.2
|
#value clamping as per spec section 9.2
|
||||||
rx = min(rx, w/2)
|
rx = min(rx, w/2)
|
||||||
ry = min(ry, h/2)
|
ry = min(ry, h/2)
|
||||||
|
|
||||||
#origin
|
#origin
|
||||||
path.MoveToPoint(x+rx, y)
|
path.MoveToPoint(x+rx, y)
|
||||||
path.AddLineToPoint(x+w-rx, y)
|
path.AddLineToPoint(x+w-rx, y)
|
||||||
|
@ -315,12 +315,12 @@ class SVGDocument(object):
|
||||||
path.AddRectangle(
|
path.AddRectangle(
|
||||||
x, y, w, h
|
x, y, w, h
|
||||||
)
|
)
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addCircleToDocument(self, node, path):
|
def addCircleToDocument(self, node, path):
|
||||||
cx, cy, r = [attrAsFloat(node, attr) for attr in ('cx', 'cy', 'r')]
|
cx, cy, r = [attrAsFloat(node, attr) for attr in ('cx', 'cy', 'r')]
|
||||||
path.AddCircle(cx, cy, r)
|
path.AddCircle(cx, cy, r)
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addEllipseToDocument(self, node, path):
|
def addEllipseToDocument(self, node, path):
|
||||||
cx, cy, rx, ry = [float(node.get(attr, 0)) for attr in ('cx', 'cy', 'rx', 'ry')]
|
cx, cy, rx, ry = [float(node.get(attr, 0)) for attr in ('cx', 'cy', 'rx', 'ry')]
|
||||||
|
@ -332,29 +332,29 @@ class SVGDocument(object):
|
||||||
x = cx - rx
|
x = cx - rx
|
||||||
y = cy - ry
|
y = cy - ry
|
||||||
path.AddEllipse(x, y, rx*2, ry*2)
|
path.AddEllipse(x, y, rx*2, ry*2)
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addLineToDocument(self, node, path):
|
def addLineToDocument(self, node, path):
|
||||||
x1, y1, x2, y2 = [attrAsFloat(node, attr) for attr in ('x1', 'y1', 'x2', 'y2')]
|
x1, y1, x2, y2 = [attrAsFloat(node, attr) for attr in ('x1', 'y1', 'x2', 'y2')]
|
||||||
path.MoveToPoint(x1, y1)
|
path.MoveToPoint(x1, y1)
|
||||||
path.AddLineToPoint(x2, y2)
|
path.AddLineToPoint(x2, y2)
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addPolyLineToDocument(self, node, path):
|
def addPolyLineToDocument(self, node, path):
|
||||||
#translate to pathdata and render that
|
#translate to pathdata and render that
|
||||||
data = "M " + node.get("points")
|
data = "M " + node.get("points")
|
||||||
self.addPathDataToPath(data, path)
|
self.addPathDataToPath(data, path)
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addPolygonToDocument(self, node, path):
|
def addPolygonToDocument(self, node, path):
|
||||||
#translate to pathdata and render that
|
#translate to pathdata and render that
|
||||||
data = "M " + node.get("points") + " Z"
|
data = "M " + node.get("points") + " Z"
|
||||||
self.addPathDataToPath(data, path)
|
self.addPathDataToPath(data, path)
|
||||||
|
|
||||||
@pathHandler
|
@pathHandler
|
||||||
def addPathDataToDocument(self, node, path):
|
def addPathDataToDocument(self, node, path):
|
||||||
self.addPathDataToPath(node.get('d', ''), path)
|
self.addPathDataToPath(node.get('d', ''), path)
|
||||||
|
|
||||||
def addPathDataToPath(self, data, path):
|
def addPathDataToPath(self, data, path):
|
||||||
self.lastControl = None
|
self.lastControl = None
|
||||||
self.lastControlQ = None
|
self.lastControlQ = None
|
||||||
|
@ -364,7 +364,7 @@ class SVGDocument(object):
|
||||||
form of (command, [list of arguments]).
|
form of (command, [list of arguments]).
|
||||||
We translate that to [(command, args[0]), (command, args[1])]
|
We translate that to [(command, args[0]), (command, args[1])]
|
||||||
via a generator.
|
via a generator.
|
||||||
|
|
||||||
M is special cased because its subsequent arguments
|
M is special cased because its subsequent arguments
|
||||||
become linetos.
|
become linetos.
|
||||||
"""
|
"""
|
||||||
|
@ -388,10 +388,10 @@ class SVGDocument(object):
|
||||||
#print "parsed in", time.time()-t
|
#print "parsed in", time.time()-t
|
||||||
for stroke in normalizeStrokes(parsed):
|
for stroke in normalizeStrokes(parsed):
|
||||||
self.addStrokeToPath(path, stroke)
|
self.addStrokeToPath(path, stroke)
|
||||||
|
|
||||||
|
|
||||||
def generatePathOps(self, path):
|
def generatePathOps(self, path):
|
||||||
""" Look at the current state and generate the
|
""" Look at the current state and generate the
|
||||||
draw operations (fill, stroke, neither) for the path"""
|
draw operations (fill, stroke, neither) for the path"""
|
||||||
ops = []
|
ops = []
|
||||||
brush = self.getBrushFromState(path)
|
brush = self.getBrushFromState(path)
|
||||||
|
@ -414,7 +414,7 @@ class SVGDocument(object):
|
||||||
(wx.GraphicsContext.StrokePath, (path,))
|
(wx.GraphicsContext.StrokePath, (path,))
|
||||||
)
|
)
|
||||||
return ops
|
return ops
|
||||||
|
|
||||||
def getPenFromState(self):
|
def getPenFromState(self):
|
||||||
pencolour = self.state.get('stroke', 'none')
|
pencolour = self.state.get('stroke', 'none')
|
||||||
if pencolour == 'currentColor':
|
if pencolour == 'currentColor':
|
||||||
|
@ -494,7 +494,7 @@ class SVGDocument(object):
|
||||||
opacity = float(opacity)
|
opacity = float(opacity)
|
||||||
opacity = min(max(opacity, 0.0), 1.0)
|
opacity = min(max(opacity, 0.0), 1.0)
|
||||||
a = 255 * opacity
|
a = 255 * opacity
|
||||||
#using try/except block instead of
|
#using try/except block instead of
|
||||||
#just setdefault because the wxBrush and wxColour would
|
#just setdefault because the wxBrush and wxColour would
|
||||||
#be created every time anyway in order to pass them,
|
#be created every time anyway in order to pass them,
|
||||||
#defeating the purpose of the cache
|
#defeating the purpose of the cache
|
||||||
|
@ -502,14 +502,14 @@ class SVGDocument(object):
|
||||||
return SVGDocument.brushCache[(r,g,b,a)]
|
return SVGDocument.brushCache[(r,g,b,a)]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return SVGDocument.brushCache.setdefault((r,g,b,a), wx.Brush(wx.Colour(r,g,b,a)))
|
return SVGDocument.brushCache.setdefault((r,g,b,a), wx.Brush(wx.Colour(r,g,b,a)))
|
||||||
|
|
||||||
|
|
||||||
def resolveURL(self, urlData):
|
def resolveURL(self, urlData):
|
||||||
"""
|
"""
|
||||||
Resolve a URL and return an elementTree Element from it.
|
Resolve a URL and return an elementTree Element from it.
|
||||||
|
|
||||||
Return None if unresolvable
|
Return None if unresolvable
|
||||||
|
|
||||||
"""
|
"""
|
||||||
scheme, netloc, path, query, fragment = urlData
|
scheme, netloc, path, query, fragment = urlData
|
||||||
if scheme == netloc == path == '':
|
if scheme == netloc == path == '':
|
||||||
|
@ -524,15 +524,15 @@ class SVGDocument(object):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self.resolveRemoteURL(urlData)
|
return self.resolveRemoteURL(urlData)
|
||||||
|
|
||||||
def resolveRemoteURL(self, url):
|
def resolveRemoteURL(self, url):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def addStrokeToPath(self, path, stroke):
|
def addStrokeToPath(self, path, stroke):
|
||||||
""" Given a stroke from a path command
|
""" Given a stroke from a path command
|
||||||
(in the form (command, arguments)) create the path
|
(in the form (command, arguments)) create the path
|
||||||
commands that represent it.
|
commands that represent it.
|
||||||
|
|
||||||
TODO: break out into (yet another) class/module,
|
TODO: break out into (yet another) class/module,
|
||||||
especially so we can get O(1) dispatch on type?
|
especially so we can get O(1) dispatch on type?
|
||||||
"""
|
"""
|
||||||
|
@ -564,8 +564,8 @@ class SVGDocument(object):
|
||||||
)
|
)
|
||||||
self.lastControl = control2
|
self.lastControl = control2
|
||||||
path.AddCurveToPoint(
|
path.AddCurveToPoint(
|
||||||
control1,
|
control1,
|
||||||
control2,
|
control2,
|
||||||
endpoint
|
endpoint
|
||||||
)
|
)
|
||||||
#~ cp = path.GetCurrentPoint()
|
#~ cp = path.GetCurrentPoint()
|
||||||
|
@ -574,7 +574,7 @@ class SVGDocument(object):
|
||||||
#~ path.AddCircle(x,y, 7)
|
#~ path.AddCircle(x,y, 7)
|
||||||
#~ path.MoveToPoint(cp)
|
#~ path.MoveToPoint(cp)
|
||||||
#~ print "C", control1, control2, endpoint
|
#~ print "C", control1, control2, endpoint
|
||||||
|
|
||||||
elif type == 'S':
|
elif type == 'S':
|
||||||
#control2, endpoint = arg
|
#control2, endpoint = arg
|
||||||
control2, endpoint = map(
|
control2, endpoint = map(
|
||||||
|
@ -584,11 +584,11 @@ class SVGDocument(object):
|
||||||
control1 = reflectPoint(self.lastControl, path.GetCurrentPoint())
|
control1 = reflectPoint(self.lastControl, path.GetCurrentPoint())
|
||||||
else:
|
else:
|
||||||
control1 = path.GetCurrentPoint()
|
control1 = path.GetCurrentPoint()
|
||||||
#~ print "S", self.lastControl,":",control1, control2, endpoint
|
#~ print "S", self.lastControl,":",control1, control2, endpoint
|
||||||
self.lastControl = control2
|
self.lastControl = control2
|
||||||
path.AddCurveToPoint(
|
path.AddCurveToPoint(
|
||||||
control1,
|
control1,
|
||||||
control2,
|
control2,
|
||||||
endpoint
|
endpoint
|
||||||
)
|
)
|
||||||
elif type == "Q":
|
elif type == "Q":
|
||||||
|
@ -603,50 +603,50 @@ class SVGDocument(object):
|
||||||
cx, cy = path.GetCurrentPoint()
|
cx, cy = path.GetCurrentPoint()
|
||||||
self.lastControlQ = (cx, cy)
|
self.lastControlQ = (cx, cy)
|
||||||
path.AddQuadCurveToPoint(cx, cy, x, y)
|
path.AddQuadCurveToPoint(cx, cy, x, y)
|
||||||
|
|
||||||
elif type == "V":
|
elif type == "V":
|
||||||
_, y = normalizePoint((0, arg))
|
_, y = normalizePoint((0, arg))
|
||||||
x, _ = path.GetCurrentPoint()
|
x, _ = path.GetCurrentPoint()
|
||||||
path.AddLineToPoint(x,y)
|
path.AddLineToPoint(x,y)
|
||||||
|
|
||||||
elif type == "H":
|
elif type == "H":
|
||||||
x, _ = normalizePoint((arg, 0))
|
x, _ = normalizePoint((arg, 0))
|
||||||
_, y = path.GetCurrentPoint()
|
_, y = path.GetCurrentPoint()
|
||||||
path.AddLineToPoint(x,y)
|
path.AddLineToPoint(x,y)
|
||||||
|
|
||||||
elif type == "A":
|
elif type == "A":
|
||||||
#wxGC currently only supports circular arcs,
|
#wxGC currently only supports circular arcs,
|
||||||
#not eliptical ones
|
#not eliptical ones
|
||||||
|
|
||||||
(
|
(
|
||||||
(rx, ry), #radii of ellipse
|
(rx, ry), #radii of ellipse
|
||||||
angle, #angle of rotation on the ellipse in degrees
|
angle, #angle of rotation on the ellipse in degrees
|
||||||
(fa, fs), #arc and stroke angle flags
|
(fa, fs), #arc and stroke angle flags
|
||||||
(x, y) #endpoint on the arc
|
(x, y) #endpoint on the arc
|
||||||
) = arg
|
) = arg
|
||||||
|
|
||||||
x, y = normalizePoint((x,y))
|
x, y = normalizePoint((x,y))
|
||||||
cx, cy = path.GetCurrentPoint()
|
cx, cy = path.GetCurrentPoint()
|
||||||
if (cx, cy) == (x, y):
|
if (cx, cy) == (x, y):
|
||||||
return #noop
|
return #noop
|
||||||
|
|
||||||
if (rx == 0 or ry == 0):
|
if (rx == 0 or ry == 0):
|
||||||
#no radius is effectively a line
|
#no radius is effectively a line
|
||||||
path.AddLineToPoint(x,y)
|
path.AddLineToPoint(x,y)
|
||||||
return
|
return
|
||||||
|
|
||||||
#find the center point for the ellipse
|
#find the center point for the ellipse
|
||||||
#translation via the angle
|
#translation via the angle
|
||||||
angle = angle % 360
|
angle = angle % 360
|
||||||
angle = math.radians(angle)
|
angle = math.radians(angle)
|
||||||
|
|
||||||
#translated endpoint
|
#translated endpoint
|
||||||
xPrime = math.cos(angle) * ((cx-x)/2)
|
xPrime = math.cos(angle) * ((cx-x)/2)
|
||||||
xPrime += math.sin(angle) * ((cx-x)/2)
|
xPrime += math.sin(angle) * ((cx-x)/2)
|
||||||
yPrime = -(math.sin(angle)) * ((cy-y)/2)
|
yPrime = -(math.sin(angle)) * ((cy-y)/2)
|
||||||
yPrime += (math.cos(angle)) * ((cy-y)/2)
|
yPrime += (math.cos(angle)) * ((cy-y)/2)
|
||||||
|
|
||||||
|
|
||||||
temp = ((rx**2) * (ry**2)) - ((rx**2) * (yPrime**2)) - ((ry**2) * (xPrime**2))
|
temp = ((rx**2) * (ry**2)) - ((rx**2) * (yPrime**2)) - ((ry**2) * (xPrime**2))
|
||||||
temp /= ((rx**2) * (yPrime**2)) + ((ry**2)*(xPrime**2))
|
temp /= ((rx**2) * (yPrime**2)) + ((ry**2)*(xPrime**2))
|
||||||
temp = abs(temp)
|
temp = abs(temp)
|
||||||
|
@ -659,7 +659,7 @@ class SVGDocument(object):
|
||||||
cyPrime = temp * -((ry * xPrime) / rx)
|
cyPrime = temp * -((ry * xPrime) / rx)
|
||||||
if fa == fs:
|
if fa == fs:
|
||||||
cxPrime, cyPrime = -cxPrime, -cyPrime
|
cxPrime, cyPrime = -cxPrime, -cyPrime
|
||||||
|
|
||||||
#reflect backwards now for the origin
|
#reflect backwards now for the origin
|
||||||
cnx = math.cos(angle) * cxPrime
|
cnx = math.cos(angle) * cxPrime
|
||||||
cnx += math.sin(angle) * cxPrime
|
cnx += math.sin(angle) * cxPrime
|
||||||
|
@ -667,18 +667,18 @@ class SVGDocument(object):
|
||||||
cny += (math.cos(angle)) * cyPrime
|
cny += (math.cos(angle)) * cyPrime
|
||||||
cnx += ((cx+x)/2.0)
|
cnx += ((cx+x)/2.0)
|
||||||
cny += ((cy+y)/2.0)
|
cny += ((cy+y)/2.0)
|
||||||
|
|
||||||
#calculate the angle between the two endpoints
|
#calculate the angle between the two endpoints
|
||||||
lastArc = wx.Point2D(x-cnx, y-cny).GetVectorAngle()
|
lastArc = wx.Point2D(x-cnx, y-cny).GetVectorAngle()
|
||||||
firstArc = wx.Point2D(cx-cnx, cy-cny).GetVectorAngle()
|
firstArc = wx.Point2D(cx-cnx, cy-cny).GetVectorAngle()
|
||||||
lastArc = math.radians(lastArc)
|
lastArc = math.radians(lastArc)
|
||||||
firstArc = math.radians(firstArc)
|
firstArc = math.radians(firstArc)
|
||||||
|
|
||||||
|
|
||||||
#aargh buggines.
|
#aargh buggines.
|
||||||
#AddArc draws a straight line between
|
#AddArc draws a straight line between
|
||||||
#the endpoints of the arc.
|
#the endpoints of the arc.
|
||||||
#putting it in a subpath makes the strokes come out
|
#putting it in a subpath makes the strokes come out
|
||||||
#correctly, but it still only fills the slice
|
#correctly, but it still only fills the slice
|
||||||
#taking out the MoveToPoint fills correctly.
|
#taking out the MoveToPoint fills correctly.
|
||||||
path.AddEllipse(cnx-rx, cny-ry, rx*2, ry*2)
|
path.AddEllipse(cnx-rx, cny-ry, rx*2, ry*2)
|
||||||
|
@ -687,7 +687,7 @@ class SVGDocument(object):
|
||||||
#~ npath.AddEllipticalArc(cnx-rx, cny-ry, rx*2, ry*2, firstArc, lastArc, False)
|
#~ npath.AddEllipticalArc(cnx-rx, cny-ry, rx*2, ry*2, firstArc, lastArc, False)
|
||||||
#~ npath.MoveToPoint(x,y)
|
#~ npath.MoveToPoint(x,y)
|
||||||
#~ path.AddPath(npath)
|
#~ path.AddPath(npath)
|
||||||
|
|
||||||
elif type == 'Z':
|
elif type == 'Z':
|
||||||
#~ Bugginess:
|
#~ Bugginess:
|
||||||
#~ CloseSubpath() doesn't change the
|
#~ CloseSubpath() doesn't change the
|
||||||
|
@ -699,17 +699,17 @@ class SVGDocument(object):
|
||||||
#~ results
|
#~ results
|
||||||
#~ Manually closing the path *and* calling CloseSubpath() appears
|
#~ Manually closing the path *and* calling CloseSubpath() appears
|
||||||
#~ to give correct results on win32
|
#~ to give correct results on win32
|
||||||
|
|
||||||
pt = self.firstPoints.pop()
|
pt = self.firstPoints.pop()
|
||||||
path.AddLineToPoint(pt)
|
path.AddLineToPoint(pt)
|
||||||
path.CloseSubpath()
|
path.CloseSubpath()
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
if not hasattr(self, "ops"):
|
if not hasattr(self, "ops"):
|
||||||
return
|
return
|
||||||
for op, args in self.ops:
|
for op, args in self.ops:
|
||||||
op(context, *args)
|
op(context, *args)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from tests.test_document import *
|
from tests.test_document import *
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
"""
|
"""
|
||||||
SVG path data parser
|
SVG path data parser
|
||||||
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
steps = svg.parseString(pathdata)
|
steps = svg.parseString(pathdata)
|
||||||
for command, arguments in steps:
|
for command, arguments in steps:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from pyparsing import (ParserElement, Literal, Word, CaselessLiteral,
|
from pyparsing import (ParserElement, Literal, Word, CaselessLiteral,
|
||||||
Optional, Combine, Forward, ZeroOrMore, nums, oneOf, Group, ParseException, OneOrMore)
|
Optional, Combine, Forward, ZeroOrMore, nums, oneOf, Group, ParseException, OneOrMore)
|
||||||
|
|
||||||
#ParserElement.enablePackrat()
|
#ParserElement.enablePackrat()
|
||||||
|
|
||||||
def Command(char):
|
def Command(char):
|
||||||
""" Case insensitive but case preserving"""
|
""" Case insensitive but case preserving"""
|
||||||
return CaselessPreservingLiteral(char)
|
return CaselessPreservingLiteral(char)
|
||||||
|
|
||||||
def Arguments(token):
|
def Arguments(token):
|
||||||
return Group(token)
|
return Group(token)
|
||||||
|
|
||||||
|
|
||||||
class CaselessPreservingLiteral(CaselessLiteral):
|
class CaselessPreservingLiteral(CaselessLiteral):
|
||||||
""" Like CaselessLiteral, but returns the match as found
|
""" Like CaselessLiteral, but returns the match as found
|
||||||
instead of as defined.
|
instead of as defined.
|
||||||
|
@ -40,8 +40,8 @@ class CaselessPreservingLiteral(CaselessLiteral):
|
||||||
exc = self.myException
|
exc = self.myException
|
||||||
exc.loc = loc
|
exc.loc = loc
|
||||||
exc.pstr = instring
|
exc.pstr = instring
|
||||||
raise exc
|
raise exc
|
||||||
|
|
||||||
def Sequence(token):
|
def Sequence(token):
|
||||||
""" A sequence of the token"""
|
""" A sequence of the token"""
|
||||||
return OneOrMore(token+maybeComma)
|
return OneOrMore(token+maybeComma)
|
||||||
|
@ -58,13 +58,13 @@ def convertToFloat(s, loc, toks):
|
||||||
|
|
||||||
exponent = CaselessLiteral("e")+Optional(sign)+Word(nums)
|
exponent = CaselessLiteral("e")+Optional(sign)+Word(nums)
|
||||||
|
|
||||||
#note that almost all these fields are optional,
|
#note that almost all these fields are optional,
|
||||||
#and this can match almost anything. We rely on Pythons built-in
|
#and this can match almost anything. We rely on Pythons built-in
|
||||||
#float() function to clear out invalid values - loosely matching like this
|
#float() function to clear out invalid values - loosely matching like this
|
||||||
#speeds up parsing quite a lot
|
#speeds up parsing quite a lot
|
||||||
floatingPointConstant = Combine(
|
floatingPointConstant = Combine(
|
||||||
Optional(sign) +
|
Optional(sign) +
|
||||||
Optional(Word(nums)) +
|
Optional(Word(nums)) +
|
||||||
Optional(Literal(".") + Optional(Word(nums)))+
|
Optional(Literal(".") + Optional(Word(nums)))+
|
||||||
Optional(exponent)
|
Optional(exponent)
|
||||||
)
|
)
|
||||||
|
@ -75,7 +75,7 @@ number = floatingPointConstant
|
||||||
|
|
||||||
#same as FP constant but don't allow a - sign
|
#same as FP constant but don't allow a - sign
|
||||||
nonnegativeNumber = Combine(
|
nonnegativeNumber = Combine(
|
||||||
Optional(Word(nums)) +
|
Optional(Word(nums)) +
|
||||||
Optional(Literal(".") + Optional(Word(nums)))+
|
Optional(Literal(".") + Optional(Word(nums)))+
|
||||||
Optional(exponent)
|
Optional(exponent)
|
||||||
)
|
)
|
||||||
|
@ -120,7 +120,7 @@ ellipticalArcArgument = Group(
|
||||||
coordinatePair #(x,y)
|
coordinatePair #(x,y)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
ellipticalArc = Group(Command("A") + Arguments(Sequence(ellipticalArcArgument)))
|
ellipticalArc = Group(Command("A") + Arguments(Sequence(ellipticalArcArgument)))
|
||||||
|
|
||||||
smoothQuadraticBezierCurveto = Group(Command("T") + Arguments(coordinatePairSequence))
|
smoothQuadraticBezierCurveto = Group(Command("T") + Arguments(coordinatePairSequence))
|
||||||
|
@ -155,39 +155,37 @@ def profile():
|
||||||
p.disable()
|
p.disable()
|
||||||
p.print_stats()
|
p.print_stats()
|
||||||
|
|
||||||
bpath = """M204.33 139.83 C196.33 133.33 206.68 132.82 206.58 132.58 C192.33 97.08 169.35
|
bpath = """M204.33 139.83 C196.33 133.33 206.68 132.82 206.58 132.58 C192.33 97.08 169.35
|
||||||
81.41 167.58 80.58 C162.12 78.02 159.48 78.26 160.45 76.97 C161.41 75.68 167.72 79.72 168.58
|
81.41 167.58 80.58 C162.12 78.02 159.48 78.26 160.45 76.97 C161.41 75.68 167.72 79.72 168.58
|
||||||
80.33 C193.83 98.33 207.58 132.33 207.58 132.33 C207.58 132.33 209.33 133.33 209.58 132.58
|
80.33 C193.83 98.33 207.58 132.33 207.58 132.33 C207.58 132.33 209.33 133.33 209.58 132.58
|
||||||
C219.58 103.08 239.58 87.58 246.33 81.33 C253.08 75.08 256.63 74.47 247.33 81.58 C218.58 103.58
|
C219.58 103.08 239.58 87.58 246.33 81.33 C253.08 75.08 256.63 74.47 247.33 81.58 C218.58 103.58
|
||||||
210.34 132.23 210.83 132.33 C222.33 134.83 211.33 140.33 211.83 139.83 C214.85 136.81 214.83 145.83 214.83
|
210.34 132.23 210.83 132.33 C222.33 134.83 211.33 140.33 211.83 139.83 C214.85 136.81 214.83 145.83 214.83
|
||||||
145.83 C214.83 145.83 231.83 110.83 298.33 66.33 C302.43 63.59 445.83 -14.67 395.83 80.83 C393.24 85.79 375.83
|
145.83 C214.83 145.83 231.83 110.83 298.33 66.33 C302.43 63.59 445.83 -14.67 395.83 80.83 C393.24 85.79 375.83
|
||||||
105.83 375.83 105.83 C375.83 105.83 377.33 114.33 371.33 121.33 C370.3 122.53 367.83 134.33 361.83 140.83 C360.14 142.67
|
105.83 375.83 105.83 C375.83 105.83 377.33 114.33 371.33 121.33 C370.3 122.53 367.83 134.33 361.83 140.83 C360.14 142.67
|
||||||
361.81 139.25 361.83 140.83 C362.33 170.83 337.76 170.17 339.33 170.33 C348.83 171.33 350.19 183.66 350.33 183.83 C355.83
|
361.81 139.25 361.83 140.83 C362.33 170.83 337.76 170.17 339.33 170.33 C348.83 171.33 350.19 183.66 350.33 183.83 C355.83
|
||||||
190.33 353.83 191.83 355.83 194.83 C366.63 211.02 355.24 210.05 356.83 212.83 C360.83 219.83 355.99 222.72 357.33 224.83
|
190.33 353.83 191.83 355.83 194.83 C366.63 211.02 355.24 210.05 356.83 212.83 C360.83 219.83 355.99 222.72 357.33 224.83
|
||||||
C360.83 230.33 354.75 233.84 354.83 235.33 C355.33 243.83 349.67 240.73 349.83 244.33 C350.33 255.33 346.33 250.83 343.83 254.83
|
C360.83 230.33 354.75 233.84 354.83 235.33 C355.33 243.83 349.67 240.73 349.83 244.33 C350.33 255.33 346.33 250.83 343.83 254.83
|
||||||
C336.33 266.83 333.46 262.38 332.83 263.83 C329.83 270.83 325.81 269.15 324.33 270.83 C320.83 274.83 317.33 274.83 315.83 276.33
|
C336.33 266.83 333.46 262.38 332.83 263.83 C329.83 270.83 325.81 269.15 324.33 270.83 C320.83 274.83 317.33 274.83 315.83 276.33
|
||||||
C308.83 283.33 304.86 278.39 303.83 278.83 C287.83 285.83 280.33 280.17 277.83 280.33 C270.33 280.83 271.48 279.67 269.33 277.83
|
C308.83 283.33 304.86 278.39 303.83 278.83 C287.83 285.83 280.33 280.17 277.83 280.33 C270.33 280.83 271.48 279.67 269.33 277.83
|
||||||
C237.83 250.83 219.33 211.83 215.83 206.83 C214.4 204.79 211.35 193.12 212.33 195.83 C214.33 201.33 213.33 250.33 207.83 250.33
|
C237.83 250.83 219.33 211.83 215.83 206.83 C214.4 204.79 211.35 193.12 212.33 195.83 C214.33 201.33 213.33 250.33 207.83 250.33
|
||||||
C202.33 250.33 201.83 204.33 205.33 195.83 C206.43 193.16 204.4 203.72 201.79 206.83 C196.33 213.33 179.5 250.83 147.59 277.83
|
C202.33 250.33 201.83 204.33 205.33 195.83 C206.43 193.16 204.4 203.72 201.79 206.83 C196.33 213.33 179.5 250.83 147.59 277.83
|
||||||
C145.42 279.67 146.58 280.83 138.98 280.33 C136.46 280.17 128.85 285.83 112.65 278.83 C111.61 278.39 107.58 283.33 100.49 276.33
|
C145.42 279.67 146.58 280.83 138.98 280.33 C136.46 280.17 128.85 285.83 112.65 278.83 C111.61 278.39 107.58 283.33 100.49 276.33
|
||||||
C98.97 274.83 95.43 274.83 91.88 270.83 C90.39 269.15 86.31 270.83 83.27 263.83 C82.64 262.38 79.73 266.83 72.13 254.83 C69.6 250.83
|
C98.97 274.83 95.43 274.83 91.88 270.83 C90.39 269.15 86.31 270.83 83.27 263.83 C82.64 262.38 79.73 266.83 72.13 254.83 C69.6 250.83
|
||||||
65.54 255.33 66.05 244.33 C66.22 240.73 60.48 243.83 60.99 235.33 C61.08 233.84 54.91 230.33 58.45 224.83 C59.81 222.72 54.91 219.83
|
65.54 255.33 66.05 244.33 C66.22 240.73 60.48 243.83 60.99 235.33 C61.08 233.84 54.91 230.33 58.45 224.83 C59.81 222.72 54.91 219.83
|
||||||
58.96 212.83 C60.57 210.05 49.04 211.02 59.97 194.83 C62 191.83 59.97 190.33 65.54 183.83 C65.69 183.66 67.06 171.33 76.69 170.33
|
58.96 212.83 C60.57 210.05 49.04 211.02 59.97 194.83 C62 191.83 59.97 190.33 65.54 183.83 C65.69 183.66 67.06 171.33 76.69 170.33
|
||||||
C78.28 170.17 53.39 170.83 53.9 140.83 C53.92 139.25 55.61 142.67 53.9 140.83 C47.82 134.33 45.32 122.53 44.27 121.33 C38.19 114.33
|
C78.28 170.17 53.39 170.83 53.9 140.83 C53.92 139.25 55.61 142.67 53.9 140.83 C47.82 134.33 45.32 122.53 44.27 121.33 C38.19 114.33
|
||||||
39.71 105.83 39.71 105.83 C39.71 105.83 22.08 85.79 19.46 80.83 C-31.19 -14.67 114.07 63.59 118.22 66.33 C185.58 110.83 202 145.83
|
39.71 105.83 39.71 105.83 C39.71 105.83 22.08 85.79 19.46 80.83 C-31.19 -14.67 114.07 63.59 118.22 66.33 C185.58 110.83 202 145.83
|
||||||
202 145.83 C202 145.83 202.36 143.28 203 141.83 C203.64 140.39 204.56 140.02 204.33 139.83 z"""
|
202 145.83 C202 145.83 202.36 143.28 203 141.83 C203.64 140.39 204.56 140.02 204.33 139.83 z"""
|
||||||
|
|
||||||
def ptest():
|
def ptest():
|
||||||
svg.parseString(bpath)
|
svg.parseString(bpath)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
#~ from tests.test_pathdata import *
|
#~ from tests.test_pathdata import *
|
||||||
#~ unittest.main()
|
#~ unittest.main()
|
||||||
profile()
|
profile()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ def PrintHeader():
|
||||||
|
|
||||||
def PrintMenu():
|
def PrintMenu():
|
||||||
return '<div id="mainmenu"><ul><li><a href="/">home</a></li><li><a href="/settings">settings</a></li><li><a href="/console">console</a></li><li><a href="/status">status (XML)</a></li></ul></div>'
|
return '<div id="mainmenu"><ul><li><a href="/">home</a></li><li><a href="/settings">settings</a></li><li><a href="/console">console</a></li><li><a href="/status">status (XML)</a></li></ul></div>'
|
||||||
|
|
||||||
def PrintFooter():
|
def PrintFooter():
|
||||||
return "</body></html>"
|
return "</body></html>"
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ def TReloadPage(action):
|
||||||
|
|
||||||
def clear_text(mypass):
|
def clear_text(mypass):
|
||||||
return mypass
|
return mypass
|
||||||
|
|
||||||
gPronterPtr = 0
|
gPronterPtr = 0
|
||||||
gWeblog = ""
|
gWeblog = ""
|
||||||
gLogRefresh =5
|
gLogRefresh =5
|
||||||
|
@ -80,7 +80,7 @@ class ConnectButton(object):
|
||||||
'tools.basic_auth.realm': 'My Print Server',
|
'tools.basic_auth.realm': 'My Print Server',
|
||||||
'tools.basic_auth.users': users,
|
'tools.basic_auth.users': users,
|
||||||
'tools.basic_auth.encrypt': clear_text}
|
'tools.basic_auth.encrypt': clear_text}
|
||||||
|
|
||||||
class DisconnectButton(object):
|
class DisconnectButton(object):
|
||||||
def index(self):
|
def index(self):
|
||||||
#handle connect push, then reload page
|
#handle connect push, then reload page
|
||||||
|
@ -149,7 +149,7 @@ class MoveButton(object):
|
||||||
'tools.basic_auth.realm': 'My Print Server',
|
'tools.basic_auth.realm': 'My Print Server',
|
||||||
'tools.basic_auth.users': users,
|
'tools.basic_auth.users': users,
|
||||||
'tools.basic_auth.encrypt': clear_text}
|
'tools.basic_auth.encrypt': clear_text}
|
||||||
|
|
||||||
class CustomButton(object):
|
class CustomButton(object):
|
||||||
def button(self, *args):
|
def button(self, *args):
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -164,7 +164,7 @@ class CustomButton(object):
|
||||||
'tools.basic_auth.realm': 'My Print Server',
|
'tools.basic_auth.realm': 'My Print Server',
|
||||||
'tools.basic_auth.users': users,
|
'tools.basic_auth.users': users,
|
||||||
'tools.basic_auth.encrypt': clear_text}
|
'tools.basic_auth.encrypt': clear_text}
|
||||||
|
|
||||||
class HomeButton(object):
|
class HomeButton(object):
|
||||||
def axis(self, *args):
|
def axis(self, *args):
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -183,13 +183,13 @@ class HomeButton(object):
|
||||||
if(taxis == "all"):
|
if(taxis == "all"):
|
||||||
gPronterPtr.onecmd('home')
|
gPronterPtr.onecmd('home')
|
||||||
return ReloadPage("Home All")
|
return ReloadPage("Home All")
|
||||||
|
|
||||||
axis.exposed = True
|
axis.exposed = True
|
||||||
axis._cp_config = {'tools.basic_auth.on': True,
|
axis._cp_config = {'tools.basic_auth.on': True,
|
||||||
'tools.basic_auth.realm': 'My Print Server',
|
'tools.basic_auth.realm': 'My Print Server',
|
||||||
'tools.basic_auth.users': users,
|
'tools.basic_auth.users': users,
|
||||||
'tools.basic_auth.encrypt': clear_text}
|
'tools.basic_auth.encrypt': clear_text}
|
||||||
|
|
||||||
class XMLstatus(object):
|
class XMLstatus(object):
|
||||||
def index(self):
|
def index(self):
|
||||||
#handle connect push, then reload page
|
#handle connect push, then reload page
|
||||||
|
@ -203,7 +203,7 @@ class XMLstatus(object):
|
||||||
state="Printing"
|
state="Printing"
|
||||||
if gPronterPtr.paused:
|
if gPronterPtr.paused:
|
||||||
state="Paused"
|
state="Paused"
|
||||||
|
|
||||||
txt=txt+'<state>'+state+'</state>\n'
|
txt=txt+'<state>'+state+'</state>\n'
|
||||||
txt=txt+'<file>'+str(gPronterPtr.filename)+'</file>\n'
|
txt=txt+'<file>'+str(gPronterPtr.filename)+'</file>\n'
|
||||||
txt=txt+'<status>'+str(gPronterPtr.status.GetStatusText())+'</status>\n'
|
txt=txt+'<status>'+str(gPronterPtr.status.GetStatusText())+'</status>\n'
|
||||||
|
@ -234,13 +234,13 @@ class XMLstatus(object):
|
||||||
index.exposed = True
|
index.exposed = True
|
||||||
|
|
||||||
class WebInterface(object):
|
class WebInterface(object):
|
||||||
|
|
||||||
def __init__(self, pface):
|
def __init__(self, pface):
|
||||||
if (sys.version_info[1] > 6):
|
if (sys.version_info[1] > 6):
|
||||||
# 'allow_no_value' wasn't added until 2.7
|
# 'allow_no_value' wasn't added until 2.7
|
||||||
config = ConfigParser.SafeConfigParser(allow_no_value=True)
|
config = ConfigParser.SafeConfigParser(allow_no_value=True)
|
||||||
else:
|
else:
|
||||||
config = ConfigParser.SafeConfigParser()
|
config = ConfigParser.SafeConfigParser()
|
||||||
config.read(configfile(pface.web_auth_config or 'auth.config'))
|
config.read(configfile(pface.web_auth_config or 'auth.config'))
|
||||||
users[config.get("user", "user")] = config.get("user", "pass")
|
users[config.get("user", "user")] = config.get("user", "pass")
|
||||||
self.pface = pface
|
self.pface = pface
|
||||||
|
@ -248,12 +248,12 @@ class WebInterface(object):
|
||||||
global gWeblog
|
global gWeblog
|
||||||
self.name="<div id='title'>Pronterface Web-Interface</div>"
|
self.name="<div id='title'>Pronterface Web-Interface</div>"
|
||||||
gWeblog = ""
|
gWeblog = ""
|
||||||
gPronterPtr = self.pface
|
gPronterPtr = self.pface
|
||||||
|
|
||||||
settings = SettingsPage()
|
settings = SettingsPage()
|
||||||
logpage = LogPage()
|
logpage = LogPage()
|
||||||
console = ConsolePage()
|
console = ConsolePage()
|
||||||
|
|
||||||
#actions
|
#actions
|
||||||
connect = ConnectButton()
|
connect = ConnectButton()
|
||||||
disconnect = DisconnectButton()
|
disconnect = DisconnectButton()
|
||||||
|
@ -264,7 +264,7 @@ class WebInterface(object):
|
||||||
home = HomeButton()
|
home = HomeButton()
|
||||||
move = MoveButton()
|
move = MoveButton()
|
||||||
custom =CustomButton()
|
custom =CustomButton()
|
||||||
|
|
||||||
def index(self):
|
def index(self):
|
||||||
pageText=PrintHeader()+self.name+PrintMenu()
|
pageText=PrintHeader()+self.name+PrintMenu()
|
||||||
pageText+="<div id='content'>\n"
|
pageText+="<div id='content'>\n"
|
||||||
|
@ -274,20 +274,20 @@ class WebInterface(object):
|
||||||
pageText+="<li><a href='/reset'>Reset</a></li>\n"
|
pageText+="<li><a href='/reset'>Reset</a></li>\n"
|
||||||
pageText+="<li><a href='/printbutton'>Print</a></li>\n"
|
pageText+="<li><a href='/printbutton'>Print</a></li>\n"
|
||||||
pageText+="<li><a href='/pausebutton'>Pause</a></li>\n"
|
pageText+="<li><a href='/pausebutton'>Pause</a></li>\n"
|
||||||
|
|
||||||
for i in gPronterPtr.cpbuttons:
|
for i in gPronterPtr.cpbuttons:
|
||||||
pageText+="<li><a href='/custom/button/"+i[1]+"'>"+i[0]+"</a></li>\n"
|
pageText+="<li><a href='/custom/button/"+i[1]+"'>"+i[0]+"</a></li>\n"
|
||||||
|
|
||||||
#for i in gPronterPtr.custombuttons:
|
#for i in gPronterPtr.custombuttons:
|
||||||
# print(str(i));
|
# print(str(i));
|
||||||
|
|
||||||
pageText+="</ul>\n"
|
pageText+="</ul>\n"
|
||||||
pageText+="</div>\n"
|
pageText+="</div>\n"
|
||||||
pageText+="<div id='gui'>\n"
|
pageText+="<div id='gui'>\n"
|
||||||
pageText+="<div id='control_xy'>"
|
pageText+="<div id='control_xy'>"
|
||||||
pageText+="<img src='/images/control_xy.png' usemap='#xymap'/>"
|
pageText+="<img src='/images/control_xy.png' usemap='#xymap'/>"
|
||||||
pageText+='<map name="xymap">'
|
pageText+='<map name="xymap">'
|
||||||
|
|
||||||
pageText+='<area shape="rect" coords="8,5,51,48" href="/home/axis/x" alt="X Home" title="X Home" />'
|
pageText+='<area shape="rect" coords="8,5,51,48" href="/home/axis/x" alt="X Home" title="X Home" />'
|
||||||
pageText+='<area shape="rect" coords="195,6,236,46" href="/home/axis/y" alt="Y Home" title="Y Home" />'
|
pageText+='<area shape="rect" coords="195,6,236,46" href="/home/axis/y" alt="Y Home" title="Y Home" />'
|
||||||
pageText+='<area shape="rect" coords="7,192,48,232" href="/home/axis/all" alt="All Home" title="All Home" />'
|
pageText+='<area shape="rect" coords="7,192,48,232" href="/home/axis/all" alt="All Home" title="All Home" />'
|
||||||
|
@ -336,7 +336,7 @@ class WebInterface(object):
|
||||||
# pageText+="<ul><li><b>Bed Temp:</b></li><li><a href='/off'>OFF</a></li><li><a href='/185'>185 (PLA)</a></li><li><a href='/240'>240 (ABS)</a></li></ul>"
|
# pageText+="<ul><li><b>Bed Temp:</b></li><li><a href='/off'>OFF</a></li><li><a href='/185'>185 (PLA)</a></li><li><a href='/240'>240 (ABS)</a></li></ul>"
|
||||||
# pageText+="</div>"
|
# pageText+="</div>"
|
||||||
# pageText+="</div>"
|
# pageText+="</div>"
|
||||||
|
|
||||||
pageText=pageText+"<div id='file'>File Loaded: <i>"+str(gPronterPtr.filename)+"</i></div>"
|
pageText=pageText+"<div id='file'>File Loaded: <i>"+str(gPronterPtr.filename)+"</i></div>"
|
||||||
pageText+="<div id='logframe'><iframe src='/logpage' width='100%' height='100%'>iFraming Not Supported?? No log for you.</iframe></div>"
|
pageText+="<div id='logframe'><iframe src='/logpage' width='100%' height='100%'>iFraming Not Supported?? No log for you.</iframe></div>"
|
||||||
pageText+=PrintFooter()
|
pageText+=PrintFooter()
|
||||||
|
@ -357,7 +357,7 @@ class WebInterfaceStub(object):
|
||||||
|
|
||||||
def KillWebInterfaceThread():
|
def KillWebInterfaceThread():
|
||||||
cherrypy.engine.exit()
|
cherrypy.engine.exit()
|
||||||
|
|
||||||
def StartWebInterfaceThread(webInterface):
|
def StartWebInterfaceThread(webInterface):
|
||||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
cherrypy.config.update({'engine.autoreload_on':False})
|
cherrypy.config.update({'engine.autoreload_on':False})
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import wx, os, math
|
import wx, os, math
|
||||||
from bufferedcanvas import *
|
from bufferedcanvas import *
|
||||||
from printrun_utils import *
|
from printrun_utils import *
|
||||||
|
|
||||||
def sign(n):
|
def sign(n):
|
||||||
if n < 0: return -1
|
if n < 0: return -1
|
||||||
|
@ -56,10 +56,10 @@ class XYButtons(BufferedCanvas):
|
||||||
self.lastMove = None
|
self.lastMove = None
|
||||||
self.lastCorner = None
|
self.lastCorner = None
|
||||||
|
|
||||||
self.bgcolor = wx.Colour()
|
self.bgcolor = wx.Colour()
|
||||||
self.bgcolor.SetFromName(bgcolor)
|
self.bgcolor.SetFromName(bgcolor)
|
||||||
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
|
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
|
||||||
|
|
||||||
BufferedCanvas.__init__(self, parent, ID)
|
BufferedCanvas.__init__(self, parent, ID)
|
||||||
self.SetSize(self.bg_bmp.GetSize())
|
self.SetSize(self.bg_bmp.GetSize())
|
||||||
|
|
||||||
|
@ -70,11 +70,11 @@ class XYButtons(BufferedCanvas):
|
||||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
|
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
|
||||||
self.Bind(wx.EVT_KEY_UP, self.OnKey)
|
self.Bind(wx.EVT_KEY_UP, self.OnKey)
|
||||||
wx.GetTopLevelParent(self).Bind(wx.EVT_CHAR_HOOK, self.OnTopLevelKey)
|
wx.GetTopLevelParent(self).Bind(wx.EVT_CHAR_HOOK, self.OnTopLevelKey)
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def enable(self):
|
def enable(self):
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
self.update()
|
self.update()
|
||||||
|
@ -84,7 +84,7 @@ class XYButtons(BufferedCanvas):
|
||||||
self.moveCallback(*self.lastMove)
|
self.moveCallback(*self.lastMove)
|
||||||
if self.lastCorner:
|
if self.lastCorner:
|
||||||
self.cornerCallback(self.lastCorner)
|
self.cornerCallback(self.lastCorner)
|
||||||
|
|
||||||
def clearRepeat(self):
|
def clearRepeat(self):
|
||||||
self.lastMove = None
|
self.lastMove = None
|
||||||
self.lastCorner = None
|
self.lastCorner = None
|
||||||
|
@ -95,7 +95,7 @@ class XYButtons(BufferedCanvas):
|
||||||
pxlen = x1 - pos.x
|
pxlen = x1 - pos.x
|
||||||
pylen = y1 - pos.y
|
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):
|
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)
|
||||||
|
|
||||||
|
@ -103,17 +103,17 @@ class XYButtons(BufferedCanvas):
|
||||||
idx = self.keypad_idx + 1
|
idx = self.keypad_idx + 1
|
||||||
if idx > 2: idx = 0
|
if idx > 2: idx = 0
|
||||||
return idx
|
return idx
|
||||||
|
|
||||||
def setKeypadIndex(self, idx):
|
def setKeypadIndex(self, idx):
|
||||||
self.keypad_idx = idx
|
self.keypad_idx = idx
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def getMovement(self):
|
def getMovement(self):
|
||||||
xdir = [1, 0, -1, 0][self.quadrant]
|
xdir = [1, 0, -1, 0][self.quadrant]
|
||||||
ydir = [0, 1, 0, -1][self.quadrant]
|
ydir = [0, 1, 0, -1][self.quadrant]
|
||||||
magnitude = math.pow(10, self.concentric-1)
|
magnitude = math.pow(10, self.concentric-1)
|
||||||
return (magnitude * xdir, magnitude * ydir)
|
return (magnitude * xdir, magnitude * ydir)
|
||||||
|
|
||||||
def lookupConcentric(self, radius):
|
def lookupConcentric(self, radius):
|
||||||
idx = 0
|
idx = 0
|
||||||
for r in XYButtons.concentric_circle_radii[1:]:
|
for r in XYButtons.concentric_circle_radii[1:]:
|
||||||
|
@ -134,27 +134,27 @@ class XYButtons(BufferedCanvas):
|
||||||
quadrant = 1 # Up
|
quadrant = 1 # Up
|
||||||
else:
|
else:
|
||||||
quadrant = 2 # Left
|
quadrant = 2 # Left
|
||||||
|
|
||||||
idx = self.lookupConcentric(radius)
|
idx = self.lookupConcentric(radius)
|
||||||
return (quadrant, idx)
|
return (quadrant, idx)
|
||||||
|
|
||||||
def mouseOverKeypad(self, mpos):
|
def mouseOverKeypad(self, mpos):
|
||||||
for idx, kpos in XYButtons.keypad_positions.items():
|
for idx, kpos in XYButtons.keypad_positions.items():
|
||||||
radius = self.distanceToPoint(mpos[0], mpos[1], kpos[0], kpos[1])
|
radius = self.distanceToPoint(mpos[0], mpos[1], kpos[0], kpos[1])
|
||||||
if radius < 9:
|
if radius < 9:
|
||||||
return idx
|
return idx
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def drawPartialPie(self, gc, center, r1, r2, angle1, angle2):
|
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 = gc.CreatePath()
|
||||||
path.MoveToPoint(p1.x, p1.y)
|
path.MoveToPoint(p1.x, p1.y)
|
||||||
path.AddArc(center.x, center.y, r1, angle1, angle2, True)
|
path.AddArc(center.x, center.y, r1, angle1, angle2, True)
|
||||||
path.AddArc(center.x, center.y, r2, angle2, angle1, False)
|
path.AddArc(center.x, center.y, r2, angle2, angle1, False)
|
||||||
path.AddLineToPoint(p1.x, p1.y)
|
path.AddLineToPoint(p1.x, p1.y)
|
||||||
gc.DrawPath(path)
|
gc.DrawPath(path)
|
||||||
|
|
||||||
def highlightQuadrant(self, gc, quadrant, concentric):
|
def highlightQuadrant(self, gc, quadrant, concentric):
|
||||||
assert(quadrant >= 0 and quadrant <= 3)
|
assert(quadrant >= 0 and quadrant <= 3)
|
||||||
assert(concentric >= 0 and concentric <= 3)
|
assert(concentric >= 0 and concentric <= 3)
|
||||||
|
@ -175,12 +175,12 @@ class XYButtons(BufferedCanvas):
|
||||||
elif quadrant == 3:
|
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
|
center.y += inner_ring_radius
|
||||||
|
|
||||||
r1 = XYButtons.concentric_circle_radii[concentric]
|
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):
|
def drawCorner(self, gc, x, y, angle=0.0):
|
||||||
w, h = XYButtons.corner_size
|
w, h = XYButtons.corner_size
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ class XYButtons(BufferedCanvas):
|
||||||
w, h = XYButtons.corner_size
|
w, h = XYButtons.corner_size
|
||||||
cx, cy = XYButtons.center
|
cx, cy = XYButtons.center
|
||||||
ww, wh = self.GetSizeTuple()
|
ww, wh = self.GetSizeTuple()
|
||||||
|
|
||||||
inset = 10
|
inset = 10
|
||||||
if corner == 0:
|
if corner == 0:
|
||||||
x, y = (cx - ww/2 + inset, cy - wh/2 + inset)
|
x, y = (cx - ww/2 + inset, cy - wh/2 + inset)
|
||||||
|
@ -215,10 +215,10 @@ class XYButtons(BufferedCanvas):
|
||||||
elif corner == 3:
|
elif corner == 3:
|
||||||
x, y = (cx - ww/2 + inset, cy + wh/2 - inset)
|
x, y = (cx - ww/2 + inset, cy + wh/2 - inset)
|
||||||
self.drawCorner(gc, x+w/2, y-h/2, math.pi*3/2)
|
self.drawCorner(gc, x+w/2, y-h/2, math.pi*3/2)
|
||||||
|
|
||||||
|
|
||||||
def draw(self, dc, w, h):
|
def draw(self, dc, w, h):
|
||||||
dc.SetBackground(wx.Brush(self.bgcolor))
|
dc.SetBackground(wx.Brush(self.bgcolor))
|
||||||
dc.Clear()
|
dc.Clear()
|
||||||
gc = wx.GraphicsContext.Create(dc)
|
gc = wx.GraphicsContext.Create(dc)
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ class XYButtons(BufferedCanvas):
|
||||||
if self.bg_bmp:
|
if self.bg_bmp:
|
||||||
w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
|
w, h = (self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
|
||||||
gc.DrawBitmap(self.bg_bmp, 0, 0, w, h)
|
gc.DrawBitmap(self.bg_bmp, 0, 0, w, h)
|
||||||
|
|
||||||
if self.enabled:
|
if self.enabled:
|
||||||
# Brush and pen for grey overlay when mouse hovers over
|
# Brush and pen for grey overlay when mouse hovers over
|
||||||
gc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
|
gc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
|
||||||
|
@ -238,13 +238,13 @@ class XYButtons(BufferedCanvas):
|
||||||
self.highlightQuadrant(gc, self.quadrant, self.concentric)
|
self.highlightQuadrant(gc, self.quadrant, self.concentric)
|
||||||
elif self.corner != None:
|
elif self.corner != None:
|
||||||
self.highlightCorner(gc, self.corner)
|
self.highlightCorner(gc, self.corner)
|
||||||
|
|
||||||
if self.keypad_idx >= 0:
|
if self.keypad_idx >= 0:
|
||||||
padw, padh = (self.keypad_bmp.GetWidth(), self.keypad_bmp.GetHeight())
|
padw, padh = (self.keypad_bmp.GetWidth(), self.keypad_bmp.GetHeight())
|
||||||
pos = XYButtons.keypad_positions[self.keypad_idx]
|
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)
|
gc.DrawBitmap(self.keypad_bmp, pos[0], pos[1], padw, padh)
|
||||||
|
|
||||||
# Draw label overlays
|
# Draw label overlays
|
||||||
gc.SetPen(wx.Pen(wx.Colour(255,255,255,128), 1))
|
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)))
|
||||||
|
@ -256,7 +256,7 @@ class XYButtons(BufferedCanvas):
|
||||||
gc.SetPen(wx.Pen(self.bgcolor, 0))
|
gc.SetPen(wx.Pen(self.bgcolor, 0))
|
||||||
gc.SetBrush(wx.Brush(self.bgcolormask))
|
gc.SetBrush(wx.Brush(self.bgcolormask))
|
||||||
gc.DrawRectangle(0, 0, w, h)
|
gc.DrawRectangle(0, 0, w, h)
|
||||||
|
|
||||||
|
|
||||||
# Used to check exact position of keypad dots, should we ever resize the bg image
|
# Used to check exact position of keypad dots, should we ever resize the bg image
|
||||||
# for idx, kpos in XYButtons.label_overlay_positions.items():
|
# for idx, kpos in XYButtons.label_overlay_positions.items():
|
||||||
|
@ -289,7 +289,7 @@ class XYButtons(BufferedCanvas):
|
||||||
else:
|
else:
|
||||||
evt.Skip()
|
evt.Skip()
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.moveCallback:
|
if self.moveCallback:
|
||||||
self.concentric = self.keypad_idx
|
self.concentric = self.keypad_idx
|
||||||
x, y = self.getMovement()
|
x, y = self.getMovement()
|
||||||
|
@ -301,7 +301,7 @@ class XYButtons(BufferedCanvas):
|
||||||
def OnMotion(self, event):
|
def OnMotion(self, event):
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
oldcorner = self.corner
|
oldcorner = self.corner
|
||||||
oldq, oldc = self.quadrant, self.concentric
|
oldq, oldc = self.quadrant, self.concentric
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ class XYButtons(BufferedCanvas):
|
||||||
# If mouse hovers in space between quadrants, don't commit to a quadrant
|
# If mouse hovers in space between quadrants, don't commit to a quadrant
|
||||||
if riseDist <= XYButtons.spacer or fallDist <= XYButtons.spacer:
|
if riseDist <= XYButtons.spacer or fallDist <= XYButtons.spacer:
|
||||||
self.quadrant = None
|
self.quadrant = None
|
||||||
|
|
||||||
cx, cy = XYButtons.center
|
cx, cy = XYButtons.center
|
||||||
if mpos.x < cx and mpos.y < cy:
|
if mpos.x < cx and mpos.y < cy:
|
||||||
self.corner = 0
|
self.corner = 0
|
||||||
|
@ -335,7 +335,7 @@ class XYButtons(BufferedCanvas):
|
||||||
def OnLeftDown(self, event):
|
def OnLeftDown(self, event):
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Take focus when clicked so that arrow keys can control movement
|
# Take focus when clicked so that arrow keys can control movement
|
||||||
self.SetFocus()
|
self.SetFocus()
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ class XYButtons(BufferedCanvas):
|
||||||
self.setKeypadIndex(-1)
|
self.setKeypadIndex(-1)
|
||||||
else:
|
else:
|
||||||
self.setKeypadIndex(idx)
|
self.setKeypadIndex(idx)
|
||||||
|
|
||||||
def OnLeaveWindow(self, evt):
|
def OnLeaveWindow(self, evt):
|
||||||
self.quadrant = None
|
self.quadrant = None
|
||||||
self.concentric = None
|
self.concentric = None
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import wx, os, math
|
import wx, os, math
|
||||||
from bufferedcanvas import *
|
from bufferedcanvas import *
|
||||||
from printrun_utils import *
|
from printrun_utils import *
|
||||||
|
|
||||||
def sign(n):
|
def sign(n):
|
||||||
if n < 0: return -1
|
if n < 0: return -1
|
||||||
|
@ -42,9 +42,9 @@ class ZButtons(BufferedCanvas):
|
||||||
# Remember the last clicked value, so we can repeat when spacebar pressed
|
# Remember the last clicked value, so we can repeat when spacebar pressed
|
||||||
self.lastValue = None
|
self.lastValue = None
|
||||||
|
|
||||||
self.bgcolor = wx.Colour()
|
self.bgcolor = wx.Colour()
|
||||||
self.bgcolor.SetFromName(bgcolor)
|
self.bgcolor.SetFromName(bgcolor)
|
||||||
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
|
self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128)
|
||||||
|
|
||||||
BufferedCanvas.__init__(self, parent, ID)
|
BufferedCanvas.__init__(self, parent, ID)
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class ZButtons(BufferedCanvas):
|
||||||
def disable(self):
|
def disable(self):
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def enable(self):
|
def enable(self):
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
self.update()
|
self.update()
|
||||||
|
@ -78,7 +78,7 @@ class ZButtons(BufferedCanvas):
|
||||||
return idx
|
return idx
|
||||||
idx += 1
|
idx += 1
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def highlight(self, gc, rng, dir):
|
def highlight(self, gc, rng, dir):
|
||||||
assert(rng >= -1 and rng <= 3)
|
assert(rng >= -1 and rng <= 3)
|
||||||
assert(dir >= -1 and dir <= 1)
|
assert(dir >= -1 and dir <= 1)
|
||||||
|
@ -93,13 +93,13 @@ class ZButtons(BufferedCanvas):
|
||||||
gc.DrawRoundedRectangle(x, y, w, h, 4)
|
gc.DrawRoundedRectangle(x, y, w, h, 4)
|
||||||
# gc.DrawRectangle(x, y, w, h)
|
# gc.DrawRectangle(x, y, w, h)
|
||||||
# self.drawPartialPie(dc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
|
# self.drawPartialPie(dc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
|
||||||
|
|
||||||
def getRangeDir(self, pos):
|
def getRangeDir(self, pos):
|
||||||
ydelta = ZButtons.center[1] - pos[1]
|
ydelta = ZButtons.center[1] - pos[1]
|
||||||
return (self.lookupRange(abs(ydelta)), sign(ydelta))
|
return (self.lookupRange(abs(ydelta)), sign(ydelta))
|
||||||
|
|
||||||
def draw(self, dc, w, h):
|
def draw(self, dc, w, h):
|
||||||
dc.SetBackground(wx.Brush(self.bgcolor))
|
dc.SetBackground(wx.Brush(self.bgcolor))
|
||||||
dc.Clear()
|
dc.Clear()
|
||||||
gc = wx.GraphicsContext.Create(dc)
|
gc = wx.GraphicsContext.Create(dc)
|
||||||
if self.bg_bmp:
|
if self.bg_bmp:
|
||||||
|
@ -114,7 +114,7 @@ class ZButtons(BufferedCanvas):
|
||||||
if kpos and idx != self.range:
|
if kpos and idx != self.range:
|
||||||
r = kpos[2]
|
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
|
# Top 'layer' is the mouse-over highlights
|
||||||
gc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
|
gc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
|
||||||
gc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
|
gc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
|
||||||
|
@ -132,7 +132,7 @@ class ZButtons(BufferedCanvas):
|
||||||
def OnMotion(self, event):
|
def OnMotion(self, event):
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
oldr, oldd = self.range, self.direction
|
oldr, oldd = self.range, self.direction
|
||||||
|
|
||||||
mpos = event.GetPosition()
|
mpos = event.GetPosition()
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class scapewin(wx.Frame):
|
||||||
self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO))
|
self.SetIcon(wx.Icon("plater.ico",wx.BITMAP_TYPE_ICO))
|
||||||
self.SetClientSize(size)
|
self.SetClientSize(size)
|
||||||
self.panel=wx.Panel(self,size=size)
|
self.panel=wx.Panel(self,size=size)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -82,4 +82,3 @@ if __name__ == '__main__':
|
||||||
"""
|
"""
|
||||||
zimage("catposthtmap2.jpg","testobj.stl")
|
zimage("catposthtmap2.jpg","testobj.stl")
|
||||||
del a
|
del a
|
||||||
|
|
||||||
|
|
217
pronsole.py
217
pronsole.py
|
@ -1,23 +1,23 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import cmd, sys
|
import cmd, sys
|
||||||
import glob, os, time, datetime
|
import glob, os, time, datetime
|
||||||
import sys, subprocess
|
import sys, subprocess
|
||||||
import math, codecs
|
import math, codecs
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ except:
|
||||||
|
|
||||||
def dosify(name):
|
def dosify(name):
|
||||||
return os.path.split(name)[1].split(".")[0][:8]+".g"
|
return os.path.split(name)[1].split(".")[0][:8]+".g"
|
||||||
|
|
||||||
def measurements(g):
|
def measurements(g):
|
||||||
Xcur=0.0
|
Xcur=0.0
|
||||||
Ycur=0.0
|
Ycur=0.0
|
||||||
|
@ -56,8 +56,8 @@ def measurements(g):
|
||||||
Xtot=0
|
Xtot=0
|
||||||
Ytot=0
|
Ytot=0
|
||||||
Ztot=0
|
Ztot=0
|
||||||
|
|
||||||
|
|
||||||
for i in g:
|
for i in g:
|
||||||
if "X" in i and ("G1" in i or "G0" in i):
|
if "X" in i and ("G1" in i or "G0" in i):
|
||||||
try:
|
try:
|
||||||
|
@ -73,7 +73,7 @@ def measurements(g):
|
||||||
if Ycur>Ymax: Ymax=Ycur
|
if Ycur>Ymax: Ymax=Ycur
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if "Z" in i and ("G1" in i or "G0" in i):
|
if "Z" in i and ("G1" in i or "G0" in i):
|
||||||
try:
|
try:
|
||||||
Zcur = float(i.split("Z")[1].split(" ")[0])
|
Zcur = float(i.split("Z")[1].split(" ")[0])
|
||||||
|
@ -81,12 +81,12 @@ def measurements(g):
|
||||||
if Zcur>Zmax: Zmax=Zcur
|
if Zcur>Zmax: Zmax=Zcur
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
Xtot = Xmax - Xmin
|
Xtot = Xmax - Xmin
|
||||||
Ytot = Ymax - Ymin
|
Ytot = Ymax - Ymin
|
||||||
Ztot = Zmax - Zmin
|
Ztot = Zmax - Zmin
|
||||||
|
|
||||||
return (Xtot,Ytot,Ztot,Xmin,Xmax,Ymin,Ymax,Zmin,Zmax)
|
return (Xtot,Ytot,Ztot,Xmin,Xmax,Ymin,Ymax,Zmin,Zmax)
|
||||||
|
|
||||||
def totalelength(g):
|
def totalelength(g):
|
||||||
|
@ -108,11 +108,11 @@ def get_coordinate_value(axis, parts):
|
||||||
return float(i[1:])
|
return float(i[1:])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def hypot3d(X1, Y1, Z1, X2=0.0, Y2=0.0, Z2=0.0):
|
def hypot3d(X1, Y1, Z1, X2=0.0, Y2=0.0, Z2=0.0):
|
||||||
return math.hypot(X2-X1, math.hypot(Y2-Y1, Z2-Z1))
|
return math.hypot(X2-X1, math.hypot(Y2-Y1, Z2-Z1))
|
||||||
|
|
||||||
def estimate_duration(g):
|
def estimate_duration(g):
|
||||||
|
|
||||||
lastx = lasty = lastz = laste = lastf = 0.0
|
lastx = lasty = lastz = laste = lastf = 0.0
|
||||||
x = y = z = e = f = 0.0
|
x = y = z = e = f = 0.0
|
||||||
currenttravel = 0.0
|
currenttravel = 0.0
|
||||||
|
@ -150,7 +150,7 @@ def estimate_duration(g):
|
||||||
f = get_coordinate_value("F", parts[1:])
|
f = get_coordinate_value("F", parts[1:])
|
||||||
if f is None: f=lastf
|
if f is None: f=lastf
|
||||||
else: f /= 60.0 # mm/s vs mm/m
|
else: f /= 60.0 # mm/s vs mm/m
|
||||||
|
|
||||||
# given last feedrate and current feedrate calculate the distance needed to achieve current feedrate.
|
# 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.
|
# 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
|
# then calculate the time taken to complete the remaining distance
|
||||||
|
@ -279,7 +279,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.webrequested=False
|
self.webrequested=False
|
||||||
self.web_config=None
|
self.web_config=None
|
||||||
self.web_auth_config=None
|
self.web_auth_config=None
|
||||||
|
|
||||||
def set_temp_preset(self,key,value):
|
def set_temp_preset(self,key,value):
|
||||||
if not key.startswith("bed"):
|
if not key.startswith("bed"):
|
||||||
self.temps["pla"] = str(self.settings.temperature_pla)
|
self.temps["pla"] = str(self.settings.temperature_pla)
|
||||||
|
@ -289,7 +289,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.bedtemps["pla"] = str(self.settings.bedtemp_pla)
|
self.bedtemps["pla"] = str(self.settings.bedtemp_pla)
|
||||||
self.bedtemps["abs"] = str(self.settings.bedtemp_abs)
|
self.bedtemps["abs"] = str(self.settings.bedtemp_abs)
|
||||||
print "Bed temperature presets updated, pla:%s, abs:%s" % (self.bedtemps["pla"],self.bedtemps["abs"])
|
print "Bed temperature presets updated, pla:%s, abs:%s" % (self.bedtemps["pla"],self.bedtemps["abs"])
|
||||||
|
|
||||||
def scanserial(self):
|
def scanserial(self):
|
||||||
"""scan for available ports. return a list of device names."""
|
"""scan for available ports. return a list of device names."""
|
||||||
baselist=[]
|
baselist=[]
|
||||||
|
@ -309,16 +309,16 @@ class pronsole(cmd.Cmd):
|
||||||
print "Printer is now online"
|
print "Printer is now online"
|
||||||
sys.stdout.write(self.prompt)
|
sys.stdout.write(self.prompt)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def help_help(self,l):
|
def help_help(self,l):
|
||||||
self.do_help("")
|
self.do_help("")
|
||||||
|
|
||||||
def do_gcodes(self,l):
|
def do_gcodes(self,l):
|
||||||
self.help_gcodes()
|
self.help_gcodes()
|
||||||
|
|
||||||
def help_gcodes(self):
|
def help_gcodes(self):
|
||||||
print "Gcodes are passed through to the printer as they are"
|
print "Gcodes are passed through to the printer as they are"
|
||||||
|
|
||||||
def complete_macro(self,text,line,begidx,endidx):
|
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)]
|
return [i for i in self.macros.keys() if i.startswith(text)]
|
||||||
|
@ -326,7 +326,7 @@ class pronsole(cmd.Cmd):
|
||||||
return [i for i in ["/D", "/S"] + self.completenames(text) if i.startswith(text)]
|
return [i for i in ["/D", "/S"] + self.completenames(text) if i.startswith(text)]
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def hook_macro(self,l):
|
def hook_macro(self,l):
|
||||||
l = l.rstrip()
|
l = l.rstrip()
|
||||||
ls = l.lstrip()
|
ls = l.lstrip()
|
||||||
|
@ -336,8 +336,8 @@ class pronsole(cmd.Cmd):
|
||||||
# pass the unprocessed line to regular command processor to not require empty line in .pronsolerc
|
# pass the unprocessed line to regular command processor to not require empty line in .pronsolerc
|
||||||
return self.onecmd(l)
|
return self.onecmd(l)
|
||||||
self.cur_macro_def += l + "\n"
|
self.cur_macro_def += l + "\n"
|
||||||
|
|
||||||
def end_macro(self):
|
def end_macro(self):
|
||||||
if self.__dict__.has_key("onecmd"): del self.onecmd # remove override
|
if self.__dict__.has_key("onecmd"): del self.onecmd # remove override
|
||||||
self.prompt="PC>"
|
self.prompt="PC>"
|
||||||
if self.cur_macro_def!="":
|
if self.cur_macro_def!="":
|
||||||
|
@ -360,7 +360,7 @@ class pronsole(cmd.Cmd):
|
||||||
else:
|
else:
|
||||||
print "Empty macro - cancelled"
|
print "Empty macro - cancelled"
|
||||||
del self.cur_macro_name,self.cur_macro_def
|
del self.cur_macro_name,self.cur_macro_def
|
||||||
|
|
||||||
def compile_macro_line(self,line):
|
def compile_macro_line(self,line):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
ls = line.lstrip()
|
ls = line.lstrip()
|
||||||
|
@ -370,7 +370,7 @@ class pronsole(cmd.Cmd):
|
||||||
return ws + ls[1:] + "\n" # python mode
|
return ws + ls[1:] + "\n" # python mode
|
||||||
else:
|
else:
|
||||||
return ws + 'self.onecmd("'+ls+'".format(*arg))\n' # parametric command mode
|
return ws + 'self.onecmd("'+ls+'".format(*arg))\n' # parametric command mode
|
||||||
|
|
||||||
def compile_macro(self,macro_name,macro_def):
|
def compile_macro(self,macro_name,macro_def):
|
||||||
if macro_def.strip() == "":
|
if macro_def.strip() == "":
|
||||||
print "Empty macro - cancelled"
|
print "Empty macro - cancelled"
|
||||||
|
@ -384,7 +384,7 @@ class pronsole(cmd.Cmd):
|
||||||
pycode += self.compile_macro_line(l)
|
pycode += self.compile_macro_line(l)
|
||||||
exec pycode
|
exec pycode
|
||||||
return macro
|
return macro
|
||||||
|
|
||||||
def start_macro(self,macro_name,prev_definition="",suppress_instructions=False):
|
def start_macro(self,macro_name,prev_definition="",suppress_instructions=False):
|
||||||
if not self.processing_rc and not suppress_instructions:
|
if not self.processing_rc and not suppress_instructions:
|
||||||
print "Enter macro using indented lines, end with empty line"
|
print "Enter macro using indented lines, end with empty line"
|
||||||
|
@ -392,7 +392,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.cur_macro_def = ""
|
self.cur_macro_def = ""
|
||||||
self.onecmd = self.hook_macro # override onecmd temporarily
|
self.onecmd = self.hook_macro # override onecmd temporarily
|
||||||
self.prompt="..>"
|
self.prompt="..>"
|
||||||
|
|
||||||
def delete_macro(self,macro_name):
|
def delete_macro(self,macro_name):
|
||||||
if macro_name in self.macros.keys():
|
if macro_name in self.macros.keys():
|
||||||
delattr(self.__class__,"do_"+macro_name)
|
delattr(self.__class__,"do_"+macro_name)
|
||||||
|
@ -427,7 +427,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.start_macro(macro_name,self.macros[macro_name])
|
self.start_macro(macro_name,self.macros[macro_name])
|
||||||
else:
|
else:
|
||||||
self.start_macro(macro_name)
|
self.start_macro(macro_name)
|
||||||
|
|
||||||
def help_macro(self):
|
def help_macro(self):
|
||||||
print "Define single-line macro: macro <name> <definition>"
|
print "Define single-line macro: macro <name> <definition>"
|
||||||
print "Define multi-line macro: macro <name>"
|
print "Define multi-line macro: macro <name>"
|
||||||
|
@ -436,7 +436,7 @@ class pronsole(cmd.Cmd):
|
||||||
print "Delete macro: macro <name> /d"
|
print "Delete macro: macro <name> /d"
|
||||||
print "Show macro definition: macro <name> /s"
|
print "Show macro definition: macro <name> /s"
|
||||||
print "'macro' without arguments displays list of defined macros"
|
print "'macro' without arguments displays list of defined macros"
|
||||||
|
|
||||||
def subhelp_macro(self,macro_name):
|
def subhelp_macro(self,macro_name):
|
||||||
if macro_name in self.macros.keys():
|
if macro_name in self.macros.keys():
|
||||||
macro_def = self.macros[macro_name]
|
macro_def = self.macros[macro_name]
|
||||||
|
@ -458,7 +458,7 @@ class pronsole(cmd.Cmd):
|
||||||
print "Unknown variable '%s'" % var
|
print "Unknown variable '%s'" % var
|
||||||
except ValueError, ve:
|
except ValueError, ve:
|
||||||
print "Bad value for variable '%s', expecting %s (%s)" % (var,repr(t)[1:-1],ve.args[0])
|
print "Bad value for variable '%s', expecting %s (%s)" % (var,repr(t)[1:-1],ve.args[0])
|
||||||
|
|
||||||
def do_set(self,argl):
|
def do_set(self,argl):
|
||||||
args = argl.split(None,1)
|
args = argl.split(None,1)
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
|
@ -473,7 +473,7 @@ class pronsole(cmd.Cmd):
|
||||||
print "Unknown variable '%s'" % args[0]
|
print "Unknown variable '%s'" % args[0]
|
||||||
return
|
return
|
||||||
self.set(args[0],args[1])
|
self.set(args[0],args[1])
|
||||||
|
|
||||||
def help_set(self):
|
def help_set(self):
|
||||||
print "Set variable: set <variable> <value>"
|
print "Set variable: set <variable> <value>"
|
||||||
print "Show variable: set <variable>"
|
print "Show variable: set <variable>"
|
||||||
|
@ -486,11 +486,11 @@ class pronsole(cmd.Cmd):
|
||||||
return [i for i in self.settings._tabcomplete(line.split()[1]) if i.startswith(text)]
|
return [i for i in self.settings._tabcomplete(line.split()[1]) if i.startswith(text)]
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def postloop(self):
|
def postloop(self):
|
||||||
self.p.disconnect()
|
self.p.disconnect()
|
||||||
cmd.Cmd.postloop(self)
|
cmd.Cmd.postloop(self)
|
||||||
|
|
||||||
def load_rc(self,rc_filename):
|
def load_rc(self,rc_filename):
|
||||||
self.processing_rc=True
|
self.processing_rc=True
|
||||||
try:
|
try:
|
||||||
|
@ -505,7 +505,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.rc_loaded = True
|
self.rc_loaded = True
|
||||||
finally:
|
finally:
|
||||||
self.processing_rc=False
|
self.processing_rc=False
|
||||||
|
|
||||||
def load_default_rc(self,rc_filename=".pronsolerc"):
|
def load_default_rc(self,rc_filename=".pronsolerc"):
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
|
@ -515,10 +515,10 @@ class pronsole(cmd.Cmd):
|
||||||
except IOError:
|
except IOError:
|
||||||
# make sure the filename is initialized
|
# make sure the filename is initialized
|
||||||
self.rc_filename = os.path.abspath(os.path.join(os.path.expanduser("~"),rc_filename))
|
self.rc_filename = os.path.abspath(os.path.join(os.path.expanduser("~"),rc_filename))
|
||||||
|
|
||||||
def save_in_rc(self,key,definition):
|
def save_in_rc(self,key,definition):
|
||||||
"""
|
"""
|
||||||
Saves or updates macro or other definitions in .pronsolerc
|
Saves or updates macro or other definitions in .pronsolerc
|
||||||
key is prefix that determines what is being defined/updated (e.g. 'macro foo')
|
key is prefix that determines what is being defined/updated (e.g. 'macro foo')
|
||||||
definition is the full definition (that is written to file). (e.g. 'macro foo move x 10')
|
definition is the full definition (that is written to file). (e.g. 'macro foo move x 10')
|
||||||
Set key as empty string to just add (and not overwrite)
|
Set key as empty string to just add (and not overwrite)
|
||||||
|
@ -566,17 +566,17 @@ class pronsole(cmd.Cmd):
|
||||||
print "Saving failed for",key+":",str(e)
|
print "Saving failed for",key+":",str(e)
|
||||||
finally:
|
finally:
|
||||||
del rci,rco
|
del rci,rco
|
||||||
|
|
||||||
def preloop(self):
|
def preloop(self):
|
||||||
print "Welcome to the printer console! Type \"help\" for a list of available commands."
|
print "Welcome to the printer console! Type \"help\" for a list of available commands."
|
||||||
cmd.Cmd.preloop(self)
|
cmd.Cmd.preloop(self)
|
||||||
|
|
||||||
def do_connect(self,l):
|
def do_connect(self,l):
|
||||||
a=l.split()
|
a=l.split()
|
||||||
p=self.scanserial()
|
p=self.scanserial()
|
||||||
port=self.settings.port
|
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]
|
port=p[0]
|
||||||
baud=self.settings.baudrate or 115200
|
baud=self.settings.baudrate or 115200
|
||||||
if(len(a)>0):
|
if(len(a)>0):
|
||||||
port=a[0]
|
port=a[0]
|
||||||
|
@ -597,7 +597,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.settings.baudrate = baud
|
self.settings.baudrate = baud
|
||||||
self.save_in_rc("set baudrate","set baudrate %d" % baud)
|
self.save_in_rc("set baudrate","set baudrate %d" % baud)
|
||||||
self.p.connect(port, baud)
|
self.p.connect(port, baud)
|
||||||
|
|
||||||
def help_connect(self):
|
def help_connect(self):
|
||||||
print "Connect to printer"
|
print "Connect to printer"
|
||||||
print "connect <port> <baudrate>"
|
print "connect <port> <baudrate>"
|
||||||
|
@ -607,7 +607,7 @@ class pronsole(cmd.Cmd):
|
||||||
print "Available ports: ", " ".join(ports)
|
print "Available ports: ", " ".join(ports)
|
||||||
else:
|
else:
|
||||||
print "No serial ports were automatically found."
|
print "No serial ports were automatically found."
|
||||||
|
|
||||||
def complete_connect(self, text, line, begidx, endidx):
|
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)]
|
return [i for i in self.scanserial() if i.startswith(text)]
|
||||||
|
@ -615,13 +615,13 @@ class pronsole(cmd.Cmd):
|
||||||
return [i for i in ["2400", "9600", "19200", "38400", "57600", "115200"] if i.startswith(text)]
|
return [i for i in ["2400", "9600", "19200", "38400", "57600", "115200"] if i.startswith(text)]
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def do_disconnect(self,l):
|
def do_disconnect(self,l):
|
||||||
self.p.disconnect()
|
self.p.disconnect()
|
||||||
|
|
||||||
def help_disconnect(self):
|
def help_disconnect(self):
|
||||||
print "Disconnects from the printer"
|
print "Disconnects from the printer"
|
||||||
|
|
||||||
def do_load(self,l):
|
def do_load(self,l):
|
||||||
if len(l)==0:
|
if len(l)==0:
|
||||||
print "No file name given."
|
print "No file name given."
|
||||||
|
@ -633,7 +633,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.f=[i.replace("\n","").replace("\r","") for i in open(l)]
|
self.f=[i.replace("\n","").replace("\r","") for i in open(l)]
|
||||||
self.filename=l
|
self.filename=l
|
||||||
print "Loaded ",l,", ",len(self.f)," lines."
|
print "Loaded ",l,", ",len(self.f)," lines."
|
||||||
|
|
||||||
def complete_load(self, text, line, begidx, endidx):
|
def complete_load(self, text, line, begidx, endidx):
|
||||||
s=line.split()
|
s=line.split()
|
||||||
if len(s)>2:
|
if len(s)>2:
|
||||||
|
@ -643,11 +643,11 @@ class pronsole(cmd.Cmd):
|
||||||
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.g*")]
|
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.g*")]
|
||||||
else:
|
else:
|
||||||
return glob.glob("*/")+glob.glob("*.g*")
|
return glob.glob("*/")+glob.glob("*.g*")
|
||||||
|
|
||||||
def help_load(self):
|
def help_load(self):
|
||||||
print "Loads a gcode file (with tab-completion)"
|
print "Loads a gcode file (with tab-completion)"
|
||||||
|
|
||||||
|
|
||||||
def do_upload(self,l):
|
def do_upload(self,l):
|
||||||
if len(l)==0:
|
if len(l)==0:
|
||||||
print "No file name given."
|
print "No file name given."
|
||||||
|
@ -699,8 +699,8 @@ class pronsole(cmd.Cmd):
|
||||||
self.p.clear=1
|
self.p.clear=1
|
||||||
self.p.startprint([])
|
self.p.startprint([])
|
||||||
print "A partial file named ",tname," may have been written to the sd card."
|
print "A partial file named ",tname," may have been written to the sd card."
|
||||||
|
|
||||||
|
|
||||||
def complete_upload(self, text, line, begidx, endidx):
|
def complete_upload(self, text, line, begidx, endidx):
|
||||||
s=line.split()
|
s=line.split()
|
||||||
if len(s)>2:
|
if len(s)>2:
|
||||||
|
@ -710,17 +710,17 @@ class pronsole(cmd.Cmd):
|
||||||
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.g*")]
|
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.g*")]
|
||||||
else:
|
else:
|
||||||
return glob.glob("*/")+glob.glob("*.g*")
|
return glob.glob("*/")+glob.glob("*.g*")
|
||||||
|
|
||||||
def help_upload(self):
|
def help_upload(self):
|
||||||
print "Uploads a gcode file to the sd card"
|
print "Uploads a gcode file to the sd card"
|
||||||
|
|
||||||
|
|
||||||
def help_print(self):
|
def help_print(self):
|
||||||
if self.f is None:
|
if self.f is None:
|
||||||
print "Send a loaded gcode file to the printer. Load a file with the load command first."
|
print "Send a loaded gcode file to the printer. Load a file with the load command first."
|
||||||
else:
|
else:
|
||||||
print "Send a loaded gcode file to the printer. You have "+self.filename+" loaded right now."
|
print "Send a loaded gcode file to the printer. You have "+self.filename+" loaded right now."
|
||||||
|
|
||||||
def do_print(self, l):
|
def do_print(self, l):
|
||||||
if self.f is None:
|
if self.f is None:
|
||||||
print "No file loaded. Please use load first."
|
print "No file loaded. Please use load first."
|
||||||
|
@ -734,7 +734,7 @@ class pronsole(cmd.Cmd):
|
||||||
#self.p.pause()
|
#self.p.pause()
|
||||||
#self.paused=True
|
#self.paused=True
|
||||||
#self.do_resume(None)
|
#self.do_resume(None)
|
||||||
|
|
||||||
def do_pause(self,l):
|
def do_pause(self,l):
|
||||||
if self.sdprinting:
|
if self.sdprinting:
|
||||||
self.p.send_now("M25")
|
self.p.send_now("M25")
|
||||||
|
@ -743,14 +743,14 @@ class pronsole(cmd.Cmd):
|
||||||
print "Not printing, cannot pause."
|
print "Not printing, cannot pause."
|
||||||
return
|
return
|
||||||
self.p.pause()
|
self.p.pause()
|
||||||
#self.p.connect()# This seems to work, but is not a good solution.
|
#self.p.connect()# This seems to work, but is not a good solution.
|
||||||
self.paused=True
|
self.paused=True
|
||||||
|
|
||||||
#self.do_resume(None)
|
#self.do_resume(None)
|
||||||
|
|
||||||
def help_pause(self):
|
def help_pause(self):
|
||||||
print "Pauses a running print"
|
print "Pauses a running print"
|
||||||
|
|
||||||
def do_resume(self,l):
|
def do_resume(self,l):
|
||||||
if not self.paused:
|
if not self.paused:
|
||||||
print "Not paused, unable to resume. Start a print first."
|
print "Not paused, unable to resume. Start a print first."
|
||||||
|
@ -761,16 +761,16 @@ class pronsole(cmd.Cmd):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.p.resume()
|
self.p.resume()
|
||||||
|
|
||||||
def help_resume(self):
|
def help_resume(self):
|
||||||
print "Resumes a paused print."
|
print "Resumes a paused print."
|
||||||
|
|
||||||
def emptyline(self):
|
def emptyline(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def do_shell(self,l):
|
def do_shell(self,l):
|
||||||
exec(l)
|
exec(l)
|
||||||
|
|
||||||
def listfiles(self,line):
|
def listfiles(self,line):
|
||||||
if "Begin file list" in line:
|
if "Begin file list" in line:
|
||||||
self.listing=1
|
self.listing=1
|
||||||
|
@ -779,7 +779,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.recvlisteners.remove(self.listfiles)
|
self.recvlisteners.remove(self.listfiles)
|
||||||
elif self.listing:
|
elif self.listing:
|
||||||
self.sdfiles+=[line.replace("\n","").replace("\r","").lower()]
|
self.sdfiles+=[line.replace("\n","").replace("\r","").lower()]
|
||||||
|
|
||||||
def do_ls(self,l):
|
def do_ls(self,l):
|
||||||
if not self.p.online:
|
if not self.p.online:
|
||||||
print "Printer is not online. Try connect to it first."
|
print "Printer is not online. Try connect to it first."
|
||||||
|
@ -790,10 +790,10 @@ class pronsole(cmd.Cmd):
|
||||||
self.p.send_now("M20")
|
self.p.send_now("M20")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
print " ".join(self.sdfiles)
|
print " ".join(self.sdfiles)
|
||||||
|
|
||||||
def help_ls(self):
|
def help_ls(self):
|
||||||
print "lists files on the SD card"
|
print "lists files on the SD card"
|
||||||
|
|
||||||
def waitforsdresponse(self,l):
|
def waitforsdresponse(self,l):
|
||||||
if "file.open failed" in l:
|
if "file.open failed" in l:
|
||||||
print "Opening file failed."
|
print "Opening file failed."
|
||||||
|
@ -820,13 +820,13 @@ class pronsole(cmd.Cmd):
|
||||||
self.percentdone=100.0*int(vals[0])/int(vals[1])
|
self.percentdone=100.0*int(vals[0])/int(vals[1])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def do_reset(self,l):
|
def do_reset(self,l):
|
||||||
self.p.reset()
|
self.p.reset()
|
||||||
|
|
||||||
def help_reset(self):
|
def help_reset(self):
|
||||||
print "Resets the printer."
|
print "Resets the printer."
|
||||||
|
|
||||||
def do_sdprint(self,l):
|
def do_sdprint(self,l):
|
||||||
if not self.p.online:
|
if not self.p.online:
|
||||||
print "Printer is not online. Try connect to it first."
|
print "Printer is not online. Try connect to it first."
|
||||||
|
@ -844,11 +844,11 @@ class pronsole(cmd.Cmd):
|
||||||
print "Printing file: "+l.lower()+" from SD card."
|
print "Printing file: "+l.lower()+" from SD card."
|
||||||
print "Requesting SD print..."
|
print "Requesting SD print..."
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def help_sdprint(self):
|
def help_sdprint(self):
|
||||||
print "Print a file from the SD card. Tabcompletes with available file names."
|
print "Print a file from the SD card. Tabcompletes with available file names."
|
||||||
print "sdprint filename.g"
|
print "sdprint filename.g"
|
||||||
|
|
||||||
def complete_sdprint(self, text, line, begidx, endidx):
|
def complete_sdprint(self, text, line, begidx, endidx):
|
||||||
if self.sdfiles==[] and self.p.online:
|
if self.sdfiles==[] and self.p.online:
|
||||||
self.listing=2
|
self.listing=2
|
||||||
|
@ -857,7 +857,7 @@ class pronsole(cmd.Cmd):
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
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)]
|
return [i for i in self.sdfiles if i.startswith(text)]
|
||||||
|
|
||||||
def recvcb(self,l):
|
def recvcb(self,l):
|
||||||
if "T:" in l:
|
if "T:" in l:
|
||||||
self.tempreadings=l
|
self.tempreadings=l
|
||||||
|
@ -868,11 +868,11 @@ class pronsole(cmd.Cmd):
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
for i in self.recvlisteners:
|
for i in self.recvlisteners:
|
||||||
i(l)
|
i(l)
|
||||||
|
|
||||||
def help_shell(self):
|
def help_shell(self):
|
||||||
print "Executes a python command. Example:"
|
print "Executes a python command. Example:"
|
||||||
print "! os.listdir('.')"
|
print "! os.listdir('.')"
|
||||||
|
|
||||||
def default(self,l):
|
def default(self,l):
|
||||||
if(l[0] in self.commandprefixes.upper()):
|
if(l[0] in self.commandprefixes.upper()):
|
||||||
if(self.p and self.p.online):
|
if(self.p and self.p.online):
|
||||||
|
@ -890,24 +890,24 @@ class pronsole(cmd.Cmd):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
cmd.Cmd.default(self,l)
|
cmd.Cmd.default(self,l)
|
||||||
|
|
||||||
def help_help(self):
|
def help_help(self):
|
||||||
self.do_help("")
|
self.do_help("")
|
||||||
|
|
||||||
def tempcb(self,l):
|
def tempcb(self,l):
|
||||||
if "T:" in l:
|
if "T:" in l:
|
||||||
print l.replace("\r","").replace("T","Hotend").replace("B","Bed").replace("\n","").replace("ok ","")
|
print l.replace("\r","").replace("T","Hotend").replace("B","Bed").replace("\n","").replace("ok ","")
|
||||||
|
|
||||||
def do_gettemp(self,l):
|
def do_gettemp(self,l):
|
||||||
if self.p.online:
|
if self.p.online:
|
||||||
self.recvlisteners+=[self.tempcb]
|
self.recvlisteners+=[self.tempcb]
|
||||||
self.p.send_now("M105")
|
self.p.send_now("M105")
|
||||||
time.sleep(0.75)
|
time.sleep(0.75)
|
||||||
self.recvlisteners.remove(self.tempcb)
|
self.recvlisteners.remove(self.tempcb)
|
||||||
|
|
||||||
def help_gettemp(self):
|
def help_gettemp(self):
|
||||||
print "Read the extruder and bed temperature."
|
print "Read the extruder and bed temperature."
|
||||||
|
|
||||||
def do_settemp(self,l):
|
def do_settemp(self,l):
|
||||||
try:
|
try:
|
||||||
l=l.lower().replace(",",".")
|
l=l.lower().replace(",",".")
|
||||||
|
@ -924,16 +924,16 @@ class pronsole(cmd.Cmd):
|
||||||
print "You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0."
|
print "You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0."
|
||||||
except:
|
except:
|
||||||
print "You must enter a temperature."
|
print "You must enter a temperature."
|
||||||
|
|
||||||
def help_settemp(self):
|
def help_settemp(self):
|
||||||
print "Sets the hotend temperature to the value entered."
|
print "Sets the hotend temperature to the value entered."
|
||||||
print "Enter either a temperature in celsius or one of the following keywords"
|
print "Enter either a temperature in celsius or one of the following keywords"
|
||||||
print ", ".join([i+"("+self.temps[i]+")" for i in self.temps.keys()])
|
print ", ".join([i+"("+self.temps[i]+")" for i in self.temps.keys()])
|
||||||
|
|
||||||
def complete_settemp(self, text, line, begidx, endidx):
|
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)]
|
return [i for i in self.temps.keys() if i.startswith(text)]
|
||||||
|
|
||||||
def do_bedtemp(self,l):
|
def do_bedtemp(self,l):
|
||||||
try:
|
try:
|
||||||
l=l.lower().replace(",",".")
|
l=l.lower().replace(",",".")
|
||||||
|
@ -950,16 +950,16 @@ class pronsole(cmd.Cmd):
|
||||||
print "You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0."
|
print "You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0."
|
||||||
except:
|
except:
|
||||||
print "You must enter a temperature."
|
print "You must enter a temperature."
|
||||||
|
|
||||||
def help_bedtemp(self):
|
def help_bedtemp(self):
|
||||||
print "Sets the bed temperature to the value entered."
|
print "Sets the bed temperature to the value entered."
|
||||||
print "Enter either a temperature in celsius or one of the following keywords"
|
print "Enter either a temperature in celsius or one of the following keywords"
|
||||||
print ", ".join([i+"("+self.bedtemps[i]+")" for i in self.bedtemps.keys()])
|
print ", ".join([i+"("+self.bedtemps[i]+")" for i in self.bedtemps.keys()])
|
||||||
|
|
||||||
def complete_bedtemp(self, text, line, begidx, endidx):
|
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)]
|
return [i for i in self.bedtemps.keys() if i.startswith(text)]
|
||||||
|
|
||||||
def do_move(self,l):
|
def do_move(self,l):
|
||||||
if(len(l.split())<2):
|
if(len(l.split())<2):
|
||||||
print "No move specified."
|
print "No move specified."
|
||||||
|
@ -999,14 +999,14 @@ class pronsole(cmd.Cmd):
|
||||||
self.p.send_now("G91")
|
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")
|
self.p.send_now("G90")
|
||||||
|
|
||||||
def help_move(self):
|
def help_move(self):
|
||||||
print "Move an axis. Specify the name of the axis and the amount. "
|
print "Move an axis. Specify the name of the axis and the amount. "
|
||||||
print "move X 10 will move the X axis forward by 10mm at ",self.settings.xy_feedrate,"mm/min (default XY speed)"
|
print "move X 10 will move the X axis forward by 10mm at ",self.settings.xy_feedrate,"mm/min (default XY speed)"
|
||||||
print "move Y 10 5000 will move the Y axis forward by 10mm at 5000mm/min"
|
print "move Y 10 5000 will move the Y axis forward by 10mm at 5000mm/min"
|
||||||
print "move Z -1 will move the Z axis down by 1mm at ",self.settings.z_feedrate,"mm/min (default Z speed)"
|
print "move Z -1 will move the Z axis down by 1mm at ",self.settings.z_feedrate,"mm/min (default Z speed)"
|
||||||
print "Common amounts are in the tabcomplete list."
|
print "Common amounts are in the tabcomplete list."
|
||||||
|
|
||||||
def complete_move(self, text, line, begidx, endidx):
|
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)]
|
return [i for i in ["X ","Y ","Z ","E "] if i.lower().startswith(text)]
|
||||||
|
@ -1020,7 +1020,7 @@ class pronsole(cmd.Cmd):
|
||||||
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)]
|
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:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def do_extrude(self,l,override=None,overridefeed=300):
|
def do_extrude(self,l,override=None,overridefeed=300):
|
||||||
length=5#default extrusion length
|
length=5#default extrusion length
|
||||||
feed=self.settings.e_feedrate#default speed
|
feed=self.settings.e_feedrate#default speed
|
||||||
|
@ -1053,14 +1053,14 @@ class pronsole(cmd.Cmd):
|
||||||
self.p.send_now("G91")
|
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")
|
self.p.send_now("G90")
|
||||||
|
|
||||||
def help_extrude(self):
|
def help_extrude(self):
|
||||||
print "Extrudes a length of filament, 5mm by default, or the number of mm given as a parameter"
|
print "Extrudes a length of filament, 5mm by default, or the number of mm given as a parameter"
|
||||||
print "extrude - extrudes 5mm of filament at 300mm/min (5mm/s)"
|
print "extrude - extrudes 5mm of filament at 300mm/min (5mm/s)"
|
||||||
print "extrude 20 - extrudes 20mm of filament at 300mm/min (5mm/s)"
|
print "extrude 20 - extrudes 20mm of filament at 300mm/min (5mm/s)"
|
||||||
print "extrude -5 - REVERSES 5mm of filament at 300mm/min (5mm/s)"
|
print "extrude -5 - REVERSES 5mm of filament at 300mm/min (5mm/s)"
|
||||||
print "extrude 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)"
|
print "extrude 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)"
|
||||||
|
|
||||||
def do_reverse(self, l):
|
def do_reverse(self, l):
|
||||||
length=5#default extrusion length
|
length=5#default extrusion length
|
||||||
feed=self.settings.e_feedrate#default speed
|
feed=self.settings.e_feedrate#default speed
|
||||||
|
@ -1082,23 +1082,23 @@ class pronsole(cmd.Cmd):
|
||||||
except:
|
except:
|
||||||
print "Invalid speed given."
|
print "Invalid speed given."
|
||||||
self.do_extrude("",length*-1.0,feed)
|
self.do_extrude("",length*-1.0,feed)
|
||||||
|
|
||||||
def help_reverse(self):
|
def help_reverse(self):
|
||||||
print "Reverses the extruder, 5mm by default, or the number of mm given as a parameter"
|
print "Reverses the extruder, 5mm by default, or the number of mm given as a parameter"
|
||||||
print "reverse - reverses 5mm of filament at 300mm/min (5mm/s)"
|
print "reverse - reverses 5mm of filament at 300mm/min (5mm/s)"
|
||||||
print "reverse 20 - reverses 20mm of filament at 300mm/min (5mm/s)"
|
print "reverse 20 - reverses 20mm of filament at 300mm/min (5mm/s)"
|
||||||
print "reverse 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)"
|
print "reverse 10 210 - extrudes 10mm of filament at 210mm/min (3.5mm/s)"
|
||||||
print "reverse -5 - EXTRUDES 5mm of filament at 300mm/min (5mm/s)"
|
print "reverse -5 - EXTRUDES 5mm of filament at 300mm/min (5mm/s)"
|
||||||
|
|
||||||
def do_exit(self,l):
|
def do_exit(self,l):
|
||||||
print "Disconnecting from printer..."
|
print "Disconnecting from printer..."
|
||||||
self.p.disconnect()
|
self.p.disconnect()
|
||||||
print "Exiting program. Goodbye!"
|
print "Exiting program. Goodbye!"
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def help_exit(self):
|
def help_exit(self):
|
||||||
print "Disconnects from the printer and exits the program."
|
print "Disconnects from the printer and exits the program."
|
||||||
|
|
||||||
def do_monitor(self,l):
|
def do_monitor(self,l):
|
||||||
interval=5
|
interval=5
|
||||||
if not self.p.online:
|
if not self.p.online:
|
||||||
|
@ -1121,23 +1121,23 @@ class pronsole(cmd.Cmd):
|
||||||
#print (self.tempreadings.replace("\r","").replace("T","Hotend").replace("B","Bed").replace("\n","").replace("ok ",""))
|
#print (self.tempreadings.replace("\r","").replace("T","Hotend").replace("B","Bed").replace("\n","").replace("ok ",""))
|
||||||
if(self.p.printing):
|
if(self.p.printing):
|
||||||
print "Print progress: ", 100*float(self.p.queueindex)/len(self.p.mainqueue), "%"
|
print "Print progress: ", 100*float(self.p.queueindex)/len(self.p.mainqueue), "%"
|
||||||
|
|
||||||
if(self.sdprinting):
|
if(self.sdprinting):
|
||||||
print "SD print progress: ", self.percentdone,"%"
|
print "SD print progress: ", self.percentdone,"%"
|
||||||
|
|
||||||
except:
|
except:
|
||||||
print "Done monitoring."
|
print "Done monitoring."
|
||||||
pass
|
pass
|
||||||
self.monitoring=0
|
self.monitoring=0
|
||||||
|
|
||||||
def help_monitor(self):
|
def help_monitor(self):
|
||||||
print "Monitor a machine's temperatures and an SD print's status."
|
print "Monitor a machine's temperatures and an SD print's status."
|
||||||
print "monitor - Reports temperature and SD print status (if SD printing) every 5 seconds"
|
print "monitor - Reports temperature and SD print status (if SD printing) every 5 seconds"
|
||||||
print "monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds"
|
print "monitor 2 - Reports temperature and SD print status (if SD printing) every 2 seconds"
|
||||||
|
|
||||||
def expandcommand(self,c):
|
def expandcommand(self,c):
|
||||||
return c.replace("$python",sys.executable)
|
return c.replace("$python",sys.executable)
|
||||||
|
|
||||||
def do_skein(self,l):
|
def do_skein(self,l):
|
||||||
l=l.split()
|
l=l.split()
|
||||||
if len(l)==0:
|
if len(l)==0:
|
||||||
|
@ -1166,7 +1166,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.do_load(l[0].replace(".stl","_export.gcode"))
|
self.do_load(l[0].replace(".stl","_export.gcode"))
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
print "Skeinforge execution failed: ",e
|
print "Skeinforge execution failed: ",e
|
||||||
|
|
||||||
def complete_skein(self, text, line, begidx, endidx):
|
def complete_skein(self, text, line, begidx, endidx):
|
||||||
s=line.split()
|
s=line.split()
|
||||||
if len(s)>2:
|
if len(s)>2:
|
||||||
|
@ -1176,14 +1176,14 @@ class pronsole(cmd.Cmd):
|
||||||
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.stl")]
|
return [i[len(s[1])-len(text):] for i in glob.glob(s[1]+"*/")+glob.glob(s[1]+"*.stl")]
|
||||||
else:
|
else:
|
||||||
return glob.glob("*/")+glob.glob("*.stl")
|
return glob.glob("*/")+glob.glob("*.stl")
|
||||||
|
|
||||||
def help_skein(self):
|
def help_skein(self):
|
||||||
print "Creates a gcode file from an stl model using the slicer (with tab-completion)"
|
print "Creates a gcode file from an stl model using the slicer (with tab-completion)"
|
||||||
print "skein filename.stl - create gcode file"
|
print "skein filename.stl - create gcode file"
|
||||||
print "skein filename.stl view - create gcode file and view using skeiniso"
|
print "skein filename.stl view - create gcode file and view using skeiniso"
|
||||||
print "skein set - adjust slicer settings"
|
print "skein set - adjust slicer settings"
|
||||||
|
|
||||||
|
|
||||||
def do_home(self,l):
|
def do_home(self,l):
|
||||||
if not self.p.online:
|
if not self.p.online:
|
||||||
print "Printer is not online. Unable to move."
|
print "Printer is not online. Unable to move."
|
||||||
|
@ -1202,7 +1202,7 @@ class pronsole(cmd.Cmd):
|
||||||
if not len(l):
|
if not len(l):
|
||||||
self.p.send_now("G28")
|
self.p.send_now("G28")
|
||||||
self.p.send_now("G92 E0")
|
self.p.send_now("G92 E0")
|
||||||
|
|
||||||
def help_home(self):
|
def help_home(self):
|
||||||
print "Homes the printer"
|
print "Homes the printer"
|
||||||
print "home - homes all axes and zeroes the extruder(Using G28 and G92)"
|
print "home - homes all axes and zeroes the extruder(Using G28 and G92)"
|
||||||
|
@ -1210,7 +1210,7 @@ class pronsole(cmd.Cmd):
|
||||||
print "home z - homes z axis only (Using G28)"
|
print "home z - homes z axis only (Using G28)"
|
||||||
print "home e - set extruder position to zero (Using G92)"
|
print "home e - set extruder position to zero (Using G92)"
|
||||||
print "home xyze - homes all axes and zeroes the extruder (Using G28 and G92)"
|
print "home xyze - homes all axes and zeroes the extruder (Using G28 and G92)"
|
||||||
|
|
||||||
def parse_cmdline(self,args):
|
def parse_cmdline(self,args):
|
||||||
import getopt
|
import getopt
|
||||||
opts,args = getopt.getopt(args, "c:e:hw", ["conf=","config=","help","web","web-config=", "web-auth-config="])
|
opts,args = getopt.getopt(args, "c:e:hw", ["conf=","config=","help","web","web-config=", "web-auth-config="])
|
||||||
|
@ -1240,7 +1240,7 @@ class pronsole(cmd.Cmd):
|
||||||
self.processing_args = False
|
self.processing_args = False
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
|
|
||||||
interp=pronsole()
|
interp=pronsole()
|
||||||
interp.parse_cmdline(sys.argv[1:])
|
interp.parse_cmdline(sys.argv[1:])
|
||||||
try:
|
try:
|
||||||
|
@ -1248,4 +1248,3 @@ if __name__=="__main__":
|
||||||
except:
|
except:
|
||||||
interp.p.disconnect()
|
interp.p.disconnect()
|
||||||
#raise
|
#raise
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ from printrun.zbuttons import ZButtons
|
||||||
from printrun.graph import Graph
|
from printrun.graph import Graph
|
||||||
from printrun.printrun_utils import pixmapfile, configfile
|
from printrun.printrun_utils import pixmapfile, configfile
|
||||||
import pronsole
|
import pronsole
|
||||||
|
|
||||||
def dosify(name):
|
def dosify(name):
|
||||||
return os.path.split(name)[1].split(".")[0][:8]+".g"
|
return os.path.split(name)[1].split(".")[0][:8]+".g"
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
wx.CallAfter(self.settbtn.SetForegroundColour, "")
|
wx.CallAfter(self.settbtn.SetForegroundColour, "")
|
||||||
wx.CallAfter(self.htemp.SetBackgroundColour, "white")
|
wx.CallAfter(self.htemp.SetBackgroundColour, "white")
|
||||||
wx.CallAfter(self.htemp.Refresh)
|
wx.CallAfter(self.htemp.Refresh)
|
||||||
|
|
||||||
def do_settemp(self, l = ""):
|
def do_settemp(self, l = ""):
|
||||||
try:
|
try:
|
||||||
if not l.__class__ in (str, unicode) or not len(l):
|
if not l.__class__ in (str, unicode) or not len(l):
|
||||||
|
@ -579,7 +579,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
#self.minibtn.Bind(wx.EVT_BUTTON,self.toggleview)
|
#self.minibtn.Bind(wx.EVT_BUTTON,self.toggleview)
|
||||||
|
|
||||||
#uts.Add((25,-1))
|
#uts.Add((25,-1))
|
||||||
|
|
||||||
#uts.Add((15,-1),flag=wx.EXPAND)
|
#uts.Add((15,-1),flag=wx.EXPAND)
|
||||||
#uts.Add(self.minibtn,0,wx.ALIGN_CENTER)
|
#uts.Add(self.minibtn,0,wx.ALIGN_CENTER)
|
||||||
|
|
||||||
|
@ -642,7 +642,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
#lls.Add((200,375))
|
#lls.Add((200,375))
|
||||||
|
|
||||||
szbuttons=wx.GridBagSizer()
|
szbuttons=wx.GridBagSizer()
|
||||||
|
|
||||||
self.xyb = XYButtons(self.panel, self.moveXY, self.homeButtonClicked, self.spacebarAction, self.settings.bgcolor)
|
self.xyb = XYButtons(self.panel, self.moveXY, self.homeButtonClicked, self.spacebarAction, self.settings.bgcolor)
|
||||||
szbuttons.Add(self.xyb,pos=(0,1),flag=wx.ALIGN_CENTER)
|
szbuttons.Add(self.xyb,pos=(0,1),flag=wx.ALIGN_CENTER)
|
||||||
self.zb = ZButtons(self.panel, self.moveZ, self.settings.bgcolor)
|
self.zb = ZButtons(self.panel, self.moveZ, self.settings.bgcolor)
|
||||||
|
@ -738,7 +738,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
self.btemp.SetValue(i)
|
self.btemp.SetValue(i)
|
||||||
for i in htemp_choices:
|
for i in htemp_choices:
|
||||||
if i.split()[0] == str(self.settings.last_temperature).split('.')[0] or i.split()[0] == str(self.settings.last_temperature) :
|
if i.split()[0] == str(self.settings.last_temperature).split('.')[0] or i.split()[0] == str(self.settings.last_temperature) :
|
||||||
self.htemp.SetValue(i)
|
self.htemp.SetValue(i)
|
||||||
|
|
||||||
if( '(' not in self.btemp.Value):
|
if( '(' not in self.btemp.Value):
|
||||||
self.btemp.SetValue(self.btemp.Value + ' (user)')
|
self.btemp.SetValue(self.btemp.Value + ' (user)')
|
||||||
|
@ -748,7 +748,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
#lls.Add(self.btemp,pos=(4,1),span=(1,3))
|
#lls.Add(self.btemp,pos=(4,1),span=(1,3))
|
||||||
#lls.Add(self.setbbtn,pos=(4,4),span=(1,2))
|
#lls.Add(self.setbbtn,pos=(4,4),span=(1,2))
|
||||||
self.tempdisp=wx.StaticText(self.panel,-1,"")
|
self.tempdisp=wx.StaticText(self.panel,-1,"")
|
||||||
|
|
||||||
self.edist=wx.SpinCtrl(self.panel,-1,"5",min=0,max=1000,size=(60,-1))
|
self.edist=wx.SpinCtrl(self.panel,-1,"5",min=0,max=1000,size=(60,-1))
|
||||||
self.edist.SetBackgroundColour((225,200,200))
|
self.edist.SetBackgroundColour((225,200,200))
|
||||||
self.edist.SetForegroundColour("black")
|
self.edist.SetForegroundColour("black")
|
||||||
|
@ -767,7 +767,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
self.zfeedc.SetBackgroundColour((180,255,180))
|
self.zfeedc.SetBackgroundColour((180,255,180))
|
||||||
self.zfeedc.SetForegroundColour("black")
|
self.zfeedc.SetForegroundColour("black")
|
||||||
# lls.Add((10,0),pos=(0,11),span=(1,1))
|
# lls.Add((10,0),pos=(0,11),span=(1,1))
|
||||||
|
|
||||||
#self.hottgauge=TempGauge(self.panel,size=(200,24),title=_("Heater:"),maxval=230)
|
#self.hottgauge=TempGauge(self.panel,size=(200,24),title=_("Heater:"),maxval=230)
|
||||||
#lls.Add(self.hottgauge,pos=(7,0),span=(1,4))
|
#lls.Add(self.hottgauge,pos=(7,0),span=(1,4))
|
||||||
#self.bedtgauge=TempGauge(self.panel,size=(200,24),title=_("Bed:"),maxval=130)
|
#self.bedtgauge=TempGauge(self.panel,size=(200,24),title=_("Bed:"),maxval=130)
|
||||||
|
@ -778,11 +778,11 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
# elif e.GetWheelRotation()<0:
|
# elif e.GetWheelRotation()<0:
|
||||||
# self.do_settemp(str(max(0,self.hsetpoint-1)))
|
# self.do_settemp(str(max(0,self.hsetpoint-1)))
|
||||||
#self.tgauge.Bind(wx.EVT_MOUSEWHEEL,scroll_setpoint)
|
#self.tgauge.Bind(wx.EVT_MOUSEWHEEL,scroll_setpoint)
|
||||||
|
|
||||||
self.graph = Graph(self.panel, wx.ID_ANY)
|
self.graph = Graph(self.panel, wx.ID_ANY)
|
||||||
lls.Add(self.graph, pos=(3,5), span=(3,3))
|
lls.Add(self.graph, pos=(3,5), span=(3,3))
|
||||||
lls.Add(self.tempdisp,pos=(6,0),span=(1,1))
|
lls.Add(self.tempdisp,pos=(6,0),span=(1,1))
|
||||||
|
|
||||||
self.gviz=gviz.gviz(self.panel,(300,300),
|
self.gviz=gviz.gviz(self.panel,(300,300),
|
||||||
build_dimensions=self.build_dimensions_list,
|
build_dimensions=self.build_dimensions_list,
|
||||||
grid=(self.settings.preview_grid_step1,self.settings.preview_grid_step2),
|
grid=(self.settings.preview_grid_step1,self.settings.preview_grid_step2),
|
||||||
|
@ -845,12 +845,12 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
self.commandbox.SetSelection(0,len(self.commandbox.history[self.commandbox.histindex]))
|
self.commandbox.SetSelection(0,len(self.commandbox.history[self.commandbox.histindex]))
|
||||||
elif e.GetKeyCode()==wx.WXK_DOWN:
|
elif e.GetKeyCode()==wx.WXK_DOWN:
|
||||||
if self.commandbox.histindex==len(self.commandbox.history):
|
if self.commandbox.histindex==len(self.commandbox.history):
|
||||||
self.commandbox.history+=[self.commandbox.GetValue()] #save current command
|
self.commandbox.history+=[self.commandbox.GetValue()] #save current command
|
||||||
if len(self.commandbox.history):
|
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.SetValue(self.commandbox.history[self.commandbox.histindex])
|
||||||
self.commandbox.SetSelection(0,len(self.commandbox.history[self.commandbox.histindex]))
|
self.commandbox.SetSelection(0,len(self.commandbox.history[self.commandbox.histindex]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
e.Skip()
|
e.Skip()
|
||||||
|
|
||||||
|
@ -957,10 +957,10 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
b.SetToolTip(wx.ToolTip(_("click to add new custom button")))
|
b.SetToolTip(wx.ToolTip(_("click to add new custom button")))
|
||||||
b.Bind(wx.EVT_BUTTON,self.cbutton_edit)
|
b.Bind(wx.EVT_BUTTON,self.cbutton_edit)
|
||||||
else:
|
else:
|
||||||
b=wx.Button(self.panel,-1,".",size=(1,1))
|
b=wx.Button(self.panel,-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=wx.StaticText(self.panel,-1,"",size=(72,22),style=wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE) #+wx.SIMPLE_BORDER
|
||||||
b.Disable()
|
b.Disable()
|
||||||
#continue
|
#continue
|
||||||
b.custombutton=i
|
b.custombutton=i
|
||||||
b.properties=btndef
|
b.properties=btndef
|
||||||
if btndef is not None:
|
if btndef is not None:
|
||||||
|
@ -984,9 +984,9 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
def nextarg(rest):
|
def nextarg(rest):
|
||||||
rest=rest.lstrip()
|
rest=rest.lstrip()
|
||||||
if rest.startswith('"'):
|
if rest.startswith('"'):
|
||||||
return rest[1:].split('"',1)
|
return rest[1:].split('"',1)
|
||||||
else:
|
else:
|
||||||
return rest.split(None,1)
|
return rest.split(None,1)
|
||||||
#try:
|
#try:
|
||||||
num,argstr=nextarg(argstr)
|
num,argstr=nextarg(argstr)
|
||||||
num=int(num)
|
num=int(num)
|
||||||
|
@ -1385,7 +1385,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
except:
|
except:
|
||||||
break
|
break
|
||||||
wx.CallAfter(self.status.SetStatusText,_("Not connected to printer."))
|
wx.CallAfter(self.status.SetStatusText,_("Not connected to printer."))
|
||||||
|
|
||||||
def capture(self, func, *args, **kwargs):
|
def capture(self, func, *args, **kwargs):
|
||||||
stdout=sys.stdout
|
stdout=sys.stdout
|
||||||
cout=None
|
cout=None
|
||||||
|
@ -1518,7 +1518,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
self.f=[i.replace("\n","").replace("\r","") for i in of]
|
self.f=[i.replace("\n","").replace("\r","") for i in of]
|
||||||
of.close()
|
of.close()
|
||||||
if self.p.online:
|
if self.p.online:
|
||||||
wx.CallAfter(self.printbtn.Enable)
|
wx.CallAfter(self.printbtn.Enable)
|
||||||
|
|
||||||
wx.CallAfter(self.status.SetStatusText,_("Loaded ")+self.filename+_(", %d lines") % (len(self.f),))
|
wx.CallAfter(self.status.SetStatusText,_("Loaded ")+self.filename+_(", %d lines") % (len(self.f),))
|
||||||
wx.CallAfter(self.pausebtn.Disable)
|
wx.CallAfter(self.pausebtn.Disable)
|
||||||
|
@ -1553,7 +1553,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
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 (*.*)|*.*"))
|
dlg.SetWildcard(_("OBJ, STL, and GCODE files (*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ)|*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ|All Files (*.*)|*.*"))
|
||||||
if(filename is not None or dlg.ShowModal() == wx.ID_OK):
|
if(filename is not None or dlg.ShowModal() == wx.ID_OK):
|
||||||
if filename is not None:
|
if filename is not None:
|
||||||
name=filename
|
name=filename
|
||||||
|
@ -1810,4 +1810,3 @@ if __name__ == '__main__':
|
||||||
app.MainLoop()
|
app.MainLoop()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
10
setup.py
10
setup.py
|
@ -1,17 +1,17 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# This file is part of the Printrun suite.
|
# This file is part of the Printrun suite.
|
||||||
#
|
#
|
||||||
# Printrun is free software: you can redistribute it and/or modify
|
# Printrun is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# Printrun is distributed in the hope that it will be useful,
|
# Printrun is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class install (_install):
|
||||||
except:
|
except:
|
||||||
self.warn ("Could not write installed files list %s" % \
|
self.warn ("Could not write installed files list %s" % \
|
||||||
INSTALLED_FILES)
|
INSTALLED_FILES)
|
||||||
return
|
return
|
||||||
file.write (data)
|
file.write (data)
|
||||||
file.close ()
|
file.close ()
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class uninstall (_install):
|
||||||
except:
|
except:
|
||||||
self.warn ("Could not read installed files list %s" % \
|
self.warn ("Could not read installed files list %s" % \
|
||||||
INSTALLED_FILES)
|
INSTALLED_FILES)
|
||||||
return
|
return
|
||||||
files = file.readlines ()
|
files = file.readlines ()
|
||||||
file.close ()
|
file.close ()
|
||||||
prepend = ""
|
prepend = ""
|
||||||
|
|
Loading…
Reference in New Issue