Internal BoM: Added footprint X, Y, rotation and side columns

- First step towards XYRS support
This commit is contained in:
Salvador E. Tropea 2022-02-11 11:01:14 -03:00
parent 23c8eae16b
commit 644f6d1fda
9 changed files with 55 additions and 18 deletions

View File

@ -895,6 +895,7 @@ Next time you need this list just use an alias, like this:
- `ref_id`: [string=''] A prefix to add to all the references from this project. Used for multiple projects.
- `ref_separator`: [string=' '] Separator used for the list of references.
- `source_by_id`: [boolean=false] Generate the `Source BoM` column using the reference ID instead of the project name.
- `units`: [string='millimeters'] [millimeters,inches] Units used for the positions ('Footprint X' and 'Footprint Y' columns).
- `use_alt`: [boolean=false] Print grouped references in the alternate compressed style eg: R1-R7,R18.
- `variant`: [string=''] Board variant, used to determine which components
are output to the BoM..

View File

@ -242,6 +242,8 @@ outputs:
ref_separator: ' '
# [boolean=false] Generate the `Source BoM` column using the reference ID instead of the project name
source_by_id: false
# [string='millimeters'] [millimeters,inches] Units used for the positions ('Footprint X' and 'Footprint Y' columns)
units: 'millimeters'
# [boolean=false] Print grouped references in the alternate compressed style eg: R1-R7,R18
use_alt: false
# [string=''] Board variant, used to determine which components

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2021 Salvador E. Tropea
# Copyright (c) 2020-2021 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2016-2020 Oliver Henry Walters (@SchrodingersGat)
# License: MIT
# Project: KiBot (formerly KiPlot)
@ -302,7 +302,7 @@ class ComponentGroup(object):
fld=value, ref=ref))
self.fields[field] += " " + value
def update_fields(self, usealt=False):
def update_fields(self, conv, usealt=False):
for c in self.components:
for f, v in c.get_user_fields():
self.update_field(f, v, c.ref)
@ -330,6 +330,10 @@ 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
self.fields[ColumnList.COL_FP_X_L] = "{:.4f}".format(comp.footprint_x * conv)
self.fields[ColumnList.COL_FP_Y_L] = "{:.4f}".format(comp.footprint_y * conv)
self.fields[ColumnList.COL_FP_ROT_L] = comp.footprint_rot
self.fields[ColumnList.COL_FP_SIDE_L] = "bottom" if comp.bottom else "top"
self.fields[ColumnList.COL_FP_LIB_L] = comp.footprint_lib
self.fields[ColumnList.COL_SHEETPATH_L] = comp.sheet_path_h
if not self.fields[ColumnList.COL_DESCRIPTION_L]:
@ -449,7 +453,7 @@ def group_components(cfg, components):
# Sort the references within each group
g.sort_components()
# Fill the columns
g.update_fields(cfg.use_alt)
g.update_fields(cfg.conv_units, cfg.use_alt)
if cfg.normalize_values:
g.fields[ColumnList.COL_VALUE_L] = normalize_value(g.components[0], decimal_point)
# Sort the groups

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Salvador E. Tropea
# Copyright (c) 2020 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2016-2020 Oliver Henry Walters (@SchrodingersGat)
# License: MIT
# Project: KiBot (formerly KiPlot)
@ -31,6 +31,14 @@ class ColumnList:
COL_FP_L = COL_FP.lower()
COL_FP_LIB = 'Footprint Lib'
COL_FP_LIB_L = COL_FP_LIB.lower()
COL_FP_X = 'Footprint X'
COL_FP_X_L = COL_FP_X.lower()
COL_FP_Y = 'Footprint Y'
COL_FP_Y_L = COL_FP_Y.lower()
COL_FP_ROT = 'Footprint Rot'
COL_FP_ROT_L = COL_FP_ROT.lower()
COL_FP_SIDE = 'Footprint Side'
COL_FP_SIDE_L = COL_FP_SIDE.lower()
COL_PART = 'Part'
COL_PART_L = COL_PART.lower()
COL_PART_LIB = 'Part Lib'
@ -92,6 +100,10 @@ class ColumnList:
COL_DATASHEET_L,
COL_SHEETPATH_L,
COL_FP_L,
COL_FP_X_L,
COL_FP_Y_L,
COL_FP_ROT_L,
COL_FP_SIDE_L,
COL_FP_LIB_L
}

View File

@ -180,6 +180,12 @@ class GS(object):
return settings.GetAuxOrigin()
return GS.board.GetAuxOrigin()
@staticmethod
def get_center(m):
if GS.ki5():
return m.GetCenter()
return m.GetPosition()
@staticmethod
def ki6():
return GS.kicad_version_n >= KICAD_VERSION_5_99

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2021 Salvador E. Tropea
# Copyright (c) 2020-2021 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
"""
@ -869,6 +869,8 @@ class SchematicComponent(object):
- fixed: means you can't change it by a replacement without authorization
Is just a flag and doesn't affect much.
- footprint_rot: angle to rotate the part in the pick & place.
- footprint_x: x position of the part in the pick & place.
- footprint_y: y position of the part in the pick & place.
- qty: ammount of this part used.
"""
ref_re = re.compile(r'([^\d]+)([\?\d]+)')
@ -890,6 +892,8 @@ class SchematicComponent(object):
self.fixed = False
self.bottom = False
self.footprint_rot = 0.0
self.footprint_x = 0
self.footprint_y = 0
self.qty = 1
self.annotation_error = False
# KiCad 5 PCB flags (mutually exclusive)

View File

@ -277,6 +277,9 @@ def get_board_comps_data(comps):
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
attrs = m.GetAttributes()
if GS.ki5():
# KiCad 5

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2021 Salvador E. Tropea
# Copyright (c) 2020-2021 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# License: MIT
# Project: KiBot (formerly KiPlot)
"""
@ -9,6 +9,7 @@ This is somehow compatible with KiBoM.
"""
import os
import re
from pcbnew import IU_PER_MM, IU_PER_MILS
from .gs import GS
from .misc import W_BADFIELD, W_NEEDSPCB
from .optionable import Optionable, BaseOptions
@ -383,6 +384,8 @@ class BoMOptions(BaseOptions):
""" [string|list(string)] Exclude this distributors list. They are removed after computing `distributors` """
self.count_smd_tht = False
""" Show the stats about how many of the components are SMD/THT. You must provide the PCB """
self.units = 'millimeters'
""" [millimeters,inches] Units used for the positions ('Footprint X' and 'Footprint Y' columns) """
self._format_example = 'CSV'
super().__init__()
@ -579,6 +582,7 @@ class BoMOptions(BaseOptions):
self.revision = GS.sch_rev
self.debug_level = GS.debug_level
self.kicad_version = GS.kicad_version
self.conv_units = 1.0/IU_PER_MM if self.units == 'millimeters' else 0.001/IU_PER_MILS
# Get the components list from the schematic
comps = GS.sch.get_components()
get_board_comps_data(comps)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-2021 Salvador E. Tropea
# Copyright (c) 2020-2021 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2020-2022 Salvador E. Tropea
# Copyright (c) 2020-2022 Instituto Nacional de Tecnología Industrial
# Copyright (c) 2019 Romain Deterre (@rdeterre)
# License: GPL-3.0
# Project: KiBot (formerly KiPlot)
@ -245,17 +245,18 @@ class PositionOptions(VariantOptions):
footprint = c.footprint
is_bottom = c.bottom
rotation = c.footprint_rot
center_x = c.footprint_x
center_y = c.footprint_y
if value is None:
value = m.GetValue()
footprint = str(m.GetFPID().GetLibItemName()) # pcbnew.UTF8 type
is_bottom = m.IsFlipped()
rotation = m.GetOrientationDegrees()
center = GS.get_center(m)
center_x = center.x
center_y = center.y
# If passed check the position options
if (self.only_smd and is_pure_smd(m)) or (not self.only_smd and (is_not_virtual(m) or self.include_virtual)):
if GS.ki5():
center = m.GetCenter()
else:
center = m.GetPosition()
# KiCad: PLACE_FILE_EXPORTER::GenPositionData() in export_footprints_placefile.cpp
row = []
for k in self.columns:
@ -266,12 +267,12 @@ class PositionOptions(VariantOptions):
elif k == 'Package':
row.append(quote_char+footprint+quote_char)
elif k == 'PosX':
pos_x = (center.x - x_origin) * conv
pos_x = (center_x - x_origin) * conv
if self.bottom_negative_x and is_bottom:
pos_x = -pos_x
row.append("{:.4f}".format(pos_x))
elif k == 'PosY':
row.append("{:.4f}".format(-(center.y - y_origin) * conv))
row.append("{:.4f}".format(-(center_y - y_origin) * conv))
elif k == 'Rot':
row.append("{:.4f}".format(rotation))
elif k == 'Side':