cassetta_atrezzi_auto/cassetta_atrezzi_auto.py
  1from cadquery import Assembly, Workplane, Color, Vertex, Vector
  2from cadquery.selectors import AreaNthSelector
  3
  4BOX_LENGTH = 240
  5BOX_WIDTH = 180
  6BOX_DEPTH = 20
  7BORDER_RADIUS = 20
  8CHAMFER_SIZE = 2
  9WALL_THICKNESS = 2
 10EDGE_DEPTH = 5
 11REINFORCEMENT_WIDTH = 20
 12TOL = 0.001
 13
 14
 15def box_walls(
 16    length: float,
 17    width: float,
 18    depth: float,
 19    border_radius: float,
 20    thickness: float = 0,
 21    chamfer_size: float = 0,
 22) -> Workplane:
 23    box = Workplane("XY").box(length, width, depth).edges("|Z").fillet(border_radius)
 24    if chamfer_size > 0:
 25        box = box.edges("<Z").chamfer(chamfer_size)
 26    if thickness > 0:
 27        box = box.faces(">Z").shell(-thickness)
 28    return box
 29
 30
 31def box_edge(
 32    length: float,
 33    width: float,
 34    depth: float,
 35    thickness: float,
 36    border_radius: float,
 37    chamfer_size: float,
 38    inset_depth: float = 2,
 39) -> Workplane:
 40    inset = (
 41        Workplane("XY")
 42        .box(length + chamfer_size, width + chamfer_size, inset_depth)
 43        .edges("|Z")
 44        .fillet(border_radius + chamfer_size)
 45        .faces(">Z or <Z")
 46        .shell(-thickness)
 47        .translate((0, 0, depth / 2))
 48        .faces("<Z")
 49        .chamfer(thickness / 2 - TOL)
 50    )
 51    return (
 52        Workplane("XY")
 53        .box(length + 2 * chamfer_size, width + 2 * chamfer_size, depth)
 54        .edges("|Z")
 55        .fillet(border_radius + chamfer_size)
 56        .faces(">Z or <Z")
 57        .shell(-(thickness + chamfer_size))
 58        .faces("<Z")
 59        .wires(AreaNthSelector(1))
 60        .chamfer(chamfer_size)
 61        - inset
 62    )
 63
 64
 65def latch_side(depth: float, height: float) -> Workplane:
 66    return (
 67        Workplane("YZ")
 68        .lineTo(0, height)
 69        .lineTo(depth, height)
 70        .radiusArc((0, 0), height)
 71        .close()
 72        .extrude(5)
 73    )
 74
 75
 76def latch_holder(depth: float, height: float) -> Workplane:
 77    return latch_side(depth, height)  # + latch_side().translate((40, 0, 0))
 78
 79
 80def assembly() -> Assembly:
 81    _box_walls = box_walls(
 82        BOX_LENGTH,
 83        BOX_WIDTH,
 84        BOX_DEPTH - EDGE_DEPTH,
 85        BORDER_RADIUS,
 86        WALL_THICKNESS,
 87        CHAMFER_SIZE,
 88    )
 89    _box_edge = box_edge(
 90        BOX_LENGTH,
 91        BOX_WIDTH,
 92        EDGE_DEPTH,
 93        WALL_THICKNESS,
 94        BORDER_RADIUS,
 95        CHAMFER_SIZE,
 96    )
 97    _latch = latch_holder(10, BOX_DEPTH - CHAMFER_SIZE)
 98
 99    front_center = _box_walls.faces(">Y").val().Center()
100    return (
101        Assembly()
102        .add(_box_walls, name="box_walls", color=Color("gray90"))
103        .add(_box_edge, name="box_edge", color=Color("gray70"))
104        # .add(reinforcements, name="reinforcements", color=Color("gray50"))
105        .add(_latch, name="latch", color=Color("gray30"))
106        # Fix edge on top of box
107        .constrain("box_walls@faces@>Z", "box_edge@faces@<Z", "Plane")
108        .constrain("box_edge@faces@<Z", "FixedRotation", (0, 0, 0))
109        # Fix latch-holder on front of box
110        .constrain(
111            "box_walls",
112            Vertex.makeVertex(*front_center + Vector(0, 0, EDGE_DEPTH)),
113            "latch",
114            _latch.faces("<Y").val(),
115            "Point",
116        )
117        .constrain("box_walls@faces@>Y", "latch@faces@<Y", "Plane")
118        .constrain("latch@faces@<Y", "FixedRotation", (0, 0, 0))
119        .solve()
120    )
121
122
123bottom_part = assembly()