def gerberToPNG(filename, png, pixel_mm=0.1): """ Convert to png. Return pixel size in mm. """ try: import gerber except Exception as e: if 'hull' in str(e).lower(): raise Exception('Module pyhull not found. Try "pip install pyhull"?') raise Exception('The gerber module can be found at https://github.com/curtacircuitos/pcb-tools.') try: from gerber.render import GerberCairoContext except Exception as e: if 'cairo' in str(e).lower(): raise Exception('Failed to load gerber.render. Do you have the py2cairo package, which provides the cairo module?') raise e # Read gerber and Excellon files data = gerber.read(filename) data.to_metric() # Rendering context ctx = GerberCairoContext(scale=1.0/pixel_mm) # Scale is pixels/mm # Create SVG image data.render(ctx) ctx.dump(png) return png, np.mean(data.size) / np.mean(ctx.size_in_pixels)
def is_gerber_file(path): try: gerber.read(path) except IOError: return False except Exception as e: logger.error(f'错误信息为:{e}') return False return True
def get_layers(self): if self._layers: return self._layers for filename in os.listdir(self._path): full_path = os.path.join( self._path, filename, ) if not os.path.isfile(full_path): continue try: layer = gerber.read(full_path) layer_type = self.detect_layer_type(filename, layer) self._layers[layer_type] = layer logger.debug("Loaded %s", full_path) except UnknownLayerType: logger.error("Could not identify layer type for %s.", full_path) except gerber.common.ParseError: logger.debug("Unable to parse %s; probably not a gerber.", full_path) return self._layers
def gerberToPNG(filename, png, pixel_mm=0.1): """ Convert to png. Return pixel size in mm. """ try: import gerber except Exception as e: if 'hull' in str(e).lower(): raise Exception( 'Module pyhull not found. Try "pip install pyhull"?') raise Exception( 'The gerber module can be found at https://github.com/curtacircuitos/pcb-tools.' ) try: from gerber.render.cairo_backend import GerberCairoContext except Exception as e: if 'cairo' in str(e).lower(): raise Exception( 'Failed to load gerber.render. Do you have the py2cairo package, which provides the cairo module?' ) raise e # Read gerber and Excellon files data = gerber.read(filename) data.to_metric() # Rendering context ctx = GerberCairoContext(scale=1.0 / pixel_mm) # Scale is pixels/mm # Create SVG image data.render(ctx) ctx.dump(png) return png, np.mean(data.size) / np.mean(ctx.size_in_pixels)
def load(self, path) -> gcp.shapes.ShapesCollection: geber_layer = gerber.read(path) return gcp.shapes.ShapesCollection( list( filter(None, [ self._cvt_shape(geber_primitive) for geber_primitive in geber_layer.primitives ])))
def read_s8tp_file(file_path, img_name='test-gerber.png'): print('transfer gerber to image...') gerber_obj = gerber.read(file_path) ctx = GerberCairoContext() gerber_obj.render(ctx) ctx.dump(img_name) # img_ram = cv2.imread('test-gerber.png') # os.remove('test-gerber.png') return img_name
def _read_gbr(self, filename, layer): ''' Read a Gerber file. ''' # Parse gerber file gbr = gerber.read(filename) # Convert to metric units gbr.to_metric() # read file contents self._read_gbr_recurse(gbr.primitives, layer)
def get_drills_of_dia(drill_file_path, diameter, normalize=True): drills = gerber.read(drill_file_path) tool = None for t in drills.tools: if drills.tools[t].diameter == diameter: tool = drills.tools[t] if not tool: raise Exit(f'Tool for diameter {diameter} not found!') hits = [hit for hit in drills.hits if hit.tool is tool] for hit in hits: hit.to_metric() coords = [hit.position for hit in hits] return normalize_coords(coords)
def readGerber(file): top_copper = gerber.read(file).statements polygons = [] LastStmtIndex = 0 #Find mode statement for cnt in range(len(top_copper)): Stmt = str(top_copper[cnt]) if re.search(MODE, Stmt) != None: setMode(Stmt) LaststmtIndex = cnt break if mode == "": raise Exception("FileFormat", "No Unit mode Statement found") #Find scale factors for cnt in range(LastStmtIndex, len(top_copper)): Stmt = str(top_copper[cnt]) if re.search(SCALE, Stmt) != None: setScale(Stmt) LaststmtIndex = cnt break #Find polygons factors for cnt in range(LastStmtIndex, len(top_copper)): Stmt = str(top_copper[cnt]) if re.search(RMStmtStart, Stmt) != None: PolyStmt = [] i = 0 while cnt + i < len(top_copper): Stmt = str(top_copper[cnt + i]) if re.search(RMStmtStop, Stmt) != None: LaststmtIndex = cnt + i poly = new_Polygon(PolyStmt) polygons.append(poly) break else: PolyStmt.append(Stmt) i += 1 return polygons
def gerberToPNG(filename, png, pixel_mm=0.1): """ Convert to png. Return pixel size in mm. """ import gerber from gerber.render import GerberCairoContext # Read gerber and Excellon files data = gerber.read(filename) data.to_metric() # Rendering context ctx = GerberCairoContext(scale=1.0/pixel_mm) # Scale is pixels/mm # Create SVG image data.render(ctx) ctx.dump(png) return png, np.mean(data.size) / np.mean(ctx.size_in_pixels)
def __init__(self, filename): self.gbr = gerber.read(filename) self._populateShapelyPrimitives() union = sop.unary_union(self.shapelyPrimitives) self.closedPolygons = [geo.polygon.orient(poly) for poly in union] self.polygonLines = [] self.pads = [] self.tolerance = 1e-6 for poly in self.closedPolygons: boundary = poly.boundary for i in range(len(boundary.coords) - 1): self.polygonLines.append( geo.LineString( [boundary.coords[i], boundary.coords[i + 1]]))
def gerberToPNG(filename, png, pixel_mm=0.1): """ Convert to png. Return pixel size in mm. """ import gerber from gerber.render import GerberCairoContext # Read gerber and Excellon files data = gerber.read(filename) data.to_metric() # Rendering context ctx = GerberCairoContext(scale=1.0 / pixel_mm) # Scale is pixels/mm # Create SVG image data.render(ctx) ctx.dump(png) return png, np.mean(data.size) / np.mean(ctx.size_in_pixels)
def get_all_primitives_from_gerber(gerber_file): parsed_gerber = gerber.read(gerber_file) return parsed_gerber.primitives
This example demonstrates the use of pcb-tools with cairo to render a composite image from a set of gerber files. Each layer is loaded and drawn using a GerberCairoContext. The color and opacity of each layer can be set individually. Once all thedesired layers are drawn on the context, the context is written to a .png file. """ import os from gerber import read from gerber.render import GerberCairoContext GERBER_FOLDER = os.path.abspath(os.path.join(os.path.dirname(__file__), 'gerbers')) # Open the gerber files copper = read(os.path.join(GERBER_FOLDER, 'copper.GTL')) mask = read(os.path.join(GERBER_FOLDER, 'soldermask.GTS')) silk = read(os.path.join(GERBER_FOLDER, 'silkscreen.GTO')) drill = read(os.path.join(GERBER_FOLDER, 'ncdrill.DRD')) # Create a new drawing context ctx = GerberCairoContext() # Draw the copper layer copper.render(ctx) # Set opacity and color for soldermask layer ctx.alpha = 0.6 ctx.color = (0.2, 0.2, 0.75)
import gerber from gerber.render import GerberCairoContext # Read gerber and Excellon files dim = gerber.read('tty.dim') # Rendering context ctx = GerberCairoContext() # Create SVG image ctx.color = (0, 1, 0) dim.render(ctx, "tty_dim.svg") print(ctx) ctx.dump("foo.svg")
gre.filename gre.size help(pl.top_layers) help(pcb.drill_layers) for x in pcb.board_bounds: print(x) help(gerber) import os os.path.basename('/oo/ee/eue.qu') file = gerber.read('/home/roman/repos/Modules/sensors/LIGHTNING01A/hw/cam_profi/LIGHTNING01A-B.Cu.gbr') file = gerber.read('/home/roman/repos/Modules/sensors/LIGHTNING01A/hw/cam_profi/LIGHTNING01A.drl') file.offset(10,10) file.write('/home/roman/repos/Modules/sensors/LIGHTNING01A/hw/cam_profi/aaa/a.drl') file.bounding_box file.bounds help(file) help(file) file.statements[40].y file.bounding_box
This example demonstrates the use of pcb-tools with cairo to render a composite image from a set of gerber files. Each layer is loaded and drawn using a GerberCairoContext. The color and opacity of each layer can be set individually. Once all thedesired layers are drawn on the context, the context is written to a .png file. """ import os from gerber import read from gerber.render import GerberCairoContext GERBER_FOLDER = os.path.abspath( os.path.join(os.path.dirname(__file__), 'gerbers')) # Open the gerber files copper = read(os.path.join(GERBER_FOLDER, 'copper.GTL')) mask = read(os.path.join(GERBER_FOLDER, 'soldermask.GTS')) silk = read(os.path.join(GERBER_FOLDER, 'silkscreen.GTO')) drill = read(os.path.join(GERBER_FOLDER, 'ncdrill.DRD')) # Create a new drawing context ctx = GerberCairoContext() # Draw the copper layer copper.render(ctx) # Set opacity and color for soldermask layer ctx.alpha = 0.6 ctx.color = (0.2, 0.2, 0.75) # Draw the soldermask layer
# drl file TSP path optimizer # import sys import math import gerber from tsp_solver.greedy import solve_tsp # https://github.com/dmishin/tsp-solver # https://github.com/curtacircuitos/pcb-tools if len(sys.argv) != 2: print "usage: drl-optimize.py [drill-file.drl]" sys.exit(0) f = gerber.read(sys.argv[1]) #print(f.report()) cnt = {} l = {} t = {} for a,b in f.hits: n = a.number if n not in cnt.keys(): cnt[n] = 0 l[n] = [] t[n] = (a,b) cnt[n] += 1 l[n].append(b)
# write as gerber. not so difficult, right? statements = [] settings = dict( notation='', units='mm', zero_suppression=False, zeros=False, format='', angle_units='radian') primitives = [] # [Line((0,0), (10,10)),] filename = 'output.GML' # fill primitives for p in parsed_paths: for pp in p: new_line = Line( (pp.start.real, pp.start.imag), (pp.end.real, pp.end.imag)) primitives.append(new_line) test_gerber = gerber.read('test/test.GML') # cannibalize test file :-) import pdb; pdb.set_trace() # apparently, the result is the same as test.GML (primitives are not used...) g = GerberFile( test_gerber.statements, test_gerber.settings, primitives) #import pdb; pdb.set_trace() g.write('joee.GML') #import pdb; pdb.set_trace()
def load_nc_drill(name): # Read gerber and Excellon files ncdata = gerber.read(name) #assume 3d printer to be metric ncdata.to_metric() return ncdata
def get_info_from_gerber(gerber_file): parsed_gerber = gerber.read(gerber_file) return parsed_gerber
# Created by mqgao at 2019/3/19 """ Feature: #Enter feature name here # Enter feature description here Scenario: #Enter scenario name here # Enter steps here Test File Location: # Enter """ import gerber import os from gerber.render import GerberCairoContext gm2_dir = '/Users/mqgao/PycharmProjects/auto-pcb-ii/tokenization/gerber_tokenization/data/gerbers' for i, f in enumerate(os.listdir(gm2_dir)): print(i) gerber_obj = gerber.read(os.path.join(gm2_dir, f)) ctx = GerberCairoContext() gerber_obj.render(ctx) ctx.dump('test-gerber-{}.png'.format(i)) print('generate end!')
'tsp-solver can be downloaded from:\n' ' http://github.com/dmishin/tsp-solver.\n' '=================================================================') sys.exit(0) if __name__ == '__main__': # Get file name to open if len(sys.argv) < 2: fname = 'gerbers/shld.drd' else: fname = sys.argv[1] # Read the excellon file f = gerber.read(fname) positions = {} tools = {} hit_counts = f.hit_count() oldpath = sum(f.path_length().values()) #Get hit positions for hit in f.hits: tool_num = hit.tool.number if tool_num not in positions.keys(): positions[tool_num] = [] positions[tool_num].append(hit.position) hits = []
import os import gerber import sys import json from gerber.render import GerberCairoContext from gerber.utils import parse_gerber_value from gerber.rs274x import GerberParser copper = gerber.read('input.GTL') # argument string is the filename # Rendering context ctx = GerberCairoContext() # Create PNG copper.render(ctx) # js = GerberParser.parse('input.GTL') # print(js) # # with open('data.json', 'w') as outfile: # # json.dump(js, outfile) # # with open('data.json') as f: # # data = json.load(f) # # print(data[0]) ctx.dump(os.path.join(os.path.dirname(__file__), 'output.png')) #print("Saved") exit()
def _load_file(self): """ Loads a single file to be turned into an array Input should be a zipfile with all the layers included in it :return: """ self.logger.info("Please input path to gerber file") self.gerber_file_path = Path(input("File: ").strip().replace("\\", "")) # self.gerber_file_path = Path(self._temp_path) _found_profile_file = None self.logger.info("Loading file: {}".format(self.gerber_file_path)) if self.gerber_file_path.suffix == ".zip": with ZipFile(self.gerber_file_path, 'r') as zip_file: for file in zip_file.namelist(): _file_name = Path(file).name # First check that the file is not in the ignored list if True not in [ part.startswith(_file_name) for part in self.ignored_file_starts ]: self.logger.debug( "File from zip archive: {}".format(_file_name)) self.gerber_file_list.append(_file_name) if True in [ ext in _file_name for ext in self.profile_file_extensions ]: # Got a profile file, now we can have a look at the max bounds of the file self.logger.debug("Found a profile file") self.logger.info( "Profile file name: {}".format(_file_name)) _found_profile_file = file # Extract profile file to temp dir zip_file.extract(file, str(self.temp_path)) break else: self._exit_error("Can't load file, needs to be a .zip.") if _found_profile_file is not None: read_pcb = gerber.read(str(self.temp_path / _found_profile_file)) # Check what units the gerber file is in _current_units = read_pcb.units if _current_units == "metric": self.logger.info( "PCB units are metric, no conversion required") elif _current_units == "inch": self.logger.info( "PCB units are imperial, converting to metric") read_pcb.to_metric() # bounds is a tuple of the form ((min_x, max_x), (min_y, max_y)) pcb_bounds = read_pcb.bounds self.pcb_info["size_x"] = round( pcb_bounds[0][1] - pcb_bounds[0][0], 6) self.pcb_info["size_y"] = round( pcb_bounds[1][1] - pcb_bounds[1][0], 6) # Work out surface area in dm2 _surface_area = (self.pcb_info["size_x"] * self.pcb_info["size_y"]) / 10000 self.pcb_info["surface_area"] = round(_surface_area, 6) # origin is how far away the bottom left corner of the pcb is to the 'origin' of the board # need to flip the sign to get the coord of the origin wrt the bl corner self.pcb_info["origin_x"] = round(pcb_bounds[0][0] * -1, 6) self.pcb_info["origin_y"] = round(pcb_bounds[1][0] * -1, 6) # Get number of layers so we can make the panel frame properly num_layers = self._determine_number_of_layers() num_layers_correct = input( f"Number of layers found - {num_layers}, is this correct? (*Y/N): " ) or "Y" if num_layers_correct.upper() == "Y": self.pcb_info["num_copper_layers"] = num_layers elif num_layers_correct.upper() == "N": num_layers = int( input("Please enter number of layers in PCB: ")) self.pcb_info["num_copper_layers"] = num_layers self.logger.info("PCB info: {}".format(self.pcb_info)) else: self._exit_error( "No profile file found in zip, does it have the extension .gko?" )
if len(sys.argv) >= 2: if len(sys.argv) == 3: if sys.argv[2] == 'fast': algorithm = 0 elif sys.argv[2] == 'opt-2': algorithm = 1 else: print 'Invalid algorithm. Options are "fast" or "opt-2". "fast" is the default, if no algorithm is defined' print 'Exiting the script...' sys.exit(0) else: algorithm = 0 print "Loading Excellon file..." in_filename = sys.argv[1] f = gerber.read(in_filename) points = [] for p in f.hits: points.append(p.position) if algorithm == 1: print "Searching the best route for %d points using algorithm opt-2. This will take some time..." % ( len(points)) route = two_opt(np.array(points), IMPROVEMENT_THRESHOLD, in_filename) else: print "Searching a good route for %d points using the fast algorithm (This may be not the shortest route)..." % ( len(points)) route = fast(points, IMPROVEMENT_THRESHOLD, in_filename) else: print '''
'This example requires tsp-solver be installed in order to run.\n\n' 'tsp-solver can be downloaded from:\n' ' http://github.com/dmishin/tsp-solver.\n' '=================================================================') sys.exit(0) if __name__ == '__main__': # Get file name to open if len(sys.argv) < 2: fname = 'gerbers/shld.drd' else: fname = sys.argv[1] # Read the excellon file f = gerber.read(fname) positions = {} tools = {} hit_counts = f.hit_count() oldpath = sum(f.path_length().values()) #Get hit positions for hit in f.hits: tool_num = hit.tool.number if tool_num not in positions.keys(): positions[tool_num] = [] positions[tool_num].append(hit.position) hits = []