From 9f037e569fa0a69d61b65cc30a3f169fe60c6258 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Thu, 21 Apr 2022 10:28:03 -0300 Subject: [PATCH] Added global option `drill_size_increment` - Now we can round the drill sizes - Added a context for drill tools (adjusted and rounded) - Added a context for oval holes Related to #164 --- kibot/globals.py | 3 + kibot/gs.py | 1 + kibot/out_report.py | 65 +++++++++++++++---- kibot/report_templates/report_full.txt | 8 +++ .../reference/5_1_6/light_control-report.txt | 19 +++++- .../5_1_6/light_control-report.txt_2 | 19 +++++- .../5_1_6/light_control-report_simple.txt | 2 +- .../reference/6_0_4/light_control-report.txt | 19 +++++- .../6_0_4/light_control-report_simple.txt | 2 +- 9 files changed, 117 insertions(+), 21 deletions(-) diff --git a/kibot/globals.py b/kibot/globals.py index cdcdc6da..af41ad10 100644 --- a/kibot/globals.py +++ b/kibot/globals.py @@ -92,6 +92,9 @@ class Globals(FiltersOptions): """ How many millimeters the manufacturer will add to plated holes. This is because the plating reduces the hole, so you need to use a bigger drill. For more information consult: https://www.eurocircuits.com/pcb-design-guidelines/drilled-holes/ """ + self.drill_size_increment = 0.05 + """ This is the difference between drill tools in millimeters. + A manufacturer with 0.05 of increment has drills for 0.1, 0.15, 0.2, 0.25, etc. """ self.set_doc('filters', " [list(dict)] KiBot warnings to be ignored ") self._filter_what = 'KiBot warnings' self._unkown_is_error = True diff --git a/kibot/gs.py b/kibot/gs.py index 1ca04e36..d6ecdc32 100644 --- a/kibot/gs.py +++ b/kibot/gs.py @@ -117,6 +117,7 @@ class GS(object): global_edge_plating = None global_impedance_controlled = None global_extra_pth_drill = None + global_drill_size_increment = None test_boolean = True stackup = None diff --git a/kibot/out_report.py b/kibot/out_report.py index a284326d..2d674814 100644 --- a/kibot/out_report.py +++ b/kibot/out_report.py @@ -126,6 +126,19 @@ def get_pad_info(pad): to_mm(pad.GetSize(), 4), to_mm(pad.GetDrillSize(), 4))) +def adjust_drill(val, is_pth=True, pad=None): + """ Add drill_size_increment if this is a PTH hole and round it to global_extra_pth_drill """ + step = GS.global_drill_size_increment*pcbnew.IU_PER_MM + if is_pth: + val += GS.global_extra_pth_drill*pcbnew.IU_PER_MM + res = int((val+step/2)/step)*step + # if pad: + # logger.error(f"{to_mm(val)} -> {to_mm(res)} {get_pad_info(pad)}") + # else: + # logger.error(f"{to_mm(val)} -> {to_mm(res)}") + return res + + class ReportOptions(BaseOptions): def __init__(self): with document: @@ -265,6 +278,20 @@ class ReportOptions(BaseOptions): text += self.do_replacements(line, {'drill': d, 'count': self._drills[d]}) return text + def context_oval_hole_sizes(self, line): + """ Replace iterator for the `oval_hole_sizes` context """ + text = '' + for d in sorted(self._drills_oval.keys()): + text += self.do_replacements(line, {'drill_1': d[0], 'drill_2': d[1], 'count': self._drills_oval[d]}) + return text + + def context_drill_tools(self, line): + """ Replace iterator for the `drill_tools` context """ + text = '' + for d in sorted(self._drills_real.keys()): + text += self.do_replacements(line, {'drill': d, 'count': self._drills_real[d]}) + return text + def context_stackup(self, line): """ Replace iterator for the `stackup` context """ text = '' @@ -384,7 +411,7 @@ class ReportOptions(BaseOptions): def collect_data(self, board): ds = board.GetDesignSettings() - extra_pth_drill = GS.global_extra_pth_drill*pcbnew.IU_PER_MM + self.extra_pth_drill = GS.global_extra_pth_drill*pcbnew.IU_PER_MM ########################################################### # Board size ########################################################### @@ -427,6 +454,7 @@ class ReportOptions(BaseOptions): self.oar_vias = self.track = INF self._vias = {} self._tracks_m = {} + self._drills_real = {} track_type = 'TRACK' if GS.ki5() else 'PCB_TRACK' via_type = 'VIA' if GS.ki5() else 'PCB_VIA' for t in tracks: @@ -439,12 +467,13 @@ class ReportOptions(BaseOptions): via = t.Cast() via_id = (via.GetDrill(), via.GetWidth()) self._vias[via_id] = self._vias.get(via_id, 0) + 1 - self.oar_vias = min(self.oar_vias, via_id[1] - (via_id[0]+extra_pth_drill)) + d = adjust_drill(via_id[0]) + self.oar_vias = min(self.oar_vias, via_id[1] - d) + self._drills_real[d] = self._drills_real.get(d, 0) + 1 self.track_min = min(self.track_d, self.track) ########################################################### # Drill (min) ########################################################### - self.extra_pth_drill = extra_pth_drill modules = board.GetModules() if GS.ki5() else board.GetFootprints() self._drills = {} self._drills_oval = {} @@ -476,22 +505,30 @@ class ReportOptions(BaseOptions): self.pad_drill = min(dr.x, self.pad_drill) self.pad_drill = min(dr.y, self.pad_drill) # Compute the drill size to get it after plating - adjust = 0 if pad.GetAttribute() == npth_attrib else extra_pth_drill - self.pad_drill_real = min(dr.x+adjust, self.pad_drill_real) - self.pad_drill_real = min(dr.y+adjust, self.pad_drill_real) + is_pth = pad.GetAttribute() != npth_attrib + dr_x_real = adjust_drill(dr.x, is_pth, pad) + dr_y_real = adjust_drill(dr.y, is_pth, pad) + self.pad_drill_real = min(dr_x_real, self.pad_drill_real) + self.pad_drill_real = min(dr_y_real, self.pad_drill_real) if dr.x == dr.y: self._drills[dr.x] = self._drills.get(dr.x, 0) + 1 + self._drills_real[dr_x_real] = self._drills_real.get(dr_x_real, 0) + 1 else: if dr.x < dr.y: m = (dr.x, dr.y) + d = dr.x + d_r = dr_x_real else: m = (dr.y, dr.x) + d = dr.y + d_r = dr_y_real self._drills_oval[m] = self._drills_oval.get(m, 0) + 1 self.slot = min(self.slot, m[0]) # print('{} @ {}'.format(dr, pad.GetPosition())) + self._drills_real[d_r] = self._drills_real.get(d_r, 0) + 1 pad_sz = pad.GetSize() - oar_x = pad_sz.x - (dr.x+adjust) - oar_y = pad_sz.y - (dr.y+adjust) + oar_x = pad_sz.x - dr_x_real + oar_y = pad_sz.y - dr_y_real oar_t = min(oar_x, oar_y) if oar_t > 0: self.oar_pads = min(self.oar_pads, oar_t) @@ -500,6 +537,8 @@ class ReportOptions(BaseOptions): format(to_mm(oar_t, 4), get_pad_info(pad))) elif oar_t < 0: logger.warning(W_WRONGOAR+"Negative OAR detected for pad "+get_pad_info(pad)) + elif oar_t == 0 and is_pth: + logger.warning(W_WRONGOAR+"Plated pad without copper "+get_pad_info(pad)) self._vias_m = sorted(self._vias.keys()) # Via Pad size self.via_pad_d = ds.m_ViasMinSize @@ -511,13 +550,13 @@ class ReportOptions(BaseOptions): self.via_drill = self._vias_m[0][0] self.via_drill_min = min(self.via_drill_d, self.via_drill) # Via Drill size before platting - self.via_drill_real_d = self.via_drill_d+extra_pth_drill - self.via_drill_real = self.via_drill+extra_pth_drill - self.via_drill_real_min = self.via_drill_min+extra_pth_drill + self.via_drill_real_d = adjust_drill(self.via_drill_d) + self.via_drill_real = adjust_drill(self.via_drill) + self.via_drill_real_min = adjust_drill(self.via_drill_min) # Pad Drill # No minimum defined (so no _d) self.pad_drill_min = self.pad_drill if GS.ki5() else ds.m_MinThroughDrill - self.pad_drill_real_min = self.pad_drill_real if GS.ki5() else ds.m_MinThroughDrill+extra_pth_drill + self.pad_drill_real_min = self.pad_drill_real if GS.ki5() else adjust_drill(ds.m_MinThroughDrill, False) # Drill overall self.drill_d = min(self.via_drill_d, self.pad_drill) self.drill = min(self.via_drill, self.pad_drill) @@ -544,7 +583,7 @@ class ReportOptions(BaseOptions): h = v.m_Drill if not d and not h: continue # KiCad 6 - self.oar_vias_d = min(self.oar_vias_d, d - (h+extra_pth_drill)) + self.oar_vias_d = min(self.oar_vias_d, d - adjust_drill(h)) self._vias_defined.add((h, d)) self._via_sizes_sorted.append((h, d)) ########################################################### diff --git a/kibot/report_templates/report_full.txt b/kibot/report_templates/report_full.txt index 33862836..fe01dc4f 100644 --- a/kibot/report_templates/report_full.txt +++ b/kibot/report_templates/report_full.txt @@ -98,6 +98,14 @@ Holes (excluding vias): #hole_sizes_no_vias:- ${drill_mm} mm (${drill_mils} mils) (${count}) +Oval holes: + +#oval_hole_sizes:- ${drill_1_mm}x${drill_2_mm} mm (${drill_1_mils}x${drill_2_mils} mils) (${count}) + +Drill tools (including vias and computing adjusts and rounding): + +#drill_tools:- ${drill_mm} mm (${drill_mils} mils) (${count}) + #?schematic_svgs # Schematic diff --git a/tests/reference/5_1_6/light_control-report.txt b/tests/reference/5_1_6/light_control-report.txt index 06af4226..de340131 100644 --- a/tests/reference/5_1_6/light_control-report.txt +++ b/tests/reference/5_1_6/light_control-report.txt @@ -38,9 +38,9 @@ Via: 0.51/0.25 mm (20/10 mils) - Micro via: no [0.2/0.1 mm (8/4 mils)] - Burried/blind via: no -Outer Annular Ring: 0.15 mm (6 mils) +Outer Annular Ring: 0.16 mm (6 mils) -- By design rules: 0.15 mm (6 mils) +- By design rules: 0.16 mm (6 mils) Eurocircuits class: 6C @@ -84,6 +84,21 @@ Holes (excluding vias): - 1.2 mm (47 mils) (20) - 3.2 mm (126 mils) (4) +Oval holes: + +- 0.6x1.3 mm (24x51 mils) (2) + +Drill tools (including vias and computing adjusts and rounding): + +- 0.35 mm (14 mils) (23) +- 0.6 mm (24 mils) (33) +- 0.7 mm (28 mils) (2) +- 0.9 mm (35 mils) (4) +- 0.95 mm (37 mils) (2) +- 1.05 mm (41 mils) (3) +- 1.3 mm (51 mils) (20) +- 3.2 mm (126 mils) (4) + # Schematic diff --git a/tests/reference/5_1_6/light_control-report.txt_2 b/tests/reference/5_1_6/light_control-report.txt_2 index 06af4226..de340131 100644 --- a/tests/reference/5_1_6/light_control-report.txt_2 +++ b/tests/reference/5_1_6/light_control-report.txt_2 @@ -38,9 +38,9 @@ Via: 0.51/0.25 mm (20/10 mils) - Micro via: no [0.2/0.1 mm (8/4 mils)] - Burried/blind via: no -Outer Annular Ring: 0.15 mm (6 mils) +Outer Annular Ring: 0.16 mm (6 mils) -- By design rules: 0.15 mm (6 mils) +- By design rules: 0.16 mm (6 mils) Eurocircuits class: 6C @@ -84,6 +84,21 @@ Holes (excluding vias): - 1.2 mm (47 mils) (20) - 3.2 mm (126 mils) (4) +Oval holes: + +- 0.6x1.3 mm (24x51 mils) (2) + +Drill tools (including vias and computing adjusts and rounding): + +- 0.35 mm (14 mils) (23) +- 0.6 mm (24 mils) (33) +- 0.7 mm (28 mils) (2) +- 0.9 mm (35 mils) (4) +- 0.95 mm (37 mils) (2) +- 1.05 mm (41 mils) (3) +- 1.3 mm (51 mils) (20) +- 3.2 mm (126 mils) (4) + # Schematic diff --git a/tests/reference/5_1_6/light_control-report_simple.txt b/tests/reference/5_1_6/light_control-report_simple.txt index dbe785e7..d58aa6bc 100644 --- a/tests/reference/5_1_6/light_control-report_simple.txt +++ b/tests/reference/5_1_6/light_control-report_simple.txt @@ -13,7 +13,7 @@ Minimum drill size: ≥ 0.35 mm (finished metalized hole: 0.25 mm) Minimum slot width: ≥ 0.6 mm -Ring collar: ≥ 0.15 mm +Ring collar: ≥ 0.16 mm Materials: diff --git a/tests/reference/6_0_4/light_control-report.txt b/tests/reference/6_0_4/light_control-report.txt index da1c9357..5029e518 100644 --- a/tests/reference/6_0_4/light_control-report.txt +++ b/tests/reference/6_0_4/light_control-report.txt @@ -63,9 +63,9 @@ Via: 0.51/0.25 mm (20/10 mils) - Micro via: no [0.2/0.1 mm (8/4 mils)] - Burried/blind via: no -Outer Annular Ring: 0.15 mm (6 mils) +Outer Annular Ring: 0.16 mm (6 mils) -- By design rules: 0.15 mm (6 mils) +- By design rules: 0.16 mm (6 mils) Eurocircuits class: 6C @@ -107,6 +107,21 @@ Holes (excluding vias): - 1.2 mm (47 mils) (20) - 3.2 mm (126 mils) (4) +Oval holes: + +- 0.6x1.3 mm (24x51 mils) (2) + +Drill tools (including vias and computing adjusts and rounding): + +- 0.35 mm (14 mils) (23) +- 0.6 mm (24 mils) (33) +- 0.7 mm (28 mils) (2) +- 0.9 mm (35 mils) (4) +- 0.95 mm (37 mils) (2) +- 1.05 mm (41 mils) (3) +- 1.3 mm (51 mils) (20) +- 3.2 mm (126 mils) (4) + # Schematic diff --git a/tests/reference/6_0_4/light_control-report_simple.txt b/tests/reference/6_0_4/light_control-report_simple.txt index 1d97be9d..4f8b4f23 100644 --- a/tests/reference/6_0_4/light_control-report_simple.txt +++ b/tests/reference/6_0_4/light_control-report_simple.txt @@ -13,7 +13,7 @@ Minimum drill size: ≥ 0.35 mm (finished metalized hole: 0.25 mm) Minimum slot width: ≥ 0.6 mm -Ring collar: ≥ 0.15 mm +Ring collar: ≥ 0.16 mm Special features: