def parse_drill_file(filename): info("parsing drill file \"" + filename + "\"...") # altium's drill file format specification looks like: # ;FILE_FORMAT=4:3 # METRIC,LZ lines = [] for line in open(filename): line = line.rstrip("\n\r") lines.append(line) global tool tool = {} for line in lines: match = re.search("T[0-9]+C([\.0-9]*)F.*", line) if match: diameter = match.group(1) tool[diameter] = [] #debug(diameter) #debug(line) match = re.search("X([0-9]*)Y([0-9]*)", line) if match: x = match.group(1) y = match.group(2) x = +int(x)/1000.0 # fixme y = -int(y)/1000.0 # fixme location = (x, y) tool[diameter].append(location)
def save_svg_file(): info("writing svg file \"" + svg_filename + "\"...") svg.viewbox(width=panel_width, height=panel_height) #svg.viewbox(width=stencil_width, height=stencil_height) #svg.viewbox(minx=, miny=, width=panel_width, height=panel_height) #svg.size(width=str(panel_width) + "mm", height=str(panel_height) + "mm") #svg.save() # from https://bitbucket.org/mozman/svgwrite/issues/18/adding-namespaces: import xml.etree.ElementTree xml_content = svg.get_xml() xml_content.attrib['xmlns:inkscape']='http://www.inkscape.org/namespaces/inkscape' xml_content.attrib['width']=str(panel_width) + "mm" xml_content.attrib['height']=str(panel_height) + "mm" #xml_content.attrib['units']="mm" #xml_content.attrib['inkscape:window-width']="1200" #xml_content.attrib['inkscape:window-height']="800" ##xml_content.attrib['height']=str(panel_height) + "mm" xml_content.attrib['inkscape:document-units']="mm" # this is ignored by inkscape 0.91 r13725 with open(svg_filename, 'wb') as fd: fd.write(xml.etree.ElementTree.tostring(xml_content))
def generate_eps_and_dxf(): # from https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_2D_formats info("converting svg file to eps...") subprocess.call(["inkscape", svg_filename, "--export-eps=" + eps_filename]) info("converting eps file to dxf...") # pstoedit.exe -f "dxf:-polyaslines -mm" the-bicentennial-board.eps the-bicentennial-board.dxf # pstoedit.exe -f dxf:-polyaslines\ -mm the-bicentennial-board.eps the-bicentennial-board.dxf subprocess.call(["pstoedit", "-q", "-f", "dxf:-polyaslines -mm", eps_filename, dxf_filename]) info("in solidworks, open dxf file, choose import as 2d sketch, select mm")
def try_making_a_tiled_object(): info("trying to make a tiled object") tilly = svg.defs.add(svg.g(id='tilly')) tilly.add(svg.circle( (0,0), 5, fill="#00ff00" )) blah = svg.use(tilly, insert=(10,10)) svg.add(blah)
def generate_pdf(): info("converting svg file to pdf...") #/cygdrive/c/Program\ Files/Inkscape/inkscape.exe drill1.svg --export-pdf="blah.pdf" #cd /usr/local/bin #ln -s /cygdrive/c/Program\ Files/Inkscape/inkscape.exe subprocess.call(["inkscape", svg_filename, "--export-pdf=" + pdf_filename])
def parse_gerber(filename): info("parsing gerber file \"" + filename + "\"...") #global units #global zero_suppression_mode #global coordinate_mode #global layer_polarity #global x_format #global y_format #global number_of_digits #global ratio global decimal_places # fixme - a bit funny if this changes between gerbers we're reading zero_suppression_mode = "leading" coordinate_mode = "absolute" layer_polarity = "dark" x_format = "55" y_format = "55" #units = "mm" lines = [] for line in open(filename): line = line.rstrip("\n\r") lines.append(line) gerber_instructions = [] global apertures apertures = {} aperture = "00" matched_units = 0 matched_format = 0 set_ratio = 0 #gerber_instructions.append("hi there") for line in lines: matches = 0 match = re.search("^%MO([IM][NM])\*%$", line) if match: matches = matches + 1 if (match.group(1) == "IN"): #debug("set units to inches: " + line) ratio = 1000.0 / 25.4 / 1.55 # fixme/todo: 1.55 is a magic number here else: #debug("set units to mm: " + line) ratio = 1.0 matched_units = 1 match = re.search("^%FS([LTD])([AI])X([0-9][0-9])Y([0-9][0-9])\*%$", line) if match: matches = matches + 1 debug("set format: " + line) if (match.group(1) == "L"): zero_suppression_mode = "leading" else: zero_suppression_mode = "trailing" if (match.group(2) == "A"): coordinate_mode = "absolute" else: coordinate_mode = "incremental" x_format = match.group(3) y_format = match.group(4) decimal_places = int(x_format[1]) number_of_digits = int(x_format[0]) + int(x_format[1]) number_of_digits = number_of_digits + 1 # some gerber files output 7 digits for "24" format... #decimal_places = decimal_places + 1 debug("number of digits to use for coordinates = " + str(number_of_digits)) matched_format = 1 match = re.search("^%ADD([0-9]+)C,([.0-9]+)\*%$", line) # %ADD010C,0.0254*% if match: matches = matches + 1 #aperture_length = len(match.group(1)) ap = int(match.group(1)) apertures[ap] = ("C", float(match.group(2)), float(match.group(2))) debug("aperture definition: " + line) match = re.search("^%ADD([0-9]+)R,([.0-9]+)X([.0-9]+)\*%$", line) # %ADD028R,2.6X1.6*% or %ADD34R,0.0138X0.0472*% if match: matches = matches + 1 ap = int(match.group(1)) apertures[ap] = ("R", float(match.group(2)), float(match.group(3))) debug("aperture definition: " + line) match = re.search("^%ADD([0-9]+)O,([.0-9]+)X([.0-9]+)\*%$", line) # %ADD11O,0.0138X0.0669*% if match: matches = matches + 1 ap = int(match.group(1)) apertures[ap] = ("O", float(match.group(2)), float(match.group(3))) debug("aperture definition: " + line) match = re.search("^%LN([a-zA-Z0-9]+)\*%$", line) if match: matches = matches + 1 gerber_instructions.append("setlayer" + match.group(1)) match = re.search("^(G0[1-3])\*$", line) if match: matches = matches + 1 gerber_instructions.append(match.group(1)) match = re.search("^(G0[1-3][XY].*)\*$", line) if match: matches = matches + 1 gerber_instructions.append(match.group(1)) match = re.search("^([XY].*)\*$", line) if match: matches = matches + 1 #debug(line) gerber_instructions.append(match.group(1)) match = re.search("^(G54D)([0-9]+)\*$", line) if match: matches = matches + 1 debug("aperture selection: " + match.group(2)) gerber_instructions.append(match.group(1) + match.group(2)) #debug(match.group(1)) match = re.search("^%LP([DC])\*%$", line) if match: # this unfortunately only grabs the last instance... matches = matches + 1 if (match.group(1) == "D"): layer_polarity = "dark" else: layer_polarity = "clear" match = re.search("^%IPNEG\*%$", line) # %IPNEG% = reverse whole layer if match: matches = matches + 1 # do something here for this... match = re.search("^%IPPOS\*%$", line) # %IPPOS% = whole layer normal if match: matches = matches + 1 match = re.search("^G04.*$", line) if match: matches = matches + 1 match = re.search("^%$", line) if match: matches = matches + 1 match = re.search("^\*$", line) if match: matches = matches + 1 match = re.search("^G74\*$", line) if match: warning("cannot handle single quadrant G74 mode") matches = matches + 1 #exit() match = re.search("^G75\*$", line) # multi-quadrant mode if match: matches = matches + 1 match = re.search("^$", line) if match: matches = matches + 1 match = re.search("^M02\*$", line) # M02* = end of job if match: matches = matches + 1 match = re.search("^%AM(.*)\*$", line) # AM = aperture macro definition if match: matches = matches + 1 warning("ignoring aperture macro \"" + match.group(1) + "\"") match = re.search("^([$0-9]*),", line) # aperture macro definition continuation if match: matches = matches + 1 match = re.search("^%AD(.*)\*$", line) # AD = aperture macro instantiation if match: matches = matches + 1 error("aperture instantiation \"" + match.group(1) + "\" ignored - this part needs to be coded") match = re.search("^%IN(.*)\*%$", line) # IN = image name if match: matches = matches + 1 debug("ignoring image name \"" + match.group(1) + "\"") if (matches == 0): warning("did not parse \"" + line + "\"") if (set_ratio == 0) and (matched_units == 1) and (matched_format == 1): ratio = ratio / (10.0**int(decimal_places)) debug("ratio = " + str(ratio)) gerber_instructions.append("setratio" + str(ratio)) set_ratio = 1 if (matched_format == 0): error("did not find format line", 2) for aperture in apertures: (CROP, w, h) = apertures[aperture] debug("aperture[" + str(aperture) + "]: " + CROP + " " + str(w) + " " + str(h)) #debug("units: " + units) debug("x_format: " + x_format) debug("y_format: " + y_format) debug("layer_polarity: " + layer_polarity) debug("zero_suppression_mode: " + zero_suppression_mode) debug("coordinate_mode: " + coordinate_mode) return gerber_instructions