This commit is contained in:
olegart 2016-01-18 21:46:24 +03:00
commit f1bbbfb848
7 changed files with 51 additions and 30 deletions

View File

View File

@ -110,9 +110,10 @@ class ApertureMacroPrimitive:
# type 4 which is an outline and has a variable number of points.
# For outlines, the second parameter indicates the number of points,
# each of which has an (X,Y) co-ordinate. Thus, we expect an Outline
# specification to have 1+1+2*N+1=3+2N fields:
# specification to have 1+1+2+2*N+1=5+2N fields:
# - first field is exposure
# - second field is number of points
# - thrid and forth fields is for the initial point
# - 2*N fields for X,Y points
# - last field is rotation
if self.code==4:
@ -124,7 +125,7 @@ class ApertureMacroPrimitive:
except:
raise RuntimeError, 'Outline macro primitive has non-integer number of points'
if len(fields) != (3+2*N):
if len(fields) != (5+2*N):
raise RuntimeError, 'Outline macro primitive has %d fields...expecting %d fields' % (len(fields), 3+2*N)
else:
if len(fields) != len(valids):

View File

@ -24,7 +24,6 @@ import aptable
Config = {
'measurementunits': 'inch', # Unit system to use: inch or mm
'searchtimeout': 0, # moved here from hardcoded below
'skipdisclaimer': 0, # set to 1 to skip disclaimer prompt
'xspacing': 0, # Spacing in horizontal direction - default is set in parseConfigFile based on units
'yspacing': 0, # Spacing in vertical direction - ditto
'panelwidth': '12.6', # X-Dimension maximum panel size (Olimex)
@ -213,7 +212,7 @@ def parseConfigFile(fname, Config=Config, Jobs=Jobs):
global DefaultToolList
CP = ConfigParser.ConfigParser()
CP.readfp(file(fname,'rt'))
CP.readfp(file(fname.rstrip(),'rt'))
# First parse global options
if CP.has_section('Options'):

View File

@ -160,11 +160,15 @@ def writeGerberFooter(fid):
fid.write('M02*\n')
def writeExcellonHeader(fid):
if config.Config['measurementunits'] != 'inch': # metric - mm
fid.write( \
"""M48
METRIC,0000.00
""")
fid.write("M48\n")
if config.Config['excellonleadingzeros']:
zerosDef = "LZ"
else:
zerosDef = "TZ"
if config.Config['measurementunits'] == 'inch':
fid.write("INCH,%s\n" % zerosDef)
else: # metric - mm
fid.write("METRIC,%s\n" % zerosDef)
fid.write('%\n')
def writeExcellonFooter(fid):
@ -243,9 +247,6 @@ def writeCropMarks(fid, drawing_code, OriginX, OriginY, MaxXExtent, MaxYExtent):
fid.write('X%07dY%07dD01*\n' % (util.in2gerb(x+cropW), util.in2gerb(y+0.000)))
def disclaimer():
if (config.Config['skipdisclaimer'] > 0): # remove annoying disclaimer
return
print """
****************************************************
* R E A D C A R E F U L L Y *

View File

@ -68,6 +68,11 @@ IgnoreList = ( \
re.compile(r'^\*?%$'),
re.compile(r'^M0?2\*$'),
# new Gerber Attributes
re.compile(r'^%TF.*\*%'),
re.compile(r'^%TA.*\*%'),
re.compile(r'^%TD.*\*%'),
# These additional ones are for Orcad Layout, PCB, Protel, etc.
re.compile(r'\*'), # Empty statement
re.compile(r'^%IN.*\*%'),
@ -87,13 +92,15 @@ xtdef_pat = re.compile(r'^(T\d+)(?:F\d+)?(?:S\d+)?C([0-9.]+)$') # Tool+diameter
# feed/speed (for Protel)
xtdef2_pat = re.compile(r'^(T\d+)C([0-9.]+)(?:F\d+)?(?:S\d+)?$') # Tool+diameter definition with optional
# feed/speed at the end (for OrCAD)
xzsup_pat = re.compile(r'^INCH,([LT])Z$') # Leading/trailing zeros INCLUDED
xzsup_pat = re.compile(r'^INCH(,([LT])Z)?$') # Leading/trailing zeros INCLUDED
XIgnoreList = ( \
re.compile(r'^%$'),
re.compile(r'^M30$'), # End of job
re.compile(r'^M48$'), # Program header to first %
re.compile(r'^M72$') # Inches
re.compile(r'^M72$'), # Inches
re.compile(r'^G05$'), # Drill Mode
re.compile(r'^G90$') # Absolute Mode
)
# A Job is a single input board. It is expected to have:
@ -812,42 +819,52 @@ class Job:
return L
def writeExcellon(self, fid, diameter, Xoff, Yoff):
"Write out the data such that the lower-left corner of this job is at the given (X,Y) position, in inches"
"""Write out the data such that the lower-left corner of this job is at the given (X,Y) position, in inches
args:
fid - output file
diameter
Xoff - offset of this board instance in full units (float)
Yoff - offset of this board instance in full units (float)
"""
# First convert given inches to 2.4 co-ordinates. Note that Gerber is 2.5 (as of GerbMerge 1.2)
# and our internal Excellon representation is 2.4 as of GerbMerge
# version 0.91. We use X,Y to calculate DX,DY in 2.4 units (i.e., with a
# resolution of 0.0001".
# add metric support (1/1000 mm vs. 1/100,000 inch)
if config.Config['measurementunits'] == 'inch':
X = int(round(Xoff/0.00001)) # First work in 2.5 format to match Gerber
Y = int(round(Yoff/0.00001))
else:
X = int(round(Xoff/0.001)) # First work in 5.3 format to match Gerber
Y = int(round(Yoff/0.001))
X = int(round(Xoff/0.00001)) # First work in 2.5 format to match Gerber
Y = int(round(Yoff/0.00001))
# Now calculate displacement for each position so that we end up at specified origin
DX = X - self.minx
DY = Y - self.miny
# Now round down to 2.4 format
# this scaling seems to work for either unit system
DX = int(round(DX/10.0))
DY = int(round(DY/10.0))
ltools = self.findTools(diameter)
if config.Config['excellonleadingzeros']:
fmtstr = 'X%06dY%06d\n'
else:
fmtstr = 'X%dY%d\n'
def formatForXln(num):
"""
helper to convert from our 2.4 internal format to config's excellon format
returns string
"""
divisor = 10.0**(4 - config.Config['excellondecimals'])
if config.Config['excellonleadingzeros']:
fmtstr = '%06d'
else:
fmtstr = '%d'
return fmtstr % (num / divisor)
# Boogie
for ltool in ltools:
if self.xcommands.has_key(ltool):
for cmd in self.xcommands[ltool]:
x, y = cmd
fid.write(fmtstr % (x+DX, y+DY))
new_x = x+DX
new_y = y+DY
fid.write('X%sY%s\n' % (formatForXln(new_x), formatForXln(new_y)))
def writeDrillHits(self, fid, diameter, toolNum, Xoff, Yoff):
"""Write a drill hit pattern. diameter is tool diameter in inches, while toolNum is

3
misc/gerbmerge Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
python /usr/lib/python2.7/site-packages/gerbmerge/gerbmerge.py $*

View File

@ -26,7 +26,7 @@ if 0:
SampleFiles = glob.glob('testdata/*')
DocFiles = glob.glob('doc/*')
AuxFiles = ['COPYING']
AuxFiles = ['LICENSE']
if sys.platform == 'win32' or ('bdist_wininst' in sys.argv):
#DestLib = distutils.sysconfig.get_config_var('prefix')