Skip to content

Commit

Permalink
[Position][Added] Experimental support for gerber position files
Browse files Browse the repository at this point in the history
Closes #500
  • Loading branch information
set-soft committed Oct 2, 2023
1 parent bd08160 commit d0c489e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for CURRENT_DATE text variable
- Populate:
- Basic support for regular list items (#480)
- Position:
- Experimental support for gerber position files (#500)
- Help for the error levels
- Warnings:
- Explain about wrong dir/output separation (#493)
Expand Down
15 changes: 10 additions & 5 deletions docs/samples/generic_plot.kibot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2769,15 +2769,19 @@ outputs:
# [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
dnf_filter: '_none'
# [string='ASCII'] [ASCII,CSV] Format for the position file
# [string='ASCII'] [ASCII,CSV,GBR] Format for the position file.
# Note that the gerber format (GBR) needs KiCad 7+ and doesn't support most of the options.
# Only the options that explicitly say the format is supported
format: 'ASCII'
# [boolean=false] Include the board edge in the gerber output
gerber_board_edge: false
# [boolean=false] Include virtual components. For special purposes, not pick & place.
# Note that virtual components is a KiCad 5 concept.
# For KiCad 6+ we replace this concept by the option to exclude from position file
include_virtual: false
# [boolean=true] Only include the surface mount components
only_smd: true
# [string='%f-%i%I%v.%x'] Output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv').
# [string='%f-%i%I%v.%x'] Output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv'|'gbr').
# Important: when using separate files you must use `%i` to differentiate them. Affected by global options
output: '%f-%i%I%v.%x'
# [string|list(string)='_none'] Name of the filter to transform fields before applying other filters.
Expand All @@ -2791,7 +2795,8 @@ outputs:
separate_files_for_front_and_back: true
# [string='millimeters'] [millimeters,inches,mils] Units used for the positions. Affected by global options
units: 'millimeters'
# [boolean=true] Use the auxiliary axis as origin for coordinates (KiCad default)
# [boolean=true] Use the auxiliary axis as origin for coordinates (KiCad default).
# Supported by the gerber format
use_aux_axis_as_origin: true
# [string=''] Board variant to apply
variant: ''
Expand Down Expand Up @@ -2924,8 +2929,8 @@ outputs:
options:
# [string='QR'] Short name for the library
lib: 'QR'
# [string='%f-%i%I%v.%x'] Filename/dirname for the output (%i=qr, %x=lib/kicad_sym/pretty).
# You must use %x in the name to get a symbols lib and a footprint. Affected by global options
# [string='%f-%i%I%v.%x'] Filename/dirname for the output library (%i=qr, %x=lib/kicad_sym/pretty).
# You must use %x in the name to get a symbols lib and a footprints lib. Affected by global options
output: '%f-%i%I%v.%x'
# [list(dict)] QR codes to include in the library
qrs:
Expand Down
8 changes: 6 additions & 2 deletions docs/source/configuration/outputs/position.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ Parameters:

- Valid keys:

- **format** :index:`: <pair: output - position - options; format>` [string='ASCII'] [ASCII,CSV] Format for the position file.
- **format** :index:`: <pair: output - position - options; format>` [string='ASCII'] [ASCII,CSV,GBR] Format for the position file.
Note that the gerber format (GBR) needs KiCad 7+ and doesn't support most of the options.
Only the options that explicitly say the format is supported.
- **only_smd** :index:`: <pair: output - position - options; only_smd>` [boolean=true] Only include the surface mount components.
- **output** :index:`: <pair: output - position - options; output>` [string='%f-%i%I%v.%x'] Output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv').
- **output** :index:`: <pair: output - position - options; output>` [string='%f-%i%I%v.%x'] Output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv'|'gbr').
Important: when using separate files you must use `%i` to differentiate them. Affected by global options.
- **separate_files_for_front_and_back** :index:`: <pair: output - position - options; separate_files_for_front_and_back>` [boolean=true] Generate two separated files, one for the top and another for the bottom.
- **units** :index:`: <pair: output - position - options; units>` [string='millimeters'] [millimeters,inches,mils] Units used for the positions. Affected by global options.
Expand All @@ -41,6 +43,7 @@ Parameters:
- ``dnf_filter`` :index:`: <pair: output - position - options; 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.

- ``gerber_board_edge`` :index:`: <pair: output - position - options; gerber_board_edge>` [boolean=false] Include the board edge in the gerber output.
- ``include_virtual`` :index:`: <pair: output - position - options; include_virtual>` [boolean=false] Include virtual components. For special purposes, not pick & place.
Note that virtual components is a KiCad 5 concept.
For KiCad 6+ we replace this concept by the option to exclude from position file.
Expand All @@ -50,6 +53,7 @@ Parameters:
- ``quote_all`` :index:`: <pair: output - position - options; quote_all>` [boolean=false] When generating the CSV quote all values, even numbers.
- ``right_digits`` :index:`: <pair: output - position - options; right_digits>` [number=4] number of digits for mantissa part of coordinates (0 is auto).
- ``use_aux_axis_as_origin`` :index:`: <pair: output - position - options; use_aux_axis_as_origin>` [boolean=true] Use the auxiliary axis as origin for coordinates (KiCad default).
Supported by the gerber format.
- ``variant`` :index:`: <pair: output - position - options; variant>` [string=''] Board variant to apply.

- **type** :index:`: <pair: output - position; type>` [string=''] Type of output.
Expand Down
4 changes: 2 additions & 2 deletions docs/source/configuration/outputs/qr_lib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Parameters:
- Valid keys:

- **lib** :index:`: <pair: output - qr_lib - options; lib>` [string='QR'] Short name for the library.
- **output** :index:`: <pair: output - qr_lib - options; output>` [string='%f-%i%I%v.%x'] Filename/dirname for the output (%i=qr, %x=lib/kicad_sym/pretty).
You must use %x in the name to get a symbols lib and a footprint. Affected by global options.
- **output** :index:`: <pair: output - qr_lib - options; output>` [string='%f-%i%I%v.%x'] Filename/dirname for the output library (%i=qr, %x=lib/kicad_sym/pretty).
You must use %x in the name to get a symbols lib and a footprints lib. Affected by global options.
- **qrs** :index:`: <pair: output - qr_lib - options; qrs>` [list(dict)] QR codes to include in the library.

- Valid keys:
Expand Down
41 changes: 34 additions & 7 deletions kibot/out_position.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2023 Salvador E. Tropea
# Copyright (c) 2020-2023 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2019 Romain Deterre (@rdeterre)
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
Expand All @@ -10,6 +10,7 @@
from datetime import datetime
from collections import OrderedDict
from .gs import GS
from .kiplot import run_command
from .misc import UI_SMD, UI_VIRTUAL, MOD_THROUGH_HOLE, MOD_SMD, MOD_EXCLUDE_FROM_POS_FILES
from .optionable import Optionable
from .out_base import VariantOptions
Expand Down Expand Up @@ -60,13 +61,15 @@ class PositionOptions(VariantOptions):
def __init__(self):
with document:
self.format = 'ASCII'
""" *[ASCII,CSV] Format for the position file """
""" *[ASCII,CSV,GBR] Format for the position file.
Note that the gerber format (GBR) needs KiCad 7+ and doesn't support most of the options.
Only the options that explicitly say the format is supported """
self.separate_files_for_front_and_back = True
""" *Generate two separated files, one for the top and another for the bottom """
self.only_smd = True
""" *Only include the surface mount components """
self.output = GS.def_global_output
""" *Output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv').
""" *Output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv'|'gbr').
Important: when using separate files you must use `%i` to differentiate them """
self.units = 'millimeters'
""" *[millimeters,inches,mils] Units used for the positions. Affected by global options """
Expand All @@ -78,13 +81,16 @@ def __init__(self):
self.bottom_negative_x = False
""" Use negative X coordinates for footprints on bottom layer """
self.use_aux_axis_as_origin = True
""" Use the auxiliary axis as origin for coordinates (KiCad default) """
""" Use the auxiliary axis as origin for coordinates (KiCad default).
Supported by the gerber format """
self.include_virtual = False
""" Include virtual components. For special purposes, not pick & place.
Note that virtual components is a KiCad 5 concept.
For KiCad 6+ we replace this concept by the option to exclude from position file """
self.quote_all = False
""" When generating the CSV quote all values, even numbers """
self.gerber_board_edge = False
""" Include the board edge in the gerber output """
super().__init__()
self._expand_id = 'position'

Expand All @@ -105,7 +111,7 @@ def config(self, parent):
new_name = col.name if col.name else new_col
new_columns[new_col] = new_name
self.columns = new_columns
self._expand_ext = 'pos' if self.format == 'ASCII' else 'csv'
self._expand_ext = 'pos' if self.format == 'ASCII' else self.format.lower()

def _do_position_plot_ascii(self, output_dir, columns, modulesStr, maxSizes, modules_side):
topf = None
Expand Down Expand Up @@ -224,10 +230,31 @@ def get_targets(self, out_dir):
self.expand_filename(out_dir, self.output, 'bottom_pos', ext)]
return [self.expand_filename(out_dir, self.output, 'both_pos', ext)]

def run_gerber(self, output_dir):
if not GS.ki7:
raise KiPlotConfigurationError("Gerber position needs KiCad 7+")

pcb_name = self.save_tmp_board_if_variant()
cmd_base = ['kicad-cli', 'pcb', 'export', 'pos', '--format', 'gerber']
if self.use_aux_axis_as_origin:
cmd_base.append('--use-drill-file-origin')
if self.gerber_board_edge:
cmd_base.append('--gerber-board-edge')
cmd_base.append('--side')

fname = self.expand_filename(output_dir, self.output, 'top_pos', self._expand_ext)
run_command(cmd_base+['front', '-o', fname, pcb_name])

fname = self.expand_filename(output_dir, self.output, 'bottom_pos', self._expand_ext)
run_command(cmd_base+['back', '-o', fname, pcb_name])

def run(self, fname):
super().run(fname)
self.filter_pcb_components()
output_dir = os.path.dirname(fname)
if self.format == 'GBR':
self.run_gerber(output_dir)
return
self.filter_pcb_components()
columns = self.columns.values()
conv = GS.unit_name_to_scale_factor(self.units)
# Format all strings
Expand Down
10 changes: 10 additions & 0 deletions tests/test_plot/test_position.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,13 @@ def test_position_flags_3(test_dir):
ctx.run()
check_comp_list(ctx.load_csv(prj+'-both_pos.csv')[0], {'R1', 'R2', 'R3'})
ctx.clean_up()


@pytest.mark.skipif(not context.ki7(), reason="needs kicad-cli")
def test_position_gerber_1(test_dir):
prj = 'light_control'
ctx = context.TestContext(test_dir, prj, 'simple_position_gbr', POS_DIR)
ctx.run()
ctx.expect_out_file_d(prj+'-top_pos.gbr')
ctx.expect_out_file_d(prj+'-bottom_pos.gbr')
ctx.clean_up(keep_project=True)
11 changes: 11 additions & 0 deletions tests/yaml_samples/simple_position_gbr.kibot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Example KiBot config file for a basic 2-layer board
kibot:
version: 1

outputs:

- name: 'position'
type: position
dir: positiondir
options:
format: GBR

0 comments on commit d0c489e

Please sign in to comment.