class CirDrillPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "drill:circle") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Circular Drill Pattern %d" % CirDrillPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle CirDrillPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Diameter") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teDiameter = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teDiameter, "diameter") sizer.Add(self.teDiameter, pos=(ln, 1), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Hole Diameter") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teHoleDiam = wx.TextCtrl(self, wx.ID_ANY, "3", style=wx.TE_RIGHT) self.addWidget(self.teHoleDiam, "holediameter") sizer.Add(self.teHoleDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepover = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepover, "stepover") sizer.Add(self.teStepover, pos=(ln, 1), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=10) t = wx.StaticText(self, wx.ID_ANY, "Minimum space between") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teSpacing = wx.TextCtrl(self, wx.ID_ANY, "2", style=wx.TE_RIGHT) self.addWidget(self.teSpacing, "spacing") sizer.Add(self.teSpacing, pos=(ln, 3), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 szOpts = wx.BoxSizer(wx.VERTICAL) self.cbInside = wx.CheckBox(self, wx.ID_ANY, "Inside Circle") self.addWidget(self.cbInside, "inside") self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbInside) szOpts.Add(self.cbInside) szOpts.AddSpacer(10) self.cbStagger = wx.CheckBox(self, wx.ID_ANY, "Staggered rows") self.addWidget(self.cbStagger, "stagger") self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbStagger) szOpts.Add(self.cbStagger) szOpts2 = wx.BoxSizer(wx.HORIZONTAL) szOpts2.AddSpacer(80) szOpts2.Add(szOpts) sizer.Add(szOpts2, pos=(ln, 0), span=(1, 2), border=5, flag=wx.TOP+wx.BOTTOM+wx.LEFT+wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 3), border=5, flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Depth of Cut") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teDepth, "depth") sizer.Add(self.teDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbRetract = wx.CheckBox(self, wx.ID_ANY, "Retract each pass") self.addWidget(self.cbRetract, "retract") sizer.Add(self.cbRetract, pos=(ln, 2), span=(1,2), flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbRetract) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Center X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "centerx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Center Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "centery") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Center Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1,4), flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 1), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=10) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_VERTICAL) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1,4), flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT+wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit(); def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) sz.Add(r) self.addWidget(r, labels[i]) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbCutDir.append(r) return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Center X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Center Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Center Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG23 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: cdiam = float(self.teDiameter.GetValue()) except: errs.append("Overall Diameter") try: depth = float(self.teDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: hdiam = float(self.teHoleDiam.GetValue()) except: errs.append("Hole Diameter") try: spacing = float(self.teSpacing.GetValue()) except: errs.append("Spacing") try: stepover = float(self.teStepover.GetValue()) except: errs.append("Stepover") if not ValidateNoEntryErrors(self, errs): return inside = self.cbInside.IsChecked() stagger = self.cbStagger.IsChecked() retract = self.cbRetract.IsChecked() if not ValidateToolSize(self, tdiam, hdiam, "Hole Diameter"): return if not ValidateMinLength(self, cdiam, hdiam + spacing, "Overall diameter", "Hole diameter + spacing"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) if inside: radlimit = cdiam/2 - hdiam/2 else: radlimit = cdiam/2 minx = sx - cdiam/2 maxx = sx + cdiam/2 miny = sy - cdiam/2 maxy = sy + cdiam/2 cd = self.getChosen(self.rbCutDir) if cd == "Clockwise": cmd = "G2" else: cmd = "G3" nrows = int((maxy - miny)/(hdiam+spacing)) ncols = int((maxx - minx)/(hdiam+spacing)) if not ValidateNonZero(self, ncols, "Number of calculated columns"): return if not ValidateNonZero(self, nrows, "Number of calculated rows"): return xstep = (maxx - minx) / float(ncols) ystep = (maxy - miny) / float(nrows) if stagger: ystep *= 0.866 nrows = int((nrows/0.866)+0.5) if self.settings.annotate: self.gcode.append("(Circular drill pattern center (%6.2f,%6.2f) diameter %6.2f depth from %6.2f to %6.2f)" % (sx, sy, cdiam, sz, depth)) self.gcode.append("(Cut Direction: %s)" % cd) self.gcode.append("(Inside Circle: %s)" % str(inside)) self.gcode.append("(Retract each pass: %s)" % str(retract)) self.gcode.append("(Hole diameter: %6.2f)" % hdiam) self.gcode.append("(Stagger rows: %s)" % str(stagger)) self.gcode.append("(Calculated step x/y: %6.2f/%6.2f)" % (xstep, ystep)) self.gcode.append(("G0 Z"+self.fmt+self.speedTerm(addspeed, feedzG0)) % (safez)) points = [(sx, sy)] ix = 1 while sx + ix*xstep <= maxx: if ix*xstep <= radlimit: points = [(sx - ix*xstep, sy)] + points + [(sx + ix*xstep, sy)] ix += 1 iy = 1 while sy + iy*ystep <= maxy: rowu = [] rowd = [] ix = 0 if stagger and iy%2 != 0: bx = xstep/2 else: bx = 0 while sx + ix*xstep + bx <= maxx: r = triangulate((0,0), (ix*xstep+bx, iy*ystep)) if r <= radlimit: if bx == 0 and ix == 0: rowu.append((sx + ix*xstep + bx, sy + iy*ystep)) rowd.append((sx + ix*xstep + bx, sy - iy*ystep)) else: rowu = [(sx - ix*xstep - bx, sy + iy*ystep)] + rowu + [(sx + ix*xstep + bx, sy + iy*ystep)] rowd = [(sx - ix*xstep - bx, sy - iy*ystep)] + rowd + [(sx + ix*xstep + bx, sy - iy*ystep)] ix += 1 points = rowu + points + rowd iy += 1 passes = int(math.ceil(depth/passdepth)) for p in points: self.gcode.append(("G0 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG0)) % (p[0], p[1])) cz = sz for i in range(passes): cz -= passdepth if cz < -depth: cz = -depth self.gcode.append(("G1 Z"+self.fmt+self.speedTerm(addspeed, feedzG1)) % (cz)) if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) if hdiam > tdiam: maxyoff = (hdiam-tdiam)/2.0 yoff = stepover while True: if yoff > maxyoff: yoff = maxyoff self.gcode.append(("G1 Y"+self.fmt+self.speedTerm(addspeed, feedxyG0)) % (p[1]-yoff)) self.gcode.append((cmd+" J"+self.fmt+" X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG23)) % (yoff, p[0], p[1]-yoff)) if yoff >= maxyoff: break yoff += stepover self.gcode.append(("G1 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG23)) % (p[0], p[1])) if retract: self.gcode.append(("G0 Z"+self.fmt+self.speedTerm(addspeed, feedzG0)) % (safez)) if not retract: self.gcode.append(("G0 Z"+self.fmt+self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class GridPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "carve:hatch") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Cross Hatch Pattern %d" % GridPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle GridPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Total X Size") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSizeX = wx.TextCtrl(self, wx.ID_ANY, "100", style=wx.TE_RIGHT) self.addWidget(self.teSizeX, "sizex") sizer.Add(self.teSizeX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Total Y Size") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSizeY = wx.TextCtrl(self, wx.ID_ANY, "100", style=wx.TE_RIGHT) self.addWidget(self.teSizeY, "sizey") sizer.Add(self.teSizeY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Perpendicular Gap") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teGap = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teGap, "gap") sizer.Add(self.teGap, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiam") sizer.Add(self.teToolDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Angle") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teAngle = wx.TextCtrl(self, wx.ID_ANY, "45", style=wx.TE_RIGHT) self.addWidget(self.teAngle, "angle") sizer.Add(self.teAngle, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Y Offset") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teYOffset = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teYOffset, "yoffset") sizer.Add(self.teYOffset, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Starting Point") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getStartingPoints(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Add Border") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.cbBorder = wx.CheckBox(self, wx.ID_ANY) self.addWidget(self.cbBorder, "border") self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbBorder) sizer.Add(self.cbBorder, pos=(ln, 1), flag=wx.LEFT + wx.RIGHT + wx.ALIGN_CENTER_VERTICAL, border=10) t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getStartingPoints(self): labels = [ "Lower Left", "Upper Left", "Lower Right", "Upper Right", "Center" ] self.rbStartPoints = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbStartPoints.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) sz.Add(r) self.addWidget(r, labels[i]) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: totalx = float(self.teSizeX.GetValue()) except: errs.append("Size X") try: totaly = float(self.teSizeY.GetValue()) except: errs.append("Size Y") try: totaldepth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: angle = float(self.teAngle.GetValue()) except: errs.append("Angle") try: gap = float(self.teGap.GetValue()) except: errs.append("Perpendicular Gap") try: yoffset = float(self.teYOffset.GetValue()) except: errs.append("Y Offset") try: self.tDiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") if not ValidateNoEntryErrors(self, errs): return self.gcode = self.preamble(self.getChosen(self.rbMeas), self.tDiam, self.toolInfo, safez) border = self.cbBorder.IsChecked() addspeed = self.cbAddSpeed.IsChecked() plist = hatch(angle, sx, sy, sx + totalx, sy + totaly, gap, yoffset) sp = self.getChosen(self.rbStartPoints) adjx = 0 adjy = 0 if sp == "Upper Left": adjy = -totaly elif sp == "Upper Right": adjy = -totaly adjx = -totalx elif sp == "Lower Right": adjx = -totalx elif sp == "Center": adjx = -totalx / 2 adjy = -totaly / 2 points = [[[p[0][0] + adjx, p[0][1] + adjy], [p[1][0] + adjx, p[1][1] + adjy]] for p in plist] corners = [[sx + adjx, sy + adjy], [sx + adjx, sy + totaly + adjy], [sx + totalx + adjx, sy + totaly + adjy], [sx + totalx + adjx, sy + adjy]] passes = int(math.ceil(float(totaldepth) / float(passdepth))) if self.settings.annotate: self.gcode.append( "(Cross Hatch pattern start (%6.2f,%6.2f) width %6.2f height %6.2f depth from %6.2f to %6.2f)" % (sx, sy, totalx, totaly, sz, totaldepth)) self.gcode.append("(Start point: %s)" % sp) self.gcode.append("(Y offset: %6.2f)" % yoffset) self.gcode.append("(Cut border: %s)" % str(border)) self.gcode.append("(Gap: %6.2f)" % gap) self.gcode.append("(Angle: %6.2f)" % angle) depth = 0 flag = True for i in range(passes): depth += passdepth if depth > totaldepth: depth = totaldepth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, depth)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % safez) for p in points: if flag: xa = p[0][0] ya = p[0][1] xb = p[1][0] yb = p[1][1] else: xa = p[1][0] ya = p[1][1] xb = p[0][0] yb = p[0][1] flag = not flag self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (xa, ya)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (sz - depth)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (xb, yb)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if border: self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (corners[0][0], corners[0][1])) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (sz - depth)) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (corners[1][0], corners[1][1])) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (corners[2][0], corners[2][1])) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (corners[3][0], corners[3][1])) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (corners[0][0], corners[0][1])) self.gcode.append( ("G0 Z" + self.fmt + "" + self.speedTerm(addspeed, feedzG0) + "\n") % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (sx, sy)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class CirclePanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "contour:circle") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Circle %d" % CirclePanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle CirclePanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Circle Diameter") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDiam = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teDiam, "circlediameter") sizer.Add(self.teDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Center X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "centerx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Center Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "centery") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Center Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "centerz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G2/3)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Tool Movement") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getToolMovement(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 self.cbPocket = wx.CheckBox(self, wx.ID_ANY, "Pocket") self.addWidget(self.cbPocket, "pocket") sizer.Add(self.cbPocket, pos=(ln, 0), span=(1, 2), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbPocket) t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepOver = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepOver, "stepover") sizer.Add(self.teStepOver, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getToolMovement(self): labels = ["On Circle", "Outside Circle", "Inside Circle"] self.rbToolMove = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbToolMove.append(r) return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbCutDir.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Center X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Center Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Center Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG23 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: diam = float(self.teDiam.GetValue()) except: errs.append("Diameter") try: depth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: stepover = float(self.teStepOver.GetValue()) except: errs.append("Stepover") if not ValidateNoEntryErrors(self, errs): return if not ValidateToolSize(self, tdiam, diam, "Circle Diameter"): return if not ValidateRange(self, stepover, 0.001, 1.0, "Stepover", "0 < x <= 1.0"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) self.tDiam = tdiam if self.settings.annotate: self.gcode.append( "(Circle center (%6.2f,%6.2f) radius %6.2f depth from %6.2f to %6.2f" % (sx, sy, diam / 2, sz, depth)) tm = self.getChosen(self.rbToolMove) if tm == "Inside Circle": diam -= tdiam elif tm == "Outside Circle": diam += tdiam cd = self.getChosen(self.rbCutDir) if cd == "Clockwise": cmd = "G2" else: cmd = "G3" passes = int(math.ceil(depth / passdepth)) pkt = self.cbPocket.IsChecked() if self.settings.annotate: self.gcode.append("(Cutting direction: %s)" % cd) self.gcode.append("(Tool movement: %s)" % tm) self.gcode.append("(Pocket: %s)" % pkt) if not pkt: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (sx, sy - diam / 2)) cz = sz for i in range(passes): cz -= passdepth if cz < -depth: cz = -depth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) if pkt: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (sx, sy)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) r = tdiam * stepover while r < diam / 2: self.gcode.append( ("G1 Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (sy - r)) self.gcode.append( (cmd + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (r, sx, sy - r)) r += tdiam * stepover self.gcode.append( ("G1 Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (sy - diam / 2)) else: self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) self.gcode.append( (cmd + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (diam / 2, sx, sy - diam / 2)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable(True) self.bVisualize.Enable() self.setState(False, True)
class RectanglePanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "contour:rectangle") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Rectangle %d" % RectanglePanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle RectanglePanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Height") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teHeight = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teHeight, "height") sizer.Add(self.teHeight, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Width") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teWidth = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teWidth, "width") sizer.Add(self.teWidth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Rotation Angle") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teAngle = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teAngle, "angle") sizer.Add(self.teAngle, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Starting Point") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getStartingPoints(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Tool Movement") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getToolMovement(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Pocket") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getPockets(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepOver = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepOver, "stepover") sizer.Add(self.teStepOver, pos=(ln, 3), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getStartingPoints(self): labels = [ "Lower Left", "Upper Left", "Lower Right", "Upper Right", "Center" ] self.rbStartPoints = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbStartPoints.append(r) return sz def getToolMovement(self): labels = ["On Rectangle", "Outside Rectangle", "Inside Rectangle"] self.rbToolMove = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbToolMove.append(r) return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbCutDir.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def getPockets(self): labels = ["None", "Horizontal", "Vertical", "Centered"] self.rbPkts = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbPkts.append(r) return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: height = float(self.teHeight.GetValue()) except: errs.append("Height") try: width = float(self.teWidth.GetValue()) except: errs.append("Width") try: depth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: stepover = float(self.teStepOver.GetValue()) except: errs.append("Stepover") try: angle = float(self.teAngle.GetValue()) except: errs.append("Angle") if not ValidateNoEntryErrors(self, errs): return rot = Rotator(angle) if not ValidateToolSize(self, tdiam, height, "Height"): return if not ValidateToolSize(self, tdiam, width, "Width"): return if not ValidateRange(self, stepover, 0.001, 1.0, "Stepover", "0 < x <= 1.0"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) self.tDiam = tdiam if self.settings.annotate: if angle == 0: self.gcode.append( "(Rectangle (%6.2f,%6.2f) to (%6.2f,%6.2f) depth from %6.2f to %6.2f)" % (sx, sy, width, height, sz, depth)) else: rx1, ry1 = rot.rotate(sx, sy) rx2, ry2 = rot.rotate(width + sx, height + sy) self.gcode.append( "(Rectangle (%6.2f,%6.2f) to (%6.2f,%6.2f) depth from %6.2f to %6.2f rotated %6.2f)" % (rx1, ry1, rx2, ry2, sz, depth, angle)) points = [[sx, sy], [sx, sy + height], [sx + width, sy + height], [sx + width, sy], [sx, sy]] sp = self.getChosen(self.rbStartPoints) adjx = 0 adjy = 0 if sp == "Upper Left": adjy = -height elif sp == "Upper Right": adjy = -height adjx = -width elif sp == "Lower Right": adjx = -width elif sp == "Center": adjx = -width / 2 adjy = -height / 2 for p in points: p[0] += adjx p[1] += adjy tm = self.getChosen(self.rbToolMove) rad = float(tdiam) / 2.0 if tm == "Inside Rectangle": points[0][0] += rad points[0][1] += rad points[1][0] += rad points[1][1] -= rad points[2][0] -= rad points[2][1] -= rad points[3][0] -= rad points[3][1] += rad points[4][0] += rad points[4][1] += rad elif tm == "Outside Rectangle": points[0][0] -= rad points[0][1] -= rad points[1][0] -= rad points[1][1] += rad points[2][0] += rad points[2][1] += rad points[3][0] += rad points[3][1] -= rad points[4][0] -= rad points[4][1] -= rad cd = self.getChosen(self.rbCutDir) if cd != "Clockwise": np = points[::-1] points = np pkt = self.getChosen(self.rbPkts) if self.settings.annotate: self.gcode.append("(Start point: %s)" % sp) self.gcode.append("(Cutting direction: %s)" % cd) self.gcode.append("(Tool movement: %s)" % tm) self.gcode.append("(Pocket: %s)" % pkt) if pkt == "None": self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(points[0][0], points[0][1])) xmin = min(points[0][0], points[2][0]) + tdiam / 2 xmax = max(points[0][0], points[2][0]) - tdiam / 2 ymin = min(points[0][1], points[2][1]) + tdiam / 2 ymax = max(points[0][1], points[2][1]) - tdiam / 2 passes = int(math.ceil(depth / passdepth)) cz = sz xlast = 0 ylast = 0 for i in range(passes): cz -= passdepth if cz < -depth: cz = -depth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) if pkt == "Horizontal": first = True alt = True y = ymin self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(xmin, ymin)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) while y <= ymax: if not first: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xlast, y)) if alt: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xmax, y)) xlast = xmax else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xmin, y)) xlast = xmin y += tdiam * stepover first = False alt = not alt self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(points[0][0], points[0][1])) elif pkt == "Vertical": first = True alt = True x = xmin self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(xmin, ymin)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) while x <= xmax: if not first: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(x, ylast)) if alt: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(x, ymax)) ylast = ymax else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(x, ymin)) ylast = ymin x += tdiam * stepover first = False alt = not alt self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(points[0][0], points[0][1])) elif pkt == "Centered": vertical = False if (xmax - xmin) > (ymax - ymin): ya = (ymax + ymin) / 2.0 yb = ya d = ymax - ya xa = xmin + d xb = xmax - d elif (xmax - xmin) < (ymax - ymin): vertical = True xa = (xmax + xmin) / 2.0 xb = xa d = xmax - xa ya = ymin + d yb = ymax - d else: xa = (xmax + xmin) / 2.0 xb = xa ya = (ymax + ymin) / 2.0 yb = ya self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(xb, yb)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa, ya)) d = stepover * tdiam while (xa - d) >= xmin: if cd == "Clockwise": self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, ya - d)) if vertical: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, yb + d)) else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, ya + d)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xb + d, yb + d)) if vertical: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xb + d, ya - d)) else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xb + d, yb - d)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, ya - d)) else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, ya - d)) if vertical: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xb + d, ya - d)) else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xb + d, yb - d)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xb + d, yb + d)) if vertical: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, yb + d)) else: self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, ya + d)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(xa - d, ya - d)) d += stepover * tdiam self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % rot.rotate(points[0][0], points[0][1])) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) for p in points[1:]: self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % rot.rotate(p[0], p[1])) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class RecDrillPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "drill:rectangle") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Rectangular Drill Pattern %d" % RecDrillPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle RecDrillPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Height") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teHeight = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teHeight, "height") sizer.Add(self.teHeight, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Width") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teWidth = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teWidth, "width") sizer.Add(self.teWidth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Angle") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teAngle = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teAngle, "angle") sizer.Add(self.teAngle, pos=(ln, 3), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Hole Diameter") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teHoleDiam = wx.TextCtrl(self, wx.ID_ANY, "3", style=wx.TE_RIGHT) self.addWidget(self.teHoleDiam, "holediameter") sizer.Add(self.teHoleDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Minimum space between") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSpacing = wx.TextCtrl(self, wx.ID_ANY, "2", style=wx.TE_RIGHT) self.addWidget(self.teSpacing, "spacing") sizer.Add(self.teSpacing, pos=(ln, 3), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 szOpts = wx.BoxSizer(wx.VERTICAL) self.cbInside = wx.CheckBox(self, wx.ID_ANY, "Inside Rectangle") self.addWidget(self.cbInside, "inside") szOpts.AddSpacer(20) szOpts.Add(self.cbInside) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbInside) self.cbPerimeter = wx.CheckBox(self, wx.ID_ANY, "Perimeter Only") self.addWidget(self.cbPerimeter, "perimeter") szOpts.AddSpacer(10) szOpts.Add(self.cbPerimeter) self.Bind(wx.EVT_CHECKBOX, self.onCbPerimeter, self.cbPerimeter) self.cbStagger = wx.CheckBox(self, wx.ID_ANY, "Staggered rows") self.addWidget(self.cbStagger, "stagger") szOpts.AddSpacer(10) szOpts.Add(self.cbStagger) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbStagger) sizer.Add(szOpts, pos=(ln, 0), span=(2, 2), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Starting Point") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getStartingPoints(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Depth of Cut") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teDepth, "depth") sizer.Add(self.teDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbRetract = wx.CheckBox(self, wx.ID_ANY, "Retract after each pass") self.addWidget(self.cbRetract, "retract") sizer.Add(self.cbRetract, pos=(ln, 2), span=(1, 2), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbRetract) t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepover = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepover, "stepover") sizer.Add(self.teStepover, pos=(ln, 1), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 1), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getStartingPoints(self): labels = [ "Lower Left", "Upper Left", "Lower Right", "Upper Right", "Center" ] self.rbStartPoints = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) sz.Add(r) self.addWidget(r, labels[i]) self.rbStartPoints.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) sz.Add(r) self.addWidget(r, labels[i]) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbCutDir.append(r) return sz def onCbPerimeter(self, _): self.setState(True, False) flag = self.cbPerimeter.IsChecked() self.cbStagger.Enable(not flag) def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bVisualize.Enable(False) self.bSave.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: angle = float(self.teAngle.GetValue()) except: errs.append("Angle") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG23 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: height = float(self.teHeight.GetValue()) except: errs.append("Height") try: width = float(self.teWidth.GetValue()) except: errs.append("Width") try: depth = float(self.teDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: stepover = float(self.teStepover.GetValue()) except: errs.append("Stepover") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: hdiam = float(self.teHoleDiam.GetValue()) except: errs.append("Hole Diameter") try: spacing = float(self.teSpacing.GetValue()) except: errs.append("Spacing") if not ValidateNoEntryErrors(self, errs): return if not ValidateToolSize(self, tdiam, hdiam, "Hole Diameter"): return if not ValidateMinLength(self, height, hdiam + spacing, "Height", "Hole Diameter + Spacing"): return if not ValidateMinLength(self, width, hdiam + spacing, "Width", "Hole Diameter + Spacing"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) sp = self.getChosen(self.rbStartPoints) if sp == "Upper Left": sy -= height elif sp == "Upper Right": sy -= height sx -= width elif sp == "Lower Right": sx -= width elif sp == "Center": sx -= width / 2 sy -= height / 2 perimeteronly = self.cbPerimeter.IsChecked() inside = self.cbInside.IsChecked() if perimeteronly: stagger = False else: stagger = self.cbStagger.IsChecked() retract = self.cbRetract.IsChecked() if inside: minx = sx + hdiam / 2 maxx = sx + width - hdiam / 2 miny = sy + hdiam / 2 maxy = sy + height - hdiam / 2 else: minx = sx maxx = sx + width miny = sy maxy = sy + height cd = self.getChosen(self.rbCutDir) if cd == "Clockwise": cmd = "G2" else: cmd = "G3" nrows = int((maxy - miny) / (hdiam + spacing)) ncols = int((maxx - minx) / (hdiam + spacing)) xstep = (maxx - minx) / float(ncols) ystep = (maxy - miny) / float(nrows) if stagger: ystep *= 0.866 nrows = int((nrows / 0.866) + 0.5) cx = minx cy = miny rot = None if angle != 0: rot = Rotator(angle) if self.settings.annotate: self.gcode.append( "(Rectangular drill pattern start (%6.2f,%6.2f) height %6.2f width %6.2f depth from %6.2f to %6.2f)" % (sx, sy, height, width, sz, depth)) self.gcode.append("(Starting point: %s)" % sp) self.gcode.append("(Cut Direction: %s)" % cd) self.gcode.append("(Inside Circle: %s)" % str(inside)) self.gcode.append("(Perimeter Only: %s)" % str(perimeteronly)) self.gcode.append("(Retract each pass: %s)" % str(retract)) self.gcode.append("(Hole diameter: %6.2f)" % hdiam) self.gcode.append("(Stagger rows: %s)" % str(stagger)) self.gcode.append("(Calculated step x/y: %6.2f/%6.2f)" % (xstep, ystep)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) passes = int(math.ceil(depth / passdepth)) maxyoff = hdiam / 2 - tdiam / 2 for iy in range(nrows + 1): for ix in range(ncols + 1): includeHole = False if not perimeteronly: if cx <= maxx and cy <= maxy: includeHole = True else: if ix == 0 or ix == ncols or iy == 0 or iy == nrows: includeHole = True if includeHole: if rot is None: nx = cx ny = cy else: nx, ny = rot.rotate(cx, cy) self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (nx, ny)) cz = sz for i in range(passes): cz -= passdepth if cz < -depth: cz = -depth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) if hdiam > tdiam: maxyoff = (hdiam - tdiam) / 2.0 yoff = stepover while True: if yoff > maxyoff: yoff = maxyoff self.gcode.append( ("G1 Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (ny - yoff)) self.gcode.append( (cmd + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (yoff, nx, ny - yoff)) if yoff >= maxyoff: break yoff += stepover self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (nx, ny)) if retract: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if not retract: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) cx += xstep cy += ystep if stagger and iy % 2 == 0: cx = minx + xstep / 2 else: cx = minx if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.setState(False, True) self.bVisualize.Enable() self.bSave.Enable()
class LinDrillPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "drill:linear") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Linear Drill Pattern %d" % LinDrillPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle LinDrillPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safex") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Angle") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teAngle = wx.TextCtrl(self, wx.ID_ANY, "45", style=wx.TE_RIGHT) self.addWidget(self.teAngle, "angle") sizer.Add(self.teAngle, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Number of Holes") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teNHoles = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teNHoles, "numberholes") sizer.Add(self.teNHoles, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Hole Spacing") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSpacing = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teSpacing, "spacing") sizer.Add(self.teSpacing, pos=(ln, 1), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Hole Diameter") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teHoleDiam = wx.TextCtrl(self, wx.ID_ANY, "3", style=wx.TE_RIGHT) self.addWidget(self.teHoleDiam, "holediameter") sizer.Add(self.teHoleDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Step Over") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepover = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepover, "stepover") sizer.Add(self.teStepover, pos=(ln, 1), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) self.cbRetract = wx.CheckBox(self, wx.ID_ANY, "Retract each pass") self.addWidget(self.cbRetract, "retract") sizer.Add(self.cbRetract, pos=(ln, 2), span=(1, 2), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbRetract) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 1), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) sz.Add(r) self.addWidget(r, labels[i]) self.rbCutDir.append(r) return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG23 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: totaldepth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: hdiam = float(self.teHoleDiam.GetValue()) except: errs.append("Hole Diameter") try: spacing = float(self.teSpacing.GetValue()) except: errs.append("Spacing") try: nholes = int(self.teNHoles.GetValue()) except: errs.append("Number of Holes") try: angle = float(self.teAngle.GetValue()) except: errs.append("Angle") try: stepover = float(self.teStepover.GetValue()) except: errs.append("Stepover") if not ValidateNoEntryErrors(self, errs): return if not ValidateToolSize(self, tdiam, hdiam, "Hole Diameter"): return if not ValidateMinLength(self, spacing, hdiam, "Hole Spacing", "Hole Diameter"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) retract = self.cbRetract.IsChecked() cd = self.getChosen(self.rbCutDir) if cd == "Clockwise": cmd = "G2" else: cmd = "G3" dy = spacing * math.sin(math.radians(angle)) dx = spacing * math.cos(math.radians(angle)) if self.settings.annotate: self.gcode.append( "(Linear drill pattern start (%6.2f,%6.2f) Number of holes %d depth from %6.2f to %6.2f)" % (sx, sy, nholes, sz, totaldepth)) self.gcode.append("(Cut Direction: %s)" % cd) self.gcode.append("(Spacing: %6.2f)" % spacing) self.gcode.append("(Angle: %6.2f)" % angle) self.gcode.append("(Retract each pass: %s)" % str(retract)) self.gcode.append("(Hole diameter: %6.2f)" % hdiam) self.gcode.append("(Calculated step x/y: %6.2f/%6.2f)" % (dx, dy)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) passes = int(math.ceil(totaldepth / passdepth)) for ix in range(nholes): cx = sx + ix * dx cy = sy + ix * dy self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (cx, cy)) cz = sz for i in range(passes): cz -= passdepth if cz < -totaldepth: cz = -totaldepth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) if hdiam > tdiam: maxyoff = (hdiam - tdiam) / 2.0 yoff = stepover while True: if yoff > maxyoff: yoff = maxyoff self.gcode.append( ("G1 Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (cy - yoff)) self.gcode.append( (cmd + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (yoff, cx, cy - yoff)) if yoff >= maxyoff: break yoff += stepover self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG23)) % (cx, cy)) if retract: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if not retract: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class PolyPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "contour:polygon") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Regular Polygon %d" % PolyPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle PolyPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Side length") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSLength = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teSLength, "sidelength") sizer.Add(self.teSLength, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Number of Sides") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSides = wx.TextCtrl(self, wx.ID_ANY, "6", style=wx.TE_RIGHT) self.addWidget(self.teSides, "numbersides") sizer.Add(self.teSides, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Rotation Angle") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teAngle = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teAngle, "angle") sizer.Add(self.teAngle, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Center X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "centerx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Center Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "centery") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Center Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "centerz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Tool Movement") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getToolMovement(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 self.cbPocket = wx.CheckBox(self, wx.ID_ANY, "Pocket") self.addWidget(self.cbPocket, "pocket") sizer.Add(self.cbPocket, pos=(ln, 0), span=(1, 2), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbPocket) t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepOver = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepOver, "stepover") sizer.Add(self.teStepOver, pos=(ln, 3), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getToolMovement(self): labels = ["On Polygon", "Outside Polygon", "Inside Polygon"] self.rbToolMove = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbToolMove.append(r) return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbCutDir.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Center X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Center Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Center Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: length = float(self.teSLength.GetValue()) except: errs.append("Side Length") try: angle = float(self.teAngle.GetValue()) except: errs.append("Angle") try: depth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: stepover = float(self.teStepOver.GetValue()) except: errs.append("Stepover") try: sides = int(self.teSides.GetValue()) except: errs.append("Number of Sides") if not ValidateNoEntryErrors(self, errs): return if not ValidateRange(self, stepover, 0.001, 1.0, "Stepover", "0 < x <= 1.0"): return if not ValidateMinLength(self, sides, 3, "Mumber of Sides", "3"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) self.tDiam = tdiam if self.settings.annotate: self.gcode.append( "(Regular Polygon center at (%6.2f,%6.2f) depth from %6.2f to %6.2f" % (sx, sy, sz, depth)) step = 360.0 / sides a = 0 angles = [] while a < 360: angles.append(a + angle) a += step angles = angles[: sides] #make sure we didn't get an extra one because of rounding angles.append(angles[0]) cd = self.getChosen(self.rbCutDir) if cd == "Clockwise": na = angles[::-1] angles = na pkt = self.cbPocket.IsChecked() tm = self.getChosen(self.rbToolMove) if tm == "Inside Polygon": length -= tdiam / 2.0 elif tm == "Outside Polygon": length += tdiam / 2.0 passes = int(math.ceil(depth / passdepth)) if self.settings.annotate: self.gcode.append("(Cutting direction: %s)" % cd) self.gcode.append("(Tool movement: %s)" % tm) self.gcode.append("(Pocket: %s)" % pkt) cz = sz self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if not pkt: x = length * math.cos(math.radians(angles[0])) y = length * math.sin(math.radians(angles[0])) self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (x + sx, y + sy)) for i in range(passes): cz -= passdepth if cz < -depth: cz = -depth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) if pkt: self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (sx, sy)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) l = tdiam * stepover while l < length: self.gcode.append("(pocket pass at radius %f)" % l) for a in angles: x = l * math.cos(math.radians(a)) y = l * math.sin(math.radians(a)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (x + sx, y + sy)) l += tdiam * stepover self.gcode.append("(final pass)") for a in angles: x = length * math.cos(math.radians(a)) y = length * math.sin(math.radians(a)) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (x + sx, y + sy)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) else: self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) self.gcode.append("(contour only)") for a in angles[1:]: x = length * math.cos(math.radians(a)) y = length * math.sin(math.radians(a)) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (x + sx, y + sy)) if not pkt: self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class PolyPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "contour:polyline") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Polyline %d" % PolyPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle PolyPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Point List") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.tePoints = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_RIGHT + wx.TE_READONLY) self.addWidget(self.tePoints, "pointlist") sizer.Add(self.tePoints, pos=(ln, 1), span=(1,2), flag=wx.EXPAND, border=10) self.bEditPoints = wx.Button(self, wx.ID_ANY, "...", size=(30, 20)) self.bEditPoints.SetToolTip("Edit Point List") bsz = wx.BoxSizer(wx.HORIZONTAL) bsz.AddSpacer(20) bsz.Add(self.bEditPoints) sizer.Add(bsz, pos=(ln, 3)) self.Bind(wx.EVT_BUTTON, self.bEditPointsPressed, self.bEditPoints) ln += 1 self.cbClosePath = wx.CheckBox(self, wx.ID_ANY, "Close Path") self.addWidget(self.cbClosePath, "closepath") sizer.Add(self.cbClosePath, pos=(ln, 0), span=(1,4), flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbClosePath) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "totaldepth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1,4), flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Movement") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getToolMovement(), pos=(ln, 1), border=5, flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Tracks") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.scTracks = wx.SpinCtrl(self, wx.ID_ANY, "", size=(50, -1), style=wx.ALIGN_RIGHT) self.addWidget(self.scTracks, "tracks") self.scTracks.SetRange(1,20) self.scTracks.SetValue(1) self.Bind(wx.EVT_SPINCTRL, self.onTracks, self.scTracks) sz = wx.BoxSizer(wx.HORIZONTAL) sz.AddSpacer(30) sz.Add(self.scTracks) sizer.Add(sz, pos=(ln, 3), border=5, flag=wx.LEFT+wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepOver = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepOver, "stepover") sizer.Add(self.teStepOver, pos=(ln, 3), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 1), border=5, flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT+wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1,4), flag=wx.TOP+wx.BOTTOM+wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT+wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit(); def getToolMovement(self): labels = ["On Polyline", "Left of Forward", "Right of Forward"] self.rbToolMove = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbToolMove.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def onTracks(self, _): self.setState(True, False) def bEditPointsPressed(self, _): try: data = eval(self.tePoints.GetValue()) except: data = None minVal = 2 if self.cbClosePath.IsChecked(): minVal = 3 dlg = PointListEditDialog(self, data, minVal) rc = dlg.ShowModal() if rc == wx.ID_OK: self.tePoints.SetValue(str(dlg.getValues())) self.setState(True, False) dlg.Destroy() def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: data = eval(self.tePoints.GetValue()) except: errs.append("Point List") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") closePath = self.cbClosePath.IsChecked() addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: depth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: stepover = float(self.teStepOver.GetValue()) except: errs.append("Stepover") if not ValidateNoEntryErrors(self, errs): return if closePath and len(data) < 3: ValidateTrue(self, False, "Need >2 points for a closed path") return if not ValidateRange(self, stepover, 0.001, 1.0, "Stepover", "0 < x <= 1.0"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) self.tDiam = tdiam if self.settings.annotate: self.gcode.append("(Polyline depth from %6.2f to %6.2f" % (sz, depth)) tracks = self.scTracks.GetValue() tm = self.getChosen(self.rbToolMove) passes = int(math.ceil(depth/passdepth)) if tm == "Left of Forward": offset = tdiam/2.0 offset2 = stepover elif tm == "Right of Forward": offset = -tdiam/2.0 offset2 = -stepover else: offset = 0 offset2 = 0 if tracks != 1: dlg = wx.MessageDialog(self, "Cannot have more than 1 track when tool movement is \"On Polyline\".\nAssuming a value of 1.", 'Only 1 Track permitted', wx.OK | wx.ICON_WARNING) dlg.ShowModal() dlg.Destroy() tracks = 1 if offset != 0: data = offsetPath(data, offset, closePath) if data is None: ValidateTrue(self, False, "Unable to calculate offset path for track 0") return if self.settings.annotate: self.gcode.append("(Tool movement: %s)" % tm) self.gcode.append("(Tracks: %d)" % tracks) cz = sz - passdepth if cz < -depth: cz = -depth self.gcode.append(("G0 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG0)) % (data[0][0], data[0][1])) saveData = [x for x in data] for p in range(passes): if self.settings.annotate: self.gcode.append("(pass %d at depth %6.2f)" % (p, cz)) self.gcode.append(("G1 Z"+self.fmt+self.speedTerm(addspeed, feedzG1)) % (cz)) for trk in range(tracks): for pt in data[1:]: self.gcode.append(("G1 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG1)) % (pt[0], pt[1])) if closePath: self.gcode.append(("G1 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG1)) % (data[0][0], data[0][1])) else: self.gcode.append(("G0 Z"+self.fmt+self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG1)) % (data[0][0], data[0][1])) self.gcode.append(("G1 Z"+self.fmt+self.speedTerm(addspeed, feedzG1)) % (cz)) if trk+1 < tracks: # if not last track data = offsetPath(data, offset2, closePath) if data is None: ValidateTrue(self, False, "Unable to calculate offset path for track %d" % (trk+1)) return self.gcode.append(("G1 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG1)) % (data[0][0], data[0][1])) data = [x for x in saveData] self.gcode.append(("G1 X"+self.fmt+" Y"+self.fmt+self.speedTerm(addspeed, feedxyG1)) % (data[0][0], data[0][1])) cz -= passdepth if cz < -depth: cz = -depth self.gcode.append(("G0 Z"+self.fmt+self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class GridPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "carve:grid") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Grid Pattern %d" % GridPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle GridPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Total X Size") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSizeX = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teSizeX, "sizex") sizer.Add(self.teSizeX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Total Y Size") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSizeY = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teSizeY, "sizey") sizer.Add(self.teSizeY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "X Segments") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teXSegments = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teXSegments, "xsegments") sizer.Add(self.teXSegments, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Y Segments") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teYSegments = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teYSegments, "ysegments") sizer.Add(self.teYSegments, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 1), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Starting Point") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getStartingPoints(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getStartingPoints(self): labels = [ "Lower Left", "Upper Left", "Lower Right", "Upper Right", "Center" ] self.rbStartPoints = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbStartPoints.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) sz.Add(r) self.addWidget(r, labels[i]) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: sizex = float(self.teSizeX.GetValue()) except: errs.append("Size X") try: sizey = float(self.teSizeY.GetValue()) except: errs.append("Size Y") try: totaldepth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: segmentx = int(self.teXSegments.GetValue()) except: errs.append("X Segments") try: segmenty = int(self.teYSegments.GetValue()) except: errs.append("Y Segments") try: self.tDiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") if not ValidateNoEntryErrors(self, errs): return self.gcode = self.preamble(self.getChosen(self.rbMeas), self.tDiam, self.toolInfo, safez) addspeed = self.cbAddSpeed.IsChecked() segszx = sizex / segmentx segszy = sizey / segmenty sp = self.getChosen(self.rbStartPoints) adjx = 0 adjy = 0 if sp == "Upper Left": adjy = -sizey elif sp == "Upper Right": adjy = -sizey adjx = -sizex elif sp == "Lower Right": adjx = -sizex elif sp == "Center": adjx = -sizex / 2 adjy = -sizey / 2 xvals = [sx + i * segszx + adjx for i in range(segmentx + 1)] yvals = [sy + i * segszy + adjy for i in range(segmenty + 1)] points = [] flag = False for i in range(0, segmentx + 1): if not flag: points.append([xvals[i], yvals[0], xvals[i], yvals[-1]]) else: points.append([xvals[i], yvals[-1], xvals[i], yvals[0]]) flag = not flag flag = False for i in range(0, segmenty + 1): if not flag: points.append([xvals[0], yvals[i], xvals[-1], yvals[i]]) else: points.append([xvals[-1], yvals[i], xvals[0], yvals[i]]) flag = not flag passes = int(math.ceil(float(totaldepth) / float(passdepth))) if self.settings.annotate: self.gcode.append( "(Grid pattern start (%6.2f,%6.2f) width %6.2f height %6.2f segments %d,%d depth from %6.2f to %6.2f)" % (sx, sy, sizex, sizey, segmentx, segmenty, sz, totaldepth)) self.gcode.append("(Start point: %s)" % sp) depth = 0 for i in range(passes): depth += passdepth if depth > totaldepth: depth = totaldepth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, depth)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % safez) for p in points: self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (p[0], p[1])) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (sz - depth)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (p[2], p[3])) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (sx, sy)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)
class SlotPanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "contour:slot") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Rounded Slot %d" % SlotPanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle SlotPanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.Bind(wx.EVT_CLOSE, self.onClose) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 self.setTitleFlag() t = wx.StaticText(self, wx.ID_ANY, "Length") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teLength = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teLength, "length") sizer.Add(self.teLength, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Width") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teWidth = wx.TextCtrl(self, wx.ID_ANY, "10", style=wx.TE_RIGHT) self.addWidget(self.teWidth, "width") sizer.Add(self.teWidth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Rotation Angle") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teAngle = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teAngle, "angle") sizer.Add(self.teAngle, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Starting Point") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getStartingPoints(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Tool Movement") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getToolMovement(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Cutting Direction") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getCuttingDirection(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 self.cbPocket = wx.CheckBox(self, wx.ID_ANY, "Pocket") self.addWidget(self.cbPocket, "pocket") sizer.Add(self.cbPocket, pos=(ln, 0), span=(1, 2), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onChange, self.cbPocket) t = wx.StaticText(self, wx.ID_ANY, "Stepover") so = "%6.3f" % speedInfo["stepover"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStepOver = wx.TextCtrl(self, wx.ID_ANY, so, style=wx.TE_RIGHT) self.addWidget(self.teStepOver, "stepover") sizer.Add(self.teStepOver, pos=(ln, 3), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getStartingPoints(self): labels = [ "Lower Left", "Upper Left", "Lower Right", "Upper Right", "Center" ] self.rbStartPoints = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbStartPoints.append(r) return sz def getToolMovement(self): labels = ["On Perimeter", "Outside", "Inside"] self.rbToolMove = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbToolMove.append(r) return sz def getCuttingDirection(self): labels = ["Clockwise", "Counter Clockwise"] self.rbCutDir = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbCutDir.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: self.safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") self.addspeed = self.cbAddSpeed.IsChecked() try: self.feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: self.feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: self.feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: self.feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: length = float(self.teLength.GetValue()) except: errs.append("Length") try: width = float(self.teWidth.GetValue()) except: errs.append("Width") try: self.depth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: self.passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") try: stepover = float(self.teStepOver.GetValue()) except: errs.append("Stepover") try: angle = float(self.teAngle.GetValue()) except: errs.append("Angle") if not ValidateNoEntryErrors(self, errs): return if not ValidateToolSize(self, tdiam, length, "Length"): return if not ValidateToolSize(self, tdiam, width, "Width"): return if not ValidateRange(self, stepover, 0.001, 1.0, "Stepover", "0 < x <= 1.0"): return if not ValidateMinLength(self, length, width, "Length", "Width"): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, self.safez) self.tDiam = tdiam if self.settings.annotate: self.gcode.append( "(Rounded slot start (%6.2f,%6.2f) length %6.2f width %6.2f depth from %6.2f to %6.2f)" % (sx, sy, width, length, sz, self.depth)) length -= width points = [[sx, sy], [sx, sy + width], [sx + length, sy + width], [sx + length, sy]] centers = [[sx, sy + width / 2], [sx + length, sy + width / 2]] sp = self.getChosen(self.rbStartPoints) adjx = 0 adjy = 0 if sp == "Upper Left": adjy = -width elif sp == "Upper Right": adjy = -width adjx = -length elif sp == "Lower Right": adjx = -length elif sp == "Center": adjx = -length / 2 adjy = -width / 2 for p in points: p[0] += adjx p[1] += adjy for c in centers: c[0] += adjx c[1] += adjy tm = self.getChosen(self.rbToolMove) rad = float(tdiam) / 2.0 if tm == "Inside": points[0][1] += rad points[1][1] -= rad points[2][1] -= rad points[3][1] += rad elif tm == "Outside": points[0][1] -= rad points[1][1] += rad points[2][1] += rad points[3][1] -= rad np = [] nc = [] cosv = math.cos(math.radians(angle)) sinv = math.sin(math.radians(angle)) for p in points: np.append([p[0] * cosv - p[1] * sinv, p[0] * sinv + p[1] * cosv]) for c in centers: nc.append([c[0] * cosv - c[1] * sinv, c[0] * sinv + c[1] * cosv]) cd = self.getChosen(self.rbCutDir) clockwise = True if cd != "Clockwise": clockwise = False pkt = self.cbPocket.IsChecked() if self.settings.annotate: self.gcode.append("(Start point: %s)" % sp) self.gcode.append("(Cutting direction: %s)" % cd) self.gcode.append("(Tool movement: %s)" % tm) self.gcode.append("(Pocket: %s)" % pkt) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(self.addspeed, self.feedzG0)) % (self.safez)) passes = int(math.ceil(self.depth / self.passdepth)) cz = sz for i in range(passes): cz -= self.passdepth if cz < -self.depth: cz = -self.depth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) if pkt: self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG0)) % (nc[1][0], nc[1][1])) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(self.addspeed, self.feedzG1)) % (cz)) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (nc[0][0], nc[0][1])) d = centers[0][1] - points[0][1] cd = stepover * tdiam while cd < d: pc = [p for p in centers] pp = [[pc[0][0], pc[0][1] - cd], [pc[0][0], pc[0][1] + cd], [pc[1][0], pc[1][1] + cd], [pc[1][0], pc[1][1] - cd]] npp = [] npc = [] for p in pp: npp.append([ p[0] * cosv - p[1] * sinv, p[0] * sinv + p[1] * cosv ]) for c in pc: npc.append([ c[0] * cosv - c[1] * sinv, c[0] * sinv + c[1] * cosv ]) self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (npp[0][0], npp[0][1])) self.loop(npp, npc, clockwise) cd += stepover * tdiam self.gcode.append( ("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (np[0][0], np[0][1])) else: self.gcode.append( ("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG0)) % (np[0][0], np[0][1])) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(self.addspeed, self.feedzG1)) % (cz)) self.loop(np, nc, clockwise) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(self.addspeed, self.feedzG0)) % (self.safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True) def loop(self, points, centers, clockwise): cmd = "G3" if clockwise: cmd = "G2" if clockwise: self.gcode.append( (cmd + " I" + self.fmt + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (centers[0][0] - points[0][0], centers[0][1] - points[0][1], points[1][0], points[1][1])) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (points[2][0], points[2][1])) self.gcode.append( (cmd + " I" + self.fmt + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (centers[1][0] - points[2][0], centers[1][1] - points[2][1], points[3][0], points[3][1])) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (points[0][0], points[0][1])) else: self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (points[3][0], points[3][1])) self.gcode.append( (cmd + " I" + self.fmt + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (centers[1][0] - points[3][0], centers[1][1] - points[3][1], points[2][0], points[2][1])) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (points[1][0], points[1][1])) self.gcode.append( (cmd + " I" + self.fmt + " J" + self.fmt + " X" + self.fmt + " Y" + self.fmt + self.speedTerm(self.addspeed, self.feedxyG1)) % (centers[0][0] - points[1][0], centers[0][1] - points[1][1], points[0][0], points[0][1]))
class LinePanel(wx.Panel, CNCObject): seqNo = 1 def __init__(self, toolInfo, speedInfo, parent): CNCObject.__init__(self, parent, "contour:line") self.toolInfo = toolInfo self.modified = False self.unsaved = False self.viewTitle = "Line %d" % LinePanel.seqNo self.titleText = "G Code Generator: %s" % self.viewTitle self.setTitleFlag() LinePanel.seqNo += 1 wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.TAB_TRAVERSAL) sizer = wx.GridBagSizer(wx.HORIZONTAL) sizer.Add(10, 10, wx.GBPosition(0, 4)) ln = 1 t = wx.StaticText(self, wx.ID_ANY, "Start X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartX = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartX, "startx") sizer.Add(self.teStartX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Start Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartY = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartY, "starty") sizer.Add(self.teStartY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "End X") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teEndX = wx.TextCtrl(self, wx.ID_ANY, "100", style=wx.TE_RIGHT) self.addWidget(self.teEndX, "endx") sizer.Add(self.teEndX, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "End Y") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teEndY = wx.TextCtrl(self, wx.ID_ANY, "100", style=wx.TE_RIGHT) self.addWidget(self.teEndY, "endy") sizer.Add(self.teEndY, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Start Z") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teStartZ = wx.TextCtrl(self, wx.ID_ANY, "0", style=wx.TE_RIGHT) self.addWidget(self.teStartZ, "startz") sizer.Add(self.teStartZ, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Safe Z above surface") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teSafeZ = wx.TextCtrl(self, wx.ID_ANY, "0.5", style=wx.TE_RIGHT) self.addWidget(self.teSafeZ, "safez") sizer.Add(self.teSafeZ, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Total Depth") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teTotalDepth = wx.TextCtrl(self, wx.ID_ANY, "1", style=wx.TE_RIGHT) self.addWidget(self.teTotalDepth, "depth") sizer.Add(self.teTotalDepth, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Depth/Pass") dpp = "%6.3f" % speedInfo["depthperpass"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.tePassDepth = wx.TextCtrl(self, wx.ID_ANY, dpp, style=wx.TE_RIGHT) self.addWidget(self.tePassDepth, "passdepth") sizer.Add(self.tePassDepth, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 self.cbAddSpeed = wx.CheckBox(self, wx.ID_ANY, "Add Speed Parameter") self.addWidget(self.cbAddSpeed, "addspeed") sizer.Add(self.cbAddSpeed, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) self.Bind(wx.EVT_CHECKBOX, self.onCbAddSpeed, self.cbAddSpeed) self.cbAddSpeed.SetValue(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G0)") g0xy = "%7.2f" % speedInfo["G0XY"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG0 = wx.TextCtrl(self, wx.ID_ANY, g0xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG0, "feedXYG0") sizer.Add(self.teFeedXYG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate XY (G1)") g1xy = "%7.2f" % speedInfo["G1XY"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedXYG1 = wx.TextCtrl(self, wx.ID_ANY, g1xy, style=wx.TE_RIGHT) self.addWidget(self.teFeedXYG1, "feedXYG1") sizer.Add(self.teFeedXYG1, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G0)") g0z = "%7.2f" % speedInfo["G0Z"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG0 = wx.TextCtrl(self, wx.ID_ANY, g0z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG0, "feedZG0") sizer.Add(self.teFeedZG0, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Feed Rate Z (G1)") g1z = "%7.2f" % speedInfo["G1Z"] sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teFeedZG1 = wx.TextCtrl(self, wx.ID_ANY, g1z, style=wx.TE_RIGHT) self.addWidget(self.teFeedZG1, "feedZG1") sizer.Add(self.teFeedZG1, pos=(ln, 3), flag=wx.LEFT, border=10) self.teFeedXYG0.Enable(self.settings.addspeed) self.teFeedXYG1.Enable(self.settings.addspeed) self.teFeedZG0.Enable(self.settings.addspeed) self.teFeedZG1.Enable(self.settings.addspeed) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Diameter") td = "%6.3f" % toolInfo["diameter"] sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teToolDiam = wx.TextCtrl(self, wx.ID_ANY, td, style=wx.TE_RIGHT) self.addWidget(self.teToolDiam, "tooldiameter") sizer.Add(self.teToolDiam, pos=(ln, 1), flag=wx.LEFT, border=10) t = wx.StaticText(self, wx.ID_ANY, "Decimal Places") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) self.teDecimals = wx.TextCtrl(self, wx.ID_ANY, "4", style=wx.TE_RIGHT) self.addWidget(self.teDecimals, "decimals") sizer.Add(self.teDecimals, pos=(ln, 3), flag=wx.LEFT, border=10) ln += 1 t = wx.StaticText(self, wx.ID_ANY, "Tool Movement") sizer.Add(t, pos=(ln, 0), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getToolMovement(), pos=(ln, 1), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) t = wx.StaticText(self, wx.ID_ANY, "Measurement System") sizer.Add(t, pos=(ln, 2), flag=wx.LEFT + wx.ALIGN_CENTER_VERTICAL, border=20) sizer.Add(self.getMeasurementSystem(), pos=(ln, 3), border=5, flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_VERTICAL) ln += 1 sizer.Add(20, 20, wx.GBPosition(ln, 0)) ln += 1 bsz = self.buttons() sizer.Add(bsz, pos=(ln, 0), span=(1, 4), flag=wx.TOP + wx.BOTTOM + wx.ALIGN_CENTER_HORIZONTAL, border=5) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) ln += 1 self.gcl = GCodeList(self) sizer.Add(self.gcl, pos=(ln, 0), span=(1, 4), flag=wx.LEFT + wx.EXPAND, border=10) ln += 1 sizer.Add(10, 10, wx.GBPosition(ln, 0)) self.Bind(wx.EVT_TEXT, self.onChange) self.Bind(wx.EVT_RADIOBUTTON, self.onChange) self.SetSizer(sizer) self.Layout() self.Fit() def getToolMovement(self): labels = [ "Centered", "Left of forward motion", "Right of forward motion" ] self.rbToolMove = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbToolMove.append(r) return sz def getMeasurementSystem(self): labels = ["Metric", "Imperial"] self.rbMeas = [] sz = wx.BoxSizer(wx.VERTICAL) for i in range(len(labels)): if i == 0: style = wx.RB_GROUP else: style = 0 r = wx.RadioButton(self, wx.ID_ANY, labels[i], style=style) self.addWidget(r, labels[i]) sz.Add(r) self.rbMeas.append(r) if self.settings.metric: self.setChosen(self.rbMeas, "Metric") else: self.setChosen(self.rbMeas, "Imperial") return sz def onCbAddSpeed(self, _): self.setState(True, False) flag = self.cbAddSpeed.IsChecked() self.teFeedXYG0.Enable(flag) self.teFeedXYG1.Enable(flag) self.teFeedZG0.Enable(flag) self.teFeedZG1.Enable(flag) def bGeneratePressed(self, _): self.bSave.Enable(False) self.bVisualize.Enable(False) self.gcl.clear() self.gcode = [] errs = [] try: dec = int(self.teDecimals.GetValue()) self.fmt = "%0." + str(dec) + "f" except: errs.append("Decimal Places") try: sx = float(self.teStartX.GetValue()) except: errs.append("Start X") try: sy = float(self.teStartY.GetValue()) except: errs.append("Start Y") try: ex = float(self.teEndX.GetValue()) except: errs.append("End X") try: ey = float(self.teEndY.GetValue()) except: errs.append("End Y") try: sz = float(self.teStartZ.GetValue()) except: errs.append("Start Z") try: safez = float(self.teSafeZ.GetValue()) except: errs.append("Safe Z") addspeed = self.cbAddSpeed.IsChecked() try: feedzG0 = float(self.teFeedZG0.GetValue()) except: errs.append("Z G0 Speed") try: feedzG1 = float(self.teFeedZG1.GetValue()) except: errs.append("Z G1 Speed") try: feedxyG0 = float(self.teFeedXYG0.GetValue()) except: errs.append("XY G0 Speed") try: feedxyG1 = float(self.teFeedXYG1.GetValue()) except: errs.append("XY G1 Speed") try: depth = float(self.teTotalDepth.GetValue()) except: errs.append("Depth") try: passdepth = float(self.tePassDepth.GetValue()) except: errs.append("Depth per Pass") try: tdiam = float(self.teToolDiam.GetValue()) except: errs.append("Tool Diameter") if not ValidateNoEntryErrors(self, errs): return self.gcode = self.preamble(self.getChosen(self.rbMeas), tdiam, self.toolInfo, safez) self.tDiam = tdiam rise = float(ey) - float(sy) run = float(ex) - float(sx) sign = 1 if run < 0: sign = -1 if run == 0: trise = 0 if rise > 0: trun = -tdiam / 2 else: trun = tdiam / 2 else: angler = math.atan(rise / run) trise = sign * math.cos(angler) * tdiam / 2 trun = sign * (-(math.sin(angler) * tdiam / 2)) tm = self.getChosen(self.rbToolMove) if tm == "Left of forward motion": sx += trun ex += trun sy += trise ey += trise elif tm == "Right of forward motion": sx -= trun ex -= trun sy -= trise ey -= trise if self.settings.annotate: self.gcode.append("(Tool movement: %s)" % tm) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) passes = int(math.ceil(depth / passdepth)) if self.settings.annotate: self.gcode.append( "(Line (%6.2f,%6.2f) to (%6.2f,%6.2f) depth from %6.2f to %6.2f)" % (sx, sy, ex, ey, sz, depth)) cz = sz for i in range(passes): cz -= passdepth if cz < -depth: cz = -depth if self.settings.annotate: self.gcode.append("(Pass number %d at depth %f)" % (i, cz)) self.gcode.append(("G0 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG0)) % (sx, sy)) self.gcode.append( ("G1 Z" + self.fmt + self.speedTerm(addspeed, feedzG1)) % (cz)) self.gcode.append(("G1 X" + self.fmt + " Y" + self.fmt + self.speedTerm(addspeed, feedxyG1)) % (ex, ey)) self.gcode.append( ("G0 Z" + self.fmt + self.speedTerm(addspeed, feedzG0)) % (safez)) if self.settings.annotate: self.gcode.append("(End object %s)" % self.viewTitle) self.gcl.updateList(self.gcode) self.bSave.Enable() self.bVisualize.Enable() self.setState(False, True)