Gallery

Articulated objects

Objects whose parts move, each one program. Pick one on the left, press Play, or move a joint with its slider; click a part to light the code that builds it. The joints are the ones the program declares with joint; export writes them to GLB, URDF and USD.

drag to turn · scroll to zoom · click a part
1"""A front-loading washing machine, articulated: what #82's vocabulary writes in one piece.2 3Millimetres; the front looks +X, Z up. Four joints, each on a frame read on the cabinet:4the door centred on the porthole, hinged at its outer -Y edge so that it clears the5cabinet (it opens outward about "-Z", 0–143°), the drum endless about the front's6normal, the detergent drawer sliding out 0–200 mm, the dial endless. The drawer's bay and the dial's seat are cut by `seat`, as they sit at rest;7the door's glass is seated in a groove of its ring. Built at rest; `washer_open()` poses it.8"""9import sand3d as s3d10 11 12def washer(w=600, d=600, h=850, porthole=440, door_d=480, drum_d=420):13    cab = s3d.box("cabinet", w, d, h)14    s3d.fillet(cab, 12, edges="side")15    front = cab.face("+X")                                             # X is +Y, Y is up16    s3d.pocket(cab, s3d.circle(porthole), d - 100, on=front.move(0, 400))17    s3d.material(cab, "plastic", color="#f2f2f0")18 19    back = front.move(0, 400).offset(-(d - 200))                     # a solid's height runs along its frame's normal20    drum = s3d.at(s3d.cylinder("drum", drum_d, d - 220), on=back)21    s3d.cut(drum, s3d.at(s3d.cylinder("bore", drum_d - 20, d - 229), on=back.offset(10)))22    s3d.join(drum, s3d.at(s3d.cylinder("axle", 40, 60), on=back.offset(-60)))23    s3d.material(drum, "brushed_steel")24 25    ring = s3d.at(s3d.tube("ring", door_d, 300, 45), on=front.move(0, 400))  # centred on the porthole26    glass = s3d.at(s3d.cylinder("glass", 320, 16), on=front.move(0, 400).offset(14))27    hinge = front.move(-door_d / 2, 400).offset(45)                    # the ring's outer -Y edge: it clears the cabinet28    s3d.seat(ring, glass)29    s3d.material(ring, "painted_metal", color="#3a3d42")30    s3d.material(glass, "glass", color="#cfe3e6", opacity=0.4)31    handle = s3d.at(s3d.box("handle", 24, 110, 30), on=s3d.bbox(ring, "+X").move(x=door_d / 2 - 40))32    door = s3d.group("door", ring, glass, handle)                      # the handle and the glass move with it33 34    top_band = front.move(0, h - 75)35    drawer = s3d.at(s3d.box("drawer", 200, 100, 231), on=top_band.move(150).offset(-230))36    s3d.join(drawer, s3d.at(s3d.box("drawer_front", 220, 120, 15), on=top_band.move(150)))37    s3d.seat(cab, drawer)38    dial = s3d.at(s3d.cylinder("dial", 60, 30), on=top_band.move(-150).offset(-10))39    s3d.seat(cab, dial)40    s3d.material([drawer, dial], "plastic", color="#e6e6e3")41 42    s3d.joint("door_hinge", door, hinge, axis="-Z", range=(0, 143))43    s3d.joint("drum_spin", drum, front.move(0, 400), kind="continuous")44    s3d.joint("drawer_slide", drawer, top_band.move(150), kind="prismatic", axis="+X", range=(0, 200))45    s3d.joint("dial_turn", dial, top_band.move(-150), kind="continuous")46    return s3d.assembly("washing_machine", cab, drum, door, drawer, dial, front=front)47 48 49def washer_open():50    machine = washer()51    s3d.pose(machine, 92, joint="door_hinge")52    s3d.pose(machine, 120, joint="drawer_slide")53    s3d.pose(machine, 30, joint="dial_turn")54    return machine

54 lines · 1038 tokens (o200k_base)

The washing machine is sand3d's own. The other objects are sand3d rewrites of records of Articraft-10K (Zhou et al., arXiv 2605.15187), CC BY 4.0.

sand3d 1.6.2 · generated by tools/quickstart from the code it shows Sandflow