import cadquery as cq # pixel coordinates based on a picture in the Hiwin's # linear rail guidebook hgr_profile = [ (0, 0), (37, 0), (37 + 6, 6), (96 - 6, 6), (96, 0), (186-17, 0), (186, 17), (186, 76), (129, 133), (129, 59 + 133), (129 + 20, 59 + 133 + 20), (31, 129 + 20 + 31, 133 + 20 + 31), (186 - 6, 316 - 42 - 25 - 6), (186, 316 - 42 - 25), (186, 316 - 42), (186 - 6, 316 - 42 + 6 - 1), (31, 186 - 6 - 31, 316 - 6 - 1), (143 + 6, 316 - 6), (143, 316), (0, 316) ] scale = (10/186*17/316)**0.5 scaled_profile = [tuple((scale * v for v in vals)) for vals in hgr_profile] class HGR20: def __init__(self, base, l): self.base = base.workplane() self.l = l def holes(self, w): pts = [(0, x-self.l/2) for x in range(20, self.l, 60)] print("points", pts) w = (w.copyWorkplane(self.base) .transformed(offset=(0,0,17)) .pushPoints(pts) .hole(5)) return w def rail(self): # workplane or face to use, length of rail # TODO rotate w xy = cq.Workplane().copyWorkplane(self.base) w = xy.transformed((90, 0, 0), (0, self.l/2, 0)) for v in scaled_profile[1:]: if len(v) == 2: w = w.lineTo(*v) else: w = w.lineTo(*v[1:3]) # TODO draw an arc instead w = w.mirrorY() w = w.extrude(self.l) pts = [(0, x-self.l/2) for x in range(20, self.l, 60)] print("points", pts) w = (w.copyWorkplane(xy) .transformed(offset=(0,0,17)) .pushPoints(pts) .hole(5)) # TODO replace with counterbore and get proper diameter return w plate = (cq.Workplane("XY") .rect(200, 200) .extrude(10) .faces(">Z") .workplane() .tag("railmount") .end() ) hgr20 = HGR20(plate.workplaneFromTagged("railmount"), 300) plate2 = hgr20.holes(plate) hgrtest = hgr20.rail() show_object(plate2) show_object(hgrtest)