Пример #1
0
def box(width, height, depth, half=False, topbox=False):
    obj = sp.part()
    left = sp.cube([thickness, depth, height])
    right = left.copy()
    right = spu.right(width - thickness)(right)
    obj += left + right

    top = sp.cube([width - 2 * thickness, depth, thickness])
    top = spu.right(thickness)(top)
    if (half):
        ha = spu.up(height / 2 - thickness / 2)(top)
        obj += ha
    h = sp.cylinder(holes / 2, thickness + 10)
    top -= sp.translate([50, 50, 0])(h)
    top -= sp.translate([width - 50, 50, 0])(h)
    top -= sp.translate([width - 50, depth - 50, 0])(h)
    top -= sp.translate([50, depth - 50, 0])(h)
    bottom = top
    top = spu.up(height - thickness)(top)
    obj += top + bottom

    if (not topbox):
        sta = sp.cube([width * 3 / 4, thickness, 100])
        sta = sp.rotate([0, -45, 0])(sta)
        cutout = sp.cube([width, depth, height])
        cutout = spu.down(height / 4)(spu.left(width / 4)(cutout))
        cutout -= spu.back(5)(sp.cube(
            [width / 2 - thickness, depth + 10, height / 2 - thickness]))
        sta -= spu.back(depth / 2)(cutout)
        sta = spu.right(thickness)(sta)
        sta += spu.right(width)(sp.mirror([1, 0, 0])(sta))
        sta += sp.mirror([0, 0, 1])(sta)
        sta = spu.forward(depth - thickness)(sta)
        obj += (spu.up(height / 2)(sta) - ha)

    if (half and topbox):
        window = sp.cube(
            [width - 2 * thickness, thickness, height / 2 - 1.5 * thickness])
        window = sp.translate([thickness, 0, thickness])(window)
        obj += spu.up(height / 2 - thickness / 2)(window)
    return obj
Пример #2
0
 def getOblongArm(self):
     '''Return a SolidPython object modeling an oblong arm (per specs in
     ArmParams object) bounded by four arcs of circles.        '''
     eps = 0.01
     p, q, s, t, u, w = self.p, self.q, self.s, self.t, self.u, self.w
     r1, r2 = p - s, q - t
     domis, chi, dhi = 2 * max(r1, r2), 1.1, -0.05
     arc1 = back(r1 + s)(cylinder(r=r1, h=1))
     arc2 = back(q - r2)(cylinder(r=r2, h=1))
     rl, vl, p1, p2 = self.solveArcArc(p, q, s, t, u)
     rr, vr, p3, p4 = self.solveArcArc(p, q, s, t, w)
     rightcircle = color(Green)(translate([u, -vl, dhi])(cylinder(r=rl,
                                                                  h=chi)))
     leftcircle = color(Red)(translate([w, -vr, dhi])(cylinder(r=rr,
                                                               h=chi)))
     yrhi, yrlo, ylhi, yllo = p1[1], p2[1], p3[1], p4[1]
     xr, xl = min(p1[0], p2[0]), max(p3[0], p4[0])
     dominol = translate([xl - domis, -yllo,
                          dhi])(cube([domis, yllo - ylhi, chi]))
     dominor = translate([xr, -yrlo, dhi])(cube([domis, yrlo - yrhi, chi]))
     return (arc1 * arc2 - dominol - dominor) + rightcircle + leftcircle
Пример #3
0
def key_lettering():
    messages = ["LeRoy", "Dental"]
    layout = union()([
        forward((index - 0.5) * -LETTER_HEIGHT)(text(message,
                                                     halign='center',
                                                     valign='center'))
        for index, message in enumerate(messages)
    ])
    lettering = up(THICKNESS / 2 - LETTERING_RISE)(
        linear_extrude(height=2 * LETTERING_RISE)(scale([0.8, 0.8,
                                                         1])(layout)))
    return back(HANDLE_DIAMETER / 2)(lettering)
Пример #4
0
def makeBridges(rail, span):
    BridgeN      = rail.Bridges
    BridgeOffset = rail.BridgeOffset
    BridgeWide   = rail.BridgeWide
    BridgeStep   = (rail.CapLen-2*rail.BridgeOffset)/max(1,BridgeN-1)
    CapWide      = rail.CapWide
    asm = None
    proto = cube([BridgeWide, span, rail.CapThik])
    proto = back(span-CapWide)(proto)
    for k in range(BridgeN):
        b = right(BridgeOffset+k*BridgeStep-BridgeWide/2)(proto)
        asm = b + asm if asm else b
    return color(Cyan)(asm) if asm else None
Пример #5
0
def ueyeholder():
    """ueyeholder
    creates a holder for an ueye camera

    A holder for an uEye camera to view upward.
    The uEye camera cannot look upward due its connector on the back.
    This design solves this problem via a cubical enclosure.
    """
    #### UEYE cubical dimension
    margin = 0.3
    size_x = 34  # mm
    size_y = 32  # mm
    size_z = 34.6  # mm
    ### UEYE screw
    screw_d = 3  # mm
    screw_z = 30.4  # sep z-direction
    screw_z -= screw_d
    screw_ytop = 19.8  # mm
    screw_ytop -= screw_d
    screw_ybottom = 21.8
    screw_ybottom -= screw_d
    screw_zoff = 1.3 + screw_d / 2
    connector_z = 18  # mm
    connector_x = 16.2  # mm
    ####
    # box
    # camera is pushed in from bottom
    holder = cube([
        size_x + 2 * THCKW + margin, size_y + 2 * THCKW + margin,
        size_z + THCKW + connector_z + margin
    ])
    holder -= translate([THCKW, THCKW, THCKW])(cube([
        size_x + margin, size_y + margin, size_z + THCKW + connector_z + margin
    ]))
    # 4 screw holes
    socket = cylinder(h=size_x + 2 * THCKW, r=screw_d / 2, segments=SGM)
    socket = rotate([0, 90, 0])(socket)
    sockets = socket + forward(screw_ybottom)(socket)
    temp = (screw_ytop - screw_ybottom) * 0.5
    sockets += up(screw_z)(back(temp)(socket) +
                           forward(screw_ytop - temp)(socket))
    # substraction prep sockets
    holder -= translate([
        0, (size_y - screw_ybottom) * 0.5 + THCKW + 0.5 * margin,
        screw_zoff + THCKW + connector_z + 0.5 * margin
    ])(sockets)
    # space connector
    holder -= translate([THCKW + 0.5 * (size_x - connector_x), 0, THCKW])(cube(
        [connector_x, THCKW, size_z + THCKW + connector_z]))
    return holder
Пример #6
0
def laserbase(laserheight):
    """laserabase
    creates the basis for the laser with ventilation wall

    The laserbase is in the XY plane at quadrant 1.
    One corner is at the origin. The width is parallel to the x-axis.
    The laser was provided by Odic Force, productid OFL510-1.
    The padheight is laser height- 16.5 The laserbundle travels in
    the +x direction and departs from the center, that is 15 mm.
    param: laserheight: the desired height of the laser
    """
    # The laser tube is at 8 mm from bottom.
    # The laser tube has a diameter of 17 mm
    # The laser is at 8 + 17 * 0.5 - 1  = 16.5 mm (shim of 1 mm needed)
    # The laser base is 30x60 mm, which was made
    # 30x75 mm to make room for the ventilator

    # PARAMETERS
    height = laserheight - 15.5  # [mm],
    xdisp = 48.5  # [mm], x-displacement screws
    ydisp = 16  # [mm], y-displacement screws
    r_shaft = 2  # [mm], shaft radius screws
    h_head = 5  # [mm], height shaft head
    r_head = 3.5  # [mm], top radius screws
    tspile = 4  # [mm], y-thickness ventilation spile
    hspile = 25  # [mm], height ventilation spile
    length = 75  # [mm], x-direction length laser
    width = 30  # [mm], y-direction width laser
    screw_offst = 7  # [mm], screw offset +x-edge

    # MINIMAL MATERIAL BASE
    screws = screw(r_head, h_head, r_shaft, height) + right(xdisp)(screw(
        r_head, h_head, r_shaft, height))
    spiegel = forward(ydisp / 2)(mirror([0, 1, 0])(back(ydisp / 2)(screws)))
    screws += spiegel
    base = translate([length - xdisp - screw_offst, (width - ydisp) / 2,
                      0])(screws)
    # ventilation wall
    # spile
    spile = up(height)(cube([THICK_WALL, tspile, hspile]))
    nofspiles = ceil((width) / (tspile * 2))
    # shift base
    base = right(THICK_WALL)(base)
    # add wall
    base += cube([THICK_WALL, width, HEIGHT_WALL])
    # create pockets
    for i in range(0, nofspiles):
        base -= hole()(forward(i * 2 * tspile + THICK_WALL)(spile))

    return base
Пример #7
0
    def mounting_posts(self, distance_from_surface):
        positioning_post_height = distance_from_surface + self.board_thickness + 3
        positioning_post = forward(1)(
            up(positioning_post_height / 2)(
                cube((4, 4, positioning_post_height), center=True)
            )
        )

        return (
            back(self.board_length + m2_shaft_radius + FUDGE)(
                mount_post_m2(distance_from_surface)
            )
            + left(7)(positioning_post)
            + right(7)(positioning_post)
        )
def switch_plate():
    top_wall = forward((1.5 + keyswitch_length) / 2)(
        up(plate_thickness / 2)(
            cube((keyswitch_width + 3, 1.5, plate_thickness), center=True) -
            down(notch_plate_thickness)(  # Notch for switch clips
                back(0.75)(cube((notch_width, notch_depth * 2,
                                 plate_thickness),
                                center=True)))))

    left_wall = left((1.5 + keyswitch_width) / 2)(up(plate_thickness / 2)(cube(
        (1.5, keyswitch_length + 3, plate_thickness), center=True)))

    plate_half = top_wall + left_wall

    return plate_half + mirror((0, 1, 0))(mirror((1, 0, 0))(plate_half))
Пример #9
0
def projection():
    from . import arm_mount
    magic_1 = (arm_mount.face_diameter / 2.)

    bar = sp.translate(
        (0., -magic_1, 0.))(plate.projection(size=(width, length + magic_1)))

    mounting_holes = place_mounting_holes(
        drilled_hole.projection(mounting_hole_diameter))

    tie_rod_holes = spu.back(tie_rod_hole_offset)(place_at_centres(
        (tie_rod_hole_centres, 0.),
        drilled_hole.projection(tie_rod_hole_diameter)))

    return bar - mounting_holes - tie_rod_holes
Пример #10
0
def bard_brick():
    double_thickness = 2 * THICKNESS
    base = basic_brick(WIDTH, LENGTH, HEIGHT)
    interior = down(THICKNESS)(basic_brick(WIDTH - double_thickness,
                                           LENGTH - double_thickness, HEIGHT))
    handle = up(HEIGHT - HANDLE_HEIGHT)(
        forward((LENGTH + HANDLE_LENGTH) / 2 - THICKNESS)(grounded_cube(
            [HANDLE_WIDTH, THICKNESS + HANDLE_LENGTH, HANDLE_HEIGHT])))
    chop = back(LENGTH / 2)(cube([CHOP_WIDTH, CHOP_LENGTH, 2 * CHOP_HEIGHT],
                                 center=True))
    side_ridge = grounded_cube([SIDE_RIDGE_THICKNESS, LENGTH, HEIGHT])
    side_ridges = union()([right(x)(side_ridge) for x in RIDGE_X])
    end_ridge = forward(END_RIDGE_Y)(grounded_cube(
        [END_RIDGE_W + THICKNESS, END_RIDGE_DEPTH, HEIGHT]))
    brick = base - interior + handle - chop + side_ridges + end_ridge
    return mirror([0, 0, 1])(down(HEIGHT)(brick))
Пример #11
0
def assembly():
    x_bars = sp.rotate([0, 90, 0])(
        [
            spu.back(d)(
                box_section.volume(
                    length=outer * 2. + box_section.default_size[0],
                    center=True
                )
            ) for d in split_centers(seat_depth)
        ]
    )

    y_bars = sp.rotate([90, 0, 0])(
        [
            spu.left(d)(
                box_section.volume(
                    length=seat_depth - box_section.default_size[0],
                    center=True
                )
            ) for d in [-outer, outer]
        ]
    )

    _mount_bar_centres = (mount_bar_centres - box_section.default_size[0]) / 2.
    mount_bars = spu.up(box_section.default_size[0])(
        sp.rotate([90, 0, 0])(
            [
                spu.left(d)(
                    box_section.volume(
                        length=seat_depth + box_section.default_size[0],
                        center=True
                    )
                ) for d in [-_mount_bar_centres, _mount_bar_centres]
            ]
        )
    )

    frame = sp.union()(
        sp.color('red')(x_bars),
        sp.color('green')(y_bars),
        sp.color('blue')(mount_bars),
    )

    return frame
Пример #12
0
def assembly():
    magic_1 = inner_length - 100.

    return sp.union()(
        sp.color('red')(lower_frame.assembly()),
        sp.color('green')(sp.translate((0, 180, 160))(seat_mount.assembly())),
        sp.color('blue')(
            sp.translate(
                (
                    0, rear_axle_position, -(box_section.default_size[0] / 2.) -
                    rear_axle_bearing.shaft_height
                )
            )(rear_axle.assembly())
        ),
        sp.color('magenta')(
            sp.translate((inner + (box_section.default_size[0] / 2.), 300, 0))(
                sp.rotate((90, 0, -90))(motor.assembly())
            )
        ),
        sp.color('pink')(
            spu.forward(inner_length + box_section.default_size[0])(
                sp.rotate((90, 0, 180))(bumpers.front.assembly())
            ),
            spu.back(box_section.default_size[1])(
                sp.rotate((90, 0, 0))(bumpers.rear.assembly())
            ),
        ),
        sp.color('lime')(
            sp.translate(
                (-inner + (box_section.default_size[0] / 2.) + 1., magic_1, 0)
            )(brake_pedal.assembly())
        ),
        sp.color('orange')(
            sp.translate((0, 1100., 0))(
                sp.rotate((50., 0, 0))(steering.assembly())
            )
        ),
        sp.color('brown')(
            sp.translate((0, 75, box_section.default_size[0] / 2.))(
                electronics_tray.assembly()
            )
        ),
    )
Пример #13
0
def ur_corner_clipper_clipper():
    return right(SHIFTINESS)(
        back(SHIFTINESS)(
            grounded_cube([PLATTER_WIDTH, PLATTER_LENGTH, HOLE_HEIGHT])))
Пример #14
0
def x_side_slots():
    slot = rounded_platter([TOP_SLOT_LENGTH, SIDE_SLOT_WIDTH, HOLE_HEIGHT], SIDE_SLOT_RADIUS)
    return forward(CORNER_HOLE_Y_OFFSET)(slot) + back(CORNER_HOLE_Y_OFFSET)(slot)
Пример #15
0
 def make_hole(self):
     body = square([self.width, self.height])
     layer_width = (phone_width + 2 * radius)
     moved_right = right(layer_width / 2 - self.width / 2)(body)
     moved_down = back(self.height / 2 + self.y_adjust)(moved_right)
     return moved_down
Пример #16
0
def holes():
    return sp.rotate((0., 0., 180.))(sp.union()(
        light.holes(),
        spu.back((light.diameter / 2.) + 9.)(mount.holes()),
    ))
Пример #17
0
 def horizontal_beams(self, width, elevation):
     cross_beam = up(elevation - self.beam_size)(
         grounded_cube([width, self.beam_size, self.beam_size])
     )
     return forward(self.horizontal_beam_offset_y)(cross_beam) + back(self.horizontal_beam_offset_y)(cross_beam)
Пример #18
0
def cleat_opening():
    return down(DEFAULT_CONNECTOR_BLOCK_THICKNESS)(back(
        SWITCH_CLEAT_LENGTH / 2)(right(SWITCH_CLEAT_OFFSET)(cube([
            SWITCH_CLEAT_WIDTH, SWITCH_CLEAT_LENGTH,
            3 * DEFAULT_CONNECTOR_BLOCK_THICKNESS
        ]))))
Пример #19
0
def renderparts():
    """
    renderparts

    renders all the subcomponents of the box
    placed in separate function to prevent collision
    """
    print_screw = screw(3, 2, 2, 10)  # create a printable screw
    scad_render_to_file(print_screw, 'print_screw.scad')

    print_lasershim = lasershim(1)
    scad_render_to_file(print_lasershim, 'shim.scad')

    print_laserbase = laserbase(LASER_HEIGHT)
    scad_render_to_file(print_laserbase, 'laserbase.scad')

    fasten = cable_fasten(TIE_HEIGHT, TIE_WIDTH, THICK_WALL, True)
    scad_render_to_file(fasten, 'cable_fasten.scad')

    print_insert = threadedinsert(True, THICK_WALL, 4.0, 5.8)
    scad_render_to_file(print_insert, 'print_insert.scad')

    print_polygonshim = polygonshim(1)
    scad_render_to_file(print_polygonshim, 'polygonshim.scad')

    print_polygonbase = polygonbase(LASER_HEIGHT)
    scad_render_to_file(print_polygonbase, 'polygonbase.scad')

    print_boxmount = boxmount()
    scad_render_to_file(print_boxmount, 'boxmount.scad')

    mirror_mount_down = mirrormount(True, LASER_HEIGHT)
    mirror_mount_down += back(20)(cube([30, 50, 2]))
    scad_render_to_file(mirror_mount_down, 'mirror_mount_down.scad')

    topdownr = topbox(True, False)
    scad_render_to_file(topdownr, 'topboxdown.scad')

    topupr = topbox(False, False)
    scad_render_to_file(topupr, 'topboxup.scad')

    top_height = 4  # top height screw in mm
    top_r = 3.5  # top r screw in mm for screw head
    shaft_r = 2  # screw radius
    offset = 5
    screw_length = THICK_WALL + offset

    print_hscrew = hscrew(top_r, top_height, shaft_r, 5 + THICK_WALL)
    scad_render_to_file(print_hscrew, 'hscrew.scad')

    print_xulabase = xulaconnector()
    scad_render_to_file(print_xulabase, "xulabase.scad")
    # logo = createlogo()
    # scad_render_to_file(logo, 'logo.scad')

    panelmountr = panelmountmini()
    scad_render_to_file(panelmountr, 'panelmountmini.scad')

    onderkantdown = onderkantbox(True)
    scad_render_to_file(onderkantdown, 'onderkantdown.scad')

    onderkantup = onderkantbox(False)
    scad_render_to_file(onderkantup, 'onderkantup.scad')
Пример #20
0
def holes():
    return spu.back(40.)(drilled_hole.projection(10.)),
Пример #21
0
def top_clipper():
    return back(SHIFTINESS)(grounded_cube([2 * PLATTER_WIDTH, PLATTER_LENGTH, HOLE_HEIGHT]))
def function_row(width_units,
                 wall_height=default_wall_height,
                 margin_length=0,
                 margin_width=0):
    x_grid_size = mount_width + switch_spacing
    y_grid_size = mount_length + switch_spacing

    case = key_grid_tester(
        1,
        width_units,
        wall_height=wall_height,
        margin_length=margin_length,
        margin_width=margin_width,
    )

    wall_length, wall_width = key_grid_tester_wall_dimensions(
        1, width_units, wall_height, margin_length, margin_width)

    board_left = wall_width / 2 - 70
    board_up = 10
    board_forward = wall_length / 2 - wall_thickness

    def position_board(part):
        if 1 == 1:
            return left(board_left)(down(1)(rotate((0, 0, 90))(part)))

        return left(board_left)(up(board_up)(forward(board_forward)(rotate(
            (0, -90, 90))(part))))

    control_box_case, control_box_cutout = control_box(wall_length, wall_width,
                                                       wall_height)

    split_offset = x_grid_size / 2 if width_units % 2 else 0

    def position_mounting_points(part):
        x_offset = wall_width / 2 - wall_thickness
        y_offset = wall_length / 2 - wall_thickness
        return (left(x_offset)(forward(y_offset)(part)) +
                right(x_offset)(forward(y_offset)(part)) +
                left(x_offset)(back(y_offset)(part)) +
                right(x_offset)(back(y_offset)(part)) +
                right(split_offset - wall_thickness)(forward(y_offset)(part)) +
                right(split_offset + wall_thickness)(forward(y_offset)(part)) +
                right(split_offset - wall_thickness)(back(y_offset)(part)) +
                right(split_offset + wall_thickness)(back(y_offset)(part)))

    full_case = (
        case - control_box_cutout + control_box_case -
        left(wall_width / 2 - 20)(cube(
            (15, 1 * y_grid_size * 2, 23 * 2), center=True))
        #- position_board(pro_micro.board_profile(3))
        + position_mounting_points(
            cylinder(wall_thickness * 2 / 3, wall_height, segments=16)) -
        position_mounting_points(down(2)(cylinder_outer(m2_shaft_radius, 10))))

    big_block = cube((200, 200, 200), center=True)

    alignment_tab = cube(
        (wall_thickness, wall_thickness / 2, wall_height - wall_thickness),
        center=True)
    alignment_tabs = right(split_offset)(up(
        (wall_height - wall_thickness) /
        2)(forward(wall_length / 2 - wall_thickness)(alignment_tab) +
           back(wall_length / 2 - wall_thickness)(alignment_tab)))

    return (
        (full_case - right(100 + split_offset)(big_block) + alignment_tabs),
        (full_case - left(100 - split_offset)(big_block) - alignment_tabs),
    )
Пример #23
0
def assembly():
    return sp.rotate((0., 0., 180.))(sp.union()(
        sp.color("red")(spu.up(15.)(light.volume())),
        sp.color("green")(spu.back((light.diameter / 2.) + 9.)(
            mount.volume())),
    ))
Пример #24
0
                        end_comment='[45:90]')
v.screw_head_radius = s.var(4,
                            comment='Radius of hole to fix screw length.',
                            end_comment='[2:4.5]')
v.screw_radius = s.var(2,
                       comment='Radius of screw thread.',
                       end_comment='[1:4.5]')
v.screw_length = s.var(10,
                       comment='Length of thread to be inside spacer.',
                       end_comment='[3:45]')
v.head_hole_height = s.var('spacer_height - screw_length')

body = s.cube(size=[spacer_depth, spacer_width, v.spacer_height])

slot = u.up(3)(s.cube(size=[spacer_depth, 10, 2]))
slot_round = u.back(1)(u.up(2)(s.rotate(a=v.spacer_height, v=[1, 0, 0])(
    s.cube(size=[spacer_depth, 4, 4]))))

screw_hole = u.forward(
    5)(s.cylinder(r=v.screw_head_radius, h=v.head_hole_height, segments=32) +
       u.up(v.head_hole_height)
       (s.cylinder(r=v.screw_radius, h=v.screw_length, segments=32)))

screw_hole_1 = u.right(screw_offset)(screw_hole)
screw_hole_2 = u.right(screw_offset_2)(screw_hole)

wire_run = u.up(20)(s.cube(size=[spacer_depth, 4, 9]))

final = body - slot - slot_round - screw_hole_1 - screw_hole_2 - wire_run

s.scad_render_to_file(final, __file__.replace('.py', '.scad'), variables=v)
Пример #25
0
 def posts(self):
     post = cylinder(r=self.crown_radius, h=self.post_height, segments=16)
     post_pair = forward(self.wall_y_offset)(post) + back(
         self.wall_y_offset)(post)
     return left(self.wall_x_offset)(post_pair) + right(
         self.wall_x_offset)(post_pair)
Пример #26
0
 def back_wall(self):
     return back(self.wall_y_offset)(self.main_wall())
Пример #27
0
                            comment='Radius of hole to fix screw length.',
                            end_comment='[2:4.5]')
v.screw_radius = s.var(2,
                       comment='Radius of screw thread.',
                       end_comment='[1:4.5]')
v.screw_length = s.var(10,
                       comment='Length of thread to be inside spacer.',
                       end_comment='[3:45]')
v.head_hole_height = s.var('spacer_height - screw_length')

body = s.cube(size=[spacer_depth, spacer_width, v.spacer_height])

slot = u.up(3)(s.cube(size=[spacer_depth, 10, 2]))
slot_round = u.back(1)(u.up(2)(
    s.rotate(a=v.spacer_height, v=[1, 0, 0])(
        s.cube(size=[spacer_depth, 4, 4])
    )
))


screw_hole = u.forward(5)(
    s.cylinder(r=v.screw_head_radius, h=v.head_hole_height, segments=32) +
    u.up(v.head_hole_height)(
        s.cylinder(r=v.screw_radius, h=v.screw_length, segments=32)
    )
)

screw_hole_1 = u.right(screw_offset)(screw_hole)
screw_hole_2 = u.right(screw_offset_2)(screw_hole)

wire_run = u.up(20)(s.cube(size=[spacer_depth, 4, 9]))
Пример #28
0
 def back(self, d: float) -> "SolidBuilder":
     self._center_y -= d
     self._origin_y -= d
     self._oso = back(d)(self._oso)
     return self
Пример #29
0
def toothpaste_key():
    non_lettering = back(1 * mm)(key_shaft()) + key_handle()
    if DO_SMUDGE:
        non_lettering = smudge(SMUDGE, non_lettering)
    key = up(THICKNESS / 2)(non_lettering + key_lettering())
    return rotate(-90, [0, 0, 1])(key)
Пример #30
0
def projection():
    return spu.back(y_offset)(plate.projection(size)) - common.bearing_holes()