diff options
author | Paulo Henrique Silva <ph.silva@gmail.com> | 2016-01-05 22:05:19 -0200 |
---|---|---|
committer | Paulo Henrique Silva <ph.silva@gmail.com> | 2016-01-05 22:05:19 -0200 |
commit | 7a532514631384dbfc9d7fc2002cbbfe52433c9f (patch) | |
tree | 5678cff7ba877e9c93ea63445f081fd0430f8b4b /gerber/pcb.py | |
parent | af5541ac93b222c05229ee05c9def8dbae5f6e25 (diff) | |
parent | 6a005436b475e3517fd6a583473b60e601bcc661 (diff) | |
download | gerbonara-7a532514631384dbfc9d7fc2002cbbfe52433c9f.tar.gz gerbonara-7a532514631384dbfc9d7fc2002cbbfe52433c9f.tar.bz2 gerbonara-7a532514631384dbfc9d7fc2002cbbfe52433c9f.zip |
Merge pull request #53 from curtacircuitos/pcb_interface
Add PCB interface
Diffstat (limited to 'gerber/pcb.py')
-rw-r--r-- | gerber/pcb.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/gerber/pcb.py b/gerber/pcb.py new file mode 100644 index 0000000..0518dd4 --- /dev/null +++ b/gerber/pcb.py @@ -0,0 +1,94 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# copyright 2015 Hamilton Kibbe <ham@hamiltonkib.be> +# +# 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. + + +import os +from .exceptions import ParseError +from .layers import PCBLayer, LayerSet, sort_layers +from .common import read as gerber_read +from .utils import listdir + + +class PCB(object): + + @classmethod + def from_directory(cls, directory, board_name=None, verbose=False): + layers = [] + names = set() + # Validate + directory = os.path.abspath(directory) + if not os.path.isdir(directory): + raise TypeError('{} is not a directory.'.format(directory)) + # Load gerber files + for filename in listdir(directory, True, True): + try: + camfile = gerber_read(os.path.join(directory, filename)) + layer = PCBLayer.from_gerber(camfile) + layers.append(layer) + names.add(os.path.splitext(filename)[0]) + if verbose: + print('Added {} layer <{}>'.format(layer.layer_class, filename)) + except ParseError: + if verbose: + print('Skipping file {}'.format(filename)) + # Try to guess board name + if board_name is None: + if len(names) == 1: + board_name = names.pop() + else: + board_name = os.path.basename(directory) + # Return PCB + return cls(layers, board_name) + + def __init__(self, layers, name=None): + self.layers = sort_layers(layers) + self.name = name + + def __len__(self): + return len(self.layers) + + @property + def top_layers(self): + board_layers = [l for l in reversed(self.layers) if l.layer_class in ('topsilk', 'topmask', 'top')] + drill_layers = [l for l in self.drill_layers if 'top' in l.layers] + return board_layers + drill_layers + + @property + def bottom_layers(self): + board_layers = [l for l in self.layers if l.layer_class in ('bottomsilk', 'bottommask', 'bottom')] + drill_layers = [l for l in self.drill_layers if 'bottom' in l.layers] + return board_layers + drill_layers + + @property + def drill_layers(self): + return [l for l in self.layers if l.layer_class == 'drill'] + + @property + def layer_count(self): + """ Number of *COPPER* layers + """ + return len([l for l in self.layers if l.layer_class in ('top', 'bottom', 'internal')]) + + @property + def board_bounds(self): + for layer in self.layers: + if layer.layer_class == 'outline': + return layer.bounds + for layer in self.layers: + if layer.layer_class == 'top': + return layer.bounds + |