Added variants suport to out_position
Also: we never include virtual components.
This commit is contained in:
parent
5e11b325a1
commit
26ee971e26
|
|
@ -827,11 +827,14 @@ Next time you need this list just use an alias, like this:
|
|||
- `name`: [string=''] Used to identify this particular output definition.
|
||||
- `options`: [dict] Options for the `position` output.
|
||||
* Valid keys:
|
||||
- `dnf_filter`: [string|list(string)=''] Name of the filter to mark components as not fitted.
|
||||
A short-cut to use for simple cases where a variant is an overkill.
|
||||
- `format`: [string='ASCII'] [ASCII,CSV] format for the position file.
|
||||
- `only_smd`: [boolean=true] only include the surface mount components.
|
||||
- `output`: [string='%f-%i%v.%x'] output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv'). Affected by global options.
|
||||
- `separate_files_for_front_and_back`: [boolean=true] generate two separated files, one for the top and another for the bottom.
|
||||
- `units`: [string='millimeters'] [millimeters,inches] units used for the positions.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
|
||||
* PS (Postscript)
|
||||
* Type: `ps`
|
||||
|
|
|
|||
|
|
@ -634,6 +634,9 @@ outputs:
|
|||
type: 'position'
|
||||
dir: 'Example/position_dir'
|
||||
options:
|
||||
# [string|list(string)=''] 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: ''
|
||||
# [string='ASCII'] [ASCII,CSV] format for the position file
|
||||
format: 'ASCII'
|
||||
# [boolean=true] only include the surface mount components
|
||||
|
|
@ -644,6 +647,8 @@ outputs:
|
|||
separate_files_for_front_and_back: true
|
||||
# [string='millimeters'] [millimeters,inches] units used for the positions
|
||||
units: 'millimeters'
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
|
||||
# PS (Postscript):
|
||||
# This output is what you get from the File/Plot menu in pcbnew.
|
||||
|
|
|
|||
|
|
@ -8,9 +8,19 @@
|
|||
import operator
|
||||
from datetime import datetime
|
||||
from pcbnew import (IU_PER_MM, IU_PER_MILS)
|
||||
from .optionable import BaseOptions
|
||||
from .optionable import BaseOptions, Optionable
|
||||
from .registrable import RegOutput
|
||||
from .gs import GS
|
||||
from .kiplot import load_sch
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from .fil_base import BaseFilter, apply_fitted_filter
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
# KiCad 5 GUI values for the attribute
|
||||
UI_THT = 0
|
||||
UI_SMD = 1
|
||||
UI_VIRTUAL = 2
|
||||
|
||||
|
||||
class PositionOptions(BaseOptions):
|
||||
|
|
@ -26,8 +36,18 @@ class PositionOptions(BaseOptions):
|
|||
""" output file name (%i='top_pos'|'bottom_pos'|'both_pos', %x='pos'|'csv') """
|
||||
self.units = 'millimeters'
|
||||
""" [millimeters,inches] units used for the positions """
|
||||
self.variant = ''
|
||||
""" Board variant(s) to apply """
|
||||
self.dnf_filter = Optionable
|
||||
""" [string|list(string)=''] Name of the filter to mark components as not fitted.
|
||||
A short-cut to use for simple cases where a variant is an overkill """
|
||||
super().__init__()
|
||||
|
||||
def config(self):
|
||||
super().config()
|
||||
self.variant = RegOutput.check_variant(self.variant)
|
||||
self.dnf_filter = BaseFilter.solve_filter(self.dnf_filter, 'dnf_filter')
|
||||
|
||||
def _do_position_plot_ascii(self, board, output_dir, columns, modulesStr, maxSizes):
|
||||
topf = None
|
||||
botf = None
|
||||
|
|
@ -120,6 +140,18 @@ class PositionOptions(BaseOptions):
|
|||
bothf.close()
|
||||
|
||||
def run(self, output_dir, board):
|
||||
comps = None
|
||||
if self.dnf_filter or self.variant:
|
||||
load_sch()
|
||||
# Get the components list from the schematic
|
||||
comps = GS.sch.get_components()
|
||||
# Apply the filter
|
||||
apply_fitted_filter(comps, self.dnf_filter)
|
||||
# Apply the variant
|
||||
if self.variant:
|
||||
# Apply the variant
|
||||
self.variant.filter(comps)
|
||||
comps_hash = {c.ref: c for c in comps}
|
||||
columns = ["Ref", "Val", "Package", "PosX", "PosY", "Rot", "Side"]
|
||||
colcount = len(columns)
|
||||
# Note: the parser already checked the units are milimeters or inches
|
||||
|
|
@ -131,12 +163,22 @@ class PositionOptions(BaseOptions):
|
|||
# Format all strings
|
||||
modules = []
|
||||
for m in sorted(board.GetModules(), key=operator.methodcaller('GetReference')):
|
||||
if (self.only_smd and m.GetAttributes() == 1) or not self.only_smd:
|
||||
ref = m.GetReference()
|
||||
# Apply any filter or variant data
|
||||
if comps:
|
||||
c = comps_hash.get(ref, None)
|
||||
if c:
|
||||
logger.debug("{} {} {}".format(ref, c.fitted, c.in_bom))
|
||||
if c and not c.fitted:
|
||||
continue
|
||||
# If passed check the position options
|
||||
if (self.only_smd and m.GetAttributes() == UI_SMD) or \
|
||||
(not self.only_smd and m.GetAttributes() != UI_VIRTUAL):
|
||||
center = m.GetCenter()
|
||||
# See PLACE_FILE_EXPORTER::GenPositionData() in
|
||||
# export_footprints_placefile.cpp for C++ version of this.
|
||||
modules.append([
|
||||
"{}".format(m.GetReference()),
|
||||
"{}".format(ref),
|
||||
"{}".format(m.GetValue()),
|
||||
"{}".format(m.GetFPID().GetLibItemName()),
|
||||
"{:.4f}".format(center.x * conv),
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ pytest-3 --log-cli-level debug
|
|||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
# Look for the 'utils' module from where the script is running
|
||||
prev_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if prev_dir not in sys.path:
|
||||
|
|
@ -145,3 +146,26 @@ def test_3Rs_position_inches_csv():
|
|||
expect_position(ctx, pos_top, ['R1'], ['R2', 'R3'], inches=True, csv=True)
|
||||
expect_position(ctx, pos_bot, ['R2'], ['R1', 'R3'], inches=True, csv=True)
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def check_comps(rows, comps):
|
||||
assert len(rows) == len(comps)
|
||||
logging.debug('{} components OK'.format(len(rows)))
|
||||
col1 = [r[0] for r in rows]
|
||||
assert col1 == comps
|
||||
logging.debug('Components list {} OK'.format(comps))
|
||||
|
||||
|
||||
def test_position_variant_t2i():
|
||||
prj = 'kibom-variant_3'
|
||||
ctx = context.TestContext('test_position_variant_t2i', prj, 'simple_position_t2i', POS_DIR)
|
||||
ctx.run()
|
||||
rows, header, info = ctx.load_csv(prj+'-both_pos.csv')
|
||||
check_comps(rows, ['R1', 'R2', 'R3'])
|
||||
rows, header, info = ctx.load_csv(prj+'-both_pos_[2].csv')
|
||||
check_comps(rows, ['R1', 'R2', 'R3'])
|
||||
rows, header, info = ctx.load_csv(prj+'-both_pos_(production).csv')
|
||||
check_comps(rows, ['C2', 'R1', 'R2', 'R3'])
|
||||
rows, header, info = ctx.load_csv(prj+'-both_pos_(test).csv')
|
||||
check_comps(rows, ['C2', 'R1', 'R3'])
|
||||
ctx.clean_up()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
variants:
|
||||
- name: 'production'
|
||||
comment: 'Production variant'
|
||||
type: ibom
|
||||
file_id: '_(production)'
|
||||
variants_blacklist: T2
|
||||
|
||||
- name: 'test'
|
||||
comment: 'Test variant'
|
||||
type: ibom
|
||||
file_id: '_(test)'
|
||||
variants_blacklist: T1
|
||||
|
||||
- name: 'default'
|
||||
comment: 'Default variant'
|
||||
type: ibom
|
||||
variants_blacklist: T2,T3
|
||||
|
||||
- name: 'default2'
|
||||
comment: 'Default variant 2'
|
||||
type: ibom
|
||||
file_id: '_[2]'
|
||||
variants_whitelist: T1, Default
|
||||
|
||||
outputs:
|
||||
- name: 'bom_internal'
|
||||
comment: "Bill of Materials in CSV format"
|
||||
type: position
|
||||
dir: positiondir
|
||||
options:
|
||||
format: CSV
|
||||
separate_files_for_front_and_back: false
|
||||
only_smd: false
|
||||
variant: default
|
||||
|
||||
- name: 'bom_internal2'
|
||||
comment: "Bill of Materials in CSV format (2)"
|
||||
type: position
|
||||
dir: positiondir
|
||||
options:
|
||||
format: CSV
|
||||
separate_files_for_front_and_back: false
|
||||
only_smd: false
|
||||
variant: default2
|
||||
|
||||
- name: 'bom_internal_production'
|
||||
comment: "Bill of Materials in CSV format for production"
|
||||
type: position
|
||||
dir: positiondir
|
||||
options:
|
||||
format: CSV
|
||||
separate_files_for_front_and_back: false
|
||||
only_smd: false
|
||||
variant: production
|
||||
|
||||
- name: 'bom_internal_test'
|
||||
comment: "Bill of Materials in CSV format for test"
|
||||
type: position
|
||||
dir: positiondir
|
||||
options:
|
||||
format: CSV
|
||||
separate_files_for_front_and_back: false
|
||||
only_smd: false
|
||||
variant: test
|
||||
Loading…
Reference in New Issue