cyclone-pcb-factory/Software/Replath/replath/build/scripts-2.7/replath

868 lines
38 KiB
Python
Executable File

#!/usr/bin/python
__author__ = "Stefan Blanke (greenarrow) (greenarrow@users.sourceforge.net)"
__credits__ = ""
__license__ = "GPL 3.0"
__version__ = "0.8"
__licence__ = """
pyRepRap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyRepRap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pyRepRap. If not, see <http://www.gnu.org/licenses/>.
"""
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.1 on Wed Apr 23 11:49:08 2008
import wx, pygame, reprap, time, sys, os, threading
import replath.wxpygame as wxpygame
import reprap.shapeplotter, replath.plugins, reprap.toolpath
import replath
appTitle = "RepRap Plot"
plotterPlugins = replath.plugins.getPlugins(replath.plugins.PLUGIN_IMPORT)
outputPlugins = replath.plugins.getPlugins(replath.plugins.PLUGIN_OUTPUT)
toolheadPlugins = replath.plugins.getPlugins(replath.plugins.PLUGIN_TOOLHEAD)
plotterList = replath.plugins.listTitles(plotterPlugins)
outputList = replath.plugins.listTitles(outputPlugins)
toolheadList = replath.plugins.listTitles(toolheadPlugins)
if sys.platform=="win32":
# Windows (taking path of this script)
iconPath = os.path.join( os.getcwd(), "graphics" )
else:
# Linux
iconPath = "/usr/local/share/replath/icons/"
appIcon = os.path.join(iconPath, "reprap.png")
# Feedback action definitions
EVT_FBM_ID = wx.NewId()
FB_STATUS = 1
FB_COMPLETE = 2
FB_ABORTED = 3
FB_MESSAGE = 4
# Feedback message event object. Always used by feedbackmessagehandler (external plotters do not use it)
class FeedbackMessageEvent(wx.PyEvent):
"""Simple event to carry arbitrary result data."""
def __init__(self, action, data):
"""Init Result Event."""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_FBM_ID)
self.action = action
self.data = data
# Passed to plotters so they can give feedback info to the gui (including when they are finished)
class FeedbackMessageHandler:
def __init__(self, parent):
self.parent = parent
parent.Connect(-1, -1, EVT_FBM_ID, self.onEvent)
def onEvent(self, event):
if event.action == FB_STATUS:
self.parent.setStatusBar(event.data)
elif event.action == FB_COMPLETE:
self.parent.plotComplete()
elif event.action == FB_ABORTED:
self.parent.plotAborted()
elif event.action == FB_MESSAGE:
dlg = wx.MessageDialog(self.parent, str(event.data) + '\n', caption = appTitle, style = wx.OK)
#dlg = wx.MessageDialog(self.parent, 'moo\n', caption = 'moo', style = wx.OK)
dlg.ShowModal()
def plotComplete(self):
wx.PostEvent( self.parent, FeedbackMessageEvent(FB_COMPLETE, None) )
def setStatus(self, text):
wx.PostEvent( self.parent, FeedbackMessageEvent(FB_STATUS, text) )
def setProgressPopup(self, text, progress = 0):
#if text:
# #show window
# self.progressDialog.progress.SetValue(int(progress))
#else:
# #hide window
pass
def updateProgressPopup(self, progress):
#self.progressDialog.progress.SetValue(int(progress))
pass
def showMessagePopup(self, text):
wx.PostEvent( self.parent, FeedbackMessageEvent(FB_MESSAGE, text) )
def aborted(self):
wx.PostEvent( self.parent, FeedbackMessageEvent(FB_ABORTED, None) )
# content of this block not found: did you rename this class?
pass
# Dialog class for preferences
class PreferencesDialog(wx.Dialog):
def __init__(self, *args, **kwds):
# begin wxGlade: PreferencesDialog.__init__
kwds["style"] = wx.DEFAULT_DIALOG_STYLE
wx.Dialog.__init__(self, *args, **kwds)
self.notebook_main = wx.Notebook(self, -1, style=wx.NB_LEFT)
self.panel_toolheads = wx.Panel(self.notebook_main, -1)
self.panel_outputs = wx.Panel(self.notebook_main, -1)
self.panel_inputs = wx.Panel(self.notebook_main, -1)
self.panel_general = wx.Panel(self.notebook_main, -1)
self.sizer_7_staticbox = wx.StaticBox(self, -1, "")
self.sizer_9_staticbox = wx.StaticBox(self.panel_general, -1, "")
self.label_8 = wx.StaticText(self.panel_general, -1, "Plot offset (mm) : ")
self.label_9 = wx.StaticText(self.panel_general, -1, "X : ")
self.text_offsetX = wx.TextCtrl(self.panel_general, -1, "")
self.label_10 = wx.StaticText(self.panel_general, -1, "Y :")
self.text_offsetY = wx.TextCtrl(self.panel_general, -1, "")
self.label_11 = wx.StaticText(self.panel_general, -1, "Fill density (lines / mm) :")
self.text_fillDensity = wx.TextCtrl(self.panel_general, -1, "")
self.label_16 = wx.StaticText(self.panel_general, -1, "Circle resolution (lines / mm in c) :")
self.text_circleResolution = wx.TextCtrl(self.panel_general, -1, "")
self.label_1 = wx.StaticText(self.panel_general, -1, "Delay between lines (seconds) :")
self.text_lineDelay = wx.TextCtrl(self.panel_general, -1, "")
self.label_2 = wx.StaticText(self.panel_general, -1, "Zoom step (factor) :")
self.text_zoomStep = wx.TextCtrl(self.panel_general, -1, "")
self.label_3 = wx.StaticText(self.panel_general, -1, "Grid division (mm) :")
self.text_gridDivision = wx.TextCtrl(self.panel_general, -1, "")
self.checkbox_debug = wx.CheckBox(self.panel_general, -1, "Debug")
self.notebook_inputs = wx.Notebook(self.panel_inputs, -1, style=wx.NB_LEFT)
self.notebook_outputs = wx.Notebook(self.panel_outputs, -1, style=wx.NB_LEFT)
self.notebook_toolheads = wx.Notebook(self.panel_toolheads, -1, style=wx.NB_LEFT)
self.button_Ok = wx.Button(self, wx.ID_OK, "")
self.button_Cancel = wx.Button(self, wx.ID_CANCEL, "")
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_BUTTON, self.hanBtnOk, self.button_Ok)
self.Bind(wx.EVT_BUTTON, self.hanBtnCancel, self.button_Cancel)
# end wxGlade
def __set_properties(self):
# begin wxGlade: PreferencesDialog.__set_properties
self.SetTitle("RepRap Gerber Plotter - Preferences")
_icon = wx.EmptyIcon()
_icon.CopyFromBitmap(wx.Bitmap(appIcon))
self.SetIcon(_icon)
# end wxGlade
def __do_layout(self):
print "panel load"
# Dynamically load panels from plugins
self.preferencePanels = []
for plugin in outputPlugins:
if dir(plugin).count('PreferencesPanel'):
newPanel = plugin.PreferencesPanel(self.notebook_outputs)
self.preferencePanels.append( newPanel )
self.notebook_outputs.AddPage(newPanel, plugin.Title)
for plugin in toolheadPlugins:
if dir(plugin).count('PreferencesPanel'):
newPanel = plugin.PreferencesPanel(self.notebook_toolheads)
self.preferencePanels.append( newPanel )
self.notebook_toolheads.AddPage(newPanel, plugin.Title)
for plugin in plotterPlugins:
if dir(plugin).count('PreferencesPanel'):
newPanel = plugin.PreferencesPanel(self.notebook_inputs)
self.preferencePanels.append( newPanel )
self.notebook_inputs.AddPage(newPanel, plugin.Title)
# begin wxGlade: PreferencesDialog.__do_layout
sizer_7 = wx.StaticBoxSizer(self.sizer_7_staticbox, wx.VERTICAL)
sizer_5 = wx.BoxSizer(wx.VERTICAL)
sizer_7_copy = wx.BoxSizer(wx.HORIZONTAL)
sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_9 = wx.StaticBoxSizer(self.sizer_9_staticbox, wx.VERTICAL)
grid_sizer_2 = wx.FlexGridSizer(7, 3, 4, 0)
grid_sizer_1 = wx.FlexGridSizer(4, 11, 4, 0)
grid_sizer_1.Add(self.label_8, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add(self.label_9, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add(self.text_offsetX, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add(self.label_10, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add(self.text_offsetY, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_1.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_1.AddGrowableCol(4)
grid_sizer_1.AddGrowableCol(8)
sizer_9.Add(grid_sizer_1, 0, wx.ALL|wx.EXPAND, 10)
grid_sizer_2.Add(self.label_11, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.text_fillDensity, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.label_16, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.text_circleResolution, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.label_1, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.text_lineDelay, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.label_2, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.text_zoomStep, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.label_3, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.text_gridDivision, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add(self.checkbox_debug, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((10, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
grid_sizer_2.AddGrowableCol(2)
sizer_9.Add(grid_sizer_2, 1, wx.ALL|wx.EXPAND, 10)
sizer_2.Add(sizer_9, 1, wx.ALL|wx.EXPAND, 10)
self.panel_general.SetSizer(sizer_2)
sizer_1.Add(self.notebook_inputs, 1, wx.ALL|wx.EXPAND, 10)
self.panel_inputs.SetSizer(sizer_1)
sizer_3.Add(self.notebook_outputs, 1, wx.ALL|wx.EXPAND, 10)
self.panel_outputs.SetSizer(sizer_3)
sizer_4.Add(self.notebook_toolheads, 1, wx.ALL|wx.EXPAND, 10)
self.panel_toolheads.SetSizer(sizer_4)
self.notebook_main.AddPage(self.panel_general, "General")
self.notebook_main.AddPage(self.panel_inputs, "Plotter Plugins")
self.notebook_main.AddPage(self.panel_outputs, "Output Plugins")
self.notebook_main.AddPage(self.panel_toolheads, "Toolhead Plugins")
sizer_5.Add(self.notebook_main, 1, wx.EXPAND, 0)
sizer_5.Add((20, 20), 0, wx.ADJUST_MINSIZE, 0)
sizer_7_copy.Add(self.button_Ok, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
sizer_7_copy.Add(self.button_Cancel, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
sizer_5.Add(sizer_7_copy, 0, wx.EXPAND, 0)
sizer_7.Add(sizer_5, 1, wx.ALL|wx.EXPAND|wx.ADJUST_MINSIZE, 16)
self.SetSizer(sizer_7)
sizer_7.Fit(self)
self.Layout()
self.Centre()
# end wxGlade
def setPrefHandler(self, pref):
self.preferences = pref
# Set values of frame control
def setPrefValues(self):
self.text_offsetX.SetValue( str(self.preferences.pref_plotOffsetX) )
self.text_offsetY.SetValue( str(self.preferences.pref_plotOffsetY) )
self.text_fillDensity.SetValue( str(self.preferences.pref_fillDensity) )
self.text_lineDelay.SetValue( str(self.preferences.pref_lineDelay) )
self.checkbox_debug.SetValue( self.preferences.pref_debug )
self.text_circleResolution.SetValue( str(self.preferences.pref_circleResolution) )
self.text_gridDivision.SetValue( str(self.preferences.pref_gridDivision) )
self.text_zoomStep.SetValue( str(self.preferences.pref_zoomStep) )
def getPreferences(self):
return self.preferences
# User clicked OK
def hanBtnOk(self, event): # wxGlade: PreferencesDialog.<event_handler>
self.preferences.pref_plotOffsetX = float( self.text_offsetX.GetValue() )
self.preferences.pref_plotOffsetY = float( self.text_offsetY.GetValue() )
self.preferences.pref_fillDensity = int( self.text_fillDensity.GetValue() )
self.preferences.pref_lineDelay = float( self.text_lineDelay.GetValue() )
self.preferences.pref_debug = self.checkbox_debug.GetValue()
self.preferences.pref_circleResolution = float( self.text_circleResolution.GetValue() )
self.preferences.pref_gridDivision = float( self.text_gridDivision.GetValue() )
self.preferences.pref_zoomStep = float( self.text_zoomStep.GetValue() )
for p in self.preferencePanels:
p.savePrefValues()
self.EndModal(wx.OK)
# User clicked Cancel
def hanBtnCancel(self, event): # wxGlade: PreferencesDialog.<event_handler>
self.preferences = False
self.EndModal(wx.CANCEL)
# end of class PreferencesDialog
"""
# A set of lines for drawing on the screen TODO - put draw back in
class lineSet:
def __init__(self, parent, colour):
self.parent = parent
self.colour = colour
self.clear()
def setColour(colour):
self.colour = colour
self.tableChanged = True
def addLine(self, line):
self.lines.append(line)
#self.parent.draw() #not ideal
#pygame.display.flip()
self.tableChanged = True
def getLines(self):
return self.lines
def clear(self):
self.lines = []
self.tableChanged = True
def hasChanged(self):
if self.tableChanged:
self.tableChanged = False
return True
else:
return False
"""
# Class for pygame canvas
class DrawCanvas(wxpygame.wxSDLPanel):
def __init__( self, parent, ID=-1 ):
wxpygame.wxSDLPanel.__init__(self, parent, ID)
self.previewScale = 5.0
self.offsetX, self.offsetY = 0, 0
self.black = 0, 0, 0
self.white = 255, 255, 255
self.grey = 160, 160, 160
self.greyGreen = 170, 195, 170
self.darkGrey = 140, 140, 140
self.backroundColour = self.white
self.baseColour = 166, 211, 166
self.gridColour = self.greyGreen
self.previewColour = self.darkGrey
self.plotColour = self.black
pygame.font.init()
self.font = pygame.font.Font(None, 17)
self.drawSurface = pygame.Surface( ( 0, 0 ) )
self.drawn = False
self.drawRect = 0, 0, 10, 10
def setParent(self, parent):
self.parent = parent
self.fullRedraw()
def drawText( self, surface, x, y, text, font ):
text = font.render( text, True, (255, 255, 255), (159, 182, 205) )
textRect = text.get_rect()
textRect.centerx = x
textRect.centery = y
surface.blit(text, textRect)
# Draw plot to widget
def draw( self ):
surface = self.getSurface()
w, h = self.GetSizeTuple()
if not surface is None:
surface.fill( self.backroundColour )
if self.drawn:
surface.blit( self.drawSurface, (self.offsetX, -self.offsetY) )#limit region to visible - is this needed?
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.display.flip()
def fullRedraw(self):
if self.parent.currentToolpath:
fileOffsetX, fileOffsetY = self.parent.currentToolpath.offsetX, self.parent.currentToolpath.offsetY
# Find limits
#if len(self.polygons) > 0:
minX, minY, maxX, maxY = 1000000, 1000000, -1000000, -1000000
if len(self.parent.currentToolpath.layers):
for layer in self.parent.currentToolpath.layers:
for poly in layer.polygons:
for p in poly.points:
minX = min(minX, p.x + fileOffsetX)
minY = min(minY, p.y + fileOffsetY)
maxX = max(maxX, p.x + fileOffsetX)
maxY = max(maxY, p.y + fileOffsetY)
else:
minX, minY, maxX, maxY = 0, 0, 0, 0
border = int(self.parent.preferences.pref_gridDivision * self.previewScale / 2)
w, h = self.GetSizeTuple()
width, height = int(maxX * self.previewScale) + (2 * border), int(maxY * self.previewScale) + (2 *border)
#print "wh", width, height
if width > 0 and height > 0:
self.drawSurface = pygame.Surface( ( width, height ) )
self.drawRect = 0, 0, width, height
# Only draw if we have something to show
#if len(self.polygons) > 0:
# Draw background
pygame.draw.rect( self.drawSurface, self.baseColour, self.drawRect, 0)
# Draw grid
for x in frange( 0, maxX, self.parent.preferences.pref_gridDivision ):
pygame.draw.line( self.drawSurface, self.gridColour, ( int( float(x) * self.previewScale ) + border , border ), ( int( float(x) * self.previewScale ) + border , height - border ) )
for y in frange( 0, maxY, self.parent.preferences.pref_gridDivision ):
pygame.draw.line( self.drawSurface, self.gridColour, ( border, height - border - int( float(y) * self.previewScale ) ), ( width - border, height - border - int( float(y) * self.previewScale ) ) )
# Draw axis labels
pygame.draw.line( self.drawSurface, self.black, (border, height - border), (border + 50, height - border) )
pygame.draw.line( self.drawSurface, self.black, (border, height - border), (border, height - 50 - border ) )
self.drawText( self.drawSurface, border + 25, height - border , "X", self.font )
self.drawText( self.drawSurface, border, height - border - 25, "Y", self.font )
#else:
# # Draw blank white box
# pygame.draw.rect( self.drawSurface, self.white, self.drawRect, 0)
for layer in self.parent.currentToolpath.layers:
# Draw polygons
for poly in layer.polygons:
#print "plotting poly", poly, len(poly.points)
oldX, oldY = poly.points[0].x, poly.points[0].y
for ip, p in enumerate(poly.points[ 1: ]):
if ip < poly.pointsPlotted:
lineColour = self.black
else:
lineColour = self.previewColour
x1, y1, x2, y2 = self.scaleRect( (oldX + fileOffsetX, oldY + fileOffsetY, p.x + fileOffsetX, p.y + fileOffsetY), self.previewScale )
pygame.draw.line( self.drawSurface, lineColour, (x1 + border, height - y1 - border), (x2 + border, height - y2 -border) )
oldX, oldY = p.x, p.y
# Final line if closed
if poly.closed:
x, y = poly.points[0].x, poly.points[0].y
x1, y1, x2, y2 = self.scaleRect( (oldX + fileOffsetX, oldY + fileOffsetY, x + fileOffsetX, y + fileOffsetY), self.previewScale )
pygame.draw.line( self.drawSurface, self.previewColour, (x1 + border, height - y1 - border), (x2 + border, height - y2 -border) )
self.drawn = True
self.draw()
# Simple coordiante manipulation
def scaleRect( self, rect, scale ):
x1, y1, x2, y2 = rect
scaleX = float(scale)
scaleY = float(scale)
return int( float(x1) * scale ), int( float(y1) * scale ), int( float(x2) * scale ), int( float(y2) * scale )
def offsetRect( self, rect, x, y ):
x1, y1, x2, y2 = rect
return x1 + x, y1 + y, x2, y2
def offsetLine(self, rect, x, y):
x1, y1, x2, y2 = rect
return x1 + x, y1 + y, x2 + x, y2 + y
def centreView(self, x, y):
widthV, heightV = self.GetSizeTuple()
null, null, widthD, heightD = self.drawRect
self.offsetX = (widthV - widthD + x) / 2
self.offsetY = (heightV - heightD + y) / -2
# Change draw offset to allow dragging of plot
def MouseMove(self, event):
w, h = self.GetSizeTuple()
if event.LeftIsDown():
x, y = event.GetPosition()
if event.Dragging():
self.offsetX, self.offsetY = x + self.moveDeltaX, self.moveDeltaY - y
# Record offsets for use in drag movement
def OnMouseDown(self, event):
w, h = self.GetSizeTuple()
x, y = event.GetPosition()
#print x, y
self.moveDeltaX, self.moveDeltaY = self.offsetX - x, self.offsetY + y
def OnMouseUp(self, event):
pass
# When mouse wheel moved, zoom in or out
def OnMouseWheel(self, event):
w, h = self.GetSizeTuple()
centreX, centreY = w / 2, h / 2
x, y = event.GetPosition()
#deltaX, deltaY = centreX - x, y - centreY
if event.GetWheelRotation() > 0:
self.previewScale = self.previewScale + self.parent.preferences.pref_zoomStep
elif self.previewScale >= self.parent.preferences.pref_zoomStep:
self.previewScale = self.previewScale - self.parent.preferences.pref_zoomStep
self.fullRedraw()
#null, null, widthD, heightD = self.drawRect
#self.centreView(x - self.offsetX, h - y - self.offsetY)
#self.centreView(100, 100)
# Main frame class
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# Create preference handler that stores preferences on itself
self.preferences = replath.preferences.PreferenceHandler( False, "pyRepRap.conf" )
# default values for preferences
self.preferences.pref_plotOffsetX = 10.0
self.preferences.pref_plotOffsetY = 10.0
self.preferences.pref_fillDensity = 5
self.preferences.pref_lineDelay = 0.0
self.preferences.pref_debug = False
self.preferences.pref_circleResolution = 3.0
self.preferences.pref_gridDivision = 5.0
self.preferences.pref_zoomStep = 1
self.preferences.load()
self.fileName = False
self.currentPlotter = False
self.currentToolpath = False
# begin wxGlade: MyFrame.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.panel_1 = wx.Panel(self, -1)
# Menu Bar
self.frmMain_menubar = wx.MenuBar()
self.mnuFile = wx.Menu()
self.mnuOpen = wx.MenuItem(self.mnuFile, 0, "&Open\tCtrl+O", "", wx.ITEM_NORMAL)
self.mnuFile.AppendItem(self.mnuOpen)
self.mnuFile.AppendSeparator()
self.mnuPlot = wx.MenuItem(self.mnuFile, 2, "&Plot\tCtrl+P", "", wx.ITEM_NORMAL)
self.mnuFile.AppendItem(self.mnuPlot)
self.mnuFile.AppendSeparator()
self.mnuQuit = wx.MenuItem(self.mnuFile, 1, "&Quit\tCtrl+Q", "", wx.ITEM_NORMAL)
self.mnuFile.AppendItem(self.mnuQuit)
self.frmMain_menubar.Append(self.mnuFile, "&File")
wxglade_tmp_menu = wx.Menu()
wxglade_tmp_menu.Append(10, "Pr&eferences", "", wx.ITEM_NORMAL)
self.frmMain_menubar.Append(wxglade_tmp_menu, "&Edit")
wxglade_tmp_menu = wx.Menu()
self.mnuAbout = wx.MenuItem(wxglade_tmp_menu, 40, "&About", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.AppendItem(self.mnuAbout)
self.frmMain_menubar.Append(wxglade_tmp_menu, "&Help")
self.SetMenuBar(self.frmMain_menubar)
# Menu Bar end
self.frmMain_statusbar = self.CreateStatusBar(1, 0)
# Tool Bar
self.frmMain_toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL|wx.TB_TEXT)
self.SetToolBar(self.frmMain_toolbar)
self.frmMain_toolbar.AddLabelTool(100, "Open", (wx.Bitmap( os.path.join(iconPath, 'document-open.png'), wx.BITMAP_TYPE_ANY )), wx.NullBitmap, wx.ITEM_NORMAL, "Open file", "")
self.frmMain_toolbar.AddSeparator()
self.frmMain_toolbar.AddLabelTool(110, "Stop", (wx.Bitmap( os.path.join(iconPath, 'media-playback-stop.png'), wx.BITMAP_TYPE_ANY )), wx.NullBitmap, wx.ITEM_NORMAL, "Stop current plotting action", "")
self.frmMain_toolbar.AddSeparator()
self.frmMain_toolbar.AddLabelTool(120, "Plot", (wx.Bitmap( os.path.join(iconPath, 'media-playback-start.png'), wx.BITMAP_TYPE_ANY )), wx.NullBitmap, wx.ITEM_NORMAL, "Plot to output plugin", "")
self.frmMain_toolbar.AddSeparator()
self.frmMain_toolbar.AddLabelTool(130, "Preferences", (wx.Bitmap( os.path.join(iconPath, 'configure.png'), wx.BITMAP_TYPE_ANY )), wx.NullBitmap, wx.ITEM_NORMAL, "", "")
# Tool Bar end
self.static_line_1 = wx.StaticLine(self.panel_1, -1)
self.label_22 = wx.StaticText(self.panel_1, -1, "Output :")
self.choice_output = wx.Choice(self.panel_1, -1, choices=[])
self.label_23 = wx.StaticText(self.panel_1, -1, "Toolhead :")
self.choice_toolhead = wx.Choice(self.panel_1, -1, choices=[])
self.static_line_2 = wx.StaticLine(self.panel_1, -1)
self.pygameCanvas = DrawCanvas(self.panel_1, -1)
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_MENU, self.onClickOpen, self.mnuOpen)
self.Bind(wx.EVT_MENU, self.onClickPlot, self.mnuPlot)
self.Bind(wx.EVT_MENU, self.onClickQuit, self.mnuQuit)
self.Bind(wx.EVT_MENU, self.onClickPreferences, id=10)
self.Bind(wx.EVT_MENU, self.onClickAbout, self.mnuAbout)
self.Bind(wx.EVT_TOOL, self.onClickOpen, id=100)
self.Bind(wx.EVT_TOOL, self.onClickStop, id=110)
self.Bind(wx.EVT_TOOL, self.onClickPlot, id=120)
self.Bind(wx.EVT_TOOL, self.onClickPreferences, id=130)
# end wxGlade
#self.Bind(wx.EVT_CLOSE, self.onCloseWindow)
self.pygameCanvas.setParent(self)
self.setStatusBar("RepRap Plot")
def __set_properties(self):
# begin wxGlade: MyFrame.__set_properties
self.SetTitle("RepRap Plotter")
_icon = wx.EmptyIcon()
_icon.CopyFromBitmap(wx.Bitmap(appIcon))
self.SetIcon(_icon)
self.SetSize((869, 579))
self.frmMain_statusbar.SetStatusWidths([-1])
# statusbar fields
frmMain_statusbar_fields = ["frmMain_statusbar"]
for i in range(len(frmMain_statusbar_fields)):
self.frmMain_statusbar.SetStatusText(frmMain_statusbar_fields[i], i)
self.frmMain_toolbar.SetToolBitmapSize((32, 32))
self.frmMain_toolbar.Realize()
# end wxGlade
# Load plugin names into choice lists
self.choice_output.Append("None")
for p in outputList:
self.choice_output.Append(p)
self.choice_output.SetSelection(0)
for p in toolheadList:
self.choice_toolhead.Append(p)
self.choice_toolhead.SetSelection(0)
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
sizer_6 = wx.BoxSizer(wx.VERTICAL)
sizer_main = wx.BoxSizer(wx.VERTICAL)
sizer_19 = wx.BoxSizer(wx.HORIZONTAL)
sizer_main.Add(self.static_line_1, 0, wx.ALL|wx.EXPAND, 5)
sizer_19.Add((10, 1), 0, wx.ADJUST_MINSIZE, 0)
sizer_19.Add(self.label_22, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
sizer_19.Add((10, 1), 0, wx.ADJUST_MINSIZE, 0)
sizer_19.Add(self.choice_output, 0, wx.ADJUST_MINSIZE, 0)
sizer_19.Add((20, 1), 0, wx.ADJUST_MINSIZE, 0)
sizer_19.Add(self.label_23, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
sizer_19.Add((10, 1), 0, wx.ADJUST_MINSIZE, 0)
sizer_19.Add(self.choice_toolhead, 0, wx.ADJUST_MINSIZE, 0)
sizer_main.Add(sizer_19, 0, wx.EXPAND, 0)
sizer_main.Add(self.static_line_2, 0, wx.ALL|wx.EXPAND, 5)
sizer_main.Add(self.pygameCanvas, 5, wx.EXPAND, 1)
self.panel_1.SetSizer(sizer_main)
sizer_6.Add(self.panel_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_6)
self.Layout()
self.Centre()
# end wxGlade
def plotComplete(self):
self.pygameCanvas.fullRedraw()
self.pygameCanvas.centreView(0, 0)
self.currentPlotter.join()
self.currentPlotter = False
self.setStatusBar("Plot Complete")
#dlg = wx.MessageDialog(self, "Plot Complete\n", caption = appTitle, style = wx.OK)
#dlg.ShowModal()
def plotAborted(self):
self.pygameCanvas.fullRedraw()
if self.currentPlotter:
self.currentPlotter.join()
self.currentPlotter = False
self.setStatusBar("Plot aborted")
dlg = wx.MessageDialog(self, "Plot aborted\n", caption = appTitle, style = wx.OK)
dlg.ShowModal()
# Produces strings for file formats in wx file dialog e.g. 'Gerber Files (*.pho)|*.pho'
def dialogFilterString(self, extensions, name):
rText = name + " ("
for e in extensions:
rText += '*' + e + ';'
rText = rText[ :-1 ]
rText += ")|"
for e in extensions:
rText += '*' + e + ';'
# Removed as windows did not like having no end chr
rText = rText[ :-1 ]
return rText
def importPlot(self, fileName = False, quiet = False):
if fileName:
self.fileName = fileName
else:
self.fileName = False
filters = ""
allFormats = []
# Produce strings for file formats for wx file dialog
for p in plotterPlugins:
filters += self.dialogFilterString( p.SupportedFileExtensions, p.FileTitle ) + '|'
allFormats += p.SupportedFileExtensions
# Produce all supported formats string, put it at the start of the list
filters = self.dialogFilterString( allFormats, "All Supported Files" ) + '|' + filters
filters = filters[ :-1 ]
#print "ff [" + filters + "]"
dialog = wx.FileDialog ( None, message = 'Open Gerber File', wildcard = filters, style = wx.OPEN )
if dialog.ShowModal() == wx.ID_OK:
self.fileName = dialog.GetPath()
self.setStatusBar( "Opened File '" + self.fileName + "'" )
dialog.Destroy()
if self.fileName or fileName:
self.currentToolpath = reprap.toolpath.Object()
self.currentToolpath.offsetX, self.currentToolpath.offsetY = self.preferences.pref_plotOffsetX, self.preferences.pref_plotOffsetY
self.currentPlotter = False
plugin = False
cancel = False
feedbackHandler = FeedbackMessageHandler(self)
# Find a plugin that claims to handle files with the extension
for p in plotterPlugins:
# TODO - change to look for last dot not first, as it gets confused with network locations
#(fileBaseName, fileExtension)=os.path.splitext(fileName)
extension = self.fileName[ self.fileName.find('.'): ].lower()
if p.SupportedFileExtensions.count( extension ) > 0:
# # Check if the plotter has a preferences dialog and show it if it has one
if dir(p).count('PreferencesDialog') and not quiet:
plotPrefDialog = p.PreferencesDialog(None, -1, "")
app.SetTopWindow(plotPrefDialog)
if plotPrefDialog.ShowModal() == wx.OK:
plugin = p
else:
cancel = True
break
else:
plugin = p
# If a suitable plugin has been found
if plugin:
# Create plotter
self.currentPlotter = plugin.plotter(self.fileName, self.currentToolpath,
feedbackHandler = feedbackHandler,
arcResolution = self.preferences.pref_circleResolution,
fillDensity = self.preferences.pref_fillDensity,
debug = self.preferences.pref_debug,
)
if self.currentPlotter:
# Start plotter thread
self.currentPlotter.start()
elif not cancel :
dlg = wx.MessageDialog(self, "File format unsupported\n", caption = appTitle, style = wx.OK)
dlg.ShowModal()
def exportPlot(self, fileName = False):
#self.setStatusBar( "Plotting File '" + self.fileName + "'" )
# Use user selected output module
if self.choice_output.GetSelection() > 0:
outputs = [ self.choice_output.GetSelection() - 1 ]
else:
outputs = []
feedbackHandler = FeedbackMessageHandler(self)
toolhead = toolheadPlugins[ self.choice_toolhead.GetSelection() ].tool()
outputPlotters = []
for o in outputs:
outputFilename = None
if outputPlugins[o].FileOutput:
saveDialog = wx.FileDialog(self, message='Save file as...', wildcard=outputPlugins[o].Wildcard, style=wx.SAVE | wx.OVERWRITE_PROMPT) #defaultDir=dir, defaultFile='',
if saveDialog.ShowModal() == wx.ID_OK:
outputFilename = saveDialog.GetPath()
else:
outputFilename = None
saveDialog.Destroy()
self.currentPlotter = outputPlugins[o].output(self.currentToolpath, toolhead, feedbackHandler, outputFilename)
self.currentPlotter.start()
def setStatusBar(self, text):
self.frmMain_statusbar.SetStatusText( text, 0 )
def onClickOpen(self, event): # wxGlade: MyFrame.<event_handler>
if self.currentPlotter:
dlg = wx.MessageDialog(self, "Current action must be stopped before opening a file.\n", caption = appTitle, style = wx.OK)
dlg.ShowModal()
else:
self.importPlot()
#def onCloseWindow(self, evt):
# #self.Destroy()
# wx.Exit()
def onClickQuit(self, event): # wxGlade: MyFrame.<event_handler>
wx.Exit()
def onClickPreferences(self, event): # wxGlade: MyFrame.<event_handler>
dialogPref = PreferencesDialog(None, -1, "")
app.SetTopWindow(dialogPref)
dialogPref.setPrefHandler( self.preferences )
dialogPref.setPrefValues()
dialogPref.ShowModal()
self.pygameCanvas.fullRedraw()
dialogPref.Destroy()
self.preferences.save()
def onClickAbout(self, event): # wxGlade: MyFrame.<event_handler>
description = "RepRap Plotter is a program for plotting Gerber and CAD files on a RepRap machine."
info = wx.AboutDialogInfo()
info.SetIcon(wx.Icon(appIcon, wx.BITMAP_TYPE_PNG))
info.SetName('About RepRap Plotter')
info.SetVersion(__version__)
info.SetDescription(description)
#info.SetCopyright('')
info.SetLicence(__licence__)
info.AddDeveloper(__author__)
wx.AboutBox(info)
def onClickStop(self, event): # wxGlade: MyFrame.<event_handler>
# tell plotter thread to quit
if self.currentPlotter:
self.currentPlotter.terminate()
else:
dlg = wx.MessageDialog(self, "Nothing is currently being plotted.\n", caption = appTitle, style = wx.OK)
dlg.ShowModal()
def onClickPlot(self, event): # wxGlade: MyFrame.<event_handler>
if self.currentPlotter:
dlg = wx.MessageDialog(self, "Current action must be stopped before plotting.\n", caption = appTitle, style = wx.OK)
dlg.ShowModal()
else:
self.exportPlot()
# end of class MyFrame
# Range function accepting floats (by Dinu Gherman)
def frange(start, end=None, inc=None):
if end == None:
end = start + 0.0
start = 0.0
if inc == None:
inc = 1.0
L = []
while 1:
next = start + len(L) * inc
if inc > 0 and next >= end:
break
elif inc < 0 and next <= end:
break
L.append(next)
return L
# Strip quotations
def stripQuotes(text):
if (text[0] == '"' and text[-1] == '"') or (text[0] == "'" and text[-1] == "'"):
return text[ 1:-1 ]
else:
return text
showGui = True
if len(sys.argv) > 1:
if sys.argv.count("--nogui") or sys.argv.count("--g") or sys.argv.count("--help") or sys.argv.count("-h") > 0:
showGui = False
if __name__ == "__main__":
if showGui:
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frmMain = MyFrame(None, -1, "")
app.SetTopWindow(frmMain)
frmMain.Show()
# Command line arg plot file temp TODO proper
if sys.argv.count("--quiet") or sys.argv.count("--q"):
quiet = True
else:
quiet = False
if len(sys.argv) > 1:
frmMain.importPlot( stripQuotes(sys.argv[-1]), quiet )
app.MainLoop()
else:
print "TODO : Command line only mode"
if sys.argv.count("--help"):
print "Usage: reprapplot [OPTIONS] [FILE]..."
print "Option GNU long option Meaning"
print " -h --help Show this message"
print " -g --nogui Don't show GUI"
print " -q --quiet Don't ask questions"