From 63b4c526f838a9a1f873e8ddd603b6cf9845f2c5 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Thu, 29 Sep 2022 07:54:32 -0300 Subject: [PATCH] Fixed missing XYRS information for components with multiple units Closes #306 --- CHANGELOG.md | 1 + kibot/bom/bom.py | 10 +++++--- kibot/bom/columnlist.py | 12 +++++++++ kibot/kicad/v5_sch.py | 1 + kibot/kiplot.py | 55 +++++++++++++++++++++++------------------ kibot/misc.py | 1 + 6 files changed, 53 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cb40ac2..a3252dba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - KiBot exited when downloading a datasheet and got a connection error (#289 #290) - KiCad 5 "assert "lower <= upper" failed in Clamp()" (#304) +- Missing XYRS information for components with multiple units (#306) ### Changed - Diff: diff --git a/kibot/bom/bom.py b/kibot/bom/bom.py index b167901c..561c87f2 100644 --- a/kibot/bom/bom.py +++ b/kibot/bom/bom.py @@ -15,7 +15,7 @@ from math import ceil from .units import compare_values, comp_match, get_last_warning from .bom_writer import write_bom from .columnlist import ColumnList -from ..misc import DNF, W_FIELDCONF +from ..misc import DNF, W_FIELDCONF, W_MISSFPINFO from ..gs import GS from .. import log @@ -304,7 +304,7 @@ class ComponentGroup(object): self.fields[field] += " " + value def update_fields(self, conv, bottom_negative_x, x_origin, y_origin, angle_positive, footprint_populate_values, - footprint_type_values, usealt=False): + footprint_type_values, uses_fp_info, usealt=False): for c in self.components: for f, v in c.get_user_fields(): self.update_field(f, v, c.ref) @@ -332,6 +332,8 @@ class ComponentGroup(object): self.fields[ColumnList.COL_PART_LIB_L] = comp.lib self.fields[ColumnList.COL_DATASHEET_L] = comp.datasheet self.fields[ColumnList.COL_FP_L] = comp.footprint + if uses_fp_info and not comp.has_pcb_info: + logger.warning(W_MISSFPINFO+'Missing footprint information for {}'.format(comp.ref)) pos_x = (comp.footprint_x - x_origin) * conv if bottom_negative_x and comp.bottom: pos_x = -pos_x @@ -469,6 +471,8 @@ def group_components(cfg, components): decimal_point = locale.localeconv()['decimal_point'] if decimal_point == '.': decimal_point = None + # Determine if we need information from the PCB + uses_fp_info = len(set(ColumnList.COLUMNS_FP_L).intersection({c.lower() for c in cfg.columns})) != 0 # Coordinates origin for XYRS x_origin = 0.0 y_origin = 0.0 @@ -481,7 +485,7 @@ def group_components(cfg, components): g.sort_components() # Fill the columns g.update_fields(cfg.conv_units, cfg.bottom_negative_x, x_origin, y_origin, cfg.angle_positive, - cfg.footprint_populate_values, cfg.footprint_type_values, cfg.use_alt) + cfg.footprint_populate_values, cfg.footprint_type_values, uses_fp_info, cfg.use_alt) if cfg.normalize_values: g.fields[ColumnList.COL_VALUE_L] = normalize_value(g.components[0], decimal_point) # Sort the groups diff --git a/kibot/bom/columnlist.py b/kibot/bom/columnlist.py index ca3cc01a..4e7394c0 100644 --- a/kibot/bom/columnlist.py +++ b/kibot/bom/columnlist.py @@ -95,6 +95,18 @@ class ColumnList: COL_SOURCE_BOM, ] + # Columns from the footprint + COLUMNS_FP_L = [ + COL_FP_X_L, + COL_FP_Y_L, + COL_FP_ROT_L, + COL_FP_SIDE_L, + COL_FP_TYPE_L, + COL_FP_FIT_L, + COL_FP_XS_L, + COL_FP_YS_L, + ] + # Not included by default COLUMNS_EXTRA = [ COL_FP_X, diff --git a/kibot/kicad/v5_sch.py b/kibot/kicad/v5_sch.py index 8801b635..6aae030f 100644 --- a/kibot/kicad/v5_sch.py +++ b/kibot/kicad/v5_sch.py @@ -899,6 +899,7 @@ class SchematicComponent(object): self.footprint_rot = 0.0 self.footprint_x = self.footprint_y = 0 self.footprint_w = self.footprint_h = 0 + self.has_pcb_info = False self.qty = 1 self.annotation_error = False # KiCad 5 PCB flags (mutually exclusive) diff --git a/kibot/kiplot.py b/kibot/kiplot.py index 7d6e91a2..7ca0c4a7 100644 --- a/kibot/kiplot.py +++ b/kibot/kiplot.py @@ -279,36 +279,43 @@ def get_board_comps_data(comps): if not GS.pcb_file: return load_board() - comps_hash = {c.ref: c for c in comps} + # Each reference could be more than one sub-units + # So this hash is ref -> [List of units] + comps_hash = {} + for c in comps: + cur_list = comps_hash.get(c.ref, []) + cur_list.append(c) + comps_hash[c.ref] = cur_list for m in GS.get_modules(): ref = m.GetReference() if ref not in comps_hash: logger.warning(W_PCBNOSCH + '`{}` component in board, but not in schematic'.format(ref)) continue - c = comps_hash[ref] - c.bottom = m.IsFlipped() - c.footprint_rot = m.GetOrientationDegrees() - center = GS.get_center(m) - c.footprint_x = center.x - c.footprint_y = center.y - (c.footprint_w, c.footprint_h) = GS.get_fp_size(m) - attrs = m.GetAttributes() - if GS.ki5: - # KiCad 5 - if attrs == UI_SMD: - c.smd = True - elif attrs == UI_VIRTUAL: - c.virtual = True + for c in comps_hash[ref]: + c.bottom = m.IsFlipped() + c.footprint_rot = m.GetOrientationDegrees() + center = GS.get_center(m) + c.footprint_x = center.x + c.footprint_y = center.y + (c.footprint_w, c.footprint_h) = GS.get_fp_size(m) + c.has_pcb_info = True + attrs = m.GetAttributes() + if GS.ki5: + # KiCad 5 + if attrs == UI_SMD: + c.smd = True + elif attrs == UI_VIRTUAL: + c.virtual = True + else: + c.tht = True else: - c.tht = True - else: - # 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 + # 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 def preflight_checks(skip_pre, targets): diff --git a/kibot/misc.py b/kibot/misc.py index 6f82a541..5c24a784 100644 --- a/kibot/misc.py +++ b/kibot/misc.py @@ -236,6 +236,7 @@ W_DOWN3D = '(W098) ' W_MISSREF = '(W099) ' W_COPYOVER = '(W100) ' W_PARITY = '(W101) ' +W_MISSFPINFO = '(W102) ' # Somehow arbitrary, the colors are real, but can be different PCB_MAT_COLORS = {'fr1': "937042", 'fr2': "949d70", 'fr3': "adacb4", 'fr4': "332B16", 'fr5': "6cc290"} PCB_FINISH_COLORS = {'hal': "8b898c", 'hasl': "8b898c", 'imag': "8b898c", 'enig': "cfb96e", 'enepig': "cfb96e",