// Artefakt-Tray (Service-Akte) — 3D-Aufnahme fuer die 15 Artefakt-Token // SLC-Workshop Tabletop · Einheiten: mm // Flaches Tableau mit 15 beschrifteten Steck-Slots (A1-A15), in 5 PHASEN-Reihen // gruppiert (Design -> Transition -> Operation -> Support -> Review). Liegt neben // der aktuellen Station und wandert mit. Die Token (artefakt-token.scad) tragen // die Phasenfarbe; der Tray selbst ist EINFARBIG (Beschriftung via Gravur). // // Mechanik: // - Artefakt erzeugt -> Token in seinen Slot legen. // - "Lebende" Artefakte (A2/A11/A13, hier mit eingraviertem Zusatz-Rahmen // markiert): Status-Platten oben aufstapeln -> Stapel waechst sichtbar. // - Gate-Kopplung bleibt REGEL: ein Gate "oeffnet" nur, wenn die geforderten // Token im Tray liegen (keine Mechanik am Gate-Puck). /* [Platte] */ plate_thick = 6; // Dicke margin = 8; // Aussenrand corner_r = 5; /* [Slots] (Token Ø 30x20 wird REINGELEGT) */ slot_w = 31; // Slot-Innenbreite (Token 30 + Spiel) slot_d = 21; // Slot-Innentiefe (Token 20 + Spiel) pocket_dep = 3.0; // Vertiefung (Token 4 hoch -> steht ~1 mm vor = greifbar) pocket_r = 2.5; gap_x = 7; // Abstand zwischen Slots in einer Reihe row_gap = 8; // Abstand zwischen den Phasen-Reihen header_h = 9; // Hoehe der Phasen-Kopfzeile ueber den Slots finger_r = 6; // Greifkerbe an der Slot-Unterkante /* [Gravur] */ num_size = 7; // A-Nummer im Slot-Boden num_depth = 0.8; hdr_size = 6; // Phasen-Name hdr_depth = 0.8; lf_inset = 3; // "lebend"-Rahmen: Abstand zum Slot-Rand lf_w = 1.2; // Strichstaerke lf_depth = 0.6; $fn = 48; // [Phasen-Reihe, [[A-Nummer, lebend?], ...]] — Reihenfolge = Lebenszyklus ROWS = [ ["DESIGN", [["A1", false], ["A2", true], ["A3", false], ["A4", false]]], ["TRANSITION", [["A5", false], ["A6", false], ["A7", false], ["A8", false]]], ["OPERATION", [["A9", false]]], ["SUPPORT", [["A10", false], ["A11", true], ["A12", false], ["A13", true]]], ["REVIEW", [["A14", false], ["A15", false]]] ]; cols_max = 4; n_rows = len(ROWS); // abgeleitete Maße content_w = cols_max * slot_w + (cols_max - 1) * gap_x; // 145 plate_w = content_w + 2 * margin; // 161 block_h = header_h + slot_d; // 30 content_h = n_rows * block_h + (n_rows - 1) * row_gap; // 182 plate_h = content_h + 2 * margin; // 198 // Platz von Ecke (0,0) aus; y oben = plate_h function blockTopY(r) = plate_h - margin - r * (block_h + row_gap); function slotCenterY(r) = blockTopY(r) - header_h - slot_d/2; function slotCenterX(c) = margin + slot_w/2 + c * (slot_w + gap_x); module rrect(l, w, h, r) { linear_extrude(h) offset(r) offset(-r) square([l, w], center = true); } module pocket(cx, cy, label, live) { // Vertiefung translate([cx, cy, plate_thick - pocket_dep]) rrect(slot_w, slot_d, pocket_dep + 0.1, pocket_r); // Greifkerbe an der Unterkante translate([cx, cy - slot_d/2, plate_thick - pocket_dep]) cylinder(r = finger_r, h = pocket_dep + 0.1); // A-Nummer im Boden (sichtbar bei leerem Slot) translate([cx, cy, plate_thick - pocket_dep - num_depth]) linear_extrude(num_depth + 0.1) text(label, size = num_size, halign = "center", valign = "center"); // "lebendes" Artefakt: zusaetzlicher Rahmen als Hinweis (stapeln/aktualisieren) if (live) translate([cx, cy, plate_thick - pocket_dep - lf_depth]) linear_extrude(lf_depth + 0.1) difference() { square([slot_w - 2*lf_inset, slot_d - 2*lf_inset], center = true); square([slot_w - 2*lf_inset - 2*lf_w, slot_d - 2*lf_inset - 2*lf_w], center = true); } } module tray() { difference() { translate([plate_w/2, plate_h/2, 0]) rrect(plate_w, plate_h, plate_thick, corner_r); for (r = [0 : n_rows - 1]) { hdr = ROWS[r][0]; slots = ROWS[r][1]; // Phasen-Kopfzeile (links ueber der Reihe) translate([margin + 1, blockTopY(r) - header_h/2, plate_thick - hdr_depth]) linear_extrude(hdr_depth + 0.1) text(hdr, size = hdr_size, halign = "left", valign = "center"); for (c = [0 : len(slots) - 1]) pocket(slotCenterX(c), slotCenterY(r), slots[c][0], slots[c][1]); } } } tray(); echo(plate_w = plate_w, plate_h = plate_h, plate_thick = plate_thick, slots = 15);