Esempio n. 1
0
def asm_data():
    """ provides a tuple of assembly and corresponding shape (generated explicitly) """
    n = 3
    y_spacing = 2.5

    s = data.bin_counter(0).extruded(0.1)
    row_parts = [s.make_part("shape_0").translated_x(0.5)]
    row_shapes = [s.translated_x(0.5)]

    for i in range(1, n + 1):
        s = data.bin_counter(i).extruded(0.1)

        row_parts.append(
            codecad.assembly(
                "row_{}".format(i),
                [
                    row_parts[-1],
                    s.make_part("shape_{}".format(i)).translated_x(0.5 + 2 * i),
                ],
            )
        )
        row_shapes.append(row_shapes[-1] + s.translated_x(0.5 + 2 * i))

    assembly = codecad.assembly(
        "test_assembly",
        [row.translated_y(i * y_spacing) for i, row in enumerate(row_parts)],
    )
    shape = codecad.shapes.union(
        [row.translated_y(i * y_spacing) for i, row in enumerate(row_shapes)]
    )

    assembly = assembly.rotated_x(90)
    shape = shape.rotated_x(90)

    return n, assembly, shape
Esempio n. 2
0
def asm_data():
    """ provides a tuple of assembly and corresponding shape (generated explicitly) """
    n = 3
    y_spacing = 2.5

    s = data.bin_counter(0).extruded(0.1)
    row_parts = [s.make_part("shape_0").translated_x(0.5)]
    row_shapes = [s.translated_x(0.5)]

    for i in range(1, n + 1):
        s = data.bin_counter(i).extruded(0.1)

        row_parts.append(
            codecad.assembly(
                "row_{}".format(i),
                [
                    row_parts[-1],
                    s.make_part(
                        "shape_{}".format(i)).translated_x(0.5 + 2 * i),
                ],
            ))
        row_shapes.append(row_shapes[-1] + s.translated_x(0.5 + 2 * i))

    assembly = codecad.assembly(
        "test_assembly",
        [row.translated_y(i * y_spacing) for i, row in enumerate(row_parts)],
    )
    shape = codecad.shapes.union(
        [row.translated_y(i * y_spacing) for i, row in enumerate(row_shapes)])

    assembly = assembly.rotated_x(90)
    shape = shape.rotated_x(90)

    return n, assembly, shape
Esempio n. 3
0
def test_visible_bom():
    o = codecad.shapes.sphere()
    asm = codecad.assembly(
        "test", [o.make_part("1"), o.make_part("2").hidden()])

    assert len(list(asm.bom())) == 2
    assert len(list(asm.bom(visible_only=True))) == 1
Esempio n. 4
0
def suspension_generator(right,
                         arm_angle=arm_neutral_angle,
                         bogie_angle_fraction=None):
    spring_point = get_spring_point(spring_arm_length,
                                    arm_up_angle - arm_angle)

    v = spring_point.flattened() - spring_anchor_point.flattened()
    length = abs(v)

    spring_degrees = 90 - math.degrees(math.atan2(v.y, v.x))
    spring = vitamins.spring(length)

    degrees = -math.degrees(arm_angle)

    if bogie_angle_fraction is None:
        bogie_degrees = 0
    else:
        low = -bogie_swing_angle + (arm_angle - arm_neutral_angle)
        high = bogie_swing_angle + (arm_angle - arm_neutral_angle)
        bogie_degrees = low + (high - low) * bogie_angle_fraction
        bogie_degrees = math.degrees(bogie_degrees)

    if right:
        arm = arm_right
        bogie = bogie_assembly.rotated_z(180)
        multiplier = 1
    else:
        arm = arm_left.rotated_y(180)
        bogie = bogie_assembly
        multiplier = -1

    asm = codecad.assembly("suspension_assembly_" + ("right" if right else "left"),
                           [arm \
                                .rotated_x(90) \
                                .rotated_y(degrees) \
                                .translated_y(multiplier * arm_base_offset),
                            bogie \
                                .translated_z(-bogie_pivot_z - wheel_diameter / 2) \
                                .rotated_y(-degrees - bogie_degrees) \
                                .translated_x(arm_length) \
                                .rotated_y(degrees) \
                                .translated_y(multiplier * track_offset.y),
                            spring \
                                .rotated_y(spring_degrees) \
                                .translated(spring_anchor_point.x,
                                            multiplier * (spring_anchor_point.z + vitamins.spring.top_mount_thickness / 2),
                                            spring_anchor_point.y),
                            road_wheel_screw,
                            road_wheel_screw.lock_nut,
                            spring_screw,
                            spring_screw.lock_nut,
                            vitamins.shoulder_screw,
                            vitamins.shoulder_screw,
                            vitamins.shoulder_screw.lock_nut,
                            vitamins.shoulder_screw.lock_nut,
                            vitamins.m5x20_screw,
                            vitamins.m5x20_screw.lock_nut,
                            ])

    return asm
Esempio n. 5
0
def track_row(n, modelled_n=1):
    parts = []

    for i in range(modelled_n):
        dist = (i - n / 2 + 0.5) * (segment_length + connector_length)

        conn = track_connector \
            .rotated_x(90) \
            .translated(dist + (segment_length + connector_length) / 2,
                        connector_width / 2,
                        0)

        parts.append(track_segment.translated_x(dist))
        parts.append(conn)
        parts.append(
            conn.translated_y((width - connector_width - clearance) / 2))
        parts.append(
            conn.translated_y(-(width - connector_width - clearance) / 2))

    hidden_n = n - modelled_n

    parts.extend(track_segment.hidden() for i in range(hidden_n))
    parts.extend(track_connector.hidden() for i in range(3 * hidden_n))
    parts.extend(vitamins.nail for i in range(4 * n))

    return codecad.assembly("track_assembly", parts)
Esempio n. 6
0
 def make_assembly(self):
     planet = (self.make_planet().make_part("planet").translated(
         self.planet_radius,
         0,
         self.inner_carrier_half_length - self.sun_thickness,
     ))
     return codecad.assembly(
         "gearbox",
         [
             self.make_carrier_inner().make_part("inner_carrier").rotated_x(
                 180).translated_z(self.inner_carrier_half_length),
             self.make_carrier_outer().make_part("outer_carrier").rotated_x(
                 180).translated_z(self.outer_carrier_length +
                                   self.inner_carrier_half_length),
             self.make_sun().make_part("sun_gear").translated_z(
                 self.inner_carrier_half_length -
                 self.bearing_wall_thickness - 2 * self.clearance -
                 self.sun_thickness - self.motor_gear_thickness),
             self.make_ring().make_part("ring").rotated_x(180).translated_z(
                 self.outer_carrier_length +
                 self.inner_carrier_half_length +
                 self.bearing_wall_thickness + self.clearance),
         ] + [
             planet.rotated_z(i * 360 / self.planet_count)
             for i in range(self.planet_count)
         ],
     )
Esempio n. 7
0
def test_shape_to_assembly():
    shape = codecad.shapes.sphere()
    part = shape.make_part("sphere")
    asm = codecad.assembly("test_asm", [part])

    instances = list(asm.all_instances())
    assert len(instances) == 1
    assert instances[0].part.data is shape
Esempio n. 8
0
def test_shape_to_assembly():
    shape = codecad.shapes.sphere()
    part = shape.make_part("sphere")
    asm = codecad.assembly("test_asm", [part])

    instances = list(asm.all_instances())
    assert len(instances) == 1
    assert instances[0].part.data is shape
Esempio n. 9
0
def tensioner_generator(right,
                        arm_angle=(arm_angle_back + arm_angle_front) / 2):
    spring_point = Vector.polar(
        spring_arm_length, arm_angle + spring_angle_offset) + pivot_position

    v = spring_point.flattened() - spring_anchor_point.flattened()
    length = abs(v)

    spring_degrees = 90 - math.degrees(math.atan2(v.y, v.x))
    spring = vitamins.spring(length)

    if right:
        arm = arm_right
        multiplier = 1
    else:
        arm = arm_left.rotated_y(180)
        multiplier = -1

    arm_angle = -arm_angle

    asm = codecad.assembly("tensioner_assembly_" + ("right" if right else "left"),
                           [arm \
                                .rotated_x(-90) \
                                .rotated_y(180) \
                                .rotated_y(arm_angle) \
                                .translated(pivot_position.x, pivot_position.z, pivot_position.y),
                            wheel_assembly \
                                .translated_y(-arm_width - wheel_clearance) \
                                .rotated_z(90 + 90 * multiplier) \
                                .translated_x(arm_length) \
                                .rotated_y(arm_angle) \
                                .translated(pivot_position.x, pivot_position.z, pivot_position.y),
                            spring \
                                .rotated_y(spring_degrees) \
                                .translated(spring_anchor_point.x,
                                            multiplier * (spring_anchor_point.z + vitamins.spring.top_mount_thickness / 2),
                                            spring_anchor_point.y),
                            wheel_screw,
                            wheel_screw.lock_nut,
                            spring_screw,
                            spring_screw.lock_nut,
                            vitamins.shoulder_screw,
                            vitamins.shoulder_screw.lock_nut,
                            vitamins.m5x20_screw,
                            vitamins.m5x20_screw.lock_nut])

    return asm
Esempio n. 10
0
 def make_assembly(self):
     planet = (
         self.make_planet()
         .make_part("planet")
         .translated(
             self.planet_radius,
             0,
             self.inner_carrier_half_length - self.sun_thickness,
         )
     )
     return codecad.assembly(
         "gearbox",
         [
             self.make_carrier_inner()
             .make_part("inner_carrier")
             .rotated_x(180)
             .translated_z(self.inner_carrier_half_length),
             self.make_carrier_outer()
             .make_part("outer_carrier")
             .rotated_x(180)
             .translated_z(
                 self.outer_carrier_length + self.inner_carrier_half_length
             ),
             self.make_sun()
             .make_part("sun_gear")
             .translated_z(
                 self.inner_carrier_half_length
                 - self.bearing_wall_thickness
                 - 2 * self.clearance
                 - self.sun_thickness
                 - self.motor_gear_thickness
             ),
             self.make_ring()
             .make_part("ring")
             .rotated_x(180)
             .translated_z(
                 self.outer_carrier_length
                 + self.inner_carrier_half_length
                 + self.bearing_wall_thickness
                 + self.clearance
             ),
         ]
         + [
             planet.rotated_z(i * 360 / self.planet_count)
             for i in range(self.planet_count)
         ],
     )
Esempio n. 11
0
#!/usr/bin/env python3

import codecad
import menger_sponge
import cube_thingie
import planetary
import airfoil

o = codecad.assembly(
    "benchmark_assembly",
    [
        planetary.Planetary(
            11, 60, 13, 41, 18,
            53).make_overview().make_part("sliced_gearbox").translated_x(-50),
        cube_thingie.cube_with_base(menger_sponge.sponge(6)).make_part(
            "menger_sponge_statue").translated_x(50),
        airfoil.o.make_part("meshed_airfoil").translated(-120, 0, 100),
    ],
)

if __name__ == "__main__":
    codecad.commandline_render(o)
Esempio n. 12
0
                                   arm_length, vitamins.shoulder_screw.head_diameter, vitamins.shoulder_screw.head_height - wheel_clearance, wheel_clearance,
                                   False) \
    .make_part("outer_tensioner_wheel", ["3d_print"])
arm_left = arm_generator(arm_thickness, arm_pivot_thickness, arm_width, spring_screw.length - vitamins.spring.bottom_mount_thickness,
                         arm_length, spring_arm_length, spring_angle_offset,
                         inner_bearing_height + wheel_clearance, # cone height
                         wheel_diameter, wheel_clearance,
                         vitamins.shoulder_screw.diameter2 + pivot_round_clearance,
                         wheel_bearing, wheel_screw,
                         spring_screw) \
    .make_part("tensioner_arm_left", ["3d_print"])
arm_right = arm_left.shape().mirrored_x().make_part("tensioner_arm_right",
                                                    ["3d_print"])

wheel_assembly = codecad.assembly("tensioner_wheel_assembly", [
    inner_wheel_half.rotated_x(90),
    outer_wheel_half.rotated_x(-90).translated_y(-suspension.wheel_width)
] + [wheel_bearing] * 2)


def tensioner_generator(right,
                        arm_angle=(arm_angle_back + arm_angle_front) / 2):
    spring_point = Vector.polar(
        spring_arm_length, arm_angle + spring_angle_offset) + pivot_position

    v = spring_point.flattened() - spring_anchor_point.flattened()
    length = abs(v)

    spring_degrees = 90 - math.degrees(math.atan2(v.y, v.x))
    spring = vitamins.spring(length)

    if right:
Esempio n. 13
0
Only has one face and one edge. """

import codecad
from codecad.shapes import *

minor_r = 15
major_r = 25
pin_d = 1.75
pin_h = 10
second_pin_angle = 170  # Not 180 degrees to have only one way to assemble

mp = regular_polygon2d(5, r=minor_r).revolved(r=major_r, twist=360 / 5)

pin_hole = cylinder(d=1.1 * pin_d, h=1.2 * pin_h).rotated_x(90).translated_x(major_r)
mp -= pin_hole
mp -= pin_hole.rotated_y(second_pin_angle)

half1 = (mp & half_space()).rotated_x(90).make_part("half1")
half2 = (mp - half_space()).rotated_x(-90).make_part("half2")

pin = cylinder(d=pin_d, h=pin_h, symmetrical=False).make_part("pin")
pin = pin.translated_z(-pin_h / 2).translated_x(major_r)

asm = codecad.assembly(
    "moebius_pentagon",
    [half1, half2.rotated_x(180), pin, pin.rotated_z(second_pin_angle)],
)

if __name__ == "__main__":
    codecad.commandline_render(asm)
Esempio n. 14
0
def test_visible_bom():
    o = codecad.shapes.sphere()
    asm = codecad.assembly("test", [o.make_part("1"), o.make_part("2").hidden()])

    assert len(list(asm.bom())) == 2
    assert len(list(asm.bom(visible_only=True))) == 1
Esempio n. 15
0
    arm_clearance,
    vitamins.shoulder_screw.diameter2 + pivot_round_clearance,
    3 * parameters.extrusion_width,
    6 * parameters.extrusion_width,
    parameters.layer_height,
).make_part("suspension_arm_right", ["3d_print"])
arm_left = arm_right.shape().mirrored_x().make_part("suspension_arm_left",
                                                    ["3d_print"])

bogie_assembly = codecad.assembly(
    "bogie_assembly", [
        bogie.translated_z(wheel_diameter / 2),
        inner_road_wheel.rotated_x(90).translated(
            bogie_wheel_spacing / 2, wheel_width / 2, wheel_diameter / 2),
        inner_road_wheel.rotated_x(90).translated(
            -bogie_wheel_spacing / 2, wheel_width / 2, wheel_diameter / 2),
        outer_road_wheel.rotated_x(-90).translated(
            bogie_wheel_spacing / 2, -wheel_width / 2, wheel_diameter / 2),
        outer_road_wheel.rotated_x(-90).translated(
            -bogie_wheel_spacing / 2, -wheel_width / 2, wheel_diameter / 2)
    ] + [vitamins.small_bearing] * 4 +
    [road_wheel_screw, road_wheel_screw.lock_nut] * 2 + [vitamins.o_ring] * 8)

# Y offset of a right suspension arm base in an assembly.
arm_base_offset = pivot_guide_length + pivot_screw_head_countersink

# Ofset for matching a piece of track with right suspension assembly
track_offset = Vector(
    arm_length * math.cos(arm_neutral_angle), arm_base_offset - arm_width / 2,
    arm_length * math.sin(arm_neutral_angle) - bogie_pivot_z -
    wheel_diameter / 2)
Esempio n. 16
0
    return shaft


gear_shaft2_spline = tools.spline(20)
shaft2 = shaft2_generator(drive_sprocket.spline, gear_shaft2_spline, 0.05,
                         vitamins.large_bearing,
                         (drive_sprocket.base.total_height + drive_sprocket.base.cone_height) / 2,
                         vitamins.m3x35_screw.diameter,
                         vitamins.m3x35_screw.length - drive_sprocket.center_screw_wall_thickness,
                         vitamins.m3x35_screw.lock_nut.s,
                         vitamins.m3x35_screw.lock_nut.height) \
    .make_part("transmission_shaft2", ["3d_print"])

shaft2_assembly = codecad.assembly("shaft2_assembly", [
    drive_sprocket.drive_sprocket_assembly,
    shaft2.rotated_x(90).translated_y(shaft2.part.data.length),
    vitamins.m3x35_screw, vitamins.m3x35_screw.lock_nut
])

if __name__ == "__main__":
    ratio = 1
    for t1, t2 in transmission_steps:
        assert math.gcd(t1, t2) == 1
        ratio *= t2 / t1

    speed = (motor_max_rpm / 60) * drive_sprocket.circumference / ratio
    print(
        "transmission ratios",
        ", ".join("{}:{}".format(*teeth) for teeth in transmission_steps),
        "({:.1f}:1) -> {:.1f}m/s, {:.1f}km/h".format(ratio, speed / 1000,
                                                     3.6 * speed / 1000))
Esempio n. 17
0
def test_shape_to_assembly_no_part():
    """ Test converting the shape directly to an assembly without making a part of it first.
    This should fail. """
    a = codecad.assembly("X", [codecad.shapes.sphere()])
    with pytest.raises(Exception):
        a.shape()
Esempio n. 18
0
def test_shape_to_assembly_no_part():
    """ Test converting the shape directly to an assembly without making a part of it first.
    This should fail. """
    a = codecad.assembly("X", [codecad.shapes.sphere()])
    with pytest.raises(Exception):
        a.shape()
Esempio n. 19
0
import codecad

import suspension
import drive_sprocket

layout = codecad.assembly("tank_layout_test_assembly", [
    suspension.suspension_assembly_left.hidden(),
    suspension.suspension_assembly_left.translated_x(
        suspension.suspension_spacing).hidden(),
    suspension.suspension_assembly_left.translated_x(
        2 * suspension.suspension_spacing),
    drive_sprocket.drive_sprocket_assembly.rotated_x(-90).translated_x(
        2 * suspension.suspension_spacing + 145)
])

if __name__ == "__main__":
    codecad.commandline_render(layout)
Esempio n. 20
0
#!/usr/bin/env python3

import codecad
import menger_sponge
import cube_thingie
import planetary
import airfoil

o = codecad.assembly(
    "benchmark_assembly",
    [
        planetary.Planetary(11, 60, 13, 41, 18, 53)
        .make_overview()
        .make_part("sliced_gearbox")
        .translated_x(-50),
        cube_thingie.cube_with_base(menger_sponge.sponge(6))
        .make_part("menger_sponge_statue")
        .translated_x(50),
        airfoil.o.make_part("meshed_airfoil").translated(-120, 0, 100),
    ],
)

if __name__ == "__main__":
    codecad.commandline_render(o)
Esempio n. 21
0
                      track.base_thickness, track.connector_length,
                      track.connector_thickness, track.connector_width,
                      track.width, track.guide_width, track.guide_height,
                      track.guide_side_angle, track.clearance)
spline = tools.spline(bearing.id)

inner_sprocket = inner_sprocket_generator(base,
                                          spline, 0.05,
                                          0.1, # Crown tolerance
                                          bearing.shoulder_size,
                                          bearing_shoulder_height + wheel_clearance,
                                          bearing_housing_top_diameter + 2 * wheel_clearance) \
    .make_part("inner_drive_sprocket", ["3d_print"])
outer_sprocket = outer_sprocket_generator(base,
                                          0.1, # Crown tolerance
                                          vitamins.m3x35_screw,
                                          center_screw_wall_thickness,

                                          3 * parameters.extrusion_width) \
    .make_part("outer_drive_sprocket", ["3d_print"])

drive_sprocket_assembly = codecad.assembly("drive_sprocket_assembly", [
    inner_sprocket.rotated_x(90).translated_y(track.width / 2),
    outer_sprocket.rotated_x(-90).translated_y(-track.width / 2)
])

if __name__ == "__main__":
    print("pitch radius", pitch_radius)

    codecad.commandline_render(drive_sprocket_assembly)