From c59c31fb6ecd10f2c6c7426e45d282fe030638a1 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Mon, 21 Sep 2020 19:17:31 -0300 Subject: [PATCH] Added support for KiCad v6 to the position output. --- kibot/kiplot.py | 21 +++++++++++++++------ kibot/misc.py | 15 ++++++++++++--- kibot/out_position.py | 30 ++++++++++++++++++++++++++---- tests/test_plot/test_position.py | 4 ++-- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/kibot/kiplot.py b/kibot/kiplot.py index a8a0801d..aa9ecb75 100644 --- a/kibot/kiplot.py +++ b/kibot/kiplot.py @@ -195,13 +195,22 @@ def get_board_comps_data(comps): continue c = comps_hash[ref] attrs = m.GetAttributes() - # KiCad 5 (6 will change it) - if attrs == 1: - c.smd = True - elif attrs == 2: - c.virtual = True + if GS.kicad_version_n < KICAD_VERSION_5_99: + # KiCad 5 + if attrs == UI_SMD: + c.smd = True + elif attrs == UI_VIRTUAL: + c.virtual = True + else: + c.tht = True else: - c.tht = True + # KiCad 6 + if attrs & MOD_SMD: + c.smd = True + if attrs & MOD_THROUGH_HOLE: + c.tht = True + if attrs & MOD_VIRTUAL == MOD_VIRTUAL: + c.virtual = True GS.board_comps_joined = True diff --git a/kibot/misc.py b/kibot/misc.py index 9f6125e7..786b8f7b 100644 --- a/kibot/misc.py +++ b/kibot/misc.py @@ -45,13 +45,22 @@ PCBDRAW = 'pcbdraw' URL_PCBDRAW = 'https://github.com/INTI-CMNB/pcbdraw' EXAMPLE_CFG = 'example.kibot.yaml' AUTO_SCALE = 0 +KICAD_VERSION_5_99 = 5099000 # Internal filter names IFILL_MECHANICAL = '_mechanical' # KiCad 5 GUI values for the attribute -UI_THT = 0 -UI_SMD = 1 -UI_VIRTUAL = 2 +UI_THT = 0 # 1 for KiCad 6 +UI_SMD = 1 # 2 for KiCad 6 +UI_VIRTUAL = 2 # 12 for KiCad 6 +# KiCad 6 module attributes from class_module.h +MOD_THROUGH_HOLE = 1 +MOD_SMD = 2 +MOD_EXCLUDE_FROM_POS_FILES = 4 +MOD_EXCLUDE_FROM_BOM = 8 +MOD_BOARD_ONLY = 16 # Footprint has no corresponding symbol +# This is what a virtual component gets when loaded by KiCad 6 +MOD_VIRTUAL = MOD_EXCLUDE_FROM_POS_FILES | MOD_EXCLUDE_FROM_BOM # Supported values for "do not fit" DNF = { diff --git a/kibot/out_position.py b/kibot/out_position.py index 0530a480..785e1dc6 100644 --- a/kibot/out_position.py +++ b/kibot/out_position.py @@ -7,9 +7,9 @@ # Adapted from: https://github.com/johnbeard/kiplot/pull/10 import operator from datetime import datetime -from pcbnew import (IU_PER_MM, IU_PER_MILS) +from pcbnew import (IU_PER_MM, IU_PER_MILS, GetBuildVersion) from .gs import GS -from .misc import UI_SMD, UI_VIRTUAL +from .misc import UI_SMD, UI_VIRTUAL, KICAD_VERSION_5_99, MOD_THROUGH_HOLE, MOD_SMD, MOD_EXCLUDE_FROM_POS_FILES from .out_base import VariantOptions from .macros import macros, document, output_class # noqa: F401 from . import log @@ -123,6 +123,22 @@ class PositionOptions(VariantOptions): if bothf is not None: bothf.close() + @staticmethod + def is_pure_smd_5(m): + return m.GetAttributes() == UI_SMD + + @staticmethod + def is_pure_smd_6(m): + return m.GetAttributes() & (MOD_THROUGH_HOLE | MOD_SMD) == MOD_SMD + + @staticmethod + def is_not_virtual_5(m): + return m.GetAttributes() != UI_VIRTUAL + + @staticmethod + def is_not_virtual_6(m): + return not (m.GetAttributes() & MOD_EXCLUDE_FROM_POS_FILES) + def run(self, output_dir, board): super().run(output_dir, board) columns = ["Ref", "Val", "Package", "PosX", "PosY", "Rot", "Side"] @@ -136,6 +152,13 @@ class PositionOptions(VariantOptions): # Format all strings comps_hash = self.get_refs_hash() modules = [] + if GS.kicad_version_n < KICAD_VERSION_5_99: + logger.warning(GS.kicad_version) + is_pure_smd = self.is_pure_smd_5 + is_not_virtual = self.is_not_virtual_5 + else: + is_pure_smd = self.is_pure_smd_6 + is_not_virtual = self.is_not_virtual_6 for m in sorted(board.GetModules(), key=operator.methodcaller('GetReference')): ref = m.GetReference() # Apply any filter or variant data @@ -144,8 +167,7 @@ class PositionOptions(VariantOptions): if c and (not c.fitted or not c.included): 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): + if (self.only_smd and is_pure_smd(m)) or (not self.only_smd and is_not_virtual(m)): center = m.GetCenter() # See PLACE_FILE_EXPORTER::GenPositionData() in # export_footprints_placefile.cpp for C++ version of this. diff --git a/tests/test_plot/test_position.py b/tests/test_plot/test_position.py index 8ffba527..9066df1d 100644 --- a/tests/test_plot/test_position.py +++ b/tests/test_plot/test_position.py @@ -67,8 +67,8 @@ def expect_position(ctx, file, comp, no_comp=[], inches=False, csv=False): ctx.search_not_in_file(file, texts) -def test_3Rs_position(): - ctx = context.TestContext('3Rs_position', '3Rs', 'simple_position', POS_DIR) +def test_3Rs_position_1(): + ctx = context.TestContext('3Rs_position_1', '3Rs', 'simple_position', POS_DIR) ctx.run() pos_top = ctx.get_pos_top_filename() pos_bot = ctx.get_pos_bot_filename()