コード例 #1
0
def scaledipad(x, y, height):
    """Returns an instance of the iPad scaled to have x, y mm extra size, at height"""
    xscale = (IPAD_W + x) / IPAD_W
    yscale = (IPAD_H + y) / IPAD_H
    print(xscale, yscale)
    o = linear_extrude(height)(polygon(IPAD_POINTS))
    return scale([xscale, yscale, 1])(o)
コード例 #2
0
 def test_fillet_2d_add(self):
     pts = [[0, 5], [5, 5], [5, 0], [10, 0], [10, 10], [0, 10], ]
     p = polygon(pts)
     three_points = [euclidify(pts[0:3], Point2)]
     actual = fillet_2d(three_points, orig_poly=p, fillet_rad=2, remove_material=False)
     expected = 'union(){polygon(points=[[0,5],[5,5],[5,0],[10,0],[10,10],[0,10]]);translate(v=[3.0000000000,3.0000000000]){difference(){intersection(){rotate(a=359.9000000000){translate(v=[-998,0,0]){square(center=false,size=[1000,1000]);}}rotate(a=450.1000000000){translate(v=[-998,-1000,0]){square(center=false,size=[1000,1000]);}}}circle(r=2);}}}'
     self.assertEqualOpenScadObject(expected, actual)
コード例 #3
0
ファイル: test_utils.py プロジェクト: imanyakin/SolidPython
    def test_fillet_2d_remove(self):
        pts = list((project_to_2D(p) for p in tri))
        poly = polygon(euc_to_arr(pts))
        newp = fillet_2d([pts], orig_poly=poly, fillet_rad=2, remove_material=True)
        expected = 'difference(){polygon(paths=[[0,1,2]],points=[[0,0],[10,0],[0,10]]);translate(v=[5.1715728753,2.0000000000]){difference(){intersection(){rotate(a=-90.1000000000){translate(v=[-998,0,0]){square(center=false,size=[1000,1000]);}}rotate(a=45.1000000000){translate(v=[-998,-1000,0]){square(center=false,size=[1000,1000]);}}}circle(r=2);}}}'
        actual = scad_render(newp)

        self.assertEqualNoWhitespace(expected, actual)
コード例 #4
0
 def test_imported_scad_arguments(self):
     include_file = self.expand_scad_path("examples/scad_to_include.scad")
     mod = import_scad(include_file)
     points = mod.scad_points();
     poly = polygon(points);
     actual = scad_render(poly);
     abs_path = points._get_include_path(include_file)
     expected = f'use <{abs_path}>\n\n\npolygon(points = scad_points());'
     self.assertEqual(expected, actual)
コード例 #5
0
ファイル: test_utils.py プロジェクト: yaohuic/SolidPython
    def test_fillet_2d_remove(self):
        pts = tri
        poly = polygon(euc_to_arr(tri))

        newp = fillet_2d(tri,
                         orig_poly=poly,
                         fillet_rad=2,
                         remove_material=True)
        expected = '\n\ndifference() {\n\tpolygon(paths = [[0, 1, 2]], points = [[0, 0, 0], [10, 0, 0], [0, 10, 0]]);\n\ttranslate(v = [5.1715728753, 2.0000000000, 0.0000000000]) {\n\t\tdifference() {\n\t\t\tintersection() {\n\t\t\t\trotate(a = 268.0000000000) {\n\t\t\t\t\ttranslate(v = [-998, 0, 0]) {\n\t\t\t\t\t\tsquare(center = false, size = [1000, 1000]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trotate(a = 407.0000000000) {\n\t\t\t\t\ttranslate(v = [-998, -1000, 0]) {\n\t\t\t\t\t\tsquare(center = false, size = [1000, 1000]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcircle(r = 2);\n\t\t}\n\t}\n}'
        actual = scad_render(newp)
        if expected != actual:
            print(''.join(difflib.unified_diff(expected, actual)))
        self.assertEqual(expected, actual)
コード例 #6
0
ファイル: koch.py プロジェクト: yaohuic/SolidPython
def main(out_dir):
    # Parameters
    height_ratio = 0.25
    left_loc = ONE_THIRD
    midpoint_loc = 0.5
    right_loc = 2 * ONE_THIRD
    gens = 5

    # Results
    all_polys = union()

    # setup
    ax, ay = 0, 0
    bx, by = 100, 0
    cx, cy = 50, 86.6
    base_seg1 = LineSegment2(Point2(ax, ay), Point2(cx, cy))
    base_seg2 = LineSegment2(Point2(cx, cy), Point2(bx, by))
    base_seg3 = LineSegment2(Point2(bx, by), Point2(ax, ay))
    generations = [[base_seg1, base_seg2, base_seg3]]

    # Recursively generate snowflake segments
    for g in range(1, gens):
        generations.append([])
        for seg in generations[g - 1]:
            generations[g].extend(
                kochify(seg, height_ratio, left_loc, midpoint_loc, right_loc))

    # # Put all generations into SCAD
    orig_length = abs(generations[0][0])
    for g, a_gen in enumerate(generations):
        points = [s.p1 for s in a_gen]

        # Just use arrays for points so SCAD understands
        points = [[p.x, p.y] for p in points]

        # Move each generation up in y so it doesn't overlap the others
        h = orig_length * 1.5 * g

        # Do the SCAD
        edges = [list(range(len(points)))]
        all_polys.add(forward(h)(polygon(points=points, paths=edges)))

    file_out = scad_render_to_file(all_polys,
                                   out_dir=out_dir,
                                   include_orig_code=True)
    print(f"{__file__}: SCAD file written to: {file_out}")
コード例 #7
0
ファイル: test_utils.py プロジェクト: yaohuic/SolidPython
 def test_fillet_2d_add(self):
     pts = [
         [0, 5],
         [5, 5],
         [5, 0],
         [10, 0],
         [10, 10],
         [0, 10],
     ]
     p = polygon(pts)
     newp = fillet_2d(euclidify(pts[0:3], Point3),
                      orig_poly=p,
                      fillet_rad=2,
                      remove_material=False)
     expected = '\n\nunion() {\n\tpolygon(paths = [[0, 1, 2, 3, 4, 5]], points = [[0, 5], [5, 5], [5, 0], [10, 0], [10, 10], [0, 10]]);\n\ttranslate(v = [3.0000000000, 3.0000000000, 0.0000000000]) {\n\t\tdifference() {\n\t\t\tintersection() {\n\t\t\t\trotate(a = 358.0000000000) {\n\t\t\t\t\ttranslate(v = [-998, 0, 0]) {\n\t\t\t\t\t\tsquare(center = false, size = [1000, 1000]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trotate(a = 452.0000000000) {\n\t\t\t\t\ttranslate(v = [-998, -1000, 0]) {\n\t\t\t\t\t\tsquare(center = false, size = [1000, 1000]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcircle(r = 2);\n\t\t}\n\t}\n}'
     actual = scad_render(newp)
     self.assertEqual(expected, actual)
コード例 #8
0
def threadedinsert(flip_x, thick, holesize, length):
    """insert
    heatpress insert

    Heatpress can be inserted from the top. The screw should also be inserted
    from the top. The screw is centered at the origin.
    The wall thickness are specified by;
    http://uk.farnell.com/tr-fastenings-brass-inserts-for-plastics
    The length and hole size should be obtained from the sheet.
    this threaded is supported by a triangle and can be mirrored in the
    x-direction
    :param flip_x: flip insert in, origin shifted back
    :param length: length of the insert
    :param holesize: diameter of the hole
    """
    # NOTE: other options
    # -sliding ; this results in a cable collision
    # -press insert; more recommended for photopolymer parts, less permanent
    # -bolt printed inside; requires print pause, not useful in production
    # -magnet; magnets are dangerous for electronics
    x_extent = holesize + 2 * thick
    y_extent = holesize / 2 + thick + SCREW_FIXOFFST
    base = cube([x_extent, y_extent, length])
    triangle = polygon([[0, 0], [y_extent, y_extent], [0, y_extent]])
    prism = linear_extrude(x_extent)(triangle)
    support = translate([x_extent, y_extent, 0])(rotate([90, 0, -90])(prism))
    base = support + up(y_extent)(base)
    base -= translate([holesize / 2 + thick, holesize / 2 + thick,
                       0])(cylinder(h=length + y_extent,
                                    r=holesize / 2,
                                    segments=30))
    # changed orientation to simplify placement
    base = down(y_extent + length)(base)
    # center origin at Z-axis
    base = translate(
        [-x_extent / 2, -SCREW_FIXOFFST + thick + holesize / 2, 0])(base)
    if flip_x:
        base = rotate([0, 0, 180])(base)
    return base
コード例 #9
0
def ipadcorner(height=7.2):
    """Returns a 15x15mm corner of the ipad at mm height"""
    o = linear_extrude(height)(polygon(IPAD_CORNER))
    return o
コード例 #10
0
def ipadminiholderfront():
    # Back (wall mount)
    # o = sizedipad(IPAD_W + WALL * 2 + SLIP * 2, IPAD_H + WALL * 2 + SLIP * 2, BACK)
    o = union()
    # Front supports
    o += sizedipad(
        TOTAL_W,
        IPAD_H + WALL * 2 + SLIP * 2 + INNER_WALL + WALL_PADDING,
        IPAD_D + WALL + SLIP + BACK,
    )

    sides = WALL + INNER_WALL + WALL_PADDING + SLIP

    # Cutouts for buttons, round curves around the button
    o -= translate([
        IPAD_W + WALL + SLIP * 2 + INNER_WALL + WALL_PADDING - BUTTON_D / 2 -
        BUTTON_TO_EDGE,
        (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING,
        BACK,
    ])(cylinder(d=BUTTON_D, h=50))
    o -= translate([
        sides + SCREEN_SIDE_EDGE - SCREEN_BORDER + IPAD_W -
        (SCREEN_SIDE_EDGE - SCREEN_BORDER) * 2 + BUTTON_D / 2,
        (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING +
        BUTTON_D,
        BACK,
    ])(difference()(
        translate([-BUTTON_D, -BUTTON_D, 0])(cube([BUTTON_D, BUTTON_D, 50])),
        cylinder(d=BUTTON_D, h=50),
    ))
    o -= translate([
        sides + SCREEN_SIDE_EDGE - SCREEN_BORDER + IPAD_W -
        (SCREEN_SIDE_EDGE - SCREEN_BORDER) * 2 + BUTTON_D / 2,
        (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING -
        BUTTON_D,
        BACK,
    ])(difference()(
        translate([-BUTTON_D, 0, 0])(cube([BUTTON_D, BUTTON_D, 50])),
        cylinder(d=BUTTON_D, h=50),
    ))
    # Camera
    o -= translate([
        sides + BUTTON_TO_EDGE + BUTTON_D / 2,
        (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING,
        BACK,
    ])(cylinder(d=BUTTON_D, h=50))
    o -= translate([
        sides + SCREEN_SIDE_EDGE - SCREEN_BORDER - BUTTON_D / 2,
        (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING +
        BUTTON_D,
        BACK,
    ])(difference()(
        translate([0, -BUTTON_D, 0])(cube([BUTTON_D, BUTTON_D, 50])),
        cylinder(d=BUTTON_D, h=50),
    ))
    o -= translate([
        sides + SCREEN_SIDE_EDGE - SCREEN_BORDER - BUTTON_D / 2,
        (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING -
        BUTTON_D,
        BACK,
    ])(difference()(
        translate([0, 0, 0])(cube([BUTTON_D, BUTTON_D, 50])),
        cylinder(d=BUTTON_D, h=50),
    ))

    # # Camera
    # o -= translate([WALL + SIDE_EDGE / 2, (IPAD_H + WALL * 2 + SLIP * 2) / 2, BACK])(
    #     cylinder(d=BUTTON_D, h=50)
    # )

    # Cutout for actual iPad, made very tall to allow sliding in/out
    if ALLOW_IPAD_SLIDE_IN:
        height = IPAD_H * 2 + INNER_WALL + WALL_PADDING
    else:
        height = IPAD_H + INNER_WALL * 2 + WALL_PADDING
    o -= translate([WALL, WALL, -1])(sizedipad(
        IPAD_W + SLIP * 2 + INNER_WALL * 2 + WALL_PADDING * 2,
        height,
        IPAD_D + SLIP + BACK + 1,
    ))
    # Cutout for remaining material around where the extra overhang is for the power
    # connector
    o -= translate([WALL, WALL, -1])(sizedipad(
        TOTAL_W - WALL * 2,
        IPAD_H + INNER_WALL * 2 + WALL_PADDING,
        IPAD_D + SLIP + BACK + 1,
    ))
    # Cutout for screen
    o -= translate([
        sides + SCREEN_SIDE_EDGE - SCREEN_BORDER,
        sides + SCREEN_BOTTOM_EDGE - SCREEN_BORDER,
        BACK,
    ])(cube([
        IPAD_W - (SCREEN_SIDE_EDGE - SCREEN_BORDER) * 2,
        IPAD_H - (SCREEN_BOTTOM_EDGE - SCREEN_BORDER) * 2,
        IPAD_D * 3,
    ]))
    # Side "hooks"
    o += translate([WALL, (IPAD_H - 15 * 2) + 15, 0])(rotate([90, 0, 0])(
        linear_extrude(IPAD_H - 15 * 2)(polygon([[0, 0], [1, 0], [0, 1]]))))
    o += translate([TOTAL_W - WALL * 2 + WALL, 15, 0])(rotate([-90, 180, 0])(
        linear_extrude(IPAD_H - 15 * 2)(polygon([[0, 0], [1, 0], [0, 1]]))))
    o += translate([
        (TOTAL_W - 15 * 2) + 15, WALL, 0
    ])(rotate([0, -90, 0])(linear_extrude(TOTAL_W - 15 * 2)(polygon([[0, 0],
                                                                     [1, 0],
                                                                     [0,
                                                                      1]]))))
    # o += translate([15, WALL, 0])(cube([IPAD_W - 15 * 2, WALL, WALL]))

    # Power connector
    if POWER_CONNECTOR_ACCESSIBLE:
        o -= translate([
            IPAD_W / 2,
            (IPAD_H + WALL * 2 + SLIP * 2) / 2 + INNER_WALL + WALL_PADDING -
            POWER_UNDERHANG - BUTTON_D / 2,
            -1,
        ])(cube([IPAD_W, BUTTON_D + POWER_UNDERHANG,
                 IPAD_D + SLIP + BACK + 1]))

    # Lock Button
    if ALLOW_IPAD_SLIDE_IN:
        extra = 100
    else:
        extra = 0
    o -= translate([
        -1,
        (IPAD_H + WALL * 2 + SLIP * 2) - LOCK_BUTTON_TO_EDGE -
        LOCK_BUTTON_LEN + INNER_WALL + WALL_PADDING,
        0,
    ])(cube([50, LOCK_BUTTON_LEN + extra, IPAD_D + SLIP + BACK]))

    # Screws
    o -= screws()

    if SHOW_IPAD:
        o += translate([
            WALL + INNER_WALL + SLIP + WALL_PADDING,
            WALL + INNER_WALL + SLIP + WALL_PADDING,
            BACK,
        ])(IPAD_STL).set_modifier("")

    return o
コード例 #11
0
def main(params: Params):
    # face
    face_profile = roundrect(
        [LGX_FACE_WIDTH, LGX_FACE_HEIGHT + params.lgx_face_extra_height],
        params.face_radius,
    )
    cutout_profile = roundrect([params.poe_face_width, params.poe_face_height],
                               params.poe_face_radius)
    cutout_x = LGX_FACE_WIDTH / 2 - params.poe_face_width / 2
    cutout_y = params.poe_face_lift + params.platform_thickness
    cutout = translate([cutout_x, cutout_y, 0])(cutout_profile)
    cutout_extrude = debug(
        down(params.lgx_rack_thickness)(
            linear_extrude(params.face_thickness +
                           params.lgx_rack_thickness)(cutout)))

    post = circle(d=params.face_post_d)
    posts = post + right(params.face_post_separation)(post)
    posts = translate([
        LGX_FACE_WIDTH / 2 - params.face_post_separation / 2,
        LGX_FACE_HEIGHT / 2, 0
    ])(posts)

    face = difference()(face_profile, posts)
    face_extrusion = linear_extrude(height=params.face_thickness)(face)

    tray_depth = (params.platform_thickness + params.poe_depth +
                  params.lgx_rack_thickness)

    # tray
    tray = linear_extrude(height=params.platform_thickness)(
        square(size=[LGX_PLATFORM_WIDTH, tray_depth]))

    poe_holder_outer_params = [
        params.poe_width + params.platform_thickness * 2,
        tray_depth,
    ]
    poe_holder_profile = difference()(
        square(poe_holder_outer_params),
        right(params.platform_thickness)(forward(params.lgx_rack_thickness)(
            square([
                params.poe_width,
                params.poe_depth,
            ]))),
    )
    poe_holder_extrude = linear_extrude(
        height=params.poe_retainer_height)(poe_holder_profile)
    poe_holder = translate([
        LGX_PLATFORM_WIDTH / 2 - poe_holder_outer_params[0] / 2,
        0,
        params.platform_thickness,
    ])(poe_holder_extrude)

    tray = union()(poe_holder, tray)
    tray = rotate([270, 0, 0])(translate(
        [LGX_FACE_WIDTH / 2 - LGX_PLATFORM_WIDTH / 2, 0, 0])(tray))

    # support
    support_start_inset = (params.platform_thickness + LGX_FACE_WIDTH / 2 -
                           LGX_PLATFORM_WIDTH / 2)
    point_extent = LGX_FACE_HEIGHT - params.platform_thickness
    support_profile = polygon([[0, 0], [0, point_extent], [point_extent, 0]])
    support = linear_extrude(height=params.platform_thickness)(support_profile)
    support = rotate([270, 0, 90])(support)
    support_left = translate([support_start_inset, 0, 0])(support)
    support_right = translate([
        support_start_inset + LGX_PLATFORM_WIDTH - params.platform_thickness,
        0, 0
    ])(support)

    return difference()(union()(face_extrusion, tray, support_left,
                                support_right), cutout_extrude)