← Back to team overview

kicad-developers team mailing list archive

Python scripting plot options .SetColor() gets ignored

 

Summary: Calling the .SetColor() to force the colour of a plotted layer
  gets ignored; the actual output is either black when in
  black-and-white mode, or KiCad's configured idea of what colour it
  should be when in colour mode.

Background:
  I'm attempting to write a python script to help me generate a "paper
  test" plot; this is an image I print on a high-res laser printer,
  with the silkscreen, solder mask areas and drill holes in the right
  places so I can lay components on top, poke TTH components through
  the paper, to check the layout is correct. Attached [1] is an example
  image.

  This exact image I generated by a long manual process:
    1) output layer gerbers from KiCad (Edge_Cuts, both SilkS, both
       Mask, drills)
    2) load gerber layers in gEDA's gerbv in stackup order:
         Drills
         Edge_Cuts
         *.SilkS
         *.Mask
    3) set every layer's colour to black, except the Mask layers which
       are 50% grey
    4) Make just drills/edge/fronts visible and export an SVG file
    5) Make just drills/edge/backs visible and export another SVG
    6) Create a new image file in Inkscape
    7) Import both SVG files
    8) Horizontally flip one of the files

  As you can see that's quite a long manual process, involving many
  steps that are prone to subtle error. I'd like to automate it.

To that end, I've taken one of the example python demo scripts and
tried to modify it to help generate these SVG files. But so far I have
limited success.

I see that the API allows me, in theory, to set the colour that the
plotter is about to use to plot a layer. Based on the example script, I
wrote my own (attached [2]). Centrally, the loop appears:

  for layer, colour in layers:
      pctl.SetLayer(layer)
      popt.SetColor(colour)
      popt.SetReferenceColor(colour)
      pctl.PlotLayer()

I can't get this to work - it always wants to output in the colours
that KiCad itself is configured to use. In desperation, I tried instead
altering the colours that the board is configured to use, and that
actually has an effect. 

for layer, colour in layers:
    pctl.SetLayer(layer)
    board.GetColorsSettings().SetLayerColor(layer, colour)
    popt.SetReferenceColor(colour)
    pctl.PlotLayer()

It almost works. This works fine for the Edge_Cuts and F_SilkS layers,
but still the F_Mask layer comes out in "front copper" red.

I've started staring into the depths of the code to work out why and
how it's currently working and I mostly have an idea, but before I
spend too much longer on it, my question is:

  Is this *supposed* to work?

I.e. am I supposed to be able to force the output in the plotter of one
of these layers, overriding anything KiCad wants to do by way of
colours, by calling this API? Failing that, is there some other method?
If there isn't, could one be added?

I would like the ability to force the colour of an output layer - I
want to plot every layer in total process black, except the masks which
want to be 50% grey. The reason is that a laser printer can get much
higher resolution in pure black than it can trying to halftone, but yet
I want the mask layers distinct from the solid black of the drill hit
inside it.

Can we find a way to let me do this?

-- 
Paul "LeoNerd" Evans

leonerd@xxxxxxxxxxxxxx
http://www.leonerd.org.uk/  |  https://metacpan.org/author/PEVANS

Attachment: papertest.png
Description: PNG image

import sys

from pcbnew import *
filename=sys.argv[1]

board = LoadBoard(filename)

pctl = PLOT_CONTROLLER(board)

popt = pctl.GetPlotOptions()

popt.SetOutputDirectory("plot/")

# Set some important plot options:
popt.SetPlotFrameRef(False)
popt.SetLineWidth(FromMM(0.35))

popt.SetAutoScale(False)
popt.SetScale(1)
popt.SetMirror(False)
popt.SetExcludeEdgeLayer(True);

popt.SetPlotReference(True)
popt.SetPlotValue(False)
popt.SetPlotInvisibleText(False)

pctl.OpenPlotfile("papertest-front", PLOT_FORMAT_PDF, "Papertest (front)")
pctl.SetColorMode(True)

layers = (
    (Edge_Cuts, BLACK),
    # TODO: drills??
    (F_SilkS, BLACK),
    #(F_Mask, DARKGRAY),
)

for layer, colour in layers:
    pctl.SetLayer(layer)
    # popt.SetColor(colour)
    board.GetColorsSettings().SetLayerColor(layer, colour)
    popt.SetReferenceColor(colour)
    pctl.PlotLayer()

pctl.ClosePlot()

Attachment: pgp_tj5eKgVo9.pgp
Description: OpenPGP digital signature


Follow ups