diff --git a/partsgen.py b/partsgen.py index 7de7776..a01e952 100644 --- a/partsgen.py +++ b/partsgen.py @@ -87,7 +87,7 @@ parts = [ ("99301", "Slope Brick 33 3 x 3 Double Concave"), ("3675", "Slope Brick 33 3 x 3 Double Convex"), ("3297", "Slope Brick 33 3 x 4"), - ("3048", "Slope Brick 45 2 x 1 Triple"), + ("3048", "Slope Brick 45 1 x 2 Triple"), ("3040b", "Slope Brick 45 2 x 1"), ("3044b", "Slope Brick 45 2 x 1 Double"), ("3665", "Slope Brick 45 2 x 1 Inverted"), @@ -131,83 +131,194 @@ def drawstud(studsx, studsz, x, z, lines, triangles, quads): lines.append(((p1[0], -4, p1[1]), (p2[0], -4, p2[1]))) lines.append(((p1[0], 0, p1[1]), (p2[0], 0, p2[1]))) -def render(): - for part in parts: - partid, parttext = part[:2] - m = re.match(r"(?P[A-Za-z0-9 ]+?) (?P\d+)"+ - r" x (?P\d+)(?: x (?P\d+(?:/\d+)?))?"+ - r"(?: (?PCorner)| "+ - r"(?P(?:Double|Triple|Inverted|Concave|Convex| |/)+))?", - parttext) - # sanity checks - if m.group('type') not in ['Brick', 'Plate', 'Slope Brick 18', - 'Slope Brick 31', 'Slope Brick 33', 'Slope Brick 45', - 'Slope Brick 65', 'Slope Brick 75']: - print "not supported part type: %s"%m.group('type') - exit(1) - if m.group('type') == 'Plate' and m.group('height'): - print "plates can't have a height" - exit(1) - if m.group('height') and m.group('corner'): - print "corners can't have a height" - exit(1) - if m.group('corner') and (m.group('studsx') != m.group('studsz')): - print "corners must be squares" - exit(1) - lines = list() - triangles = list() - quads = list() - studsz = int(m.group('studsz')) - studsx = int(m.group('studsx')) - if m.group('type') in ['Brick', 'Slope Brick 18', 'Slope Brick 31', - 'Slope Brick 33', 'Slope Brick 45', 'Slope Brick 65', - 'Slope Brick 75']: - if m.group('height'): - if m.group('height') == '2/3': - height = 2 - else: - height = int(m.group('height'))*3 +def render_part(part): + partid, parttext = part[:2] + m = re.match(r"(?P[A-Za-z0-9 ]+?) (?P\d+)"+ + r" x (?P\d+)(?: x (?P\d+(?:/\d+)?))?"+ + r"(?: (?PCorner)| "+ + r"(?P(?:Double|Triple|Inverted|Concave|Convex| |/)+))?", + parttext) + # sanity checks + if m.group('type') not in ['Brick', 'Plate', 'Slope Brick 18', + 'Slope Brick 31', 'Slope Brick 33', 'Slope Brick 45', + 'Slope Brick 65', 'Slope Brick 75']: + print "not supported part type: %s"%m.group('type') + exit(1) + if m.group('type') == 'Plate' and m.group('height'): + print "plates can't have a height" + exit(1) + if m.group('height') and m.group('corner'): + print "corners can't have a height" + exit(1) + if m.group('corner') and (m.group('studsx') != m.group('studsz')): + print "corners must be squares" + exit(1) + lines = list() + triangles = list() + quads = list() + studsz = int(m.group('studsz')) + studsx = int(m.group('studsx')) + if m.group('type') in ['Brick', 'Slope Brick 18', 'Slope Brick 31', + 'Slope Brick 33', 'Slope Brick 45', 'Slope Brick 65', + 'Slope Brick 75']: + if m.group('height'): + if m.group('height') == '2/3': + height = 2 else: - height = 3 + height = int(m.group('height'))*3 else: - height = 1 - if m.group('type') in ['Brick', 'Plate']: - # draw studs - for z in range(studsz): - for x in range(studsx): - if not m.group('corner') or z >= studsz/2 or x >= studsx/2: - drawstud(studsx, studsz, x, z, lines, triangles, quads) + height = 3 + else: + height = 1 + # convert plate height to LDraw units + height *= 8 + if m.group('type') in ['Brick', 'Plate']: + # draw studs + for z in range(studsz): + for x in range(studsx): + if not m.group('corner') or z >= studsz/2 or x >= studsx/2: + drawstud(studsx, studsz, x, z, lines, triangles, quads) + # create top, bottom, inner and outer rectangles + # in case of a corner, draw an L otherwise draw a square + if m.group('corner'): + coords = [(0,0),(1,0),(1,-1),(-1,-1),(-1,1),(0,1)] + else: + coords = [(1,1),(1,-1),(-1,-1),(-1,1)] + outertopcoords = [(studsx*10*x, 0, studsz*10*z) for x,z in coords] + outerbottomcoords = [(x, height, z) for x,y,z in outertopcoords] + # walls are 4 LDU thick, use sign() in case x or y are zero + innertopcoords = [(studsx*10*x-sign(x)*4, 4, studsz*10*z-sign(z)*4) for x,z in coords] + innerbottomcoords = [(x, height, z) for x,y,z in innertopcoords] + # write outer top plate and lines + # in case of a corner draw two trapezoids, otherwise draw a rectangle + if m.group('corner'): + quads.append(outertopcoords[:4]) + quads.append(outertopcoords[3:]+outertopcoords[:1]) + else: + quads.append(outertopcoords) + for p1, p2 in wrap(outertopcoords): + lines.append((p1, p2)) + # outer sides and lines + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords), wrap(outerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write inner top plate and lines + # in case of a corner draw two trapezoids, otherwise draw a rectangle + if m.group('corner'): + quads.append(innertopcoords[:4]) + quads.append(innertopcoords[3:]+innertopcoords[:1]) + else: + quads.append(innertopcoords) + for p1, p2 in wrap(innertopcoords): + lines.append((p1, p2)) + # inner sides and lines + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords), wrap(innerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write out bottom with trapezoids and lines + for (p1, p2), (p3, p4) in zip(wrap(innerbottomcoords), wrap(outerbottomcoords)): + quads.append((p1, p2, p4, p3)) + lines.append((p1, p2)) + lines.append((p3, p4)) + elif m.group('type') == 'Slope Brick 31': + # create top, bottom, inner and outer rectangles + coords = [(1,1),(1,-1),(-1,-1),(-1,1)] + outertopcoords = [(studsx*10*x, 0 if z == 1 else height-4, studsz*10*z) for x,z in coords] + outerbottomcoords = [(x, height, z) for x,y,z in outertopcoords] + # walls are 4 LDU thick, use sign() in case x or y are zero + innertopcoords = [(studsx*10*x-sign(x)*4, height-4, studsz*10*z-sign(z)*4) for x,z in coords] + innerbottomcoords = [(x, height, z) for x,y,z in innertopcoords] + # write outer top plate and lines + quads.append(outertopcoords) + for p1, p2 in wrap(outertopcoords): + lines.append((p1, p2)) + # outer sides and lines + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords), wrap(outerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write inner top plate and lines + quads.append(innertopcoords) + for p1, p2 in wrap(innertopcoords): + lines.append((p1, p2)) + # inner sides and lines + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords), wrap(innerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write out bottom with trapezoids and lines + for (p1, p2), (p3, p4) in zip(wrap(innerbottomcoords), wrap(outerbottomcoords)): + quads.append((p1, p2, p4, p3)) + lines.append((p1, p2)) + lines.append((p3, p4)) + elif m.group('type') in ['Slope Brick 18', 'Slope Brick 33', + 'Slope Brick 45', 'Slope Brick 65', 'Slope Brick 75']: + # draw studs (draw an L if double concave) + coordsL = [(0,0),(0,-1),(-1,-1),(-1,1),(1,1),(1,0)] + coords = [(-1,-1),(-1,1),(1,1),(1,-1)] + if 'Double' == m.group('slope'): # create top, bottom, inner and outer rectangles - # in case of a corner, draw an L otherwise draw a square - if m.group('corner'): - coords = [(0,0),(1,0),(1,-1),(-1,-1),(-1,1),(0,1)] - else: - coords = [(1,1),(1,-1),(-1,-1),(-1,1)] - outertopcoords = [(studsx*10*x, 0, studsz*10*z) for x,z in coords] - outerbottomcoords = [(x, height*8, z) for x,y,z in outertopcoords] + coords = [(1,1),(1,-1),(-1,-1),(-1,1)] + outertopcoords = [(studsx*10*x, 24-4, studsz*10*z) for x,z in coords] + outerbottomcoords = [(x, 24, z) for x,y,z in outertopcoords] # walls are 4 LDU thick, use sign() in case x or y are zero - innertopcoords = [(studsx*10*x-sign(x)*4, 4, studsz*10*z-sign(z)*4) for x,z in coords] - innerbottomcoords = [(x, height*8, z) for x,y,z in innertopcoords] - # write outer top plate and lines - # in case of a corner draw two trapezoids, otherwise draw a rectangle - if m.group('corner'): - quads.append(outertopcoords[:4]) - quads.append(outertopcoords[3:]+outertopcoords[:1]) + innertopcoords = [(studsx*10*x-sign(x)*4, 24-4, studsz*10*z-sign(z)*4) for x,z in coords] + innerbottomcoords = [(x, 24, z) for x,y,z in innertopcoords] + if m.group('type') == 'Slope Brick 45': + ridge = [(studsx*10,0,0),(-studsx*10,0,0)] + elif m.group('type') == 'Slope Brick 33': + ridge = [(studsx*10,24-14,0),(-studsx*10,24-14,0)] else: - quads.append(outertopcoords) - for p1, p2 in wrap(outertopcoords): + print "unsupported slope type for double" + exit(1) + # write outer top lines + lines.append(outertopcoords[1:3]) + lines.append(outertopcoords[:1]+outertopcoords[-1:]) + # outer sides and lines + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords), wrap(outerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write inner top plate and lines + quads.append(innertopcoords) + for p1, p2 in wrap(innertopcoords): + lines.append((p1, p2)) + # inner sides and lines + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords), wrap(innerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write out bottom with trapezoids and lines + for (p1, p2), (p3, p4) in zip(wrap(innerbottomcoords), wrap(outerbottomcoords)): + quads.append((p1, p2, p4, p3)) + lines.append((p1, p2)) + lines.append((p3, p4)) + # draw gables + triangles.append(ridge[:1]+outertopcoords[:2]) + triangles.append(ridge[-1:]+outertopcoords[2:]) + # draw slopes + quads.append(ridge+outertopcoords[1:3]) + quads.append(ridge+outertopcoords[-1:]+outertopcoords[:1]) + # draw lines for ridge and rakes + lines.append(ridge) + lines.append(ridge[:1]+outertopcoords[:1]) + lines.append(ridge[:1]+outertopcoords[1:2]) + lines.append(ridge[-1:]+outertopcoords[-1:]) + lines.append(ridge[-1:]+outertopcoords[2:3]) + elif 'Triple' == m.group('slope'): + # create top, bottom, inner and outer rectangles + coords = [(1,1),(1,-1),(-1,-1),(-1,1)] + outertopcoords = [(studsx*10*x, 24-4, studsz*10*z) for x,z in coords] + outerbottomcoords = [(x, 24, z) for x,y,z in outertopcoords] + # walls are 4 LDU thick, use sign() in case x or y are zero + innertopcoords = [(studsx*10*x-sign(x)*4, 24-4, studsz*10*z-sign(z)*4) for x,z in coords] + innerbottomcoords = [(x, 24, z) for x,y,z in innertopcoords] + tip = (0,0,studsz*10) + # write outer top lines + for p1, p2 in wrap(outertopcoords)[:-1]: lines.append((p1, p2)) # outer sides and lines for (p1, p2), (p3, p4) in zip(wrap(outertopcoords), wrap(outerbottomcoords)): quads.append((p1,p2,p4,p3)) lines.append((p1,p3)) # write inner top plate and lines - # in case of a corner draw two trapezoids, otherwise draw a rectangle - if m.group('corner'): - quads.append(innertopcoords[:4]) - quads.append(innertopcoords[3:]+innertopcoords[:1]) - else: - quads.append(innertopcoords) + quads.append(innertopcoords) for p1, p2 in wrap(innertopcoords): lines.append((p1, p2)) # inner sides and lines @@ -219,213 +330,248 @@ def render(): quads.append((p1, p2, p4, p3)) lines.append((p1, p2)) lines.append((p3, p4)) - elif m.group('type') in ['Slope Brick 18', 'Slope Brick 31', - 'Slope Brick 33', 'Slope Brick 45', 'Slope Brick 65', - 'Slope Brick 75']: - # draw studs (draw an L if double concave) - coordsL = [(0,0),(0,-1),(-1,-1),(-1,1),(1,1),(1,0)] - coords = [(-1,-1),(-1,1),(1,1),(1,-1)] - if m.group('type') != 'Slope Brick 31' \ - and 'Double' != m.group('slope') \ - and 'Triple' != m.group('slope') \ - and 'Double Concave / Double Convex' != m.group('slope'): - if m.group('slope') in ['Inverted', 'Inverted Double Convex']: - for z in range(studsz): - for x in range(studsx): - drawstud(studsx, studsz, x, z, lines, triangles, quads) - elif m.group('slope') == 'Double Convex': - drawstud(studsx, studsz, studsx-1, 0, lines, triangles, quads) - elif m.group('slope') == 'Double Concave': - for z in range(studsz): - for x in range(studsx): - if z == 0 or x == studsx-1: - drawstud(studsx, studsz, x, z, lines, triangles, quads) - else: + # write out slopes and lines + for p1, p2 in wrap(outertopcoords): + triangles.append([p1,p2,tip]) + lines.append((p1,tip)) + elif 'Double Concave / Double Convex' == m.group('slope'): + # create top, bottom, inner and outer rectangles + coords = [(1,1),(1,-1),(-1,-1),(-1,1)] + outertopcoords = [(studsx*10*x, 24-4, studsz*10*z) for x,z in coords] + outerbottomcoords = [(x, 24, z) for x,y,z in outertopcoords] + # walls are 4 LDU thick, use sign() in case x or y are zero + innertopcoords = [(studsx*10*x-sign(x)*4, 24-4, studsz*10*z-sign(z)*4) for x,z in coords] + innerbottomcoords = [(x, 24, z) for x,y,z in innertopcoords] + if m.group('type') != 'Slope Brick 45': + print "unsupported slope type for double concave / double convex" + exit(1) + ridge1 = [(0,0,0),(-studsx*10,0,0)] + ridge2 = [(0,0,studsz*10),(0,0,0)] + # write outer top lines (eaves) + lines.append(outertopcoords[1:3]) + lines.append(outertopcoords[:2]) + # outer sides and lines + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords), wrap(outerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write inner top plate and lines + quads.append(innertopcoords) + for p1, p2 in wrap(innertopcoords): + lines.append((p1, p2)) + # inner sides and lines + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords), wrap(innerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # write out bottom with trapezoids and lines + for (p1, p2), (p3, p4) in zip(wrap(innerbottomcoords), wrap(outerbottomcoords)): + quads.append((p1, p2, p4, p3)) + lines.append((p1, p2)) + lines.append((p3, p4)) + # draw gables + triangles.append(ridge1[-1:]+outertopcoords[2:]) + triangles.append(ridge2[:1]+outertopcoords[:1]+outertopcoords[-1:]) + # draw slopes + quads.append(ridge1+outertopcoords[1:3]) + quads.append(ridge2+outertopcoords[:2]) + triangles.append(ridge1+outertopcoords[-1:]) + triangles.append(ridge2+outertopcoords[-1:]) + # draw ridges + lines.append(ridge1) + lines.append(ridge2) + # draw rakes + lines.append(ridge1[-1:]+outertopcoords[2:3]) + lines.append(ridge1[-1:]+outertopcoords[-1:]) + lines.append(ridge2[:1]+outertopcoords[:1]) + lines.append(ridge2[:1]+outertopcoords[-1:]) + # draw valley and hip + lines.append(((0,0,0),outertopcoords[-1])) + lines.append(((0,0,0),outertopcoords[1])) + else: + if m.group('slope') in ['Inverted', 'Inverted Double Convex']: + for z in range(studsz): for x in range(studsx): - drawstud(studsx, studsz, x, 0, lines, triangles, quads) - # create top, bottom, inner and outer rectangles - if m.group('slope') == 'Inverted Double Convex': - outertopcoords = [(studsx*10*x, 0, studsz*10*z) for x,z in coords] - outertopcoords2 = [((x-studsx+1)*10, 0, (z+studsz-1)*10) for x,z in coords] # small - outerbottomcoords = [((x-studsx+1)*10, height*8, (z+studsz-1)*10) for x,z in coords] - innertopcoords = [(6*x-(studsx-1)*10, 4, z*6+(studsz-1)*10) for x,z in coords] - innerbottomcoords = [(6*x-(studsx-1)*10, height*8, z*6+(studsz-1)*10) for x,z in coords] - noseup1 = outertopcoords[:1]+outertopcoords[-1:] - nosedown1 = [(x,4,z) for x,y,z in noseup1] - noseup2 = outertopcoords[-2:-1]+outertopcoords[-1:] - nosedown2 = [(x,4,z) for x,y,z in noseup2] - elif m.group('slope') == 'Double Convex': - outertopcoords = [((x-studsx+1)*10, 0, (z+studsz-1)*10) for x,z in coords] - outerbottomcoords = [(studsx*10*x, height*8, studsz*10*z) for x,z in coords] # big - outerbottomcoords2 = [((x-studsx+1)*10, height*8, (z+studsz-1)*10) for x,z in coords] # small - innerbottomcoords = [(studsx*10*x-sign(x)*4, height*8, studsz*10*z-sign(z)*4) for x,z in coords] - innertopcoords = [(6*x-(studsx-1)*10, 4, z*6+(studsz-1)*10) for x,z in coords] - nosedown1 = outerbottomcoords[:1]+outerbottomcoords[-1:] - noseup1 = [(x,height*8-4,z) for x,y,z in nosedown1] - nosedown2 = outerbottomcoords[-2:-1]+outerbottomcoords[-1:] - noseup2 = [(x,height*8-4,z) for x,y,z in nosedown2] - elif m.group('slope') == 'Double Concave': - outertopcoords = [(studsx*10*x+(abs(x)-1)*(10*studsx-20), 0, studsz*10*z+(1-abs(z))*(10*studsz-20)) for x,z in coordsL] - outerbottomcoords = [(studsx*10*x, height*8, studsz*10*z) for x,z in coords] # big - outerbottomcoords2 = [(studsx*10*x+(abs(x)-1)*(10*studsx-20), height*8, studsz*10*z+(1-abs(z))*(10*studsz-20)) for x,z in coordsL] # small - innertopcoords = [((studsx*10-4)*x+(abs(x)-1)*(10*studsx-20), 4, (studsz*10-4)*z+(1-abs(z))*(10*studsz-20)) for x,z in coordsL] - innerbottomcoords = [((studsx*10-4)*x, height*8, (studsz*10-4)*z) for x,z in coords] - tip = [(studsx*10,height*8,-studsz*10), (studsx*10,height*8-4,-studsz*10)] - else: - outertopcoords = [(studsx*10*x, 0, (z+studsz-1)*10) for x,z in coords] - outerbottomcoords2 = [(studsx*10*x, height*8, (z+studsz-1)*10) for x,z in coords] # small - outerbottomcoords = [(studsx*10*x, height*8, studsz*10*z) for x,z in coords] # big - innertopcoords = [((studsx*10-4)*x, 4, z*6+(studsz-1)*10) for x,z in coords] - innerbottomcoords = [(studsx*10*x-sign(x)*4, height*8, studsz*10*z-sign(z)*4) for x,z in coords] - nosedown = outerbottomcoords[:1]+outerbottomcoords[-1:] - noseup = [(x,height*8-4,z) for x,y,z in nosedown] - # invert all the coordinates along the y axis - if m.group('slope') == 'Inverted': - outertopcoords, outertopcoords2, outerbottomcoords = ( - [(x,0,z) for x,y,z in outerbottomcoords], - [(x,0,z) for x,y,z in outerbottomcoords2], - [(x,height*8,z) for x,y,z in outertopcoords]) - innertopcoords, innerbottomcoords = ( - [(x,4,z) for x,y,z in innertopcoords], - [(x,height*8,z) for x,y,z in innertopcoords]) - noseup = outertopcoords[:1]+outertopcoords[-1:] - nosedown = [(x,4,z) for x,y,z in noseup] - # write outer top plate and lines - if m.group('slope') == 'Double Concave': - quads.append(outertopcoords[:4]) - quads.append(outertopcoords[3:]+outertopcoords[:1]) - else: - quads.append(outertopcoords) - for p1, p2 in wrap(outertopcoords): - lines.append((p1, p2)) - # outer sides and lines + drawstud(studsx, studsz, x, z, lines, triangles, quads) + elif m.group('slope') == 'Double Convex': + drawstud(studsx, studsz, studsx-1, 0, lines, triangles, quads) + elif m.group('slope') == 'Double Concave': + for z in range(studsz): + for x in range(studsx): + if z == 0 or x == studsx-1: + drawstud(studsx, studsz, x, z, lines, triangles, quads) + else: + for x in range(studsx): + drawstud(studsx, studsz, x, 0, lines, triangles, quads) + # create top, bottom, inner and outer rectangles + if m.group('slope') in ['Double Convex', 'Inverted Double Convex']: + outertopcoords = [((x-studsx+1)*10, 0, (z+studsz-1)*10) for x,z in coords] + outerbottomcoords = [(studsx*10*x, height, studsz*10*z) for x,z in coords] # big + helpercoords = [((x-studsx+1)*10, height, (z+studsz-1)*10) for x,z in coords] # small + innerbottomcoords = [(studsx*10*x-sign(x)*4, height, studsz*10*z-sign(z)*4) for x,z in coords] + innertopcoords = [(6*x-(studsx-1)*10, 4, z*6+(studsz-1)*10) for x,z in coords] + nosedown1 = outerbottomcoords[:1]+outerbottomcoords[-1:] + noseup1 = [(x,height-4,z) for x,y,z in nosedown1] + nosedown2 = outerbottomcoords[-2:-1]+outerbottomcoords[-1:] + noseup2 = [(x,height-4,z) for x,y,z in nosedown2] + # if an inverted piece is requested, switch coordinates around if m.group('slope') == 'Inverted Double Convex': - for (p1, p2), (p3, p4) in zip(wrap(outerbottomcoords)[:2], wrap(outertopcoords2)[:2]): - quads.append((p1,p2,p4,p3)) - for (p1, p2), (p3, p4) in zip(wrap(outerbottomcoords)[1:2], wrap(outertopcoords2)[1:2]): - lines.append((p1,p3)) - elif m.group('slope') == 'Double Convex': - for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[:2], wrap(outerbottomcoords2)[:2]): - quads.append((p1,p2,p4,p3)) - for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[1:2], wrap(outerbottomcoords2)[1:2]): - lines.append((p1,p3)) - elif m.group('slope') == 'Double Concave': - for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[1:5], wrap(outerbottomcoords2)[1:5]): - quads.append((p1,p2,p4,p3)) - for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[2:5], wrap(outerbottomcoords2)[2:5]): - lines.append((p1,p3)) - else: - for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[:3], wrap(outerbottomcoords2)[:3]): - quads.append((p1,p2,p4,p3)) - for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[1:3], wrap(outerbottomcoords2)[1:3]): - lines.append((p1,p3)) - # draw nose - if m.group('slope') in ['Inverted Double Convex', 'Double Convex']: - quads.append(noseup1+[nosedown1[1]]+[nosedown1[0]]) - quads.append(noseup2+[nosedown2[1]]+[nosedown2[0]]) - elif m.group('slope') != 'Double Concave': - quads.append(noseup+[nosedown[1]]+[nosedown[0]]) - # draw sides and lines to the nose + outerbottomcoords, helpercoords, outertopcoords = ( + [(x,0,z) for x,y,z in outerbottomcoords], + [(x,0,z) for x,y,z in helpercoords], + [(x,height,z) for x,y,z in outertopcoords]) + innertopcoords, innerbottomcoords = ( + [(x,4,z) for x,y,z in innertopcoords], + [(x,height,z) for x,y,z in innertopcoords]) + noseup1, nosedown1 = [(x,0,z) for x,y,z in nosedown1], [(x,4,z) for x,y,z in noseup1] + noseup2, nosedown2 = [(x,0,z) for x,y,z in nosedown2], [(x,4,z) for x,y,z in noseup2] + elif m.group('slope') == 'Double Concave': + outertopcoords = [(studsx*10*x+(abs(x)-1)*(10*studsx-20), 0, studsz*10*z+(1-abs(z))*(10*studsz-20)) for x,z in coordsL] + outerbottomcoords = [(studsx*10*x, height, studsz*10*z) for x,z in coords] # big + helpercoords = [(studsx*10*x+(abs(x)-1)*(10*studsx-20), height, studsz*10*z+(1-abs(z))*(10*studsz-20)) for x,z in coordsL] # small + innertopcoords = [((studsx*10-4)*x+(abs(x)-1)*(10*studsx-20), 4, (studsz*10-4)*z+(1-abs(z))*(10*studsz-20)) for x,z in coordsL] + innerbottomcoords = [((studsx*10-4)*x, height, (studsz*10-4)*z) for x,z in coords] + tip = [(studsx*10,height,-studsz*10), (studsx*10,height-4,-studsz*10)] + # there is somehow no inverted double concave piece + else: + outertopcoords = [(studsx*10*x, 0, (z+studsz-1)*10) for x,z in coords] + helpercoords = [(studsx*10*x, height, (z+studsz-1)*10) for x,z in coords] # small + outerbottomcoords = [(studsx*10*x, height, studsz*10*z) for x,z in coords] # big + innertopcoords = [((studsx*10-4)*x, 4, z*6+(studsz-1)*10) for x,z in coords] + innerbottomcoords = [(studsx*10*x-sign(x)*4, height, studsz*10*z-sign(z)*4) for x,z in coords] + nosedown = outerbottomcoords[:1]+outerbottomcoords[-1:] + noseup = [(x,height-4,z) for x,y,z in nosedown] + # if an inverted piece is requested, switch coordinates around + if m.group('slope') == 'Inverted': + outerbottomcoords, helpercoords, outertopcoords = ( + [(x,0,z) for x,y,z in outerbottomcoords], + [(x,0,z) for x,y,z in helpercoords], + [(x,height,z) for x,y,z in outertopcoords]) + innertopcoords, innerbottomcoords = ( + [(x,4,z) for x,y,z in innertopcoords], + [(x,height,z) for x,y,z in innertopcoords]) + noseup, nosedown = [(x,0,z) for x,y,z in nosedown], [(x,4,z) for x,y,z in noseup] + # outer sides and lines + if m.group('slope') in ['Double Convex', 'Inverted Double Convex']: + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[:2], wrap(helpercoords)[:2]): + quads.append((p1,p2,p4,p3)) + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[1:2], wrap(helpercoords)[1:2]): + lines.append((p1,p3)) + elif m.group('slope') == 'Double Concave': + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[1:5], wrap(helpercoords)[1:5]): + quads.append((p1,p2,p4,p3)) + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[2:5], wrap(helpercoords)[2:5]): + lines.append((p1,p3)) + else: + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[:3], wrap(helpercoords)[:3]): + quads.append((p1,p2,p4,p3)) + for (p1, p2), (p3, p4) in zip(wrap(outertopcoords)[1:3], wrap(helpercoords)[1:3]): + lines.append((p1,p3)) + # draw nose + if m.group('slope') in ['Inverted Double Convex', 'Double Convex']: + quads.append(noseup1+[nosedown1[1]]+[nosedown1[0]]) + quads.append(noseup2+[nosedown2[1]]+[nosedown2[0]]) + elif m.group('slope') != 'Double Concave': + quads.append(noseup+[nosedown[1]]+[nosedown[0]]) + # draw sides and lines to the nose + if m.group('slope') in ['Double Convex', 'Inverted Double Convex']: + quads.append(outertopcoords[-2:-1]+helpercoords[-2:-1]+noseup2[:1]+nosedown2[:1]) + quads.append(outertopcoords[:1]+helpercoords[:1]+noseup1[:1]+nosedown1[:1]) + elif m.group('slope') == 'Double Concave': + quads.append(outertopcoords[-1:]+helpercoords[-1:]+tip) + quads.append(outertopcoords[1:2]+helpercoords[1:2]+tip) + else: + quads.append(outertopcoords[-1:]+helpercoords[-1:]+nosedown[-1:]+noseup[-1:]) + quads.append(outertopcoords[:1]+helpercoords[:1]+nosedown[:1]+noseup[:1]) + if m.group('slope') in ['Inverted Double Convex', 'Double Convex']: + lines.append(noseup1[:1]+nosedown1[:1]) + lines.append(noseup1[-1:]+nosedown1[-1:]) + lines.append(noseup2[:1]+nosedown2[:1]) + lines.append(noseup2[-1:]+nosedown2[-1:]) + elif m.group('slope') == 'Double Concave': + lines.append(tip) + else: + lines.append(noseup[:1]+nosedown[:1]) + lines.append(noseup[-1:]+nosedown[-1:]) + # write inner top plate and lines + if m.group('slope') == 'Double Concave': + quads.append(innertopcoords[:4]) + quads.append(innertopcoords[3:]+innertopcoords[:1]) + else: + quads.append(innertopcoords) + for p1, p2 in wrap(innertopcoords): + lines.append((p1, p2)) + # inner sides and lines + if m.group('slope') == 'Double Concave': + # the quadrilateral sides + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords)[1:5], + wrap(innerbottomcoords)[-1:]+wrap(innerbottomcoords)[:4]): + quads.append((p1,p2,p4,p3)) + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords)[2:5], wrap(innerbottomcoords)[:4]): + lines.append((p1,p3)) + # the slopes + triangles.append(innertopcoords[-1:]+innertopcoords[:1]+innerbottomcoords[-1:]) + triangles.append(innertopcoords[:1]+innertopcoords[1:2]+innerbottomcoords[-1:]) + lines.append(innertopcoords[-1:]+innerbottomcoords[-1:]) + lines.append(innertopcoords[:1]+innerbottomcoords[-1:]) + lines.append(innertopcoords[1:2]+innerbottomcoords[-1:]) + else: + for (p1, p2), (p3, p4) in zip(wrap(innertopcoords), wrap(innerbottomcoords)): + quads.append((p1,p2,p4,p3)) + lines.append((p1,p3)) + # draw slope and lines around it + if m.group('slope') in ['Double Convex', 'Inverted Double Convex']: if m.group('slope') == 'Inverted Double Convex': - quads.append(outerbottomcoords[-2:-1]+outertopcoords2[-2:-1]+nosedown2[:1]+noseup2[:1]) - quads.append(outerbottomcoords[:1]+outertopcoords2[:1]+nosedown1[:1]+noseup1[:1]) - elif m.group('slope') == 'Double Convex': - quads.append(outertopcoords[-2:-1]+outerbottomcoords2[-2:-1]+noseup2[:1]+nosedown2[:1]) - quads.append(outertopcoords[:1]+outerbottomcoords2[:1]+noseup1[:1]+nosedown1[:1]) - elif m.group('slope') == 'Double Concave': - quads.append(outertopcoords[-1:]+outerbottomcoords2[-1:]+tip) - quads.append(outertopcoords[1:2]+outerbottomcoords2[1:2]+tip) - else: - quads.append(outertopcoords[-1:]+outerbottomcoords2[-1:]+nosedown[-1:]+noseup[-1:]) - quads.append(outertopcoords[:1]+outerbottomcoords2[:1]+nosedown[:1]+noseup[:1]) - if m.group('slope') in ['Inverted Double Convex', 'Double Convex']: - lines.append(noseup1[:1]+nosedown1[:1]) - lines.append(noseup1[-1:]+nosedown1[-1:]) - lines.append(noseup2[:1]+nosedown2[:1]) - lines.append(noseup2[-1:]+nosedown2[-1:]) - elif m.group('slope') == 'Double Concave': - lines.append(tip) - else: - lines.append(noseup[:1]+nosedown[:1]) - lines.append(noseup[-1:]+nosedown[-1:]) - # draw slope and lines around it + noseup1, nosedown1, noseup2, nosedown2 = nosedown1, noseup1, nosedown2, noseup2 + quads.append(outertopcoords[-1:]+outertopcoords[:1]+[noseup1[1]]+[noseup1[0]]) + quads.append(outertopcoords[2:3]+outertopcoords[3:4]+[noseup2[1]]+[noseup2[0]]) + lines.append(noseup1[:1]+outertopcoords[:1]) + lines.append(noseup1[-1:]+outertopcoords[-1:]) + lines.append(noseup2[-2:-1]+outertopcoords[-2:-1]) + lines.append(noseup1[:1]+noseup1[-1:]) + lines.append(noseup2[:1]+noseup2[-1:]) + elif m.group('slope') == 'Double Concave': + triangles.append(outertopcoords[-1:]+outertopcoords[:1]+[tip[1]]) + triangles.append(outertopcoords[:1]+outertopcoords[1:2]+[tip[1]]) + lines.append(outertopcoords[-1:]+[tip[1]]) + lines.append(outertopcoords[:1]+[tip[1]]) + lines.append(outertopcoords[1:2]+[tip[1]]) + else: if m.group('slope') == 'Inverted': - quads.append(outerbottomcoords[-1:]+outerbottomcoords[:1]+[nosedown[1]]+[nosedown[0]]) - lines.append(nosedown[:1]+outerbottomcoords[:1]) - lines.append(nosedown[-1:]+outerbottomcoords[-1:]) - lines.append(nosedown[:1]+nosedown[-1:]) - elif m.group('slope') == 'Inverted Double Convex': - quads.append(outerbottomcoords[-1:]+outerbottomcoords[:1]+[nosedown1[1]]+[nosedown1[0]]) - quads.append(outerbottomcoords[2:3]+outerbottomcoords[3:4]+[nosedown2[1]]+[nosedown2[0]]) - lines.append(nosedown1[:1]+outerbottomcoords[:1]) - lines.append(nosedown1[-1:]+outerbottomcoords[-1:]) - lines.append(nosedown2[-2:-1]+outerbottomcoords[-2:-1]) - lines.append(nosedown1[:1]+nosedown1[-1:]) - lines.append(nosedown2[:1]+nosedown2[-1:]) - elif m.group('slope') == 'Double Convex': - quads.append(outertopcoords[-1:]+outertopcoords[:1]+[noseup1[1]]+[noseup1[0]]) - quads.append(outertopcoords[2:3]+outertopcoords[3:4]+[noseup2[1]]+[noseup2[0]]) - lines.append(noseup1[:1]+outertopcoords[:1]) - lines.append(noseup1[-1:]+outertopcoords[-1:]) - lines.append(noseup2[-2:-1]+outertopcoords[-2:-1]) - lines.append(noseup1[:1]+noseup1[-1:]) - lines.append(noseup2[:1]+noseup2[-1:]) - elif m.group('slope') == 'Double Concave': - triangles.append(outertopcoords[-1:]+outertopcoords[:1]+[tip[1]]) - triangles.append(outertopcoords[:1]+outertopcoords[1:2]+[tip[1]]) - lines.append(outertopcoords[-1:]+[tip[1]]) - lines.append(outertopcoords[:1]+[tip[1]]) - lines.append(outertopcoords[1:2]+[tip[1]]) - else: - quads.append(outertopcoords[-1:]+outertopcoords[:1]+[noseup[1]]+[noseup[0]]) - lines.append(noseup[:1]+outertopcoords[:1]) - lines.append(noseup[-1:]+outertopcoords[-1:]) - lines.append(noseup[:1]+noseup[-1:]) - # write inner top plate and lines - if m.group('slope') == 'Double Concave': - quads.append(innertopcoords[:4]) - quads.append(innertopcoords[3:]+innertopcoords[:1]) - else: - quads.append(innertopcoords) - for p1, p2 in wrap(innertopcoords): - lines.append((p1, p2)) - # inner sides and lines - if m.group('slope') == 'Double Concave': - # the quadrilateral sides - for (p1, p2), (p3, p4) in zip(wrap(innertopcoords)[1:5], - wrap(innerbottomcoords)[-1:]+wrap(innerbottomcoords)[:4]): - quads.append((p1,p2,p4,p3)) - for (p1, p2), (p3, p4) in zip(wrap(innertopcoords)[2:5], wrap(innerbottomcoords)[:4]): - lines.append((p1,p3)) - # the slopes - triangles.append(innertopcoords[-1:]+innertopcoords[:1]+innerbottomcoords[-1:]) - triangles.append(innertopcoords[:1]+innertopcoords[1:2]+innerbottomcoords[-1:]) - lines.append(innertopcoords[-1:]+innerbottomcoords[-1:]) - lines.append(innertopcoords[:1]+innerbottomcoords[-1:]) - lines.append(innertopcoords[1:2]+innerbottomcoords[-1:]) - else: - for (p1, p2), (p3, p4) in zip(wrap(innertopcoords), wrap(innerbottomcoords)): - quads.append((p1,p2,p4,p3)) - lines.append((p1,p3)) - # write out bottom with trapezoids and lines - for (p1, p2), (p3, p4) in zip(wrap(innerbottomcoords), wrap(outerbottomcoords)): - quads.append((p1, p2, p4, p3)) - lines.append((p1, p2)) - lines.append((p3, p4)) - else: - print "not supported part type: %s"%m.group('type') - exit(1) - outfile = open("parts/%s.dat"%partid, 'w') - outfile.write("0 %s\n"%parttext) - for (x1, y1, z1), (x2, y2, z2) in lines: - outfile.write("2 24 %f %f %f %f %f %f\n"%(x1, y1, z1, x2, y2, z2)) - for (x1, y1, z1), (x2, y2, z2), (x3, y3, z3) in triangles: - outfile.write("3 16 %f %f %f %f %f %f %f %f %f\n"%( - x1, y1, z1, x2, y2, z2, x3, y3, z3)) - for (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4) in quads: - outfile.write("4 16 %f %f %f %f %f %f %f %f %f %f %f %f\n"%( - x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4)) - outfile.close() + noseup, nosedown = nosedown, noseup + quads.append(outertopcoords[-1:]+outertopcoords[:1]+[noseup[1]]+[noseup[0]]) + lines.append(noseup[:1]+outertopcoords[:1]) + lines.append(noseup[-1:]+outertopcoords[-1:]) + lines.append(noseup[:1]+noseup[-1:]) + # for drawing the top and bottom, switch the coords if necessary + if m.group('slope') in ['Inverted Double Convex', 'Inverted']: + outertopcoords, outerbottomcoords = outerbottomcoords, outertopcoords + # write out bottom with trapezoids and lines + for (p1, p2), (p3, p4) in zip(wrap(innerbottomcoords), wrap(outerbottomcoords)): + quads.append((p1, p2, p4, p3)) + lines.append((p1, p2)) + lines.append((p3, p4)) + # write outer top plate and lines + if m.group('slope') == 'Double Concave': + quads.append(outertopcoords[:4]) + quads.append(outertopcoords[3:]+outertopcoords[:1]) + else: + quads.append(outertopcoords) + for p1, p2 in wrap(outertopcoords): + lines.append((p1, p2)) + else: + print "not supported part type: %s"%m.group('type') + exit(1) + outfile = open("parts/%s.dat"%partid, 'w') + outfile.write("0 %s\n"%parttext) + for (x1, y1, z1), (x2, y2, z2) in lines: + outfile.write("2 24 %f %f %f %f %f %f\n"%(x1, y1, z1, x2, y2, z2)) + for (x1, y1, z1), (x2, y2, z2), (x3, y3, z3) in triangles: + outfile.write("3 16 %f %f %f %f %f %f %f %f %f\n"%( + x1, y1, z1, x2, y2, z2, x3, y3, z3)) + for (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4) in quads: + outfile.write("4 16 %f %f %f %f %f %f %f %f %f %f %f %f\n"%( + x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4)) + outfile.close() if __name__ == "__main__": - render() + for part in parts: + render_part(part)