Repo re-org, make gerberex tests run
|
|
@ -1,15 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
"""
|
||||
Gerber Tools Extension
|
||||
======================
|
||||
**Gerber Tools Extenstion**
|
||||
gerber-tools-extension is a extention package for gerber-tools.
|
||||
This package provide panelizing of PCB fucntion.
|
||||
"""
|
||||
|
||||
from gerberex.common import read, loads, rectangle
|
||||
from gerberex.composition import GerberComposition, DrillComposition
|
||||
from gerberex.dxf import DxfFile
|
||||
|
|
@ -15,11 +15,10 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""
|
||||
Gerber Tools
|
||||
============
|
||||
**Gerber Tools**
|
||||
Gerbonara
|
||||
=========
|
||||
|
||||
gerber-tools provides utilities for working with Gerber (RS-274X) and Excellon
|
||||
gerbonara provides utilities for working with Gerber (RS-274X) and Excellon
|
||||
files in python.
|
||||
"""
|
||||
|
||||
8
gerbonara/gerber/panelize/__init__.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from .common import read, loads, rectangle
|
||||
from .composition import GerberComposition, DrillComposition
|
||||
from .dxf import DxfFile
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.utils import *
|
||||
from gerber.am_eval import OpCode
|
||||
from gerber.am_statements import *
|
||||
from ..utils import *
|
||||
from ..am_eval import OpCode
|
||||
from ..am_statements import *
|
||||
|
||||
class AMExpression(object):
|
||||
CONSTANT = 1
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.utils import *
|
||||
from gerber.am_statements import *
|
||||
from gerber.am_eval import OpCode
|
||||
from ..utils import *
|
||||
from ..am_statements import *
|
||||
from ..am_eval import OpCode
|
||||
|
||||
from gerberex.am_expression import eval_macro, AMConstantExpression, AMOperatorExpression
|
||||
from .am_expression import eval_macro, AMConstantExpression, AMOperatorExpression
|
||||
|
||||
class AMPrimitiveDef(AMPrimitive):
|
||||
def __init__(self, code, exposure=None, rotation=None):
|
||||
|
|
@ -4,14 +4,15 @@
|
|||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import os
|
||||
from gerber.common import loads as loads_org
|
||||
from gerber.exceptions import ParseError
|
||||
from gerber.utils import detect_file_format
|
||||
import gerber.rs274x
|
||||
import gerber.ipc356
|
||||
import gerberex.rs274x
|
||||
import gerberex.excellon
|
||||
import gerberex.dxf
|
||||
from ..common import loads as loads_org
|
||||
from ..exceptions import ParseError
|
||||
from ..utils import detect_file_format
|
||||
from .. import rs274x
|
||||
from .. import ipc356
|
||||
|
||||
from . import rs274x as ex_rs274x
|
||||
from . import excellon
|
||||
from . import dxf
|
||||
|
||||
def read(filename, format=None):
|
||||
with open(filename, 'rU') as f:
|
||||
|
|
@ -21,14 +22,14 @@ def read(filename, format=None):
|
|||
|
||||
def loads(data, filename=None, format=None):
|
||||
if os.path.splitext(filename if filename else '')[1].lower() == '.dxf':
|
||||
return gerberex.dxf.loads(data, filename)
|
||||
return dxf.loads(data, filename)
|
||||
|
||||
fmt = detect_file_format(data)
|
||||
if fmt == 'rs274x':
|
||||
file = gerberex.rs274x.loads(data, filename=filename)
|
||||
return gerberex.rs274x.GerberFile.from_gerber_file(file)
|
||||
file = ex_rs274x.loads(data, filename=filename)
|
||||
return ex_rs274x.GerberFile.from_gerber_file(file)
|
||||
elif fmt == 'excellon':
|
||||
return gerberex.excellon.loads(data, filename=filename, format=format)
|
||||
return excellon.loads(data, filename=filename, format=format)
|
||||
elif fmt == 'ipc_d_356':
|
||||
return ipc356.loads(data, filename=filename)
|
||||
else:
|
||||
|
|
@ -36,5 +37,5 @@ def loads(data, filename=None, format=None):
|
|||
|
||||
|
||||
def rectangle(width, height, left=0, bottom=0, units='metric', draw_mode=None, filename=None):
|
||||
return gerberex.dxf.DxfFile.rectangle(
|
||||
return dxf.DxfFile.rectangle(
|
||||
width, height, left, bottom, units, draw_mode, filename)
|
||||
|
|
@ -4,13 +4,13 @@
|
|||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
import os
|
||||
from functools import reduce
|
||||
from gerber.cam import FileSettings
|
||||
from gerber.gerber_statements import EofStmt
|
||||
from gerber.excellon_statements import *
|
||||
from gerber.excellon import DrillSlot, DrillHit
|
||||
import gerberex.rs274x
|
||||
import gerberex.excellon
|
||||
import gerberex.dxf
|
||||
from ..cam import FileSettings
|
||||
from ..gerber_statements import EofStmt
|
||||
from ..excellon_statements import *
|
||||
from ..excellon import DrillSlot, DrillHit
|
||||
from . import rs274x
|
||||
from . import excellon
|
||||
from . import dxf
|
||||
|
||||
class Composition(object):
|
||||
def __init__(self, settings = None, comments = None):
|
||||
|
|
@ -27,9 +27,9 @@ class GerberComposition(Composition):
|
|||
self.drawings = []
|
||||
|
||||
def merge(self, file):
|
||||
if isinstance(file, gerberex.rs274x.GerberFile):
|
||||
if isinstance(file, rs274x.GerberFile):
|
||||
self._merge_gerber(file)
|
||||
elif isinstance(file, gerberex.dxf.DxfFile):
|
||||
elif isinstance(file, dxf.DxfFile):
|
||||
self._merge_dxf(file)
|
||||
else:
|
||||
raise Exception('unsupported file type')
|
||||
|
|
@ -46,7 +46,7 @@ class GerberComposition(Composition):
|
|||
self.settings.notation = 'absolute'
|
||||
self.settings.zeros = 'trailing'
|
||||
with open(path, 'w') as f:
|
||||
gerberex.rs274x.write_gerber_header(f, self.settings)
|
||||
rs274x.write_gerber_header(f, self.settings)
|
||||
for statement in statements():
|
||||
f.write(statement.to_gerber(self.settings) + '\n')
|
||||
|
||||
|
|
@ -120,9 +120,9 @@ class DrillComposition(Composition):
|
|||
self.dxf_statements = []
|
||||
|
||||
def merge(self, file):
|
||||
if isinstance(file, gerberex.excellon.ExcellonFileEx):
|
||||
if isinstance(file, excellon.ExcellonFileEx):
|
||||
self._merge_excellon(file)
|
||||
elif isinstance(file, gerberex.DxfFile):
|
||||
elif isinstance(file, DxfFile):
|
||||
self._merge_dxf(file)
|
||||
else:
|
||||
raise Exception('unsupported file type')
|
||||
|
|
@ -142,7 +142,7 @@ class DrillComposition(Composition):
|
|||
self.settings.notation = 'absolute'
|
||||
self.settings.zeros = 'trailing'
|
||||
with open(path, 'w') as f:
|
||||
gerberex.excellon.write_excellon_header(f, self.settings, self.tools)
|
||||
excellon.write_excellon_header(f, self.settings, self.tools)
|
||||
for statement in statements():
|
||||
f.write(statement + '\n')
|
||||
|
||||
|
|
@ -6,15 +6,15 @@
|
|||
import io, sys
|
||||
from math import pi, cos, sin, tan, atan, atan2, acos, asin, sqrt
|
||||
import dxfgrabber
|
||||
from gerber.cam import CamFile, FileSettings
|
||||
from gerber.utils import inch, metric, write_gerber_value, rotate_point
|
||||
from gerber.gerber_statements import ADParamStmt
|
||||
from gerber.excellon_statements import ExcellonTool
|
||||
from gerber.excellon_statements import CoordinateStmt
|
||||
from gerberex.utility import is_equal_point, is_equal_value
|
||||
from gerberex.dxf_path import generate_paths, judge_containment
|
||||
from gerberex.excellon import write_excellon_header
|
||||
from gerberex.rs274x import write_gerber_header
|
||||
from ..cam import CamFile, FileSettings
|
||||
from ..utils import inch, metric, write_gerber_value, rotate_point
|
||||
from ..gerber_statements import ADParamStmt
|
||||
from ..excellon_statements import ExcellonTool
|
||||
from ..excellon_statements import CoordinateStmt
|
||||
from .utility import is_equal_point, is_equal_value
|
||||
from .dxf_path import generate_paths, judge_containment
|
||||
from .excellon import write_excellon_header
|
||||
from .rs274x import write_gerber_header
|
||||
|
||||
ACCEPTABLE_ERROR = 0.001
|
||||
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.utils import inch, metric, write_gerber_value
|
||||
from gerber.cam import FileSettings
|
||||
from gerberex.utility import is_equal_point, is_equal_value, normalize_vec2d, dot_vec2d
|
||||
from gerberex.excellon import CoordinateStmtEx
|
||||
from ..utils import inch, metric, write_gerber_value
|
||||
from ..cam import FileSettings
|
||||
from .utility import is_equal_point, is_equal_value, normalize_vec2d, dot_vec2d
|
||||
from .excellon import CoordinateStmtEx
|
||||
|
||||
class DxfPath(object):
|
||||
def __init__(self, statements, error_range=0):
|
||||
|
|
@ -176,7 +176,7 @@ class DxfPath(object):
|
|||
return True
|
||||
|
||||
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
|
||||
from gerberex.dxf import DxfArcStatement
|
||||
from .dxf import DxfArcStatement
|
||||
if pitch == 0:
|
||||
x0, y0 = self.statements[0].start
|
||||
gerber = 'G01*\nX{0}Y{1}D02*\nG75*'.format(
|
||||
|
|
@ -222,7 +222,7 @@ class DxfPath(object):
|
|||
return gerber
|
||||
|
||||
def to_excellon(self, settings=FileSettings(), pitch=0, width=0):
|
||||
from gerberex.dxf import DxfArcStatement
|
||||
from .dxf import DxfArcStatement
|
||||
if pitch == 0:
|
||||
x0, y0 = self.statements[0].start
|
||||
excellon = 'G00{0}\nM15\n'.format(
|
||||
|
|
@ -322,7 +322,7 @@ class DxfPath(object):
|
|||
raise Exception('inconsistensy is detected while cross judgement between paths')
|
||||
|
||||
def generate_paths(statements, error_range=0):
|
||||
from gerberex.dxf import DxfPolylineStatement
|
||||
from .dxf import DxfPolylineStatement
|
||||
|
||||
paths = []
|
||||
for statement in filter(lambda s: isinstance(s, DxfPolylineStatement), statements):
|
||||
|
|
@ -365,7 +365,7 @@ def generate_paths(statements, error_range=0):
|
|||
return (closed_path, open_path)
|
||||
|
||||
def judge_containment(path1, path2, error_range=0):
|
||||
from gerberex.dxf import DxfArcStatement, DxfLineStatement
|
||||
from .dxf import DxfArcStatement, DxfLineStatement
|
||||
|
||||
nocontainment = (None, None)
|
||||
if not path1.may_be_in_collision(path2):
|
||||
|
|
@ -5,24 +5,24 @@
|
|||
|
||||
import operator
|
||||
|
||||
import gerber.excellon
|
||||
from gerber.excellon import ExcellonParser, detect_excellon_format, ExcellonFile, DrillHit, DrillSlot
|
||||
from gerber.excellon_statements import ExcellonStatement, UnitStmt, CoordinateStmt, UnknownStmt, \
|
||||
from .. import excellon
|
||||
from ..excellon import ExcellonParser, detect_excellon_format, ExcellonFile, DrillHit, DrillSlot
|
||||
from ..excellon_statements import ExcellonStatement, UnitStmt, CoordinateStmt, UnknownStmt, \
|
||||
SlotStmt, DrillModeStmt, RouteModeStmt, LinearModeStmt, \
|
||||
ToolSelectionStmt, ZAxisRoutPositionStmt, \
|
||||
RetractWithClampingStmt, RetractWithoutClampingStmt, \
|
||||
EndOfProgramStmt
|
||||
from gerber.cam import FileSettings
|
||||
from gerber.utils import inch, metric, write_gerber_value, parse_gerber_value
|
||||
from gerberex.utility import rotate
|
||||
from ..cam import FileSettings
|
||||
from ..utils import inch, metric, write_gerber_value, parse_gerber_value
|
||||
from .utility import rotate
|
||||
|
||||
def loads(data, filename=None, settings=None, tools=None, format=None):
|
||||
if not settings:
|
||||
settings = FileSettings(**detect_excellon_format(data))
|
||||
if format:
|
||||
settings.format = format
|
||||
gerber.excellon.CoordinateStmt = CoordinateStmtEx
|
||||
gerber.excellon.UnitStmt = UnitStmtEx
|
||||
excellon.CoordinateStmt = CoordinateStmtEx
|
||||
excellon.UnitStmt = UnitStmtEx
|
||||
file = ExcellonParser(settings, tools).parse_raw(data, filename)
|
||||
return ExcellonFileEx.from_file(file)
|
||||
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.gerber_statements import AMParamStmt, ADParamStmt
|
||||
from gerber.utils import inch, metric
|
||||
from gerberex.am_primitive import to_primitive_defs
|
||||
from ..gerber_statements import AMParamStmt, ADParamStmt
|
||||
from ..utils import inch, metric
|
||||
from .am_primitive import to_primitive_defs
|
||||
|
||||
class AMParamStmtEx(AMParamStmt):
|
||||
@classmethod
|
||||
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.cam import FileSettings
|
||||
import gerber.rs274x
|
||||
from gerber.gerber_statements import *
|
||||
from gerberex.gerber_statements import AMParamStmt, AMParamStmtEx, ADParamStmtEx
|
||||
from gerberex.utility import rotate
|
||||
from ..cam import FileSettings
|
||||
from .. import rs274x
|
||||
from ..gerber_statements import *
|
||||
from .gerber_statements import AMParamStmt, AMParamStmtEx, ADParamStmtEx
|
||||
from .utility import rotate
|
||||
import re
|
||||
|
||||
def loads(data, filename=None):
|
||||
cls = gerber.rs274x.GerberParser
|
||||
cls = rs274x.GerberParser
|
||||
cls.SF = \
|
||||
r"(?P<param>SF)(A(?P<a>{decimal}))?(B(?P<b>{decimal}))?".format(decimal=cls.DECIMAL)
|
||||
cls.PARAMS = (cls.FS, cls.MO, cls.LP, cls.AD_CIRCLE,
|
||||
|
|
@ -27,11 +27,11 @@ def write_gerber_header(file, settings):
|
|||
FSParamStmt('FS', settings.zero_suppression,
|
||||
settings.notation, settings.format).to_gerber(settings)))
|
||||
|
||||
class GerberFile(gerber.rs274x.GerberFile):
|
||||
class GerberFile(rs274x.GerberFile):
|
||||
@classmethod
|
||||
def from_gerber_file(cls, gerber_file):
|
||||
if not isinstance(gerber_file, gerber.rs274x.GerberFile):
|
||||
raise Exception('only gerber.rs274x.GerberFile object is specified')
|
||||
if not isinstance(gerber_file, rs274x.GerberFile):
|
||||
raise Exception('only gerbonara.gerber.rs274x.GerberFile object is specified')
|
||||
|
||||
return cls(gerber_file.statements, gerber_file.settings, gerber_file.primitives,\
|
||||
gerber_file.apertures, gerber_file.filename)
|
||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 556 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |