From a1d6ebf79ff70b1991cc643fff41751b8718c7fe Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 7 Jul 2024 16:25:01 +0200 Subject: protoboard: Improve layout distribution and index rendering --- gerbonara/cad/protoboard.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/gerbonara/cad/protoboard.py b/gerbonara/cad/protoboard.py index 79cf7dd..fed3bff 100644 --- a/gerbonara/cad/protoboard.py +++ b/gerbonara/cad/protoboard.py @@ -30,10 +30,13 @@ class ProtoBoard(Board): ko = mounting_hole_offset + mounting_hole_dia*(0.5 + 0.25) stack = MechanicalHoleStack(mounting_hole_dia, unit=unit) - self.add(Pad(mounting_hole_offset, mounting_hole_offset, pad_stack=stack, unit=unit)) - self.add(Pad(w-mounting_hole_offset, mounting_hole_offset, pad_stack=stack, unit=unit)) - self.add(Pad(mounting_hole_offset, h-mounting_hole_offset, pad_stack=stack, unit=unit)) - self.add(Pad(w-mounting_hole_offset, h-mounting_hole_offset, pad_stack=stack, unit=unit)) + self.mounting_holes = [ + Pad(mounting_hole_offset, mounting_hole_offset, pad_stack=stack, unit=unit), + Pad(w-mounting_hole_offset, mounting_hole_offset, pad_stack=stack, unit=unit), + Pad(mounting_hole_offset, h-mounting_hole_offset, pad_stack=stack, unit=unit), + Pad(w-mounting_hole_offset, h-mounting_hole_offset, pad_stack=stack, unit=unit)] + for hole in self.mounting_holes: + self.add(hole) self.keepouts.append(((0, 0), (ko, ko))) self.keepouts.append(((w-ko, 0), (w, ko))) @@ -45,9 +48,13 @@ class ProtoBoard(Board): def generate(self, unit=MM): bbox = ((self.margin, self.margin), (self.w-self.margin, self.h-self.margin)) bbox = unit.convert_bounds_from(self.unit, bbox) + hole_bboxes = [hole.bounding_box(unit) for hole in self.mounting_holes] for obj in self.content.generate(bbox, (True, True, True, True), self.keepouts, self.margin, unit): if isinstance(obj, Text): - self.add(obj, keepout_errors='ignore') + # It's okay for the text to go into the mounting hole keepouts, we just don't want it to overlap with + # the actual mounting holes. + if not any(bbox_intersect(obj.bounding_box(unit), hole_bbox) for hole_bbox in hole_bboxes): + self.add(obj, keepout_errors='ignore') else: self.add(obj, keepout_errors='skip') @@ -118,6 +125,8 @@ class PropLayout: sizes.append(((this_x, this_y), (this_w, this_h))) + # We don't want to pull in a whole bin packing implementation here, but we also don't want to be too dumb. Thus, + # we just take the leftover space and distribute it to the children in descending increment (grid / pitch size). children_sorted = reversed(sorted(enumerate(self.content), key=lambda e: e[1].increment_x() if self.direction == 'h' else e[1].increment_y())) @@ -272,10 +281,10 @@ class PatternProtoArea: (x, y), (w, h) = bbox w, h = w-x, h-y - n_x = int(w//unit(self.pitch_x, self.unit)) - n_y = int(h//unit(self.pitch_y, self.unit)) - off_x = (w % unit(self.pitch_x, self.unit)) / 2 - off_y = (h % unit(self.pitch_y, self.unit)) / 2 + n_x = int((w + 0.001)//unit(self.pitch_x, self.unit)) + n_y = int((h + 0.001)//unit(self.pitch_y, self.unit)) + off_x = (w - n_x*unit(self.pitch_x, self.unit)) / 2 + off_y = (h - n_y*unit(self.pitch_y, self.unit)) / 2 if self.numbers: # Center row/column numbers in available margin. Note the swapped axes below - the Y (row) numbers are @@ -709,9 +718,10 @@ class AlioCell(Positioned): def single_sided(self): return False - def inst(self, x, y, border_x, border_y): + def inst(self, x, y, border): + border_s, border_w, border_n, border_e = border inst = copy(self) - inst.border_x, inst.border_y = border_x, border_y + inst.border_x, inst.border_y = border_e, border_s inst.inst_x, inst.inst_y = x, y return inst -- cgit