Open issues

What the checks do not establish

Library propagation, silhouette checks and the scene's placements do not establish assembled fit or printability: the placements put a module where its opening was cut, not where a printed part lands. The hand-measured battery box clears the casing and the lid since screw 3 moved off it on 2026-10-08 (it reached about 15 mm³ into its bosses). The lid's two battery holders hold its opposite corners, 0.15 mm wider and 0.2 mm longer than the box (until 2026-10-06 their pocket lay 9.5 mm off it); since 2026-10-08 they are children of the battery's helper Lid-Battery-Pos, so the battery moves with them. Where the main board, the bottom module, the power switch or a holder reach into a module's envelope or out of the casing's inner volume, or the board or the module into the lid's parts beside them, or a screw's bosses or hole into any of them or a module's envelope, ./lx mech lid-fit and ./lx mech check print it as a FINDING (the lid's space). Since 2026-10-10 three are films: the main board 0.1 mm³ out of the inner volume the reshaped Casing-Volume-Cut leaves, screw 8's casing boss 0.1 mm³ into the board, and its lid boss 12 mm³ into Lid-Board-Holder, lid material in lid material. They see bare pins: the main board's header pins nearest the finger module stand 4.3 mm under the module's envelope, the switch's 5.0 mm, and the jumper wires and solder joints on them are not modelled. Look at both on the first build. The casing's wall above the lid seat is set by Casing-Volume-Cut, drawn by hand: 3.3–9.7 mm thick against the outer surface, where the rim below it is a constant 2.1 mm at the first layer. Verify evaluated mesh health and re-import an export to measure its units before slicing; test-print critical fits. The original casing has non-manifold seams (the lids export closed since 2026-09-26); the regression baseline is a preservation check, not print approval. The thumb cover has about 200 non-planar n-gons, up to 0.9 mm out of plane (worst near (26.8, −2.6, −7.1) mm), so its left and right STLs triangulate differently and their volumes differ by 18.7 mm³ although the vertices mirror exactly; look at them in a slicer before printing.

Purchased-module geometry (PMW3389 breakout, battery, gyro) is missing or hand-measured; the joystick thumb's stick is drawn from Alps' RKJXV122400R drawing and its dome and cap are built around Alps' 3D model, not a measured hall module (electronics/lib, dimensions.json joystick); the main board and the tower are drawn to be recognized (blender-files), and the EVQWGD001 wheel encoder is drawn from a reference model of unstated origin, not a measured part (electronics/lib). Against it the wheel window clears; the wheel's smooth rims graze two window corners by up to 0.13 mm, between the points CLEAR tests. sourced means traceable to an export, not fit-approved or qualified.

Untested fits

  • Keycap in its cutout: about 0.09 mm of play per side, where a printed sliding fit wants 0.2–0.3 mm (dimensions.json key_grid). No print of it is recorded. Print the Key-Tests coupon in clearance steps and record the result in key_grid.
  • LED plug in its window: Thumb-LED-Plug is meant as a press fit. It is modelled once, at the origin, and place_cover_parts.py places it in each window of both thumb covers (<stem>-led-plugs-placement). Measured against the window in thumb-module.blend (2026-09-27), both 32-gons: the plug is Ø3.34 mm (flats Ø3.32), 3.34 mm long; the window Ø3.50 mm (flats Ø3.48) through the 3.37 mm plate, so 0.07–0.09 mm clearance per side, a snug fit rather than a press fit before the print shrinks the hole. Its ramped tab sits in the window's tab pocket with 0.09–0.16 mm per side, 0.18 mm at the end and 0.25 mm under the pocket's ramp. Pushed in from inside until its bottom is flush with the plate, the plug's top is 0.03 mm below the outer face; nothing stops it there: the tab reaches the pocket after 0.25 mm more, with the top 0.22 mm proud. The 0.30 mm counterbore (Ø3.96) at the window's inner face does not touch the plug, which has no flange; only friction keeps a press on the plug from pushing it inward, toward its LED 5.4 mm below (centred 0.21 mm off the window). Test-print it in clearance steps.
  • The joystick thumb's dome and cap (./lx mech joystick, dimensions.json joystick): the cap's socket fits the lever with 0.05 mm per side, and the dome's two lugs press 0.1 mm into the plate once twisted shut; Alpakka, a printed gamepad on the same Alps stick, needed tight and loose cap variants. Nobody has published wear or noise figures for a printed gate: the cap's neck rides the dome's round gate at every full deflection. Test-print the socket on a sample stick and the twist lock in the cover, then record the results in joystick. Test the right cover's lock as well: it is the left one mirrored and turns the other way. Both modules stay fitted to no slot until a sample stick is checked (decided 2026-10-03), so the scene does not place them yet. Fitting one means teaching assemble.py its part set (left-thumb-module-4-keys-joystick, right-…), beside the side's left-thumb-module.
  • The second LED window is off its LED: the two windows are mirrored about the thumb module's origin, the two LEDs are not. On both hands the window over LED1 is 0.21 mm from its centre, the one over LED2 1.83 mm (./lx mech check prints it as a FINDING). Decide whether that window moves onto LED2, or whether 1.83 mm lights the plug well enough, before the plug is test-printed.
  • The USB opening and the stopper: the casing cuts the opening for the main board's plug and cable (Casing-USB-Cuts) and stops the board with Casing-Board-Stopper, all three following the board (the lid's space). Where the board sits since 2026-10-06 the plug cut removes 191 mm³ of the wall and the cable cut 1876 of its 2398 mm³, 3 mm over the lid seat (main_board.usb_wall_mm). The stopper fills the space from the board's end to the outer wall, down to the seat: the casing adds it after the lid cut, so the lid's envelope does not trim it (Stas's choice, 2026-10-08). It keeps no clearance to the lid near screw 8: on the mouse lid they overlap by 0.09 mm³, a film over about x 22–29, y 71–82 mm, where the rest of the lid keeps 0.1–0.2 mm to the casing. Check that the printed lid closes there. Around the cable cut it keeps 1.05 mm over it; its face is 13.7 mm wide for the 13 mm cut, so for the first 2–3 mm behind the face it keeps 0.5–0.8 mm beside the cut and 1.0 mm under it, and 3.1 mm beside it from about 8 mm on. The plug cut pockets the USB-C receptacle's front, which stands 0.7 mm past the board into the stopper, with 0.2 mm under it (until 2026-10-06 its lower 0.87 mm stood in the stopper). The cable cut is centred 1 mm above the receptacle's tongue, so a plug whose overmold is taller than about 5 mm touches its floor: centring it would leave 2 mm of wall under it instead of usb_wall_mm, or raise the board 1 mm. Test-fit the cable you use. Screw 6 moved 14 mm along the rim on 2026-10-06, out of the cable cut. Since 2026-10-08 screw 8 sits under the stopper, below the cable cut, under the skate Stas placed there. Since 2026-10-10 its hole is as long as the others' (Stas's choice; until then a cut 1.74 mm shorter left 1.5 mm under the cable cut): it stops about 0.27 mm under that cut, less than one printed line, so a screw longer than the hole may break into the cable's opening. Check that skin on the first print. The lid has no wire passage.
  • The bottom module in its lid (the bottom module, dimensions.json bottom_module): test-print the mouse lid's pocket and screw holes early. The holder merges into the power switch's holder (none of its cuts reaches it); since Lid-Bottom-Module-Pos moved 1.5 mm away from the main board (2026-10-16) it stands 1.24 mm clear of the main board's holder and 5.8 mm of screw 5's lid boss. The lens stack is the hand-measured breakout's (its board 3.7 mm over the lens flange, where the plan read 3.4): measure the breakout, its holes (the pocket keeps the old base's two at y ±12 mm, 0.3 mm from the lens) and its lens's underside, which may shrink the window. Which way round the breakout lies in its pocket sets the cursor's direction up to half a turn: the pocket takes it either way, and the tower's mounting yaw assumes its +y end pointing away from the user on the bench (the YL/YR trims or turning the breakout make up the rest); name that end once the breakout is measured. Its lead row, where the website's wires end, turns with it: drawn off the sellers' photos on the long edge at +x, pin 1 (VIN) at −y (mouse_sensor_ref.py). The gyro lid pockets the GY-521 (the old base's pocket, 16.9 × 23.2 mm round a 15 × 20 board) and screws it down with two M1.6 screws, a washer under each head, through its Ø3 holes; the holes' places come from a KiCad redraw of the board, not a measured one, so check a real GY-521 against them before printing (the Ø3 holes leave 0.7 mm round an M1.6). A channel under the header's side takes the pin tails of a header soldered from the other side. Its header and holes sit on opposite long edges, so the right lid holds it turned half round against the left one's mirror image: a gyro driver needs its own mounting yaw per side. The PMW3610's breakout fits no pocket (23.5 × 31.5 mm). The ADNS-5050 lid snaps the v3 board into its pocket (0.25 mm a side) under two lips (0.35 mm over it, no screws), each lip on an arm the slots cut free; the first print (0.1 mm a side, rigid lips) would not take the board. Test-print the new pocket and its arms with a v3 board, and measure a lens's flange thickness (drawn 1.73, the v3 model's; the datasheet's drawing gives 1.28) and the board's thickness. Each lid holds the board with its header towards the main board, so the right lid turns it end for end and has its own cuts, 5.5 mm farther along the holder than the left's; turned so, the right hand's sensor motion is half a turn off what the tower's mounting yaw undoes, which the cat turns back (cat_rules::mouse::adns5050::seated_deltas); which end of the board is +y on the desk is still to be confirmed against its motion. The breakout's references still hold the old base's skates (…-skates-ref), which the scene shows under the lid.

The screws: M1.6, not yet printed

Every joint takes an M1.6 pan head screw, self-tapping for plastic: M1.6 × 5 mm for the module boards and the lid, M1.6 × 4 mm for the bottom module (decided 2026-10-10; build.toml enclosure-screws, bottom-module-screws; dimensions.json fastener). The module boards' Ø2.0 holes are M1.6's coarse clearance hole (ISO 273); an M2 thread would have none. Each printed hole a screw cuts its thread into is a 1.3 mm pilot across its flats.

JointCountHole in the board or partCut in the printed partThread
Module board onto its cover4 per moduleØ2.0 mm PCB holeheptagonal pilot, 1.3 mm across its flats, 7.23 mm deep3.4 mm of a 5 mm screw
Lid onto casing8 per hand—Ø1.9 at the lid's face, Ø1.8 through its boss, then the pilot into the casing's; the head in a Ø4.2 × 1.4 mm pocket under a foot2.9 mm under a pad, 2.5 mm under a skate (its head 0.4 mm higher), the tip 0.6–1.0 mm short of the hole's end; a 6 mm screw would hit it
Bottom module into its pocket2the breakout's Ø2.44 holes, the GY-521's Ø3 (a washer under each head)Ø1.3 pilot, 3.5 mm deep2.4 mm of a 4 mm screw

The head (ISO 7045: Ø3.2 × 1.3 at most) clears the finger boards' switch pads, 1.72 mm from a hole's centre, by about 0.1 mm: a larger head would sit on a solder joint.

Test-print a module cover's boss and a casing boss with their pilots, and drive a screw into each: it should cut its thread without splitting the boss and hold the board without stripping. Record the result in fastener.pilot.

Open decision: the keycap pocket

The V pocket under each keycap does not centre on its switch's nub where the screws put the boards. The caps rest on the nubs instead of seating in the pockets (dimensions.json board_fit.keycap_pocket has the numbers; ./lx mech check prints them live). Choose one of these options:

  1. Accept the pocket as built.
  2. Move the pocket in the keycap.
  3. Trim the cover's PCB ribs and the rib stop, and move the screws together with the boards.
  4. Move the cutouts onto the nubs instead of moving the boards, once the switches and the cutouts are tied (the PCB as the origin of the keys), by changing each module's recorded relation.

Then change the placement (tools/blender/place_boards.py --refit) and the record together.