From 575a8b08deb582f86394e4674669b6b81b2eab6b Mon Sep 17 00:00:00 2001 From: robbeh81 Date: Sat, 11 Nov 2017 19:30:48 +0100 Subject: [PATCH 1/2] Added GUI option to merge small pads Adds GUI option to merge small pads utilizing "mergepads.py" by fishpepper. Rearranged GUI elements, added help option. Added gerbv direct link for OSX. --- g2g_gui.py | 108 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/g2g_gui.py b/g2g_gui.py index 482fa00..4209bdc 100755 --- a/g2g_gui.py +++ b/g2g_gui.py @@ -22,8 +22,11 @@ speed_str = StringVar() force_str = StringVar() cut_mode_str = StringVar() +merge_str = StringVar() +merge_threshold_str = StringVar() cutter_shared_name_str = StringVar() CONFPATH='./g2g_gui.cnf' +help_text = 'Help:\n\nGerber File \n- input Gerber (*.gbr) file\n\nOutput File \n- Graphtec / Silhouette (*.gpgl) file to send to the plotter\n\nOffset \n- translate to device coordinates x,y (inches)\n\nBorder \n- cut a border around the bounding box of the gerber file; 0,0 to disable\n\nMatrix \n- transform coordinates by [a b;c d]\n\nSpeed \n- use speed s in device units; s2,s3 for multiple passes\n\nForce \n- use force f in device units; f2,f3 for multiple passes\n\nMerge \n- Merge small SMD Pads\n\nMerge Threshold\n- Min Size, Min Distance\n\nCut Mode \n- 0 for highest accuracy (fine pitch), 1 for highest speed\n\nCutter Device Name (Linux) \n- device file of the plotter, e.g. /dev/usb/lp0' input_filename = '' output_filename = '' @@ -35,6 +38,8 @@ speed_text = '' force_text = '' cut_mode_text = '' +merge_text = '' +merge_threshold_text = '' cutter_shared_name_text = '' offset = (4,0.5) @@ -43,6 +48,8 @@ speed = [2,2] force = [8,30] cut_mode = 0 +merge = 0 +merge_threshold = [0.014,0.009] # min_size, min_distance in inch def floats(s): return map(float,string.split(s,',')) @@ -100,6 +107,10 @@ def main_program(): default_speed_str() if not force_str.get(): default_force_str() + if not merge_str.get(): + default_merge_str() + if not merge_threshold_str.get(): + default_merge_threshold_str() if not cut_mode_str.get(): default_cut_mode_str() @@ -108,6 +119,8 @@ def main_program(): matrix = floats(matrix_str.get()) speed = floats(speed_str.get()) force = floats(force_str.get()) + merge = floats(merge_str.get()) + merge_threshold = floats(merge_threshold_str.get()) cut_mode = int(cut_mode_str.get()) # @@ -117,6 +130,7 @@ def main_program(): import graphtec import pic import optimize + import mergepads g = graphtec.graphtec() @@ -124,6 +138,9 @@ def main_program(): g.set(offset=(offset[0]+border[0]+0.5,offset[1]+border[1]+0.5), matrix=matrix) strokes = pic.read_pic(temp_pic) + if not merge==0: + # merge multiple smaller pads to bigger pads spanning the same area + strokes = mergepads.fix_small_geometry(strokes, merge_threshold[0], merge_threshold[1]) max_x,max_y = optimize.max_extent(strokes) tx,ty = 0.5,0.5 @@ -141,13 +158,15 @@ def main_program(): g.set(speed=s, force=f) for x in lines: g.line(*x) - g.closed_path(border_path) + if border[0]!=0 or border[1]!=0: + g.closed_path(border_path) else: for (s,f) in zip(speed,force): g.set(speed=s, force=f) for s in strokes: g.closed_path(s) - g.closed_path(border_path) + if border[0]!=0 or border[1]!=0: + g.closed_path(border_path) g.end() @@ -166,6 +185,8 @@ def Save_Configuration(): f.write(matrix_str.get() + '\n') f.write(speed_str.get() + '\n') f.write(force_str.get() + '\n') + f.write(merge_str.get() + '\n') + f.write(merge_threshold_str.get() + '\n') f.write(cut_mode_str.get() + '\n') f.write(cutter_shared_name_str.get() + '\n') f.close() @@ -192,10 +213,20 @@ def Send_to_Cutter(): if os.name=='nt': os.system("copy /B \"%s\" \"%s\"" % (src, dst)) else: - os.system("cat %s > %s" % (src, dst)) + if sys.platform=='darwin': + os.system("./file2graphtec %s &" % (src)) + else: + os.system("cat %s > %s" % (src, dst)) + +def show_in_gerbv(): + src=os.path.normpath(Gerber_name.get()) + os.system("gerbv %s &" % (src)) + +def show_help(): + tkMessageBox.showinfo("Help", help_text) def get_input_filename(): - input_filename=tkFileDialog.askopenfilename(title='Select paste mask Gerber file', filetypes=[('Gerber File', '*.g*'),("All files", "*.*")] ) + input_filename=tkFileDialog.askopenfilename(title='Select paste mask Gerber file', filetypes=[('Gerber File', '*.gbr'),("All files", "*.*")] ) if input_filename: Gerber_name.set(input_filename) @@ -228,61 +259,82 @@ def default_speed_str(): def default_force_str(): force_str.set("8,30") + +def default_merge_str(): + merge_str.set("0") + +def default_merge_threshold_str(): + merge_threshold_str.set("0.014,0.009") def default_cut_mode_str(): cut_mode_str.set("0") Label(top, text="Gerber File ").grid(row=1, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=Gerber_name).grid(row=1, column=1) +Entry(top, bd =1, width=40, textvariable=Gerber_name).grid(row=1, column=1) Tkinter.Button(top, width=9, text = "Browse", command = get_input_filename).grid(row=1, column=2) Label(top, text="Output File ").grid(row=2, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=Output_name).grid(row=2, column=1) +Entry(top, bd =1, width=40, textvariable=Output_name).grid(row=2, column=1) Tkinter.Button(top, width=9, text = "Browse", command = get_output_filename).grid(row=2, column=2) if os.name=='nt': Label(top, text="gerbv path ").grid(row=3, column=0, sticky=W) - Entry(top, bd =1, width=60, textvariable=gerbv_path).grid(row=3, column=1) + Entry(top, bd =1, width=40, textvariable=gerbv_path).grid(row=3, column=1) Tkinter.Button(top, width=9, text = "Browse", command = get_gerbv_path).grid(row=3, column=2) Label(top, text="pstoedit path ").grid(row=4, column=0, sticky=W) - Entry(top, bd =1, width=60, textvariable=pstoedit_path).grid(row=4, column=1) + Entry(top, bd =1, width=40, textvariable=pstoedit_path).grid(row=4, column=1) Tkinter.Button(top, width=9, text = "Browse", command = get_pstoedit_path).grid(row=4, column=2) Label(top, text="Offset ").grid(row=5, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=offset_str).grid(row=5, column=1) +Entry(top, bd =1, width=40, textvariable=offset_str).grid(row=5, column=1) Tkinter.Button(top, width=9, text = "Default", command = default_offset_str).grid(row=5, column=2) Label(top, text="Border ").grid(row=6, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=border_str).grid(row=6, column=1) +Entry(top, bd =1, width=40, textvariable=border_str).grid(row=6, column=1) Tkinter.Button(top, width=9, text = "Default", command = default_border_str).grid(row=6, column=2) Label(top, text="Matrix ").grid(row=7, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=matrix_str).grid(row=7, column=1) +Entry(top, bd =1, width=40, textvariable=matrix_str).grid(row=7, column=1) Tkinter.Button(top, width=9, text = "Default", command = default_matrix_str).grid(row=7, column=2) Label(top, text="Speed ").grid(row=8, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=speed_str).grid(row=8, column=1) +Entry(top, bd =1, width=40, textvariable=speed_str).grid(row=8, column=1) Tkinter.Button(top, width=9, text = "Default", command = default_speed_str).grid(row=8, column=2) Label(top, text="Force ").grid(row=9, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=force_str).grid(row=9, column=1) +Entry(top, bd =1, width=40, textvariable=force_str).grid(row=9, column=1) Tkinter.Button(top, width=9, text = "Default", command = default_force_str).grid(row=9, column=2) -Label(top, text="Cut Mode ").grid(row=10, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=cut_mode_str).grid(row=10, column=1) -Tkinter.Button(top, width=9, text = "Default", command = default_cut_mode_str).grid(row=10, column=2) +Label(top, text="Merge ").grid(row=10, column=0, sticky=W) +Entry(top, bd =1, width=40, textvariable=merge_str).grid(row=10, column=1) +Tkinter.Button(top, width=9, text = "Default", command = default_merge_str).grid(row=10, column=2) + +Label(top, text="Merge Threshold").grid(row=11, column=0, sticky=W) +Entry(top, bd =1, width=40, textvariable=merge_threshold_str).grid(row=11, column=1) +Tkinter.Button(top, width=9, text = "Default", command = default_merge_threshold_str).grid(row=11, column=2) + +Label(top, text="Cut Mode ").grid(row=12, column=0, sticky=W) +Entry(top, bd =1, width=40, textvariable=cut_mode_str).grid(row=12, column=1) +Tkinter.Button(top, width=9, text = "Default", command = default_cut_mode_str).grid(row=12, column=2) if os.name=='nt': - Label(top, text="Cutter Shared Name").grid(row=11, column=0, sticky=W) + Label(top, text="Cutter Shared Name").grid(row=13, column=0, sticky=W) + else: - Label(top, text="Cutter Device Name").grid(row=11, column=0, sticky=W) -Entry(top, bd =1, width=60, textvariable=cutter_shared_name_str).grid(row=11, column=1, sticky=E) + if not sys.platform=='darwin': + Label(top, text="Cutter Device Name").grid(row=13, column=0, sticky=W) + Entry(top, bd =1, width=40, textvariable=cutter_shared_name_str).grid(row=13, column=1, sticky=E) + +if sys.platform=='darwin': + Tkinter.Button(top, width = 50, pady = 10, text = "View Gerber file in gerbv", command = show_in_gerbv).grid(row=14, column=0, columnspan=4) + +Tkinter.Button(top, width = 50, pady = 10, text = "1. Create Graphtec / Silhouette File", command = main_program).grid(row=15, column=0, columnspan=4) +Tkinter.Button(top, width = 50, pady = 10, text = "2. Send Graphtec / Silhouette File to Cutter", command = Send_to_Cutter).grid(row=16, column=0, columnspan=4) +Tkinter.Button(top, width = 50, pady = 10, text = "Save Configuration", command = Save_Configuration).grid(row=17, column=0, columnspan=4) +Tkinter.Button(top, width = 50, pady = 10, text = "Help", command = show_help).grid(row=18, column=0, columnspan=4) +Tkinter.Button(top, width = 50, pady = 10, text = "-> Exit", command = Just_Exit).grid(row=19, column=0, columnspan=4) -Tkinter.Button(top, width=40, text = "Create Graphtec File", command = main_program).grid(row=12, column=1) -Tkinter.Button(top, width=40, text = "Send Graphtec File to Silhouette Cutter", command = Send_to_Cutter).grid(row=13, column=1) -Tkinter.Button(top, width=40, text = "Save Configuration", command = Save_Configuration).grid(row=14, column=1) -Tkinter.Button(top, width=40, text = "Exit", command = Just_Exit).grid(row=15, column=1) if path.isfile(CONFPATH) and access(CONFPATH, R_OK): f = open(CONFPATH,'r') @@ -304,6 +356,10 @@ def default_cut_mode_str(): speed_text = speed_text.strip() force_text = f.readline() force_text = force_text.strip() + merge_text = f.readline() + merge_text = merge_text.strip() + merge_threshold_text = f.readline() + merge_threshold_text = merge_threshold_text.strip() cut_mode_text = f.readline() cut_mode_text = cut_mode_text.strip() cutter_shared_name_text = f.readline() @@ -334,6 +390,10 @@ def default_cut_mode_str(): speed_text="2,2" if not force_text: force_text="8,30" +if not merge_text: + merge_text="0" +if not merge_threshold_text: + merge_threshold="0.014,0.009" if not cut_mode_text: cut_mode_text="0" if not cutter_shared_name_text: @@ -351,6 +411,8 @@ def default_cut_mode_str(): matrix_str.set(matrix_text) speed_str.set(speed_text) force_str.set(force_text) +merge_str.set(merge_text) +merge_threshold_str.set(merge_threshold_text) cut_mode_str.set(cut_mode_text) cutter_shared_name_str.set(cutter_shared_name_text) From b7e369bda05a6d406fb17a770ab62f51806dac18 Mon Sep 17 00:00:00 2001 From: robbeh81 Date: Sat, 11 Nov 2017 19:35:02 +0100 Subject: [PATCH 2/2] Enlarged line thickness for readability of SVG --- svgwriter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svgwriter.py b/svgwriter.py index b1f14e4..e46fa8d 100644 --- a/svgwriter.py +++ b/svgwriter.py @@ -13,7 +13,7 @@ def draw_polygon(self, strokes, color): # create polygon list and convert user units to be in inch (*90) points.append((p[0] * 90, p[1] * 90)) - poly = self.dwg.polygon(points=points, fill='none', stroke=color, stroke_width="0.01mm") + poly = self.dwg.polygon(points=points, fill='none', stroke=color, stroke_width="0.1mm") self.dwg.add(poly) def finish(self):