summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHamilton Kibbe <hamilton.kibbe@gmail.com>2014-12-05 23:59:28 -0500
committerHamilton Kibbe <hamilton.kibbe@gmail.com>2014-12-05 23:59:28 -0500
commit29deffcf77e963ae81aec9f8cbc61b029f3052d5 (patch)
tree83bf38945af619b9ca060f1dbd518c6c2517bd9c
parentab69ee0172353e64fbe5099a974341e88feaf24b (diff)
downloadgerbonara-29deffcf77e963ae81aec9f8cbc61b029f3052d5.tar.gz
gerbonara-29deffcf77e963ae81aec9f8cbc61b029f3052d5.tar.bz2
gerbonara-29deffcf77e963ae81aec9f8cbc61b029f3052d5.zip
add ipc2581 primitives
-rw-r--r--doc/source/about.rst38
-rw-r--r--doc/source/index.rst2
-rw-r--r--doc/source/intro.rst19
-rw-r--r--gerber/gerber_statements.py16
-rw-r--r--gerber/primitives.py94
-rw-r--r--gerber/rs274x.py4
6 files changed, 133 insertions, 40 deletions
diff --git a/doc/source/about.rst b/doc/source/about.rst
new file mode 100644
index 0000000..1bb354c
--- /dev/null
+++ b/doc/source/about.rst
@@ -0,0 +1,38 @@
+About PCB Tools
+===============
+
+PCB CAM Files
+~~~~~~~~~~~~~
+
+PCB design (artwork) files are most often stored in `Gerber` files. This is
+a generic term that may refer to `RS-274X (Gerber) <http://en.wikipedia.org/wiki/Gerber_format>`_,
+`ODB++ <http://en.wikipedia.org/wiki/ODB%2B%2B>`_ , or `Excellon <http://en.wikipedia.org/wiki/Excellon_format>`_
+files. These file formats are used by the CNC equipment used to manufacutre PCBs.
+
+PCB Tools provides a set of utilities for visualizing and working with PCB design files
+in a variety of formats. PCB Tools currently supports the following file formats:
+
+- Gerber (RS-274X)
+- Excellon
+
+with planned support for IPC-2581, IPC-D-356 Netlists, ODB++ and more.
+
+Visualization
+~~~~~~~~~~~~~~
+.. image:: ../../examples/composite_top.png
+ :alt: Rendering Example
+
+The PCB Tools module provides tools to visualize PCBs and export images in a variety of formats,
+including SVG and PNG.
+
+
+Future Plans
+~~~~~~~~~~~~
+We are working on adding the following features to PCB Tools:
+
+- Design Rules Checking
+- Editing
+- Panelization
+
+
+
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 309cf88..ab29738 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -11,7 +11,7 @@ Contents:
.. toctree::
:maxdepth: 1
- intro
+ about
documentation/index
Indices and tables
diff --git a/doc/source/intro.rst b/doc/source/intro.rst
deleted file mode 100644
index 4db80ad..0000000
--- a/doc/source/intro.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-PCB Tools Intro
-==================
-
-PCB CAM (Gerber) Files
-------------
-
-PCB design files (artwork) are most often stored in `Gerber` files. This is
-a generic term that may refer to `RS-274X (Gerber) <http://en.wikipedia.org/wiki/Gerber_format>`_,
-`ODB++ <http://en.wikipedia.org/wiki/ODB%2B%2B>`_, or `Excellon <http://en.wikipedia.org/wiki/Excellon_format>`_
-files.
-
-
-PCB-Tools
-------------
-
-The gerber-tools module provides tools for working with and rendering Gerber
-and Excellon files.
-
-
diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py
index 4aaa1d0..05c84b8 100644
--- a/gerber/gerber_statements.py
+++ b/gerber/gerber_statements.py
@@ -1,5 +1,19 @@
-#! /usr/bin/env python
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
+
+# copyright 2014 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.
"""
Gerber (RS-274X) Statements
===========================
diff --git a/gerber/primitives.py b/gerber/primitives.py
index f934f74..e13e37f 100644
--- a/gerber/primitives.py
+++ b/gerber/primitives.py
@@ -19,10 +19,11 @@ from operator import sub
class Primitive(object):
-
- def __init__(self, level_polarity='dark'):
+
+ def __init__(self, level_polarity='dark', rotation=0):
self.level_polarity = level_polarity
-
+ self.rotation = rotation
+
def bounding_box(self):
""" Calculate bounding box
@@ -36,8 +37,8 @@ class Primitive(object):
class Line(Primitive):
"""
"""
- def __init__(self, start, end, width, level_polarity='dark'):
- super(Line, self).__init__(level_polarity)
+ def __init__(self, start, end, width, **kwargs):
+ super(Line, self).__init__(**kwargs)
self.start = start
self.end = end
self.width = width
@@ -61,8 +62,8 @@ class Line(Primitive):
class Arc(Primitive):
"""
"""
- def __init__(self, start, end, center, direction, width, level_polarity='dark'):
- super(Arc, self).__init__(level_polarity)
+ def __init__(self, start, end, center, direction, width, **kwargs):
+ super(Arc, self).__init__(**kwargs)
self.start = start
self.end = end
self.center = center
@@ -139,8 +140,8 @@ class Arc(Primitive):
class Circle(Primitive):
"""
"""
- def __init__(self, position, diameter, level_polarity='dark'):
- super(Circle, self).__init__(level_polarity)
+ def __init__(self, position, diameter, **kwargs):
+ super(Circle, self).__init__(**kwargs)
self.position = position
self.diameter = diameter
@@ -161,11 +162,29 @@ class Circle(Primitive):
return self.diameter
+class Ellipse(Primitive):
+ """
+ """
+ def __init__(self, position, width, height, **kwargs):
+ super(Ellipse, self).__init__(**kwargs)
+ self.position = position
+ self.width = width
+ self.height = height
+
+ @property
+ def bounding_box(self):
+ min_x = self.position[0] - (self.width / 2.0)
+ max_x = self.position[0] + (self.width / 2.0)
+ min_y = self.position[1] - (self.height / 2.0)
+ max_y = self.position[1] + (self.height / 2.0)
+ return ((min_x, max_x), (min_y, max_y))
+
+
class Rectangle(Primitive):
"""
"""
- def __init__(self, position, width, height, level_polarity='dark'):
- super(Rectangle, self).__init__(level_polarity)
+ def __init__(self, position, width, height, **kwargs):
+ super(Rectangle, self).__init__(**kwargs)
self.position = position
self.width = width
self.height = height
@@ -193,11 +212,23 @@ class Rectangle(Primitive):
return max((self.width, self.height))
+class Diamond(Primitive):
+ pass
+
+
+class ChamferRectangle(Primitive):
+ pass
+
+
+class RoundRectangle(Primitive):
+ pass
+
+
class Obround(Primitive):
"""
"""
- def __init__(self, position, width, height, level_polarity='dark'):
- super(Obround, self).__init__(level_polarity)
+ def __init__(self, position, width, height, **kwargs):
+ super(Obround, self).__init__(**kwargs)
self.position = position
self.width = width
self.height = height
@@ -242,11 +273,12 @@ class Obround(Primitive):
self.height)
return {'circle1': circle1, 'circle2': circle2, 'rectangle': rect}
+
class Polygon(Primitive):
"""
"""
- def __init__(self, position, sides, radius, level_polarity='dark'):
- super(Polygon, self).__init__(level_polarity)
+ def __init__(self, position, sides, radius, **kwargs):
+ super(Polygon, self).__init__(**kwargs)
self.position = position
self.sides = sides
self.radius = radius
@@ -263,8 +295,8 @@ class Polygon(Primitive):
class Region(Primitive):
"""
"""
- def __init__(self, points, level_polarity='dark'):
- super(Region, self).__init__(level_polarity)
+ def __init__(self, points, **kwargs):
+ super(Region, self).__init__(**kwargs)
self.points = points
@property
@@ -277,6 +309,34 @@ class Region(Primitive):
return ((min_x, max_x), (min_y, max_y))
+class RoundButterfly(Primitive):
+ """
+ """
+ def __init__(self, position, diameter, **kwargs):
+ super(RoundButterfly, self).__init__(**kwargs)
+ self.position = position
+ self.diameter = diameter
+
+ @property
+ def radius(self):
+ return self.diameter / 2.
+
+ @property
+ def bounding_box(self):
+ min_x = self.position[0] - self.radius
+ max_x = self.position[0] + self.radius
+ min_y = self.position[1] - self.radius
+ max_y = self.position[1] + self.radius
+ return ((min_x, max_x), (min_y, max_y))
+
+class SquareButterfly(Primitive):
+ pass
+
+
+class Donut(Primitive):
+ pass
+
+
class Drill(Primitive):
"""
"""
diff --git a/gerber/rs274x.py b/gerber/rs274x.py
index a41760e..6dbcc63 100644
--- a/gerber/rs274x.py
+++ b/gerber/rs274x.py
@@ -403,10 +403,10 @@ class GerberParser(object):
end = (x, y)
width = self.apertures[self.aperture].stroke_width
if self.interpolation == 'linear':
- self.primitives.append(Line(start, end, width, self.level_polarity))
+ self.primitives.append(Line(start, end, width, level_polarity=self.level_polarity))
else:
center = (start[0] + stmt.i, start[1] + stmt.j)
- self.primitives.append(Arc(start, end, center, self.direction, width, self.level_polarity))
+ self.primitives.append(Arc(start, end, center, self.direction, width, level_polarity=self.level_polarity))
elif stmt.op == "D02":
pass