Added option to generate a better frame on pcb_print (KiCad 6)

- Also documented more details about pcb_print.
This commit is contained in:
Salvador E. Tropea 2022-04-11 19:02:26 -03:00
parent 267a38c32f
commit 1507300fe4
7 changed files with 67 additions and 21 deletions

View File

@ -645,6 +645,7 @@ The available values for *type* are:
- `svg_sch_print` schematic in SVG format
- `pdf_pcb_print` PDF file containing one or more layer and the page frame
- `svg_pcb_print` SVG file containing one or more layer and the page frame
- `pcb_print` PDF/SVG, similar to `pdf_pcb_print` and `svg_pcb_print`, with more flexibility
- `report` generates a report about the PDF. Can include images from the above outputs.
- Bill of Materials
- `bom` The internal BoM generator.
@ -1519,7 +1520,9 @@ Next time you need this list just use an alias, like this:
* PCB Print
* Type: `pcb_print`
* Description: Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print`.
* Description: Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print` and `svg_pcb_print`.
KiCad 5: including the frame is slow.
KiCad 6: for custom frames use the `enable_ki6_frame_fix`, is slow.
* Valid keys:
- `comment`: [string=''] A comment for documentation purposes.
- `dir`: [string='./'] Output directory for the generated files. If it starts with `+` the rest is concatenated to the default dir.
@ -1536,6 +1539,9 @@ Next time you need this list just use an alias, like this:
- `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted.
A short-cut to use for simple cases where a variant is an overkill.
- `drill_marks`: [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale).
- `enable_ki6_frame_fix`: [boolean=false] KiCad 6 doesn't support custom title-block/frames from Python.
This option uses KiCad GUI to print the frame, is slow, but works.
Always enabled for KiCad 5, which crashes if we try to plot the frame.
- `format`: [string='PDF'] [PDF,SVG] Format for the output file/s.
- `hide_excluded`: [boolean=false] Hide components in the Fab layer that are marked as excluded by a variant.
- `output`: [string='%f-%i%I%v.%x'] Filename for the output (%i=assembly, %x=pdf)/(%i=assembly_page_NN, %x=svg). Affected by global options.
@ -1695,6 +1701,7 @@ Next time you need this list just use an alias, like this:
* Description: Exports the PCB to the most common exchange format. Suitable for printing.
This is the main format to document your PCB.
This output is what you get from the 'File/Print' menu in pcbnew.
The `pcb_print` is an alternative.
* Valid keys:
- `comment`: [string=''] A comment for documentation purposes.
- `dir`: [string='./'] Output directory for the generated files. If it starts with `+` the rest is concatenated to the default dir.
@ -2096,6 +2103,7 @@ Next time you need this list just use an alias, like this:
* Type: `svg_pcb_print`
* Description: Exports the PCB to the scalable vector graphics format.
This output is what you get from the 'File/Print' menu in pcbnew.
The `pcb_print` is an alternative.
* Valid keys:
- `comment`: [string=''] A comment for documentation purposes.
- `dir`: [string='./'] Output directory for the generated files. If it starts with `+` the rest is concatenated to the default dir.

View File

@ -438,6 +438,7 @@ The available values for *type* are:
- `svg_sch_print` schematic in SVG format
- `pdf_pcb_print` PDF file containing one or more layer and the page frame
- `svg_pcb_print` SVG file containing one or more layer and the page frame
- `pcb_print` PDF/SVG, similar to `pdf_pcb_print` and `svg_pcb_print`, with more flexibility
- `report` generates a report about the PDF. Can include images from the above outputs.
- Bill of Materials
- `bom` The internal BoM generator.

View File

@ -952,8 +952,10 @@ outputs:
# Don't use the `kicost_variant` when using internal variants/filters
variant: ''
# PCB Print:
# KiCad 5: including the frame is slow.
# KiCad 6: for custom frames use the `enable_ki6_frame_fix`, is slow.
- name: 'pcb_print_example'
comment: 'Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print`.'
comment: 'Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print` and `svg_pcb_print`.'
type: 'pcb_print'
dir: 'Example/pcb_print_dir'
options:
@ -966,6 +968,10 @@ outputs:
dnf_filter: '_none'
# [string='full'] What to use to indicate the drill places, can be none, small or full (for real scale)
drill_marks: 'full'
# [boolean=false] KiCad 6 doesn't support custom title-block/frames from Python.
# This option uses KiCad GUI to print the frame, is slow, but works.
# Always enabled for KiCad 5, which crashes if we try to plot the frame
enable_ki6_frame_fix: false
# [string='PDF'] [PDF,SVG] Format for the output file/s
format: 'PDF'
# [boolean=false] Hide components in the Fab layer that are marked as excluded by a variant
@ -1142,6 +1148,7 @@ outputs:
# PDF PCB Print (Portable Document Format):
# This is the main format to document your PCB.
# This output is what you get from the 'File/Print' menu in pcbnew.
# The `pcb_print` is an alternative.
- name: 'pdf_pcb_print_example'
comment: 'Exports the PCB to the most common exchange format. Suitable for printing.'
type: 'pdf_pcb_print'
@ -1554,6 +1561,7 @@ outputs:
layers: all
# SVG PCB Print (Scalable Vector Graphics):
# This output is what you get from the 'File/Print' menu in pcbnew.
# The `pcb_print` is an alternative.
- name: 'svg_pcb_print_example'
comment: 'Exports the PCB to the scalable vector graphics format.'
type: 'svg_pcb_print'

View File

@ -71,23 +71,40 @@ def load_svg(file, color, black_holes, monochrome):
if black_holes:
content = content.replace('#FFFFFF', '**black_hole**')
if color != '#000000':
# Files plotted
content = content.replace('#000000', color)
# Files generated by "Print"
content = content.replace('stroke:rgb(0%,0%,0%)', 'stroke:'+color)
if black_holes:
content = content.replace('**black_hole**', '#000000')
return content
def get_width(svg):
""" Finds the width in viewBox units """
return float(svg.root.get('viewBox').split(' ')[2])
def merge_svg(input_folder, input_files, output_folder, output_file, black_holes, monochrome):
""" Merge all pages into one """
first = True
for (file, color) in input_files:
file = os.path.join(input_folder, file)
new_layer = fromstring(load_svg(file, color, black_holes, monochrome))
width = get_width(new_layer)
if first:
svg_out = new_layer
# This is the width declared at the beginning of the file
base_width = width
first = False
else:
root = new_layer.getroot()
# Adjust the coordinates of this section to the main width
scale = base_width/width
if scale != 1.0:
logger.debug(' - Scaling {} by {}'.format(file, scale))
for e in root:
e.scale(scale)
root.moveto(1, 1)
svg_out.append([root])
svg_out.save(os.path.join(output_folder, output_file))
@ -230,6 +247,10 @@ class PCB_PrintOptions(VariantOptions):
Usually user colors are stored as `user`, but you can give it another name """
self.plot_sheet_reference = True
""" Include the title-block """
self.enable_ki6_frame_fix = False
""" KiCad 6 doesn't support custom title-block/frames from Python.
This option uses KiCad GUI to print the frame, is slow, but works.
Always enabled for KiCad 5, which crashes if we try to plot the frame """
self.pages = PagesOptions
""" [list(dict)] List of pages to include in the output document.
Each page contains one or more layers of the PCB """
@ -291,38 +312,38 @@ class PCB_PrintOptions(VariantOptions):
def get_targets(self, out_dir):
return [self._parent.expand_filename(out_dir, self.output)]
def clear_edge_cuts(self):
def clear_layer(self, layer):
tmp_layer = GS.board.GetLayerID(GS.work_layer)
edge = GS.board.GetLayerID('Edge.Cuts')
cleared_layer = GS.board.GetLayerID(layer)
moved = []
for g in GS.board.GetDrawings():
if g.GetLayer() == edge:
if g.GetLayer() == cleared_layer:
g.SetLayer(tmp_layer)
moved.append(g)
for m in GS.get_modules():
for gi in m.GraphicalItems():
if gi.GetLayer() == edge:
if gi.GetLayer() == cleared_layer:
gi.SetLayer(tmp_layer)
moved.append(gi)
self.moved_items = moved
self.edge_layer = edge
self.cleared_layer = cleared_layer
def restore_edge_cuts(self):
def restore_layer(self):
for g in self.moved_items:
g.SetLayer(self.edge_layer)
g.SetLayer(self.cleared_layer)
def plot_frame_ki6(self, pc, po, p):
""" KiCad 6 can plot the frame because it loads the worksheet format """
self.clear_edge_cuts()
self.clear_layer('Edge.Cuts')
po.SetPlotFrameRef(True)
po.SetScale(1.0)
po.SetNegative(False)
pc.SetLayer(self.edge_layer)
pc.OpenPlotfile('frame', PLOT_FORMAT_SVG, p.sheet)
pc.PlotLayer()
self.restore_edge_cuts()
self.restore_layer()
def plot_frame_ki5(self, dir_name):
def plot_frame_ki5(self, dir_name, layer='Edge.Cuts'):
""" KiCad 5 crashes if we try to print the frame.
So we print a frame using pcbnew_do export.
We use SVG output to then generate a vectorized PDF. """
@ -330,14 +351,14 @@ class PCB_PrintOptions(VariantOptions):
check_script(CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, '1.6.7')
# Move all the drawings away
# KiCad 5 always prints Edge.Cuts, so we make it empty
self.clear_edge_cuts()
self.clear_layer(layer)
# Save the PCB
pcb_name, pcb_dir = self.save_tmp_dir_board('pcb_print')
# Restore the layer
self.restore_edge_cuts()
self.restore_layer()
# Output file name
cmd = [CMD_PCBNEW_PRINT_LAYERS, 'export', '--output_name', output, '--monochrome', '--svg',
pcb_name, dir_name, 'Edge.Cuts']
cmd = [CMD_PCBNEW_PRINT_LAYERS, 'export', '--output_name', output, '--monochrome', '--svg', '--pads', '0',
pcb_name, dir_name, layer]
cmd, video_remove = add_extra_options(cmd)
# Execute it
ret = exec_with_retry(cmd)
@ -398,7 +419,10 @@ class PCB_PrintOptions(VariantOptions):
if self.plot_sheet_reference:
logger.debug('- Plotting the frame')
if GS.ki6():
self.plot_frame_ki6(pc, po, p)
if self.enable_ki6_frame_fix:
self.plot_frame_ki5(temp_dir)
else:
self.plot_frame_ki6(pc, po, p)
else:
self.plot_frame_ki5(temp_dir)
color = p.sheet_reference_color if p.sheet_reference_color else self._color_theme.pcb_frame
@ -431,7 +455,9 @@ class PCB_PrintOptions(VariantOptions):
@output_class
class PCB_Print(BaseOutput): # noqa: F821
""" PCB Print
Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print`. """
Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print` and `svg_pcb_print`.
KiCad 5: including the frame is slow.
KiCad 6: for custom frames use the `enable_ki6_frame_fix`, is slow. """
def __init__(self):
super().__init__()
with document:

View File

@ -27,7 +27,8 @@ class PDF_PCB_Print(BaseOutput): # noqa: F821
""" PDF PCB Print (Portable Document Format)
Exports the PCB to the most common exchange format. Suitable for printing.
This is the main format to document your PCB.
This output is what you get from the 'File/Print' menu in pcbnew. """
This output is what you get from the 'File/Print' menu in pcbnew.
The `pcb_print` is an alternative. """
def __init__(self):
super().__init__()
with document:

View File

@ -41,7 +41,8 @@ class SVG_PCB_PrintOptions(Any_PCB_PrintOptions):
class SVG_PCB_Print(BaseOutput): # noqa: F821
""" SVG PCB Print (Scalable Vector Graphics)
Exports the PCB to the scalable vector graphics format.
This output is what you get from the 'File/Print' menu in pcbnew. """
This output is what you get from the 'File/Print' menu in pcbnew.
The `pcb_print` is an alternative. """
def __init__(self):
super().__init__()
with document:

View File

@ -13,7 +13,8 @@ outputs:
# drill_marks: small
title: Chau
# plot_sheet_reference: false
format: 'SVG'
# format: 'SVG'
enable_ki6_frame_fix: true
pages:
- # monochrome: true
scaling: 2.0