From ae3bbff8b0849e0b49dc139396d7f8c57334a7b8 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Fri, 10 Oct 2014 23:07:51 -0400 Subject: Added excellon format detection --- gerber/cam.py | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 gerber/cam.py (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py new file mode 100644 index 0000000..e7a49d1 --- /dev/null +++ b/gerber/cam.py @@ -0,0 +1,124 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# copyright 2014 Hamilton Kibbe +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +CAM File +============ +**AM file classes** + +This module provides common base classes for Excellon/Gerber CNC files +""" + + +class FileSettings(object): + """ CAM File Settings + + Provides a common representation of gerber/excellon file settings + """ + def __init__(self, notation='absolute', units='inch', + zero_suppression='trailing', format=(2, 5)): + if notation not in ['absolute', 'incremental']: + raise ValueError('Notation must be either absolute or incremental') + self.notation = notation + + if units not in ['inch', 'metric']: + raise ValueError('Units must be either inch or metric') + self.units = units + + if zero_suppression not in ['leading', 'trailing']: + raise ValueError('Zero suppression must be either leading or \ + trailling') + self.zero_suppression = zero_suppression + + if len(format) != 2: + raise ValueError('Format must be a tuple(n=2) of integers') + self.format = format + + def __getitem__(self, key): + if key == 'notation': + return self.notation + elif key == 'units': + return self.units + elif key == 'zero_suppression': + return self.zero_suppression + elif key == 'format': + return self.format + else: + raise KeyError() + + +class CamFile(object): + """ Base class for Gerber/Excellon files. + + Provides a common set of settings parameters. + + Parameters + ---------- + settings : FileSettings + The current file configuration. + + filename : string + Name of the file that this CamFile represents. + + layer_name : string + Name of the PCB layer that the file represents + + Attributes + ---------- + settings : FileSettings + File settings as a FileSettings object + + notation : string + File notation setting. May be either 'absolute' or 'incremental' + + units : string + File units setting. May be 'inch' or 'metric' + + zero_suppression : string + File zero-suppression setting. May be either 'leading' or 'trailling' + + format : tuple (, ) + File decimal representation format as a tuple of (integer digits, + decimal digits) + """ + + def __init__(self, statements=None, settings=None, filename=None, + layer_name=None): + if settings is not None: + self.notation = settings['notation'] + self.units = settings['units'] + self.zero_suppression = settings['zero_suppression'] + self.format = settings['format'] + else: + self.notation = 'absolute' + self.units = 'inch' + self.zero_suppression = 'trailing' + self.format = (2, 5) + self.statements = statements if statements is not None else [] + self.filename = filename + self.layer_name = layer_name + + @property + def settings(self): + """ File settings + + Returns + ------- + settings : FileSettings (dict-like) + A FileSettings object with the specified configuration. + """ + return FileSettings(self.notation, self.units, self.zero_suppression, + self.format) -- cgit From 6d2db67e6d0973ce26ce3a6700ca44295f73fea7 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sat, 18 Oct 2014 01:44:51 -0400 Subject: Refactor rendering --- gerber/cam.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index e7a49d1..4c19588 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -70,6 +70,9 @@ class CamFile(object): settings : FileSettings The current file configuration. + primitives : iterable + List of primitives in the file. + filename : string Name of the file that this CamFile represents. @@ -95,8 +98,8 @@ class CamFile(object): decimal digits) """ - def __init__(self, statements=None, settings=None, filename=None, - layer_name=None): + def __init__(self, statements=None, settings=None, primitives=None, + filename=None, layer_name=None): if settings is not None: self.notation = settings['notation'] self.units = settings['units'] @@ -108,6 +111,7 @@ class CamFile(object): self.zero_suppression = 'trailing' self.format = (2, 5) self.statements = statements if statements is not None else [] + self.primitives = primitives self.filename = filename self.layer_name = layer_name @@ -122,3 +126,20 @@ class CamFile(object): """ return FileSettings(self.notation, self.units, self.zero_suppression, self.format) + + def render(self, ctx, filename=None): + """ Generate image of layer. + + Parameters + ---------- + ctx : :class:`GerberContext` + GerberContext subclass used for rendering the image + + filename : string + If provided, save the rendered image to `filename` + """ + ctx.set_bounds(self.bounds) + for p in self.primitives: + ctx.render(p) + if filename is not None: + ctx.dump(filename) -- cgit From 18e3b87625ddb739faeddffcaed48e12db6c7e8b Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sun, 19 Oct 2014 22:23:00 -0400 Subject: Test update --- gerber/cam.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 4c19588..051c3b5 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -59,6 +59,33 @@ class FileSettings(object): else: raise KeyError() + def __setitem__(self, key, value): + if key == 'notation': + if value not in ['absolute', 'incremental']: + raise ValueError('Notation must be either \ + absolute or incremental') + self.notation = value + elif key == 'units': + if value not in ['inch', 'metric']: + raise ValueError('Units must be either inch or metric') + self.units = value + elif key == 'zero_suppression': + if value not in ['leading', 'trailing']: + raise ValueError('Zero suppression must be either leading or \ + trailling') + self.zero_suppression = value + elif key == 'format': + if len(value) != 2: + raise ValueError('Format must be a tuple(n=2) of integers') + self.format = value + + def __eq__(self, other): + return (self.notation == other.notation and + self.units == other.units and + self.zero_suppression == other.zero_suppression and + self.format == other.format) + + class CamFile(object): """ Base class for Gerber/Excellon files. @@ -127,6 +154,12 @@ class CamFile(object): return FileSettings(self.notation, self.units, self.zero_suppression, self.format) + @property + def bounds(self): + """ File baundaries + """ + pass + def render(self, ctx, filename=None): """ Generate image of layer. -- cgit From b495d51354eff7b858dbbd41740865eba7f39100 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sun, 25 Jan 2015 14:19:48 -0500 Subject: Changed zeros/zero suppression conventions to match file format specs --- gerber/cam.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 6 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 051c3b5..a4057bc 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -27,9 +27,34 @@ class FileSettings(object): """ CAM File Settings Provides a common representation of gerber/excellon file settings + + Parameters + ---------- + notation: string + notation format. either 'absolute' or 'incremental' + + units : string + Measurement units. 'inch' or 'metric' + + zero_suppression: string + 'leading' to suppress leading zeros, 'trailing' to suppress trailing zeros. + This is the convention used in Gerber files. + + format : tuple (int, int) + Decimal format + + zeros : string + 'leading' to include leading zeros, 'trailing to include trailing zeros. + This is the convention used in Excellon files + + Notes + ----- + Either `zeros` or `zero_suppression` should be specified, there is no need to + specify both. `zero_suppression` will take on the opposite value of `zeros` + and vice versa """ def __init__(self, notation='absolute', units='inch', - zero_suppression='trailing', format=(2, 5)): + zero_suppression=None, format=(2, 5), zeros=None): if notation not in ['absolute', 'incremental']: raise ValueError('Notation must be either absolute or incremental') self.notation = notation @@ -38,15 +63,52 @@ class FileSettings(object): raise ValueError('Units must be either inch or metric') self.units = units - if zero_suppression not in ['leading', 'trailing']: - raise ValueError('Zero suppression must be either leading or \ - trailling') - self.zero_suppression = zero_suppression + + if zero_suppression is None and zeros is None: + self.zero_suppression = 'trailing' + + elif zero_suppression == zeros: + raise ValueError('Zeros and Zero Suppression must be different. \ + Best practice is to specify only one.') + + elif zero_suppression is not None: + if zero_suppression not in ['leading', 'trailing']: + raise ValueError('Zero suppression must be either leading or \ + trailling') + self.zero_suppression = zero_suppression + + + elif zeros is not None: + if zeros not in ['leading', 'trailing']: + raise ValueError('Zeros must be either leading or trailling') + self.zeros = zeros + else: + self.zeros = 'leading' + if len(format) != 2: raise ValueError('Format must be a tuple(n=2) of integers') self.format = format + @property + def zero_suppression(self): + return self._zero_suppression + + @zero_suppression.setter + def zero_suppression(self, value): + self._zero_suppression = value + self._zeros = 'leading' if value == 'trailing' else 'trailing' + + @property + def zeros(self): + return self._zeros + + @zeros.setter + def zeros(self, value): + + self._zeros = value + self._zero_suppression = 'leading' if value == 'trailing' else 'trailing' + def __getitem__(self, key): if key == 'notation': return self.notation @@ -54,6 +116,8 @@ class FileSettings(object): return self.units elif key == 'zero_suppression': return self.zero_suppression + elif key == 'zeros': + return self.zeros elif key == 'format': return self.format else: @@ -69,11 +133,18 @@ class FileSettings(object): if value not in ['inch', 'metric']: raise ValueError('Units must be either inch or metric') self.units = value + elif key == 'zero_suppression': if value not in ['leading', 'trailing']: raise ValueError('Zero suppression must be either leading or \ trailling') self.zero_suppression = value + + elif key == 'zeros': + if value not in ['leading', 'trailing']: + raise ValueError('Zeros must be either leading or trailling') + self.zeros = value + elif key == 'format': if len(value) != 2: raise ValueError('Format must be a tuple(n=2) of integers') @@ -86,7 +157,6 @@ class FileSettings(object): self.format == other.format) - class CamFile(object): """ Base class for Gerber/Excellon files. @@ -131,11 +201,13 @@ class CamFile(object): self.notation = settings['notation'] self.units = settings['units'] self.zero_suppression = settings['zero_suppression'] + self.zeros = settings['zeros'] self.format = settings['format'] else: self.notation = 'absolute' self.units = 'inch' self.zero_suppression = 'trailing' + self.zeros = 'leading' self.format = (2, 5) self.statements = statements if statements is not None else [] self.primitives = primitives -- cgit From d98d23f8b5d61bb9d20e743a3c44bf04b6b2330a Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Mon, 2 Feb 2015 00:43:08 -0500 Subject: More tests and bugfixes --- gerber/cam.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index a4057bc..9c731aa 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -62,29 +62,24 @@ class FileSettings(object): if units not in ['inch', 'metric']: raise ValueError('Units must be either inch or metric') self.units = units - - + if zero_suppression is None and zeros is None: self.zero_suppression = 'trailing' - + elif zero_suppression == zeros: raise ValueError('Zeros and Zero Suppression must be different. \ Best practice is to specify only one.') - + elif zero_suppression is not None: if zero_suppression not in ['leading', 'trailing']: raise ValueError('Zero suppression must be either leading or \ trailling') self.zero_suppression = zero_suppression - elif zeros is not None: if zeros not in ['leading', 'trailing']: raise ValueError('Zeros must be either leading or trailling') self.zeros = zeros - else: - self.zeros = 'leading' - if len(format) != 2: raise ValueError('Format must be a tuple(n=2) of integers') @@ -150,6 +145,9 @@ class FileSettings(object): raise ValueError('Format must be a tuple(n=2) of integers') self.format = value + else: + raise KeyError('%s is not a valid key' % key) + def __eq__(self, other): return (self.notation == other.notation and self.units == other.units and @@ -230,7 +228,7 @@ class CamFile(object): def bounds(self): """ File baundaries """ - pass + raise NotImplementedError('bounds must be implemented in a subclass') def render(self, ctx, filename=None): """ Generate image of layer. -- cgit From 5e23d07bcb5103b4607c6ad591a2a547c97ee1f6 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Fri, 13 Feb 2015 09:37:27 -0500 Subject: Fix rendering for line with rectangular aperture per #12. Still need to do the same for arcs. --- gerber/cam.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 9c731aa..f49f5dd 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -21,7 +21,7 @@ CAM File This module provides common base classes for Excellon/Gerber CNC files """ - +from operator import mul class FileSettings(object): """ CAM File Settings @@ -241,7 +241,8 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ - ctx.set_bounds(self.bounds) + bounds = [tuple([x * 1.2, y*1.2]) for x, y in self.bounds] + ctx.set_bounds(bounds) for p in self.primitives: ctx.render(p) if filename is not None: -- cgit From 5cf1fa74b42eb8feaab23078bef6f31f6d647c33 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sun, 15 Feb 2015 02:20:02 -0500 Subject: Tests and bugfixes --- gerber/cam.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index f49f5dd..caca517 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -21,7 +21,6 @@ CAM File This module provides common base classes for Excellon/Gerber CNC files """ -from operator import mul class FileSettings(object): """ CAM File Settings @@ -62,14 +61,14 @@ class FileSettings(object): if units not in ['inch', 'metric']: raise ValueError('Units must be either inch or metric') self.units = units - + if zero_suppression is None and zeros is None: self.zero_suppression = 'trailing' - + elif zero_suppression == zeros: raise ValueError('Zeros and Zero Suppression must be different. \ Best practice is to specify only one.') - + elif zero_suppression is not None: if zero_suppression not in ['leading', 'trailing']: raise ValueError('Zero suppression must be either leading or \ -- cgit From 288ac27084b47166ac662402ea340d0aa25d8f56 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Wed, 18 Feb 2015 04:31:23 -0500 Subject: Get unit conversion working for Gerber/Excellon files Started operations module for file operations/transforms --- gerber/cam.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index caca517..243070d 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -225,9 +225,9 @@ class CamFile(object): @property def bounds(self): - """ File baundaries + """ File boundaries """ - raise NotImplementedError('bounds must be implemented in a subclass') + pass def render(self, ctx, filename=None): """ Generate image of layer. -- cgit From b3e0ceb5c3ec755b09d2f005b8e3dcbed22d45a1 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Fri, 20 Feb 2015 22:24:34 -0500 Subject: Add IPC-D-356 Netlist Parsing --- gerber/cam.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 243070d..31b6d2f 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -53,7 +53,8 @@ class FileSettings(object): and vice versa """ def __init__(self, notation='absolute', units='inch', - zero_suppression=None, format=(2, 5), zeros=None): + zero_suppression=None, format=(2, 5), zeros=None, + angle_units='degrees'): if notation not in ['absolute', 'incremental']: raise ValueError('Notation must be either absolute or incremental') self.notation = notation @@ -84,6 +85,10 @@ class FileSettings(object): raise ValueError('Format must be a tuple(n=2) of integers') self.format = format + if angle_units not in ('degrees', 'radians'): + raise ValueError('Angle units may be degrees or radians') + self.angle_units = angle_units + @property def zero_suppression(self): return self._zero_suppression @@ -114,6 +119,8 @@ class FileSettings(object): return self.zeros elif key == 'format': return self.format + elif key == 'angle_units': + return self.angle_units else: raise KeyError() @@ -144,6 +151,11 @@ class FileSettings(object): raise ValueError('Format must be a tuple(n=2) of integers') self.format = value + elif key == 'angle_units': + if value not in ('degrees', 'radians'): + raise ValueError('Angle units may be degrees or radians') + self.angle_units = value + else: raise KeyError('%s is not a valid key' % key) @@ -151,7 +163,8 @@ class FileSettings(object): return (self.notation == other.notation and self.units == other.units and self.zero_suppression == other.zero_suppression and - self.format == other.format) + self.format == other.format and + self.angle_units == other.angle_units) class CamFile(object): -- cgit From 94f3976915d64a77135a1fdc8983085ee8d2e1f9 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 11 Jun 2015 11:20:56 -0400 Subject: Add keys to statements for linking to primitives. Add some API features to ExcellonFile, such as getting a tool path length and changing tool parameters. Excellonfiles write method generates statements based on the drill hits in the hits member, so drill hits in a generated file can be re-ordered by re-ordering the drill hits in ExcellonFile.hits. see #30 --- gerber/cam.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 31b6d2f..23d8214 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -220,7 +220,8 @@ class CamFile(object): self.zeros = 'leading' self.format = (2, 5) self.statements = statements if statements is not None else [] - self.primitives = primitives + if primitives is not None: + self.primitives = primitives self.filename = filename self.layer_name = layer_name -- cgit From 5aaf18889c3cdc31ae61b9593bf5848bc57ec09a Mon Sep 17 00:00:00 2001 From: Paulo Henrique Silva Date: Thu, 9 Jul 2015 03:54:47 -0300 Subject: Initial patch to unify our render towards cairo This branch allows a pure cairo based render for both PNG and SVG. Cairo backend is mostly the same but with improved support for configurable scale, orientation and inverted color drawing. API is not yet final. --- gerber/cam.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 31b6d2f..91ffb9a 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -253,8 +253,9 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ - bounds = [tuple([x * 1.2, y*1.2]) for x, y in self.bounds] - ctx.set_bounds(bounds) + if ctx.invert: + ctx._paint_inverted_layer() + for p in self.primitives: ctx.render(p) if filename is not None: -- cgit From b3f6ec558ca35a19bd60440f2a114eb98c0a4263 Mon Sep 17 00:00:00 2001 From: Paulo Henrique Silva Date: Thu, 9 Jul 2015 04:05:15 -0300 Subject: Fix arcs and ackground painting --- gerber/cam.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 91ffb9a..804e366 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -253,9 +253,11 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ + ctx._paint_background() + if ctx.invert: ctx._paint_inverted_layer() - + for p in self.primitives: ctx.render(p) if filename is not None: -- cgit From 39726e3936c5fa5c50158727e8eb7f5d01cb1b49 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Wed, 22 Jul 2015 22:13:09 -0400 Subject: Fix multiple layer issue in cairo-unification branch (see #33) --- gerber/cam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 804e366..0a68b23 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -253,8 +253,8 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ + ctx.set_bounds(self.bounds) ctx._paint_background() - if ctx.invert: ctx._paint_inverted_layer() -- cgit From 1cb269131bc52f0b1a1e69cef0466f2d994d52a8 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sat, 19 Dec 2015 21:54:29 -0500 Subject: Allow negative render of soldermask per #50 Update example code and rendering to show change --- gerber/cam.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index c567055..cf06ec9 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -243,7 +243,7 @@ class CamFile(object): """ pass - def render(self, ctx, filename=None): + def render(self, ctx, invert=False, filename=None): """ Generate image of layer. Parameters @@ -256,10 +256,14 @@ class CamFile(object): """ ctx.set_bounds(self.bounds) ctx._paint_background() - if ctx.invert: + if invert: + ctx.invert = True ctx._paint_inverted_layer() - for p in self.primitives: ctx.render(p) + if invert: + ctx.invert = False + ctx._render_mask() + if filename is not None: ctx.dump(filename) -- cgit From af5541ac93b222c05229ee05c9def8dbae5f6e25 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Sun, 20 Dec 2015 23:54:20 -0500 Subject: Allow renderer to write to memory per #38 Some updates to rendering colors/themes --- gerber/cam.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index cf06ec9..92ce83d 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -256,9 +256,10 @@ class CamFile(object): """ ctx.set_bounds(self.bounds) ctx._paint_background() + if invert: ctx.invert = True - ctx._paint_inverted_layer() + ctx._clear_mask() for p in self.primitives: ctx.render(p) if invert: -- cgit From 5476da8aa3f4ee424f56f4f2491e7af1c4b7b758 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 21 Jan 2016 03:57:44 -0500 Subject: Fix a bunch of rendering bugs. - 'clear' polarity primitives no longer erase background - Added aperture macro support for polygons - Added aperture macro rendring support - Renderer now creates a new surface for each layer and merges them instead of working directly on a single surface - Updated examples accordingly --- gerber/cam.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 92ce83d..dda5c10 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -22,6 +22,7 @@ CAM File This module provides common base classes for Excellon/Gerber CNC files """ + class FileSettings(object): """ CAM File Settings @@ -52,6 +53,7 @@ class FileSettings(object): specify both. `zero_suppression` will take on the opposite value of `zeros` and vice versa """ + def __init__(self, notation='absolute', units='inch', zero_suppression=None, format=(2, 5), zeros=None, angle_units='degrees'): @@ -243,6 +245,12 @@ class CamFile(object): """ pass + def to_inch(self): + pass + + def to_metric(self): + pass + def render(self, ctx, invert=False, filename=None): """ Generate image of layer. @@ -256,15 +264,11 @@ class CamFile(object): """ ctx.set_bounds(self.bounds) ctx._paint_background() - - if invert: - ctx.invert = True - ctx._clear_mask() + ctx.invert = invert + ctx._new_render_layer() for p in self.primitives: ctx.render(p) - if invert: - ctx.invert = False - ctx._render_mask() + ctx._flatten() if filename is not None: ctx.dump(filename) -- cgit From 5df38c014fd09792995b2b12b1982c535c962c9a Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 28 Jan 2016 12:19:03 -0500 Subject: Cleanup, rendering fixes. fixed rendering of tented vias fixed rendering of semi-transparent layers fixed file type detection issues added some examples --- gerber/cam.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index dda5c10..86312fb 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -251,7 +251,7 @@ class CamFile(object): def to_metric(self): pass - def render(self, ctx, invert=False, filename=None): + def render(self, ctx=None, invert=False, filename=None): """ Generate image of layer. Parameters @@ -262,13 +262,16 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ + if ctx is None: + from .render import GerberCairoContext + ctx = GerberCairoContext() ctx.set_bounds(self.bounds) ctx._paint_background() ctx.invert = invert ctx._new_render_layer() for p in self.primitives: ctx.render(p) - ctx._flatten() + ctx._paint() if filename is not None: ctx.dump(filename) -- cgit From 3fce700ef289d16053b0f60cccdfd4d5956daf5c Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Mon, 15 Feb 2016 23:53:52 +0800 Subject: Don't throw an exception for missing zero suppress, even though it is wrong --- gerber/cam.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index c567055..08d80de 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -72,9 +72,10 @@ class FileSettings(object): elif zero_suppression is not None: if zero_suppression not in ['leading', 'trailing']: - raise ValueError('Zero suppression must be either leading or \ - trailling') - self.zero_suppression = zero_suppression + # This is a common problem in Eagle files, so just suppress it + self.zero_suppression = 'leading' + else: + self.zero_suppression = zero_suppression elif zeros is not None: if zeros not in ['leading', 'trailing']: -- cgit From 223a010831f0d9dae4bd6d2e626a603a78eb0b1d Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sat, 27 Feb 2016 18:18:04 +0800 Subject: Fix critical issue with rotatin points (when the angle is zero the y would be flipped). Render AM with outline to gerber --- gerber/cam.py | 1 + 1 file changed, 1 insertion(+) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 08d80de..53f5c0d 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -255,6 +255,7 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ + ctx.set_bounds(self.bounds) ctx._paint_background() if ctx.invert: -- cgit From 20a9af279ac2217a39b73903ff94b916a3025be2 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Tue, 1 Mar 2016 00:06:14 +0800 Subject: More rendering of AMGroup to statements --- gerber/cam.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 53f5c0d..8e31bf0 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -166,6 +166,10 @@ class FileSettings(object): self.zero_suppression == other.zero_suppression and self.format == other.format and self.angle_units == other.angle_units) + + def __str__(self): + return ('' % + (self.units, self.notation, self.zero_suppression, self.format, self.angle_units)) class CamFile(object): -- cgit From 7cd6acf12670f3773113f67ed2acb35cb21c32a0 Mon Sep 17 00:00:00 2001 From: Garret Fick Date: Sun, 24 Jul 2016 17:08:47 +0800 Subject: Add many render tests based on the Umaco gerger specification. Fix multiple rendering bugs, especially related to holes in flashed apertures --- gerber/cam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 28918cb..f64aa34 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -260,7 +260,7 @@ class CamFile(object): If provided, save the rendered image to `filename` """ - ctx.set_bounds(self.bounds) + ctx.set_bounds(self.bounding_box) ctx._paint_background() if invert: -- cgit From 8cd842a41a55ab3d8f558a2e3e198beba7da58a1 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 21 Jan 2016 03:57:44 -0500 Subject: Manually mere rendering changes --- gerber/cam.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index f64aa34..0e19b05 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -22,6 +22,7 @@ CAM File This module provides common base classes for Excellon/Gerber CNC files """ + class FileSettings(object): """ CAM File Settings @@ -52,6 +53,7 @@ class FileSettings(object): specify both. `zero_suppression` will take on the opposite value of `zeros` and vice versa """ + def __init__(self, notation='absolute', units='inch', zero_suppression=None, format=(2, 5), zeros=None, angle_units='degrees'): @@ -248,6 +250,12 @@ class CamFile(object): """ pass + def to_inch(self): + pass + + def to_metric(self): + pass + def render(self, ctx, invert=False, filename=None): """ Generate image of layer. @@ -262,15 +270,11 @@ class CamFile(object): ctx.set_bounds(self.bounding_box) ctx._paint_background() - - if invert: - ctx.invert = True - ctx._clear_mask() + ctx.invert = invert + ctx._new_render_layer() for p in self.primitives: ctx.render(p) - if invert: - ctx.invert = False - ctx._render_mask() + ctx._flatten() if filename is not None: ctx.dump(filename) -- cgit From 5af19af190c1fb0f0c5be029d46d63e657dde4d9 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Thu, 21 Jan 2016 03:57:44 -0500 Subject: Commit partial merge so I can work on the plane --- gerber/cam.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 0e19b05..c5b8938 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -267,8 +267,7 @@ class CamFile(object): filename : string If provided, save the rendered image to `filename` """ - - ctx.set_bounds(self.bounding_box) + ctx.set_bounds(self.bounds) ctx._paint_background() ctx.invert = invert ctx._new_render_layer() -- cgit From 5245fb925684b4ebe056e6509bfeca6b167903b5 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Tue, 5 Jun 2018 08:57:37 -0400 Subject: Fix hard requirement of cairo per #83, and add stubs for required subclass methods to GerberContext per #84 --- gerber/cam.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gerber/cam.py') diff --git a/gerber/cam.py b/gerber/cam.py index 15b801a..4f20283 100644 --- a/gerber/cam.py +++ b/gerber/cam.py @@ -250,6 +250,10 @@ class CamFile(object): """ pass + @property + def bounding_box(self): + pass + def to_inch(self): pass @@ -271,12 +275,12 @@ class CamFile(object): from .render import GerberCairoContext ctx = GerberCairoContext() ctx.set_bounds(self.bounding_box) - ctx._paint_background() + ctx.paint_background() ctx.invert = invert - ctx._new_render_layer() + ctx.new_render_layer() for p in self.primitives: ctx.render(p) - ctx._flatten() + ctx.flatten() if filename is not None: ctx.dump(filename) -- cgit