summaryrefslogtreecommitdiff
path: root/gerberex
diff options
context:
space:
mode:
Diffstat (limited to 'gerberex')
-rw-r--r--gerberex/__init__.py4
-rw-r--r--gerberex/common.py5
-rw-r--r--gerberex/dxf.py82
3 files changed, 64 insertions, 27 deletions
diff --git a/gerberex/__init__.py b/gerberex/__init__.py
index cef11ab..f379c1c 100644
--- a/gerberex/__init__.py
+++ b/gerberex/__init__.py
@@ -10,6 +10,6 @@ gerber-tools-extension is a extention package for gerber-tools.
This package provide panelizing of PCB fucntion.
"""
-from gerberex.common import (read, loads)
-from gerberex.composition import (GerberComposition, DrillComposition)
+from gerberex.common import read, loads, rectangle
+from gerberex.composition import GerberComposition, DrillComposition
from gerberex.dxf import DxfFile
diff --git a/gerberex/common.py b/gerberex/common.py
index 4a85bd4..47bc6b3 100644
--- a/gerberex/common.py
+++ b/gerberex/common.py
@@ -33,3 +33,8 @@ def loads(data, filename=None, format=None):
return ipc356.loads(data, filename=filename)
else:
raise ParseError('Unable to detect file format')
+
+
+def rectangle(width, height, left=0, bottom=0, units='metric', draw_mode=None, filename=None):
+ return gerberex.dxf.DxfFile.rectangle(
+ width, height, left, bottom, units, draw_mode, filename)
diff --git a/gerberex/dxf.py b/gerberex/dxf.py
index 39d256b..9a2186c 100644
--- a/gerberex/dxf.py
+++ b/gerberex/dxf.py
@@ -42,10 +42,16 @@ class DxfStatement(object):
raise Exception('Not implemented')
class DxfLineStatement(DxfStatement):
- def __init__(self, entity):
+ @classmethod
+ def from_entity(cls, entity):
+ start = (entity.start[0], entity.start[1])
+ end = (entity.end[0], entity.end[1])
+ return cls(entity, start, end)
+
+ def __init__(self, entity, start, end):
super(DxfLineStatement, self).__init__(entity)
- self.start = (self.entity.start[0], self.entity.start[1])
- self.end = (self.entity.end[0], self.entity.end[1])
+ self.start = start
+ self.end = end
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
if pitch == 0:
@@ -329,7 +335,7 @@ class DxfPolylineStatement(DxfStatement):
self.entity.bulge[idx] = metric(self.entity.bulge[idx])
class DxfStatements(object):
- def __init__(self, entities, units, dcode=10, draw_mode=None):
+ def __init__(self, statements, units, dcode=10, draw_mode=None):
if draw_mode == None:
draw_mode = DxfFile.DM_LINE
self._units = units
@@ -338,16 +344,7 @@ class DxfStatements(object):
self.pitch = inch(1) if self._units == 'inch' else 1
self.width = 0
self.error_range = inch(ACCEPTABLE_ERROR) if self._units == 'inch' else ACCEPTABLE_ERROR
- self.statements = []
- for entity in entities:
- if entity.dxftype == 'LWPOLYLINE':
- self.statements.append(DxfPolylineStatement(entity))
- elif entity.dxftype == 'LINE':
- self.statements.append(DxfLineStatement(entity))
- elif entity.dxftype == 'CIRCLE':
- self.statements.append(DxfCircleStatement(entity))
- elif entity.dxftype == 'ARC':
- self.statements.append(DxfArcStatement(entity))
+ self.statements = statements
self.paths = generate_closed_paths(self.statements, self.error_range)
@property
@@ -458,18 +455,52 @@ class DxfFile(CamFile):
FT_RX274X = 0
FT_EXCELLON = 1
- def __init__(self, dxf, settings=None, draw_mode=None, filename=None):
- if not settings:
- settings = FileSettings(zero_suppression='leading')
+ @classmethod
+ def from_dxf(cls, dxf, settings=None, draw_mode=None, filename=None):
+ fsettings = settings if settings else \
+ FileSettings(zero_suppression='leading')
- if draw_mode == None:
- draw_mode = self.DM_LINE
if dxf.header['$INSUNITS'] == 1:
- settings.units = 'inch'
- settings.format = (2, 5)
+ fsettings.units = 'inch'
+ if not settings:
+ fsettings.format = (2, 5)
+ else:
+ fsettings.units = 'metric'
+ if not settings:
+ fsettings.format = (3, 4)
+
+ statements = []
+ for entity in dxf.entities:
+ if entity.dxftype == 'LWPOLYLINE':
+ statements.append(DxfPolylineStatement(entity))
+ elif entity.dxftype == 'LINE':
+ statements.append(DxfLineStatement.from_entity(entity))
+ elif entity.dxftype == 'CIRCLE':
+ statements.append(DxfCircleStatement(entity))
+ elif entity.dxftype == 'ARC':
+ statements.append(DxfArcStatement(entity))
+
+ return cls(statements, fsettings, draw_mode, filename)
+
+ @classmethod
+ def rectangle(cls, width, height, left=0, bottom=0, units='metric', draw_mode=None, filename=None):
+ if units == 'metric':
+ settings = FileSettings(units=units, zero_suppression='leading', format=(3,4))
else:
- settings.units = 'metric'
- settings.format = (3, 4)
+ settings = FileSettings(units=units, zero_suppression='leading', format=(2,5))
+ statements = [
+ DxfLineStatement(None, (left, bottom), (left + width, bottom)),
+ DxfLineStatement(None, (left + width, bottom), (left + width, bottom + height)),
+ DxfLineStatement(None, (left + width, bottom + height), (left, bottom + height)),
+ DxfLineStatement(None, (left, bottom + height), (left, bottom)),
+ ]
+ return cls(statements, settings, draw_mode, filename)
+
+ def __init__(self, statements, settings=None, draw_mode=None, filename=None):
+ if not settings:
+ settings = FileSettings(units='metric', format=(3,4), zero_suppression='leading')
+ if draw_mode == None:
+ draw_mode = self.DM_LINE
super(DxfFile, self).__init__(settings=settings, filename=filename)
self._draw_mode = draw_mode
@@ -477,7 +508,8 @@ class DxfFile(CamFile):
self.header2 = DxfHeader2Statement()
self.aperture = ADParamStmt.circle(dcode=10, diameter=0.0)
- self.statements = DxfStatements(dxf.entities, self.units, dcode=self.aperture.d, draw_mode=self.draw_mode)
+ self.statements = DxfStatements(
+ statements, self.units, dcode=self.aperture.d, draw_mode=self.draw_mode)
@property
def dcode(self):
@@ -559,4 +591,4 @@ def loads(data, filename=None):
data = unicode(data)
stream = io.StringIO(data)
dxf = dxfgrabber.read(stream)
- return DxfFile(dxf)
+ return DxfFile.from_dxf(dxf)