diff options
Diffstat (limited to 'gerbonara/gerber/rs274x.py')
-rw-r--r-- | gerbonara/gerber/rs274x.py | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/gerbonara/gerber/rs274x.py b/gerbonara/gerber/rs274x.py index cba08fc..db93fb5 100644 --- a/gerbonara/gerber/rs274x.py +++ b/gerbonara/gerber/rs274x.py @@ -54,7 +54,7 @@ class GerberFile(CamFile): """ def __init__(self, objects=None, comments=None, import_settings=None, filename=None, generator_hints=None, - layer_hints=None): + layer_hints=None, file_attrs=None): super().__init__(filename=filename) self.objects = objects or [] self.comments = comments or [] @@ -62,6 +62,7 @@ class GerberFile(CamFile): self.layer_hints = layer_hints or [] self.import_settings = import_settings self.apertures = [] # FIXME get rid of this? apertures are already in the objects. + self.file_attrs = file_attrs or {} def to_excellon(self): new_objs = [] @@ -125,7 +126,6 @@ class GerberFile(CamFile): seen_macro_names.add(new_name) def dilate(self, offset, unit=MM, polarity_dark=True): - self.apertures = [ aperture.dilated(offset, unit) for aperture in self.apertures ] offset_circle = CircleAperture(offset, unit=unit) @@ -166,6 +166,9 @@ class GerberFile(CamFile): def generate_statements(self, settings, drop_comments=True): yield 'G04 Gerber file generated by Gerbonara*' + for name, value in self.file_attrs.items(): + attrdef = ','.join([name, *map(str, value)]) + yield f'%TF{attrdef}*%' yield '%MOMM*%' if (settings.unit == 'mm') else '%MOIN*%' zeros = 'T' if settings.zeros == 'trailing' else 'L' # default to leading if "None" is specified @@ -224,6 +227,16 @@ class GerberFile(CamFile): settings.number_format = (5,6) return '\n'.join(self.generate_statements(settings)) + @property + def is_empty(self): + return not self.objects + + def __len__(self): + return len(self.objects) + + def __bool__(self): + return not self.is_empty + def offset(self, dx=0, dy=0, unit=MM): # TODO round offset to file resolution @@ -275,9 +288,7 @@ class GraphicsState: self.image_axes = 'AXBY' # AS axis mapping; deprecated self._mat = None self.file_settings = file_settings - if aperture_map is not None: - self.aperture_map = aperture_map - self.aperture_map = {} + self.aperture_map = aperture_map or {} def __setattr__(self, name, value): # input validation @@ -408,7 +419,11 @@ class GraphicsState: arc = lambda cx, cy: go.Arc(*old_point, *new_point, cx, cy, clockwise=clockwise, aperture=(self.aperture if aperture else None), polarity_dark=self.polarity_dark, unit=self.file_settings.unit, attrs=attrs) + print('arcs:') arcs = [ arc(cx, cy), arc(-cx, cy), arc(cx, -cy), arc(-cx, -cy) ] + for a in arcs: + print(f'{a.sweep_angle()=} {a.numeric_error()=} {a}') + print(GerberFile(arcs).to_svg()) arcs = [ a for a in arcs if a.sweep_angle() <= math.pi/2 ] arcs = sorted(arcs, key=lambda a: a.numeric_error()) return arcs[0] @@ -585,6 +600,7 @@ class GerberParser: self.target.apertures = list(self.aperture_map.values()) self.target.import_settings = self.file_settings self.target.unit = self.file_settings.unit + self.target.file_attrs = self.file_attrs if not self.eof_found: warnings.warn('File is missing mandatory M02 EOF marker. File may be truncated.', SyntaxWarning) @@ -863,7 +879,7 @@ class GerberParser: warnings.warn(f'Deprecated {match["mode"]} notation mode statement found. This deprecated since 2012.', DeprecationWarning) self.target.comments.append('Replaced deprecated {match["mode"]} notation mode statement with FS statement') - def _parse_attribtue(self, match): + def _parse_attribute(self, match): if match['type'] == 'TD': if match['value']: raise SyntaxError('TD attribute deletion command must not contain attribute fields') @@ -886,7 +902,7 @@ class GerberParser: target = {'TF': self.file_attrs, 'TO': self.object_attrs, 'TA': self.aperture_attrs}[match['type']] target[match['name']] = match['value'].split(',') - if 'eagle' in self.file_attrs.get('.GenerationSoftware', '').lower() or match['eagle_garbage']: + if 'EAGLE' in self.file_attrs.get('.GenerationSoftware', []) or match['eagle_garbage']: self.generator_hints.append('eagle') def _parse_eof(self, _match): |