#NEWLINE# def extractRouting( svg_in ) : #NEWLINE# #INDENT# "\n    Extracts routing from the the 'routing' SVG layers of each PCB layer.\n    Inkscape SVG layers for each PCB ('top', 'bottom', etc.) layer.\n    " #NEWLINE# output_file = os . path . join ( config . cfg [ 'base-dir' ] , ( config . cfg [ 'name' ] + '_routing.json' ) ) #NEWLINE# try : #NEWLINE# #INDENT# routing_dict_old = utils . dictFromJsonFile ( output_file , False ) #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# routing_dict_old = { #NEWLINE# #INDENT# 'routes' : { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } , #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# routing_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# xpath_expr = "//svg:g[@pcbmode:pcb-layer='%s']//svg:g[@pcbmode:sheet='routing']//svg:path[(@d) and not (@pcbmode:type='via')]" #NEWLINE# routes_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# for pcb_layer in config . stk [ 'layer-names' ] : #NEWLINE# #INDENT# routes = svg_in . xpath ( ( xpath_expr % pcb_layer ) , namespaces = { #NEWLINE# #INDENT# 'pcbmode' : config . cfg [ 'ns' ] [ 'pcbmode' ] , #NEWLINE# 'svg' : config . cfg [ 'ns' ] [ 'svg' ] , #NEWLINE# #UNINDENT# } ) #NEWLINE# for route in routes : #NEWLINE# #INDENT# route_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# route_id = route . get ( ( ( '{' + config . cfg [ 'ns' ] [ 'pcbmode' ] ) + '}id' ) ) #NEWLINE# path = route . get ( 'd' ) #NEWLINE# style_text = ( route . get ( 'style' ) or '' ) #NEWLINE# digest = utils . digest ( ( path + style_text ) ) #NEWLINE# try : #NEWLINE# #INDENT# routes_dict [ pcb_layer ] [ digest ] = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# routes_dict [ pcb_layer ] = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# routes_dict [ pcb_layer ] [ digest ] = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# routes_dict [ pcb_layer ] [ digest ] [ 'type' ] = 'path' #NEWLINE# routes_dict [ pcb_layer ] [ digest ] [ 'value' ] = path #NEWLINE# stroke_width = utils . getStyleAttrib ( style_text , 'stroke-width' ) #NEWLINE# if ( stroke_width != None ) : #NEWLINE# #INDENT# stroke_width = stroke_width . rstrip ( 'px' ) #NEWLINE# routes_dict [ pcb_layer ] [ digest ] [ 'style' ] = 'stroke' #NEWLINE# routes_dict [ pcb_layer ] [ digest ] [ 'stroke-width' ] = round ( float ( stroke_width ) , 4 ) #NEWLINE# #UNINDENT# custom_buffer = route . get ( ( ( '{' + config . cfg [ 'ns' ] [ 'pcbmode' ] ) + '}buffer-to-pour' ) ) #NEWLINE# if ( custom_buffer != None ) : #NEWLINE# #INDENT# routes_dict [ pcb_layer ] [ digest ] [ 'buffer-to-pour' ] = float ( custom_buffer ) #NEWLINE# #UNINDENT# gerber_lp = route . get ( ( ( '{' + config . cfg [ 'ns' ] [ 'pcbmode' ] ) + '}gerber-lp' ) ) #NEWLINE# if ( gerber_lp != None ) : #NEWLINE# #INDENT# routes_dict [ pcb_layer ] [ digest ] [ 'gerber-lp' ] = gerber_lp #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# routing_dict [ 'routes' ] = routes_dict #NEWLINE# total = 0 #NEWLINE# total_old = 0 #NEWLINE# new = 0 #NEWLINE# existing = 0 #NEWLINE# for pcb_layer in config . stk [ 'layer-names' ] : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# total += len ( routing_dict [ 'routes' ] [ pcb_layer ] ) #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# new_dict = routing_dict [ 'routes' ] [ pcb_layer ] #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# new_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# old_dict = routing_dict_old [ 'routes' ] [ pcb_layer ] #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# old_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# for key in new_dict : #NEWLINE# #INDENT# if ( key not in old_dict ) : #NEWLINE# #INDENT# new += 1 #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# existing += 1 #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# for pcb_layer in config . stk [ 'layer-names' ] : #NEWLINE# #INDENT# total_old += len ( old_dict ) #NEWLINE# #UNINDENT# message = ( 'Extracted %s routes; %s new (or modified), %s existing' % ( total , new , existing ) ) #NEWLINE# if ( total_old > total ) : #NEWLINE# #INDENT# message += ( ', %s removed' % ( total_old - total ) ) #NEWLINE# #UNINDENT# msg . subInfo ( message ) #NEWLINE# xpath_expr_place = '//svg:g[@pcbmode:pcb-layer="%s"]//svg:g[@pcbmode:sheet="placement"]//svg:g[@pcbmode:type="via"]' #NEWLINE# vias_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# for pcb_layer in config . stk [ 'surface-layer-names' ] : #NEWLINE# #INDENT# markers = svg_in . findall ( ( xpath_expr_place % pcb_layer ) , namespaces = { #NEWLINE# #INDENT# 'pcbmode' : config . cfg [ 'ns' ] [ 'pcbmode' ] , #NEWLINE# 'svg' : config . cfg [ 'ns' ] [ 'svg' ] , #NEWLINE# #UNINDENT# } ) #NEWLINE# for marker in markers : #NEWLINE# #INDENT# transform_data = utils . parseTransform ( marker . get ( 'transform' ) ) #NEWLINE# location = transform_data [ 'location' ] #NEWLINE# location . y *= config . cfg [ 'invert-y' ] #NEWLINE# if ( transform_data [ 'type' ] == 'matrix' ) : #NEWLINE# #INDENT# rotate = transform_data [ 'rotate' ] #NEWLINE# rotate = utils . niceFloat ( ( rotate % 360 ) ) #NEWLINE# #UNINDENT# digest = utils . digest ( ( '%s%s' % ( location . x , location . y ) ) ) #NEWLINE# vias_dict [ digest ] = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# vias_dict [ digest ] [ 'footprint' ] = marker . get ( ( ( '{' + config . cfg [ 'ns' ] [ 'pcbmode' ] ) + '}footprint' ) ) #NEWLINE# vias_dict [ digest ] [ 'location' ] = [ utils . niceFloat ( location . x ) , utils . niceFloat ( location . y ) ] #NEWLINE# vias_dict [ digest ] [ 'layer' ] = 'top' #NEWLINE# #UNINDENT# #UNINDENT# routing_dict [ 'vias' ] = vias_dict #NEWLINE# if ( len ( vias_dict ) == 0 ) : #NEWLINE# #INDENT# msg . subInfo ( 'No vias found' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( vias_dict ) == 1 ) : #NEWLINE# #INDENT# msg . subInfo ( 'Extracted 1 via' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# msg . subInfo ( ( 'Extracted %s vias' % len ( vias_dict ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# try : #NEWLINE# #INDENT# with open ( output_file , 'wb' ) as f : #NEWLINE# #INDENT# f . write ( json . dumps ( routing_dict , sort_keys = True , indent = 2 ) ) #NEWLINE# #UNINDENT# #UNINDENT# except : #NEWLINE# #INDENT# msg . error ( ( 'Cannot save file %s' % output_file ) ) #NEWLINE# #UNINDENT# return