mirror of
https://github.com/telavivmakers/at-tami.git
synced 2024-05-25 11:56:54 +03:00
109 lines
3.2 KiB
Python
109 lines
3.2 KiB
Python
|
#!/usr/bin/env python
|
||
|
"""A placement is a final arrangement of jobs at given (X,Y) positions.
|
||
|
This class is intended to "un-pack" an arragement of jobs constructed
|
||
|
manually through Layout/Panel/JobLayout/etc. (i.e., a layout.def file)
|
||
|
or automatically through a Tiling. From either source, the result is
|
||
|
simply a list of jobs.
|
||
|
--------------------------------------------------------------------
|
||
|
|
||
|
This program is licensed under the GNU General Public License (GPL)
|
||
|
Version 3. See http://www.fsf.org for details of the license.
|
||
|
|
||
|
Rugged Circuits LLC
|
||
|
http://ruggedcircuits.com/gerbmerge
|
||
|
"""
|
||
|
|
||
|
import sys
|
||
|
import re
|
||
|
|
||
|
import parselayout
|
||
|
import jobs
|
||
|
|
||
|
class Placement:
|
||
|
def __init__(self):
|
||
|
self.jobs = [] # A list of JobLayout objects
|
||
|
|
||
|
def addFromLayout(self, Layout):
|
||
|
# Layout is a recursive list of JobLayout items. At the end
|
||
|
# of each tree there is a JobLayout object which has a 'job'
|
||
|
# member, which is what we're looking for. Fortunately, the
|
||
|
# canonicalize() function flattens the tree.
|
||
|
#
|
||
|
# Positions of jobs have already been set (we're assuming)
|
||
|
# prior to calling this function.
|
||
|
self.jobs = self.jobs + parselayout.canonicalizePanel(Layout)
|
||
|
|
||
|
def addFromTiling(self, T, OriginX, OriginY):
|
||
|
# T is a Tiling. Calling its canonicalize() method will construct
|
||
|
# a list of JobLayout objects and set the (X,Y) position of each
|
||
|
# object.
|
||
|
self.jobs = self.jobs + T.canonicalize(OriginX,OriginY)
|
||
|
|
||
|
def extents(self):
|
||
|
"""Return the maximum X and Y value over all jobs"""
|
||
|
maxX = 0.0
|
||
|
maxY = 0.0
|
||
|
|
||
|
for job in self.jobs:
|
||
|
maxX = max(maxX, job.x+job.width_in())
|
||
|
maxY = max(maxY, job.y+job.height_in())
|
||
|
|
||
|
return (maxX,maxY)
|
||
|
|
||
|
def write(self, fname):
|
||
|
"""Write placement to a file"""
|
||
|
fid = file(fname, 'wt')
|
||
|
for job in self.jobs:
|
||
|
fid.write('%s %.3f %.3f\n' % (job.job.name, job.x, job.y))
|
||
|
fid.close()
|
||
|
|
||
|
def addFromFile(self, fname, Jobs):
|
||
|
"""Read placement from a file, placed against jobs in Jobs list"""
|
||
|
pat = re.compile(r'\s*(\S+)\s+(\S+)\s+(\S+)')
|
||
|
comment = re.compile(r'\s*(?:#.+)?$')
|
||
|
|
||
|
try:
|
||
|
fid = file(fname, 'rt')
|
||
|
except:
|
||
|
print 'Unable to open placement file: "%s"' % fname
|
||
|
sys.exit(1)
|
||
|
|
||
|
lines = fid.readlines()
|
||
|
fid.close()
|
||
|
|
||
|
for line in lines:
|
||
|
if comment.match(line): continue
|
||
|
|
||
|
match = pat.match(line)
|
||
|
if not match:
|
||
|
print 'Cannot interpret placement line in placement file:\n %s' % line
|
||
|
sys.exit(1)
|
||
|
|
||
|
jobname, X, Y = match.groups()
|
||
|
try:
|
||
|
X = float(X)
|
||
|
Y = float(Y)
|
||
|
except:
|
||
|
print 'Illegal (X,Y) co-ordinates in placement file:\n %s' % line
|
||
|
sys.exit(1)
|
||
|
|
||
|
rotated = 0
|
||
|
if len(jobname) > 8:
|
||
|
if jobname[-8:] == '*rotated':
|
||
|
rotated = 90
|
||
|
jobname = jobname[:-8]
|
||
|
elif jobname[-10:] == '*rotated90':
|
||
|
rotated = 90
|
||
|
jobname = jobname[:-10]
|
||
|
elif jobname[-11:] == '*rotated180':
|
||
|
rotated = 180
|
||
|
jobname = jobname[:-11]
|
||
|
elif jobname[-11:] == '*rotated270':
|
||
|
rotated = 270
|
||
|
jobname = jobname[:-11]
|
||
|
|
||
|
addjob = parselayout.findJob(jobname, rotated, Jobs)
|
||
|
addjob.setPosition(X,Y)
|
||
|
self.jobs.append(addjob)
|
||
|
|