def read_pcb(): global vertices, faces, boundarys, toolpaths, contours, slices, \ uiparams, noise_flag, tracks, gerber_data definedFileTypes = [('gerber', '.gbl .gtl .gbr .cmp'), \ ('drill files', '.drl .dbd'), ('all files', '.*')] filename = askopenfilename(filetypes=definedFileTypes) if ((find(filename, ".cmp") != -1) | (find(filename, ".CMP") != -1) \ | (find(filename, ".gtl") != -1) | (find(filename, ".GTL") != -1) \ | (find(filename, ".gbl") != -1) | (find(filename, ".GBL") != -1)): print "reading Gerber file", filename uiparams.scale = 1 uiparams.panx = 0 uiparams.pany = 0 contours = [] toolpaths = [] infilepcb.set('') infileedge.set('') infiledrill.set('') if (find(filename, ".") != -1): index2 = find(filename, ".") if (find(filename, "/") != -1): index1 = find(filename, "/") while (find(filename[index1 + 1:index2], "/") != -1): index1 = index1 + 1 + find(filename[index1 + 1:index2], "/") infilepcb.set(filename[index1 + 1:index2]) [gerber_data,tracks] = load_file(filename) status.set("Gerber read ok") read(0)
def read_edge(): global vertices, faces, boundarys, toolpaths, contours, slices, \ uiparams, noise_flag, tracks, gerber_data # # read edge file # definedFileTypes = [('gerber', '.gbl .gtl .gbr .cmp'), \ ('drill files', '.drl .dbd'), ('all files', '.*')] filename = askopenfilename(filetypes=definedFileTypes) if ((find(filename, ".gbr") != -1) | (find(filename, ".GBR") != -1)): print "reading PCB edge file", filename # Load data in SEPARATE data object [gerber_data2,edges] = load_file(filename) brdoutline = [] brdseg = -1 while len(edges) > 0: brdoutline.append([]) brdseg += 1 brdoutline[brdseg].extend(edges[0]) edges.remove(edges[0]) startpnt = brdoutline[brdseg][0] endpnt = brdoutline[brdseg][len(brdoutline[brdseg]) - 1] while (abs(startpnt[0] - endpnt[0]) > 10) | (abs(startpnt[1] - endpnt[1]) > 10): for seg in edges: if abs(seg[0][0] - endpnt[0]) < 10: if abs(seg[0][1] - endpnt[1]) < 10: brdoutline[brdseg].extend(seg) edges.remove(seg) endpnt = brdoutline[brdseg][len(brdoutline[brdseg]) - 1] continue if abs(seg[len(seg) - 1][0] - endpnt[0]) < 10: if abs(seg[len(seg) - 1][1] - endpnt[1]) < 10: edges.remove(seg) seg = seg[::-1] brdoutline[brdseg].extend(seg) endpnt = brdoutline[brdseg][len(brdoutline[brdseg]) - 1] pcb_edges = brdoutline pcb_edges = pyclipper.CleanPolygons(pcb_edges) # Remove existing edge layers = list(gerber_data.layers) for gl in layers: if gl.type == GerberLayer.TYPE_PCBEDGE: gerber_data.layers.remove(gl) # Add edge data to existing data gerber_data.layers.append(GerberReader.GerberLayer(True, "PCB Edge", pcb_edges, True, False, "blue", GerberLayer.TYPE_PCBEDGE)) toolpaths = [] if (find(filename, ".") != -1): index2 = find(filename, ".") if (find(filename, "/") != -1): index1 = find(filename, "/") while (find(filename[index1 + 1:index2], "/") != -1): index1 = index1 + 1 + find(filename[index1 + 1:index2], "/") infileedge.set(filename[index1 + 1:index2]) read(0)
def LoadEdgeFile(self, evt): if self.data is None: dlg = wx.MessageDialog(self, "You must load a Gerber file first", "Error", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return dlg = wx.FileDialog(self, "Open edge file", "", "", "Gerber Files (*.gml;*.gbl;*.gtl;*.gbr;*.cmp)|*.gml;*.gbl;*.gtl;*.gbr;*.cmp|All Files (*.*)|*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) if dlg.ShowModal() == wx.ID_CANCEL: self.SetStatusText("Load edge file cancelled by user", 0) return filename = dlg.GetPath() dlg.Destroy() self.SetStatusText("Loading edge: " + filename + "...", 0) [data, edges] = load_file(filename) brdoutline = [] brdseg = -1 while len(edges) > 0: brdoutline.append([]) brdseg += 1 brdoutline[brdseg].extend(edges[0]) edges.remove(edges[0]) startpnt = brdoutline[brdseg][0] endpnt = brdoutline[brdseg][len(brdoutline[brdseg]) - 1] while (abs(startpnt[0] - endpnt[0]) > 10) | (abs(startpnt[1] - endpnt[1]) > 10): found = False for seg in edges: if abs(seg[0][0] - endpnt[0]) < 10: if abs(seg[0][1] - endpnt[1]) < 10: brdoutline[brdseg].extend(seg) edges.remove(seg) endpnt = brdoutline[brdseg][len(brdoutline[brdseg]) - 1] found = True break if abs(seg[len(seg) - 1][0] - endpnt[0]) < 10: if abs(seg[len(seg) - 1][1] - endpnt[1]) < 10: edges.remove(seg) seg = seg[::-1] brdoutline[brdseg].extend(seg) endpnt = brdoutline[brdseg][len(brdoutline[brdseg]) - 1] found = True break if not found: dlg = wx.MessageDialog(self, "Edge outline cannot contain any gaps.\n" "No changes were made.", "Load edge file failed", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() self.SetStatusText("Load edge failed", 0) return xmin = 1E99 xmax = -1E99 ymin = 1E99 ymax = -1E99 if data.units == self.data.units: for poly in brdoutline: for (x, y) in poly: if x < xmin: xmin = x if x > xmax: xmax = x if y < ymin: ymin = y if y > ymax: ymax = y else: # finx bounds and convert units of data at same time conv = 25.4 if data.units == 1 else 1/25.4 print " Unit conversion of edge file data" for poly in brdoutline: for pt in poly: x = pt[0] = int(pt[0] * conv) y = pt[1] = int(pt[1] * conv) if x < xmin: xmin = x if x > xmax: xmax = x if y < ymin: ymin = y if y > ymax: ymax = y # Check if PCB fits inside edge. We're lazy so we just use box bounds (should really use # polygon bounds checking). eps = 10 if self.data.xmin2 + eps < xmin or self.data.xmax2 - eps > xmax or \ self.data.ymin2 + eps < ymin or self.data.ymax2 - eps > ymax: print self.data.xmin, xmin print self.data.ymin, ymin print self.data.xmax, xmax print self.data.ymax, ymax dlg = wx.MessageDialog(self, "The loaded edge does not fully contain the PCB board.\n" "Do you still wish to proceed using this edge file?", "PCB board extends past edge boundary", wx.YES | wx.NO | wx.ICON_WARNING) ans = dlg.ShowModal() dlg.Destroy() if ans != wx.ID_YES: self.SetStatusText("Load edge file cancelled by user", 0) return self.data.xmin = xmin self.data.xmax = xmax self.data.ymin = ymin self.data.ymax = ymax # View bounds # Includes the origin if xmin > 0: xmin = 0 if xmax < 0: xmax = 0 if ymin > 0: ymin = 0 if ymax < 0: ymax = 0 # Add margin ww = (xmax - xmin)*0.1 hh = (ymax - ymin)*0.1 xmin -= ww xmax += ww ymin -= hh ymax += hh pcb_edges = brdoutline pcb_edges = pyclipper.CleanPolygons(pcb_edges) for poly in pcb_edges: poly.append(poly[0]) # close off polygons # Remove existing edge layers = list(self.data.layers) for gl in layers: if gl.type == GerberLayer.TYPE_PCBEDGE: self.data.layers.remove(gl) # Add edge data to existing data self.data.layers.insert(-1, GerberLayer(True, "PCB Edge", pcb_edges, True, False, "blue", GerberLayer.TYPE_PCBEDGE)) self.pcb_edges = pcb_edges self.canvas.toolpaths = [] self.canvas.loadData2(self.data, xmin, xmax, ymin, ymax) self.layersPanel.loadLayersPanel(self.data, self.NotifyDataChange) self.SetStatusText("Load edge file completed successfully", 0)
def LoadGerberFile(self, evt): dlg = wx.FileDialog(self, "Open Gerber file", "", "", "Gerber Files (*.gbl;*.gtl;*.gbr;*.cmp)|*.gbl;*.gtl;*.gbr;*.cmp|All Files (*.*)|*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) if dlg.ShowModal() == wx.ID_CANCEL: self.SetStatusText("Load Gerber file cancelled by user", 0) return filename = dlg.GetPath() dlg.Destroy() self.SetStatusText("Loading Gerber: " + filename + "...", 0) [data, tracks] = load_file(filename) self.data = data xmin = 1E99 xmax = -1E99 ymin = 1E99 ymax = -1E99 sum1 = 0 sumReg = 0 sumBound = 0 sumTracks = 0 sumPads = 0 cbounds = pyclipper.Pyclipper() boundarys = [] pcb_edges = [] layers = list(data.layers) for gl in layers: if gl.type == GerberLayer.TYPE_PCBEDGE: data.layers.remove(gl) pcb_edges.extend(gl.points) for segment in gl.points: sum1 += len(segment) for vertex in segment: x = vertex[0] y = vertex[1] if x < xmin: xmin = x if x > xmax: xmax = x if y < ymin: ymin = y if y > ymax: ymax = y continue if gl.type == GerberLayer.TYPE_REGION: sumReg += len(gl.points) # regions.extend(gl.points) continue if gl.type == GerberLayer.TYPE_TRACK: sumTracks += len(gl.points) continue if gl.type == GerberLayer.TYPE_PAD: sumPads += len(gl.points) continue if gl.type == GerberLayer.TYPE_BOUNDARY: # if gl.isDark: # # boundarys.extend(gl.points) # # if len(boundarys) == 0: # boundarys.extend(gl.points) # # else: # # cbounds.AddPaths(boundarys, pyclipper.PT_SUBJECT) # # cbounds.AddPaths(gl.points, pyclipper.PT_SUBJECT) # # boundarys = cbounds.Execute(pyclipper.CT_UNION, pyclipper.PFT_EVENODD, pyclipper.PFT_EVENODD) # # cbounds.Clear() # else: # cbounds.AddPaths(boundarys, pyclipper.PT_SUBJECT) # cbounds.AddPaths(gl.points, pyclipper.PT_CLIP) # boundarys = cbounds.Execute(pyclipper.CT_DIFFERENCE, pyclipper.PFT_EVENODD, pyclipper.PFT_EVENODD) # cbounds.Clear() if gl.isDark: boundarys.extend(gl.points) else: cbounds.AddPaths(boundarys, pyclipper.PT_SUBJECT) cbounds.AddPaths(gl.points, pyclipper.PT_CLIP) boundarys = cbounds.Execute(pyclipper.CT_DIFFERENCE, pyclipper.PFT_NONZERO, pyclipper.PFT_NONZERO) cbounds.Clear() sumBound += len(gl.points) for segment in gl.points: sum1 += len(segment) for vertex in segment: x = vertex[0] y = vertex[1] if x < xmin: xmin = x if x > xmax: xmax = x if y < ymin: ymin = y if y > ymax: ymax = y continue if gl.type == GerberLayer.TYPE_MERGEDCOPPER: data.layers.remove(gl) continue print " fraction = ",self.data.fraction print " found", sumBound, "polygons,", sum1, "vertices" print " found", sumReg, "pours" print " found", sumTracks, "tracks" print " found", sumPads, "pads" print " found", len(pcb_edges), "edge segments" print " xmin: %0.3g " % xmin, "xmax: %0.3g " % xmax, "dx: %0.3g " % (xmax - xmin) print " ymin: %0.3g " % ymin, "ymax: %0.3g " % ymax, "dy: %0.3g " % (ymax - ymin) data.xmin2 = xmin data.xmax2 = xmax data.ymin2 = ymin data.ymax2 = ymax if len(pcb_edges) == 0: outer_offset = (1 if data.units == 0 else 0.03937) * 10**data.fraction # 1 mm # outer_offset = 0.01 * 10**data.fraction xmin -= outer_offset ymin -= outer_offset xmax += outer_offset ymax += outer_offset pcb_edge = [[xmax, ymax], [xmax, ymin], [xmin, ymin], [xmin, ymax], [xmax, ymax]] pcb_edges.append(pcb_edge) self.pcb_edges = pcb_edges self.boundarys = boundarys = pyclipper.SimplifyPolygons(boundarys, pyclipper.PFT_NONZERO) # boundarys = GerberReader3.replace_holes_with_seams(boundarys) GerberReader3.closeOffPolys(boundarys) data.layers.append(GerberLayer(True, "PCB Edge", pcb_edges, True, False, "blue", GerberLayer.TYPE_PCBEDGE)) data.layers.append(GerberLayer(True, "Merged Copper", boundarys, False, color="brown", type=GerberLayer.TYPE_MERGEDCOPPER)) # PCB bounds data.xmin = xmin data.xmax = xmax data.ymin = ymin data.ymax = ymax # View bounds # Includes the origin if xmin > 0: xmin = 0 if xmax < 0: xmax = 0 if ymin > 0: ymin = 0 if ymax < 0: ymax = 0 # Add margin ww = (xmax - xmin)*0.1 hh = (ymax - ymin)*0.1 xmin -= ww xmax += ww ymin -= hh ymax += hh self.contours = [] self.layersPanel.loadLayersPanel(data, self.NotifyDataChange) self.canvas.loadData2(self.data, xmin, xmax, ymin, ymax) self.SetStatusText("Load Gerber file completed successfully", 0) self.origincombo.SetSelection(0) self.nativeLabel.SetLabelText("(File unit: %s, Dec. places: %0d)" % ("mm" if data.units == 0 else "in", data.fraction))