Commits

saar drimer committed 14a9dab

progress

Comments (0)

Files changed (2)

      
     argp.add_argument('--fab', nargs='?',
                       dest='fab', default=False,
-                      help='Generate manufacturing files (Gerbers, Excellon, etc.)')
+                      help='Generate manufacturing files (Gerbers, Excellon, etc.) An optional argument specifies the fab, so the files are named accordingly (default is .ger)')
 
     argp.add_argument('-p', '--make-pngs',
                       action='store_true', dest='pngs', default=False,
                       action='store_true', dest='no_docs', default=False,
                       help='Do not generate documentation text (makes compilation time shorter)')
 
+    argp.add_argument('--gerbers-to-svg', nargs='?',
+                      dest='gerbers_to_svg', default=False,
+                      help="Converts Gerber files to SVGs")
+
     argp.add_argument('--renumber-refdefs', nargs='?',
                       dest='renumber', default=False,
                       help="Renumber refdefs (valid options are 'top_to_bottom', 'bottom_to_top', 'left_to_right', 'right_to_left'")
     build_dir = os.path.join(cfg['base_dir'], cfg['pcbmode']['locations']['build'])
     utils.create_dir(build_dir)
 
+
     # renumber refdefs and dump board config file
     if cmdline_args.renumber is not False:
         print "-- renumbering refdefs"
 
         utils.renumber_refdefs(cfg, order)
 
+
+    # convert gerbers to SVG
+    elif cmdline_args.gerbers_to_svg is not False:
+        print "-- converting Gerbers to SVG"
+        if cmdline_args.gerbers_to_svg is None:
+            profile = 'default'
+        else:
+            profile = cmdline_args.gerbers_to_svg.lower()    
+
+        gerber.gerbers_to_svg(cfg, profile)
+
+
     # extract routing from input SVG file
     elif cmdline_args.extract is True:
         print "-- extracting routing and placement"
         extract.extract_from_svg(cfg)
 
+
     else:
         # make the board
         if cmdline_args.make is True:
         if cmdline_args.pngs is True:
             print "-- creating PNGs"
             utils.create_pngs(cfg)
-         
+   
         
         if cmdline_args.bom is True:
             print "-- creating BOM (not implemented yet!)"
             pass
+
      
     print "-- Done!"
 
 import datetime
 from lxml import etree as et
 from itertools import product
+import pyparsing as pyp
 
 # pcbmode modules
 import svg
 
 
     return filenames
+
+
+
+
+def gerber_grammar_generator():
+   """
+   Returns the grammar of Gerber
+   """
+
+   # define grammar using pyparsing
+   space = pyp.Literal(' ')
+   comma = pyp.Literal(',')
+   floatnum = pyp.Regex(r'([\d\.]+)')
+   apperture = pyp.Literal('D').setParseAction(pyp.replaceWith('apperture'))
+   coord_x = pyp.Literal('X').setParseAction(pyp.replaceWith('x'))
+   coord_y = pyp.Literal('Y').setParseAction(pyp.replaceWith('y'))
+   gcoord = pyp.Regex(r'(-?\d+)')
+   coord_dict = pyp.dictOf((coord_x | coord_y), gcoord)
+   coord_xy = pyp.Group(coord_dict + coord_dict)
+
+   inst_del = pyp.Literal('%').suppress() # instruction delimeter
+   inst_end = pyp.Literal('*').suppress() # ending suffix
+
+   cmd_comment = pyp.Literal('G04').setParseAction(pyp.replaceWith('comment'))
+
+   cmd_closed_shape_start = pyp.Literal('G36')
+   cmd_closed_shape_end = pyp.Literal('G37')
+   #cmd_closed_shape_end.setParseAction(pyp.replaceWith('close-shape'))
+
+   cmd_units = pyp.Literal('MO')
+   cmd_units_opt_mm = pyp.Literal('MM')
+   cmd_units_opt_inch = pyp.Literal('IN')
+
+   cmd_format = pyp.Literal('FS')
+   cmd_format_opt_leading_zeros = pyp.Literal('L')
+   cmd_format_opt_absolute = pyp.Literal('A') 
+
+   cmd_app_def = pyp.Literal('AD') # apperture definition
+   cmd_app_def_opt_circ = pyp.Literal('C')
+   cmd_app_def_opt_rect = pyp.Literal('R')
+
+   cmd_polarity = pyp.Literal('LP')
+   cmd_polarity_opt_dark = pyp.Literal('D')
+   cmd_polarity_opt_clear = pyp.Literal('C')
+
+   cmd_linear_int = pyp.Literal('G01').suppress() # lineal interpolation
+   cmd_circ_int_cw = pyp.Literal('G02').suppress() # circular int. clockwise
+   cmd_circ_int_ccw = pyp.Literal('G03').suppress() # circular int. counter-clockwise
+
+   cmd_draw = pyp.Literal('D01').setParseAction(pyp.replaceWith('draw'))
+   cmd_move = pyp.Literal('D02').setParseAction(pyp.replaceWith('move'))
+   cmd_flash = pyp.Literal('D03').setParseAction(pyp.replaceWith('flash'))
+
+   # comments (suppress)
+   comment = (cmd_comment + 
+              pyp.Optional(space) + 
+              pyp.Regex(r"([^\*]+)?") + 
+              pyp.Optional(space) + 
+              inst_end).suppress()
+
+   units = (inst_del + 
+            cmd_units + 
+            (cmd_units_opt_mm | cmd_units_opt_inch) + 
+            inst_end + 
+            inst_del)
+
+   gformat = (inst_del +
+              cmd_format +
+              cmd_format_opt_leading_zeros +
+              cmd_format_opt_absolute +
+              pyp.Literal('X') + 
+              floatnum +
+              pyp.Literal('Y') + 
+              floatnum +
+              inst_end +
+              inst_del)
+
+   app_def = (inst_del + 
+              cmd_app_def +
+              pyp.Literal('D') +
+              floatnum + 
+              (cmd_app_def_opt_circ | cmd_app_def_opt_rect) +
+              comma +
+              floatnum +
+              pyp.Literal('X') +
+              pyp.Optional(floatnum) + 
+              inst_end +
+              inst_del)                            
+
+   polarity = (inst_del +
+               cmd_polarity +
+               (cmd_polarity_opt_dark | cmd_polarity_opt_clear) +
+               inst_end +
+               inst_del)                            
+
+   closed_shape_start = cmd_closed_shape_start + inst_end
+   closed_shape_end = cmd_closed_shape_end + inst_end
+
+   draw = (pyp.Optional(cmd_linear_int) +
+           pyp.Group(coord_xy + cmd_draw) +
+           inst_end)
+
+   move = (pyp.Optional(cmd_linear_int) +
+           pyp.Group(coord_xy + cmd_move) +
+           inst_end)
+
+   flash = (pyp.Optional(cmd_linear_int) +
+           pyp.Group(coord_xy + cmd_flash) +
+           inst_end)
+
+   apperture_change = pyp.dictOf(apperture, floatnum) + inst_end
+
+   # end of file (suppress)
+   the_end = (pyp.Literal('M02') + inst_end).suppress()
+
+   apperture_features = pyp.Group(apperture_change + pyp.OneOrMore(draw | move | flash))
+
+   grammar = (comment | units | gformat | app_def | polarity |
+              closed_shape_start | closed_shape_end |
+              apperture_features | 
+              draw | move | flash | apperture_change | the_end)
+
+   return pyp.OneOrMore(pyp.Group(grammar))
+
+
+
+
+
+def gerbers_to_svg(cfg, manufacturer='default'):
+    """
+    Takes Gerber files as input and generates an SVG of them
+    """
+
+    # directory for where to expect the Gerbers within the build path
+    # regardless of the source of the Gerbers, the PCBmodE directory
+    # structure is assumed
+    production_path = os.path.join(cfg['base_dir'],
+                                   cfg['pcbmode']['locations']['build'], 
+                                   'production')
+
+    #base_name = "%s_rev_%s" % (board_name, board_revision)
+
+
+    # outline gerber
+    #add = '_%s.%s' % ('outline', 
+    #                  filename_info['other']['outline'].get('ext'))
+    filename = os.path.join(production_path, 'redditoken_rev_A_top_copper.ger')
+
+    gerber = open(filename, 'r').read()
+
+    gerber_grammar = gerber_grammar_generator()
+
+    parsed = gerber_grammar.parseString(gerber)
+
+    for item in parsed:
+        print item
+
+#    for line in gerber:
+#       print line
+#       parsed = gerber_grammar.parseString(line)
+#       print parsed