diff options
Diffstat (limited to 'gerbonara/cad/kicad/pcb.py')
-rw-r--r-- | gerbonara/cad/kicad/pcb.py | 119 |
1 files changed, 56 insertions, 63 deletions
diff --git a/gerbonara/cad/kicad/pcb.py b/gerbonara/cad/kicad/pcb.py index c5b2bd3..6bbcad1 100644 --- a/gerbonara/cad/kicad/pcb.py +++ b/gerbonara/cad/kicad/pcb.py @@ -59,13 +59,14 @@ def gn_layer_to_kicad(layer, flip=False): @sexp_type('general') class GeneralSection: thickness: Named(float) = 1.60 + legacy_teardrops: Named(YesNoAtom()) = False @sexp_type('layers') class LayerSettings: index: int = 0 canonical_name: str = None - layer_type: AtomChoice(Atom.jumper, Atom.mixed, Atom.power, Atom.signal, Atom.user) = Atom.signal + layer_type: AtomChoice(Atom.jumper, Atom.mixed, Atom.power, Atom.signal, Atom.user, Atom.auxiliary) = Atom.signal custom_name: str = None @@ -92,43 +93,44 @@ class StackupSettings: edge_plating: Named(YesNoAtom()) = None -TFBool = YesNoAtom(yes=Atom.true, no=Atom.false) - @sexp_type('pcbplotparams') class ExportSettings: layerselection: Named(Atom) = None plot_on_all_layers_selection: Named(Atom) = None - disableapertmacros: Named(TFBool) = False - usegerberextensions: Named(TFBool) = True - usegerberattributes: Named(TFBool) = True - usegerberadvancedattributes: Named(TFBool) = True - creategerberjobfile: Named(TFBool) = True + disableapertmacros: Named(YesNoAtom()) = False + usegerberextensions: Named(YesNoAtom()) = True + usegerberattributes: Named(YesNoAtom()) = True + usegerberadvancedattributes: Named(YesNoAtom()) = True + creategerberjobfile: Named(YesNoAtom()) = True dashed_line_dash_ratio: Named(float) = 12.0 dashed_line_gap_ratio: Named(float) = 3.0 - svguseinch: Named(TFBool) = False + svguseinch: Named(YesNoAtom()) = False svgprecision: Named(float) = 4 - excludeedgelayer: Named(TFBool) = False - plotframeref: Named(TFBool) = False - viasonmask: Named(TFBool) = False + excludeedgelayer: Named(YesNoAtom()) = False + plotframeref: Named(YesNoAtom()) = False + viasonmask: Named(YesNoAtom()) = False mode: Named(int) = 1 - useauxorigin: Named(TFBool) = False + useauxorigin: Named(YesNoAtom()) = False hpglpennumber: Named(int) = 1 hpglpenspeed: Named(int) = 20 hpglpendiameter: Named(float) = 15.0 - pdf_front_fp_property_popups: Named(TFBool) = True - pdf_back_fp_property_popups: Named(TFBool) = True - dxfpolygonmode: Named(TFBool) = True - dxfimperialunits: Named(TFBool) = False - dxfusepcbnewfont: Named(TFBool) = True - psnegative: Named(TFBool) = False - psa4output: Named(TFBool) = False - plotreference: Named(TFBool) = True - plotvalue: Named(TFBool) = True - plotinvisibletext: Named(TFBool) = False - sketchpadsonfab: Named(TFBool) = False - subtractmaskfromsilk: Named(TFBool) = False + pdf_front_fp_property_popups: Named(YesNoAtom()) = True + pdf_back_fp_property_popups: Named(YesNoAtom()) = True + pdf_metadata: Named(YesNoAtom()) = True + dxfpolygonmode: Named(YesNoAtom()) = True + dxfimperialunits: Named(YesNoAtom()) = False + dxfusepcbnewfont: Named(YesNoAtom()) = True + psnegative: Named(YesNoAtom()) = False + psa4output: Named(YesNoAtom()) = False + plotreference: Named(YesNoAtom()) = True + plotvalue: Named(YesNoAtom()) = True + plotfptext: Named(YesNoAtom()) = True + plotinvisibletext: Named(YesNoAtom()) = False + sketchpadsonfab: Named(YesNoAtom()) = False + plotpadnumbers: Named(YesNoAtom()) = False + subtractmaskfromsilk: Named(YesNoAtom()) = False outputformat: Named(int) = 1 - mirror: Named(TFBool) = False + mirror: Named(YesNoAtom()) = False drillshape: Named(int) = 0 scaleselection: Named(int) = 1 outputdirectory: Named(str) = "gerber" @@ -141,26 +143,23 @@ class BoardSetup: solder_mask_min_width: Named(float) = None pad_to_past_clearance: Named(float) = None pad_to_paste_clearance_ratio: Named(float) = None + allow_soldermask_bridges_in_footprints: Named(YesNoAtom()) = False + tenting: Named(Array(AtomChoice(Atom.front, Atom.back))) = field(default_factory=lambda: [Atom.front, Atom.back]) aux_axis_origin: Rename(XYCoord) = None grid_origin: Rename(XYCoord) = None export_settings: ExportSettings = field(default_factory=ExportSettings) -@sexp_type('net') -class Net: - index: int = 0 - name: str = '' - - @sexp_type('segment') -class TrackSegment: +class TrackSegment(BBoxMixin): start: Rename(XYCoord) = field(default_factory=XYCoord) end: Rename(XYCoord) = field(default_factory=XYCoord) width: Named(float) = 0.5 layer: Named(str) = 'F.Cu' locked: Flag() = False net: Named(int) = 0 - tstamp: Timestamp = field(default_factory=Timestamp) + uuid: UUID = field(default_factory=UUID) + tstamp: Timestamp = None @classmethod def from_footprint_line(kls, line, flip=False): @@ -195,7 +194,7 @@ class TrackSegment: @sexp_type('arc') -class TrackArc: +class TrackArc(BBoxMixin): start: Rename(XYCoord) = field(default_factory=XYCoord) mid: Rename(XYCoord) = field(default_factory=XYCoord) end: Rename(XYCoord) = field(default_factory=XYCoord) @@ -203,14 +202,15 @@ class TrackArc: layer: Named(str) = 'F.Cu' locked: Flag() = False net: Named(int) = 0 - tstamp: Timestamp = field(default_factory=Timestamp) + uuid: UUID = field(default_factory=UUID) + tstamp: Timestamp = None _: SEXP_END = None center: XYCoord = None def __post_init__(self): self.start = XYCoord(self.start) self.end = XYCoord(self.end) - self.mid = XYCoord(self.mid) if self.mid else center_arc_to_kicad_mid(XYCoord(self.center), self.start, self.end) + self.mid = XYCoord(self.mid) if self.center is None else center_arc_to_kicad_mid(XYCoord(self.center), self.start, self.end) self.center = None @property @@ -239,7 +239,7 @@ class TrackArc: @sexp_type('via') -class Via: +class Via(BBoxMixin): via_type: AtomChoice(Atom.blind, Atom.micro) = None locked: Flag() = False at: Rename(XYCoord) = field(default_factory=XYCoord) @@ -248,9 +248,10 @@ class Via: layers: Named(Array(str)) = field(default_factory=lambda: ['F.Cu', 'B.Cu']) remove_unused_layers: Flag() = False keep_end_layers: Flag() = False - free: Wrap(Flag()) = False + free: Named(YesNoAtom()) = False net: Named(int) = 0 - tstamp: Timestamp = field(default_factory=Timestamp) + uuid: UUID = field(default_factory=UUID) + tstamp: Timestamp = None @classmethod def from_pad(kls, pad): @@ -307,7 +308,8 @@ SUPPORTED_FILE_FORMAT_VERSIONS = [20210108, 20211014, 20221018, 20230517] @sexp_type('kicad_pcb') class Board: _version: Named(int, name='version') = 20230517 - generator: Named(Atom) = Atom.gerbonara + generator: Named(str) = Atom.gerbonara + generator_version: Named(str) = Atom.gerbonara general: GeneralSection = None page: PageSettings = None layers: Named(Array(Untagged(LayerSettings))) = field(default_factory=list) @@ -333,10 +335,10 @@ class Board: # Other stuff zones: List(Zone) = field(default_factory=list) groups: List(Group) = field(default_factory=list) + embedded_fonts: Named(YesNoAtom()) = False _ : SEXP_END = None original_filename: str = None - _bounding_box: tuple = None _trace_index: rtree.index.Index = None _trace_index_map: dict = None @@ -375,15 +377,15 @@ class Board: (47, 'F.CrtYd', 'user', 'F.Courtyard'), (48, 'B.Fab', 'user', None), (49, 'F.Fab', 'user', None), - (50, 'User.1', 'user', None), - (51, 'User.2', 'user', None), - (52, 'User.3', 'user', None), - (53, 'User.4', 'user', None), - (54, 'User.5', 'user', None), - (55, 'User.6', 'user', None), - (56, 'User.7', 'user', None), - (57, 'User.8', 'user', None), - (58, 'User.9', 'user', None)]] + (50, 'User.1', 'auxiliary', None), + (51, 'User.2', 'auxiliary', None), + (52, 'User.3', 'auxiliary', None), + (53, 'User.4', 'auxiliary', None), + (54, 'User.5', 'auxiliary', None), + (55, 'User.6', 'auxiliary', None), + (56, 'User.7', 'auxiliary', None), + (57, 'User.8', 'auxiliary', None), + (58, 'User.9', 'auxiliary', None)]] def rebuild_trace_index(self): @@ -660,11 +662,11 @@ class Board: for fp in self.footprints: if name and not match_filter(name, fp.name): continue - if value and not match_filter(value, fp.properties.get('value', '')): + if value and not match_filter(value, fp.value): continue - if reference and not match_filter(reference, fp.properties.get('reference', '')): + if reference and not match_filter(reference, fp.reference): continue - if net and not any(match_filter(net, pad.net.name) for pad in fp.pads): + if net and not any(pad.net and match_filter(net, pad.net.name) for pad in fp.pads): continue if sheetname and not match_filter(sheetname, fp.sheetname): continue @@ -780,15 +782,6 @@ class Board: fe.offset(x, -y, MM) layer_stack.drill_pth.append(fe) - def bounding_box(self, unit=MM): - if not self._bounding_box: - stack = LayerStack() - layer_map = {kc_id: gn_id for kc_id, gn_id in LAYER_MAP_K2G.items() if gn_id in stack} - self.render(stack, layer_map, x=0, y=0, rotation=0, flip=False, text=False, variables={}) - self._bounding_box = stack.bounding_box(unit) - return self._bounding_box - - @dataclass class BoardInstance(cad_pr.Positioned): sexp: Board = None |