import cadquery as cq import math as m spacing = 21.5 size = spacing * 1.5 / m.sqrt(3) radius = size * 4/3 sin30, cos30 = m.sin(30/180*m.pi), m.cos(30/180*m.pi) epsi = 1e-6 def shape2points(shape): lines = shape.strip('\n').split('\n') for y, line in enumerate(lines): for x, char in enumerate(line): if char != ' ': yield x, y def gridpos(x, y, ox=0, oy=0): return (x * spacing / 2 + ox, -y * size + oy) def gridify(gen): for x, y in gen: yield gridpos(x, y) def make_outline(): results = [] key_pos = list(gridify(shape2points(''' X X X X X X X X X X X X X X X X X '''))) extras = list(gridify(shape2points(''' X X X X X '''))) return ( cq.Workplane("XY") .sketch() .push(key_pos) .regularPolygon(radius/2, 6) .reset() .push([(x+2*cos30, y-2*sin30) for x,y in extras]) .regularPolygon(radius/2, 6) .reset() .clean() .segment( gridpos(11, 1 + 2/3, ox=2*cos30, oy=-2*sin30), gridpos(8.75, 1/12-1, ox=-2*cos30, oy=-2*sin30), ) .segment(gridpos(7, -1/3)) .segment(gridpos(7, 1/3)) .segment(gridpos(8, 2/3)) .segment(gridpos(8, 4/3)) .segment(gridpos(9, 5/3, ox=2*cos30, oy=-2*sin30)) .segment(gridpos(10, 4/3, ox=2*cos30, oy=-2*sin30)) .assemble() .finalize() .extrude(1) .faces('