From b47ffd70549fd53a612af005f7dff4738f7d39a2 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 1 Aug 2018 16:31:50 +0200 Subject: [PATCH] Update python scripts examples according to recent changes in pcbnew code. Add a new example to plot files --- pcbnew/python/examples/createFPC40.py | 2 +- pcbnew/python/examples/createPcb.py | 10 +- .../gen_gerber_and_drill_files_board.py | 150 ++++++++++++++++++ pcbnew/python/examples/listPcb.py | 4 +- 4 files changed, 158 insertions(+), 8 deletions(-) create mode 100644 pcbnew/python/examples/gen_gerber_and_drill_files_board.py diff --git a/pcbnew/python/examples/createFPC40.py b/pcbnew/python/examples/createFPC40.py index 9db68191b4..f0d9d7d5c7 100644 --- a/pcbnew/python/examples/createFPC40.py +++ b/pcbnew/python/examples/createFPC40.py @@ -49,7 +49,7 @@ e.SetShape(S_SEGMENT) module.Add(e) # save the footprint to disk -fpid = LIB_ID("FPC"+str(pads)) #the name in library +fpid = LIB_ID("", "FPC"+str(pads)) #the curr lin nickname (empty) and the name in library module.SetFPID( fpid ) lib_name = "fpc40.pretty" #lib_path is actually a path, not a file diff --git a/pcbnew/python/examples/createPcb.py b/pcbnew/python/examples/createPcb.py index 1c32670a09..1f4a8546b0 100644 --- a/pcbnew/python/examples/createPcb.py +++ b/pcbnew/python/examples/createPcb.py @@ -7,12 +7,13 @@ size_1_0mm = wxSizeMM(1.0,1.0) # create a blank board pcb = BOARD() -pcb.m_NetClasses.GetDefault().SetClearance(FromMM(0.1)) +pcb.GetNetClasses().GetDefault().SetClearance(FromMM(0.1)) # create a new module, it's parent is our previously created pcb module = MODULE(pcb) module.SetReference("M1") # give it a reference name -module.Reference().SetPos0(wxPointMM(-10,-10)) +module.Reference().SetPos0(wxPointMM(6,-2)) +module.Reference().SetDrawCoord() pcb.Add(module) # add it to our pcb m_pos = wxPointMM(50,50) module.SetPosition(m_pos) @@ -26,7 +27,7 @@ for y in range (0,10): pad.SetSize(size_1_0mm) pt = wxPointMM(1.27*x,1.27*y) pad.SetPos0(pt); - #pad.SetPosition(pt) + pad.SetDrawCoord() pad.SetName(str(n)) module.Add(pad) n+=1 @@ -34,7 +35,6 @@ for y in range (0,10): # save the PCB to disk pcb.Save("my2.kicad_pcb") -pcb.Save("my2.brd") pcb = LoadBoard("my2.kicad_pcb") @@ -42,7 +42,7 @@ print map( lambda x: x.GetReference() , list(pcb.GetModules())) for m in pcb.GetModules(): for p in m.Pads(): - print p.GetName(), p.GetPosition(), p.GetOffset() + print 'pad ', p.GetName(), p.GetPosition(), p.GetOffset() # pcb.GetDesignSettings() diff --git a/pcbnew/python/examples/gen_gerber_and_drill_files_board.py b/pcbnew/python/examples/gen_gerber_and_drill_files_board.py new file mode 100644 index 0000000000..30f56bc057 --- /dev/null +++ b/pcbnew/python/examples/gen_gerber_and_drill_files_board.py @@ -0,0 +1,150 @@ +''' + A python script example to create plot files to build a board: + Gerber files + Drill files + Map dril files + + Important note: + this python script does not plot frame references (page layout). + the reason is it is not yet possible from a python script because plotting + plot frame references needs loading the corresponding page layout file + (.wks file) or the default template. + + This info (the page layout template) is not stored in the board, and therefore + not available. + + Do not try to change SetPlotFrameRef(False) to SetPlotFrameRef(true) + the result is the pcbnew lib will crash if you try to plot + the unknown frame references template. + + Anyway, in gerber and drill files the page layout is not plot +''' + +import sys +import os + +from pcbnew import * +filename=sys.argv[1] + +board = LoadBoard(filename) + +plotDir = "plot/" + +#prepare the gerber job file +gen_job_file=True + +pctl = PLOT_CONTROLLER(board) + +popt = pctl.GetPlotOptions() + +popt.SetOutputDirectory(plotDir) + +# Set some important plot options (see pcb_plot_params.h): +popt.SetPlotFrameRef(False) #do not change it +popt.SetLineWidth(FromMM(0.35)) + +popt.SetAutoScale(False) #do not change it +popt.SetScale(1) #do not change it +popt.SetMirror(False) +popt.SetUseGerberAttributes(True) +popt.SetIncludeGerberNetlistInfo(True) +popt.SetCreateGerberJobFile(gen_job_file) +popt.SetUseGerberProtelExtensions(False) +popt.SetExcludeEdgeLayer(False); +popt.SetScale(1) +popt.SetUseAuxOrigin(True) + +# This by gerbers only +popt.SetSubtractMaskFromSilk(False) +# Disable plot pad holes +popt.SetDrillMarksType( PCB_PLOT_PARAMS.NO_DRILL_SHAPE ); +# Skip plot pad NPTH when possible: when drill size and shape == pad size and shape +# usually sel to True for copper layers +popt.SetSkipPlotNPTH_Pads( False ); + + +#prepare the gerber job file +jobfile_writer = GERBER_JOBFILE_WRITER( board ) + +# Once the defaults are set it become pretty easy... +# I have a Turing-complete programming language here: I'll use it... +# param 0 is a string added to the file base name to identify the drawing +# param 1 is the layer ID +# param 2 is a comment +plot_plan = [ + ( "CuTop", F_Cu, "Top layer" ), + ( "CuBottom", B_Cu, "Bottom layer" ), + ( "PasteBottom", B_Paste, "Paste Bottom" ), + ( "PasteTop", F_Paste, "Paste top" ), + ( "SilkTop", F_SilkS, "Silk top" ), + ( "SilkBottom", B_SilkS, "Silk top" ), + ( "MaskBottom", B_Mask, "Mask bottom" ), + ( "MaskTop", F_Mask, "Mask top" ), + ( "EdgeCuts", Edge_Cuts, "Edges" ), +] + + +for layer_info in plot_plan: + if layer_info[1] <= B_Cu: + popt.SetSkipPlotNPTH_Pads( True ) + else: + popt.SetSkipPlotNPTH_Pads( False ) + + pctl.SetLayer(layer_info[1]) + pctl.OpenPlotfile(layer_info[0], PLOT_FORMAT_GERBER, layer_info[2]) + print 'plot %s' % pctl.GetPlotFileName() + if gen_job_file == True: + jobfile_writer.AddGbrFile( layer_info[1], os.path.basename(pctl.GetPlotFileName()) ); + if pctl.PlotLayer() == False: + print "plot error" + +#generate internal copper layers, if any +lyrcnt = board.GetCopperLayerCount(); + +for innerlyr in range ( 1, lyrcnt-1 ): + popt.SetSkipPlotNPTH_Pads( True ); + pctl.SetLayer(innerlyr) + lyrname = 'inner%s' % innerlyr + pctl.OpenPlotfile(lyrname, PLOT_FORMAT_GERBER, "inner") + print 'plot %s' % pctl.GetPlotFileName() + if pctl.PlotLayer() == False: + print "plot error" + + +# At the end you have to close the last plot, otherwise you don't know when +# the object will be recycled! +pctl.ClosePlot() + +# Fabricators need drill files. +# sometimes a drill map file is asked (for verification purpose) +drlwriter = EXCELLON_WRITER( board ) +drlwriter.SetMapFileFormat( PLOT_FORMAT_PDF ) + +mirror = False +minimalHeader = False +offset = wxPoint(0,0) +# False to generate 2 separate drill files (one for plated holes, one for non plated holes) +# True to generate only one drill file +mergeNPTH = False +drlwriter.SetOptions( mirror, minimalHeader, offset, mergeNPTH ) + +metricFmt = True +drlwriter.SetFormat( metricFmt ) + +genDrl = True +genMap = True +print 'create drill and map files in %s' % pctl.GetPlotDirName() +drlwriter.CreateDrillandMapFilesSet( pctl.GetPlotDirName(), genDrl, genMap ); + +# One can create a text file to report drill statistics +rptfn = pctl.GetPlotDirName() + 'drill_report.rpt' +print 'report: %s' % rptfn +drlwriter.GenDrillReportFile( rptfn ); + +if gen_job_file == True: + #job_fn=os.path.splitext(pctl.GetPlotFileName())[0] + '.gbrjob' + job_fn=os.path.dirname(pctl.GetPlotFileName()) + '/' + os.path.basename(filename) + job_fn=os.path.splitext(job_fn)[0] + '.gbrjob' + print 'create job file %s' % job_fn + jobfile_writer.CreateJobFile( job_fn ) + diff --git a/pcbnew/python/examples/listPcb.py b/pcbnew/python/examples/listPcb.py index 60ed093741..f36031f664 100644 --- a/pcbnew/python/examples/listPcb.py +++ b/pcbnew/python/examples/listPcb.py @@ -47,10 +47,10 @@ print "" print "LIST MODULES:" for module in pcb.GetModules(): - print "* Module: %s at %s"%(module.GetReference(),ToUnits(module.GetPosition())) + print "* Module: %s at %s"%(module.GetReference(), ToUnits(module.GetPosition())) print "" -print "Ratsnest cnt:",len(pcb.GetFullRatsnest()) +print "Nets cnt: ", pcb.GetNetCount() print "track w cnt:",len(pcb.GetTrackWidthList()) print "via s cnt:",len(pcb.GetViasDimensionsList())