From 317625a4a69c3656954c856e279f97c64a87803b Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Tue, 8 Mar 2016 18:04:49 +0100 Subject: [PATCH] traylayout initial commit --- traylayout.py | 343 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100755 traylayout.py diff --git a/traylayout.py b/traylayout.py new file mode 100755 index 0000000..71a07a1 --- /dev/null +++ b/traylayout.py @@ -0,0 +1,343 @@ +#!/usr/bin/python3 +# Copyright (C) 2016 Florian Festi +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, re +from boxes import * +import argparse + +class Layout(Boxes): + """Generate a typetray from a layout file""" + def __init__(self, input=None): + Boxes.__init__(self) + self.buildArgParser("h", "hi") + self.argparser.add_argument( + "--input", action="store", type=argparse.FileType('r'), + help="layout file") + self.argparser.add_argument( + "--x", action="store", type=int, default=None, + help="number of compartments side by side") + self.argparser.add_argument( + "--y", action="store", type=int, default=None, + help="number of compartments back to front") + + def fillDefault(self, x, y): + self.x = [0.0] * x + self.y = [0.0] * y + self.hwalls = [[True for i in range(x)] for j in range(y+1)] + self.vwalls = [[True for i in range(x+1)] for j in range(y)] + self.floors = [[True for i in range(x)] for j in range(y)] + + def __str__(self): + r = [] + for i, x in enumerate(self.x): + r.append(" |" * (i) + " ,> %.1fmm\n" % x) + for hwalls, vwalls, floors, y in zip( + self.hwalls, self.vwalls, self.floors, self.y): + r.append("".join(("+" + " -"[h] for h in hwalls)) + "+\n") + r.append("".join((" |"[v] + "X "[f] for v, f in zip(vwalls, floors))) + + " |"[vwalls[-1]] + " %.1fmm\n" % y) + r.append("".join(("+" + " -"[h] for h in self.hwalls[-1])) + "+\n") + return "".join(r) + + def hholes(self, y, start, end): + posx = -0.5 * self.thickness + for i in range(start, end-1): + posx += self.x[i] + self.thickness + # XXX if no holes: continue + self.fingerHolesAt(posx, 0, self.hi) + + def vholes(self, x, start, end): + posy = -0.5 * self.thickness + for i in range(start, end-1): + posy += self.y[i] + self.thickness + # XXX if no holes: continue + self.fingerHolesAt(posy, 0, self.hi) + + def vWalls(self, x, y): + "Number of vertical walls at a crossing" + result = 0 + if y>0 and self.vwalls[y-1][x]: + result += 1 + if y < len(self.y) and self.vwalls[y][x]: + result += 1 + return result + + def hWalls(self, x, y): + "Number of horizontal walls at a crossing" + result = 0 + if x>0 and self.hwalls[y][x-1]: + result += 1 + if x0 and self.floors[y-1][x]: + # Inside Wall + if self.hwalls[y][x]: + self.fingerHolesAt(posx, posy+t2, self.x[x], angle=0) + else: + # Top edge + self.edgeAt(e, posx+self.x[x], posy+t, self.x[x], + -180) + self.edgeAt("e", posx, posy+t, t, -180) + self.edgeAt("e", posx+self.x[x]+t, posy+t, t, -180) + elif y>0 and self.floors[y-1][x]: + # Bottom Edge + self.edgeAt(e, posx, posy, self.x[x]) + self.edgeAt("e", posx-t, posy, t) + self.edgeAt("e", posx+self.x[x], posy, t) + posx += self.x[x] + self. thickness + posy += self.y[y-1] + self.thickness + + posx = 0 + for x in range(lx+1): + posy = self.thickness + for y in range(ly-1, -1, -1): + if self.vwalls[y][x]: + e = "F" + else: + e = "e" + if x>0 and self.floors[y][x-1]: + if x < lx and self.floors[y][x]: + # Inside wall + if self.vwalls[y][x]: + self.fingerHolesAt(posx+t2, posy, self.y[y]) + else: + # Right edge + self.edgeAt(e, posx+t, posy, self.y[y], 90) + self.edgeAt("e", posx+t, posy-t, t, 90) + self.edgeAt("e", posx+t, posy+self.y[y], t, 90) + elif x < lx and self.floors[y][x]: + # Left edge + self.edgeAt(e, posx, posy+self.y[y], self.y[y], -90) + self.edgeAt(e, posx, posy+self.y[y]+t, t, -90) + self.edgeAt(e, posx, posy, t, -90) + posy += self.y[y] + self.thickness + if x < lx: + posx += self.x[x] + self.thickness + + self.close() + + def parse(self, input): + x = [] + y = [] + hwalls = [] + vwalls = [] + floors = [] + for line in input: + if line[0] == "#": + continue + m = re.match(r"( \|)* ,>\s*(\d*\.?\d+)\s*mm\s*", line) + if m: + x.append(float(m.group(2))) + continue + if line[0] == '+': + w = [] + for n, c in enumerate(line): + if n % 2: + if c == ' ': + w.append(False) + elif c == '-': + w.append(True) + else: + pass + #raise ValueError(line) + else: + if c != '+': + pass + #raise ValueError(line) + + + hwalls.append(w) + if line[0] in " |": + w = [] + f = [] + for n, c in enumerate(line[:len(x)*2+1]): + if n % 2: + if c == 'X': + f.append(False) + elif c == ' ': + f.append(True) + else: + raise ValueError(line) + else: + if c == ' ': + w.append(False) + elif c == '|': + w.append(True) + else: + raise ValueError(line) + + floors.append(f) + vwalls.append(w) + m = re.match(r"([ |][ X])+[ |]\s*(\d*\.?\d+)\s*mm\s*", line) + if not m: + raise ValueError(line) + else: + y.append(float(m.group(2))) + + # check sizes + lx = len(x) + ly = len(y) + if len(hwalls) != ly+1: + raise ValueError("Wrong number of horizontal wall lines: %i (%i expected)" % (len(hwalls), ly+1)) + for nr, walls in enumerate(hwalls): + if len(walls)!= lx: + raise ValueError("Wrong number of horizontal walls in line %i: %i (%i expected)" % (nr, len(walls), lx)) + if len(vwalls) != ly: + raise ValueError("Wrong number of vertical wall lines: %i (%i expected)" % (len(vwalls), ly)) + for nr, walls in enumerate(vwalls): + if len(walls) != lx+1: + raise ValueError("Wrong number of vertical walls in line %i: %i (%i expected)" % (nr, len(walls), lx+1)) + + self.x = x + self.y = y + self.hwalls = hwalls + self.vwalls = vwalls + self.floors = floors + +def main(): + l = Layout() + l.parseArgs() + if l.x and l.y: + l.fillDefault(l.x, l.y) + print(l) + elif l.input: + l.parse(l.input) + l.render() + print(str(l)) + else: + l.argparser.print_usage() + +if __name__ == '__main__': + main()