summaryrefslogtreecommitdiff
path: root/gerbonara/cad/kicad/pcb.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerbonara/cad/kicad/pcb.py')
-rw-r--r--gerbonara/cad/kicad/pcb.py117
1 files changed, 55 insertions, 62 deletions
diff --git a/gerbonara/cad/kicad/pcb.py b/gerbonara/cad/kicad/pcb.py
index 767b763..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)
@@ -250,7 +250,8 @@ class Via:
keep_end_layers: 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