update 01.06.2026
This commit is contained in:
parent
7f1a09572e
commit
1af051990f
21 changed files with 1365 additions and 380 deletions
|
|
@ -6,25 +6,21 @@ Parametrische Quellmodelle der Schlüsselteile. In [OpenSCAD](https://openscad.o
|
|||
|
||||
| Datei | Bauteil |
|
||||
|-------|---------|
|
||||
| `aktivitaets-tile.scad` | Phasen-Basistile (100×100, Verankerung Ø50, Puzzle-Tabs) |
|
||||
| `aktivitaets-plaque.scad` | Beidseitiges Aktivitätsplättchen (Ø49) — Text per Variable |
|
||||
| `aktivitaets-tile.scad` | Phasen-Basistile (100×100, Verankerung Ø60, Puzzle-Tabs) |
|
||||
| `aktivitaets-plaque.scad` | Blanko-Scheibe (Ø60) für 60-mm-Rundaufkleber — keine Gravur |
|
||||
| `action-stein.scad` | Szenario-Träger mit Kartenschlitz + M8-Gewichtsaussparung |
|
||||
| `gate-tor.scad` | Gate-Tor mit 4 Rollen-Steckplätzen + Kartenschlitz |
|
||||
| `gate-tor.scad` | Gate-Tor mit 4 Rollen-Standfeldern + Kartenschlitz |
|
||||
| `sor-tile.scad` | SOR-Sonder-Tile (Gremium): Gate-Eingang, Chip/„Gremium"-Mitte, Figuren-Ring |
|
||||
|
||||
## Serienfertigung der Plättchen
|
||||
## Serienfertigung der Scheiben
|
||||
|
||||
`aktivitaets-plaque.scad` enthält den Text als Variablen (`front_id`,
|
||||
`front_name`, `back_text`). Für alle 38 Aktivitäten empfiehlt sich ein kleines
|
||||
Skript, das die Werte aus den `service-lifecycle_*.yaml` liest und je Aktivität
|
||||
ein STL erzeugt (z.B. via OpenSCAD-Kommandozeile `-D` Parameter-Override):
|
||||
`aktivitaets-plaque.scad` ist **blanko** — alle **37 Scheiben sind identisch**
|
||||
(einmal rendern, 37× drucken). Kein Text-Override, keine Serien-STLs mehr nötig.
|
||||
|
||||
```bash
|
||||
openscad -o op_05.stl \
|
||||
-D 'front_id="op_05"' \
|
||||
-D 'front_name="Ueberwachen der Services"' \
|
||||
-D 'back_text="..."' \
|
||||
aktivitaets-plaque.scad
|
||||
```
|
||||
Die Beschriftung läuft über **60-mm-Rundaufkleber**: Ein kleines Skript liest die
|
||||
`service-lifecycle_*.yaml` und erzeugt einen **Aufkleberbogen** (ID + Kurzbezeichnung,
|
||||
Phasenfarbe) als PDF — analog zur Kartengenerierung. Vorteil: wiederverwendbar,
|
||||
korrigierbar, mehrsprachig.
|
||||
|
||||
## Hinweise
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// SLC-Workshop Tabletop · Einheiten: mm
|
||||
|
||||
/* [Fuss] */
|
||||
foot_d = 49; // sitzt in Verankerung (Ø50)
|
||||
foot_d = 59; // sitzt in Verankerung (Ø60)
|
||||
foot_h = 5;
|
||||
stand_ring = 70; // optionaler Standring fuer Kippstabilitaet
|
||||
use_ring = true;
|
||||
|
|
|
|||
|
|
@ -1,77 +1,98 @@
|
|||
// Aktiv-Feld — RACI-Stecklochleiste
|
||||
// Aktiv-Feld — RACI-Fläche (Figuren werden GESTELLT, nicht gesteckt)
|
||||
// SLC-Workshop Tabletop · Einheiten: mm
|
||||
// Steht NEBEN dem Action-Stein. Bei jeder Aktivitaet werden die beteiligten
|
||||
// Rollen-Figuren nach RACI in die passende Zone gesteckt:
|
||||
// R = Responsible · A = Accountable (genau 1) · C = Consulted · I = Informed
|
||||
// Anpassen und mit OpenSCAD nach STL exportieren (F6 -> Export).
|
||||
// Eine flache Platte mit 4 abgetrennten Bereichen R · A · C · I (gleich gross).
|
||||
// R/C/I haben je 4 Standflaechen (2x2). A hat GENAU EIN zentrales Standfeld
|
||||
// (goldene RACI-Regel: genau eine Rolle ist Accountable).
|
||||
// Standflaechen sind nur flache Gravur-Markierungen (keine Loecher).
|
||||
|
||||
/* [Leiste] */
|
||||
strip_w = 26; // Tiefe (zum Spieler)
|
||||
strip_h = 6; // Dicke
|
||||
corner_r = 3;
|
||||
/* [Platte] */
|
||||
plate_thick = 5; // Dicke der Flaeche
|
||||
corner_r = 4;
|
||||
plate_margin = 5; // Rand aussen
|
||||
|
||||
/* [Steckplaetze] */
|
||||
pin_hole_d = 4.2; // Loch fuer Figuren-Pin (Pin Oe 4,0 + Spiel)
|
||||
pin_hole_depth = 4;
|
||||
pin_pitch = 8; // Mitte-zu-Mitte innerhalb einer Zone
|
||||
zone_gap = 10; // Luecke zwischen den Zonen
|
||||
end_margin = 8; // Rand links/rechts
|
||||
socket_y = 5; // Lochreihe nach hinten versetzt (weg von der Beschriftung)
|
||||
/* [Standflaechen] (flache Markierung, kein Loch) */
|
||||
spot_d = 8; // Durchmesser
|
||||
spot_depth = 0.5; // Gravurtiefe
|
||||
spot_pitch = 9; // Mitte-zu-Mitte im Raster (R/C/I)
|
||||
grid_cols = 2; // Raster fuer R/C/I: 2 x 2 = 4 Standflaechen
|
||||
grid_rows = 2;
|
||||
a_spot_d = 11; // A: EIN groesseres zentrales Standfeld (genau 1 Figur)
|
||||
|
||||
/* [Beschriftung] */
|
||||
label_size = 7; // Buchstabengroesse
|
||||
label_depth = 0.8; // Gravurtiefe
|
||||
label_y = -8; // Position der Buchstaben (vorne, zum Spieler)
|
||||
/* [Bereiche / Zonen] — [Label, cols, rows]; A = 1x1 (goldene RACI-Regel) */
|
||||
zones = [["R", 2, 2], ["A", 1, 1], ["C", 2, 2], ["I", 2, 2]];
|
||||
cell_pad = 6; // Rand um die Standflaechen im Feld
|
||||
label_h = 9; // Platz fuer den Buchstaben unten im Feld
|
||||
zone_gap = 6; // Abstand zwischen den Feldern
|
||||
|
||||
/* [Zonen] */
|
||||
// [Label, Anzahl Steckplaetze] — A bewusst nur 1 (genau eine Rolle accountable)
|
||||
zones = [ ["R", 2], ["A", 1], ["C", 3], ["I", 3] ];
|
||||
/* [Gravur] */
|
||||
frame_w = 1.2; // Strichstaerke der Feld-Umrandung
|
||||
frame_depth = 0.6;
|
||||
label_size = 7;
|
||||
label_depth = 0.8;
|
||||
|
||||
$fn = 48;
|
||||
|
||||
// --- Hilfsfunktionen -------------------------------------------------------
|
||||
function zone_span(c) = (c - 1) * pin_pitch;
|
||||
// --- abgeleitete Maße -------------------------------------------------------
|
||||
spots_span_x = (grid_cols - 1) * spot_pitch;
|
||||
spots_span_y = (grid_rows - 1) * spot_pitch;
|
||||
cell_w = spots_span_x + 2 * cell_pad; // 21
|
||||
cell_h = spots_span_y + 2 * cell_pad + label_h; // 30
|
||||
plate_w = len(zones) * cell_w + (len(zones) - 1) * zone_gap + 2 * plate_margin;
|
||||
plate_h = cell_h + 2 * plate_margin;
|
||||
|
||||
function sumspan(i = 0) =
|
||||
i >= len(zones) ? 0 : zone_span(zones[i][1]) + sumspan(i + 1);
|
||||
function zone_cx(i) =
|
||||
-plate_w/2 + plate_margin + cell_w/2 + i * (cell_w + zone_gap);
|
||||
|
||||
function total_len() =
|
||||
end_margin * 2 + zone_gap * (len(zones) - 1) + sumspan();
|
||||
|
||||
// linker Startversatz der Zone idx (Summe vorheriger Zonen + Luecken)
|
||||
function zone_offset(idx, i = 0, acc = 0) =
|
||||
i >= idx ? acc
|
||||
: zone_offset(idx, i + 1, acc + zone_span(zones[i][1]) + zone_gap);
|
||||
|
||||
// --- Geometrie -------------------------------------------------------------
|
||||
module rounded_rect(l, w, h, r) {
|
||||
linear_extrude(h)
|
||||
offset(r) offset(-r)
|
||||
square([l, w], center = true);
|
||||
// --- Geometrie --------------------------------------------------------------
|
||||
module rrect(l, w, h, r) {
|
||||
linear_extrude(h) offset(r) offset(-r) square([l, w], center = true);
|
||||
}
|
||||
|
||||
module raci_strip() {
|
||||
L = total_len();
|
||||
module field_frame(cx) {
|
||||
// eingravierte Umrandung -> grenzt den Bereich ab
|
||||
translate([cx, 0, plate_thick - frame_depth])
|
||||
linear_extrude(frame_depth + 0.1)
|
||||
difference() {
|
||||
square([cell_w, cell_h], center = true);
|
||||
square([cell_w - 2*frame_w, cell_h - 2*frame_w], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
module zone_marks(i) {
|
||||
cx = zone_cx(i);
|
||||
lab = zones[i][0];
|
||||
nc = zones[i][1];
|
||||
nr = zones[i][2];
|
||||
if (lab == "A") {
|
||||
// genau EIN zentrales Standfeld (goldene RACI-Regel)
|
||||
translate([cx, label_h/2, plate_thick - spot_depth])
|
||||
cylinder(d = a_spot_d, h = spot_depth + 0.1);
|
||||
} else {
|
||||
for (c = [0 : nc - 1])
|
||||
for (r = [0 : nr - 1]) {
|
||||
sx = cx + (c - (nc - 1)/2) * spot_pitch;
|
||||
sy = label_h/2 + ((nr - 1)/2 - r) * spot_pitch;
|
||||
translate([sx, sy, plate_thick - spot_depth])
|
||||
cylinder(d = spot_d, h = spot_depth + 0.1);
|
||||
}
|
||||
}
|
||||
// Buchstabe unten im Feld
|
||||
translate([cx, -cell_h/2 + label_h/2, plate_thick - label_depth])
|
||||
linear_extrude(label_depth + 0.1)
|
||||
text(lab, size = label_size, halign = "center", valign = "center");
|
||||
}
|
||||
|
||||
module aktiv_feld() {
|
||||
difference() {
|
||||
rounded_rect(L, strip_w, strip_h, corner_r);
|
||||
|
||||
for (idx = [0 : len(zones) - 1]) {
|
||||
cnt = zones[idx][1];
|
||||
sx = -L/2 + end_margin + zone_offset(idx);
|
||||
|
||||
// Steckplaetze der Zone
|
||||
for (i = [0 : cnt - 1])
|
||||
translate([sx + i * pin_pitch, socket_y, strip_h - pin_hole_depth])
|
||||
cylinder(d = pin_hole_d, h = pin_hole_depth + 0.1);
|
||||
|
||||
// Zonen-Beschriftung (mittig unter den Loechern)
|
||||
cx = sx + zone_span(cnt) / 2;
|
||||
translate([cx, label_y, strip_h - label_depth])
|
||||
linear_extrude(label_depth + 0.1)
|
||||
text(zones[idx][0], size = label_size,
|
||||
halign = "center", valign = "center");
|
||||
rrect(plate_w, plate_h, plate_thick, corner_r);
|
||||
for (i = [0 : len(zones) - 1]) {
|
||||
field_frame(zone_cx(i));
|
||||
zone_marks(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
raci_strip();
|
||||
aktiv_feld();
|
||||
|
||||
// Maße zur Info (Konsole): echo(plate_w, plate_h, plate_thick);
|
||||
echo(plate_w = plate_w, plate_h = plate_h, plate_thick = plate_thick);
|
||||
|
|
|
|||
|
|
@ -1,22 +1,18 @@
|
|||
// Beidseitiges Aktivitaetsplaettchen (Rundscheibe fuer Verankerung)
|
||||
// Aktivitaets-Scheibe — BLANKO Rundscheibe fuer 60-mm-Rundaufkleber
|
||||
// SLC-Workshop Tabletop · Einheiten: mm
|
||||
// Text per Variable setzen; fuer Serie ueber Skript je Aktivitaet generieren.
|
||||
// Keine Gravur mehr: ID + Kurzbezeichnung kommen als 60-mm-Rundaufkleber auf die
|
||||
// plane Oberseite. Vorteil: wiederverwendbar (neu bekleben), mehrsprachig,
|
||||
// keine Serien-STLs noetig — alle 37 Scheiben sind identisch.
|
||||
|
||||
/* [Scheibe] */
|
||||
disc_d = 49; // Durchmesser (Verankerung 50 - Passung)
|
||||
disc_d = 60; // Durchmesser (Verankerung 60 - Passung); passt zum 60-mm-Aufkleber
|
||||
disc_h = 4; // Dicke
|
||||
chamfer = 1; // Fase als Griffhilfe
|
||||
|
||||
/* [Gravur] */
|
||||
engrave_depth = 0.8;
|
||||
front_id = "op_05";
|
||||
front_name = "Ueberwachen der Services";
|
||||
back_text = "Laufende Ueberwachung von Verfuegbarkeit, Leistung und Qualitaet des Service.";
|
||||
font = "Liberation Sans:style=Bold";
|
||||
chamfer = 1; // Fase als Griffhilfe (oben + unten). Aufkleber Ø58 sitzt plan,
|
||||
// Ø60 ueberdeckt die obere Fase leicht.
|
||||
$fn = 96;
|
||||
|
||||
module disc_body() {
|
||||
// Scheibe mit beidseitiger Fase
|
||||
// Scheibe mit beidseitiger Fase, plane Oberseite fuer den Aufkleber
|
||||
hull() {
|
||||
cylinder(d = disc_d - 2*chamfer, h = 0.01);
|
||||
translate([0,0,chamfer]) cylinder(d = disc_d, h = disc_h - 2*chamfer);
|
||||
|
|
@ -24,25 +20,4 @@ module disc_body() {
|
|||
}
|
||||
}
|
||||
|
||||
module front_engraving() {
|
||||
translate([0, 6, disc_h - engrave_depth])
|
||||
linear_extrude(engrave_depth + 0.1)
|
||||
text(front_id, size=7, halign="center", font=font);
|
||||
translate([0, -6, disc_h - engrave_depth])
|
||||
linear_extrude(engrave_depth + 0.1)
|
||||
text(front_name, size=3.2, halign="center", font=font);
|
||||
}
|
||||
|
||||
module back_engraving() {
|
||||
// gespiegelt, weil Rueckseite
|
||||
mirror([1,0,0])
|
||||
translate([0, 0, -0.1])
|
||||
linear_extrude(engrave_depth + 0.1)
|
||||
text(back_text, size=2.6, halign="center", font=font);
|
||||
}
|
||||
|
||||
difference() {
|
||||
disc_body();
|
||||
front_engraving();
|
||||
back_engraving();
|
||||
}
|
||||
disc_body();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ tile_height = 6; // Dicke
|
|||
corner_r = 3; // Eckenradius
|
||||
|
||||
/* [Verankerung / Sockel] */
|
||||
socket_d = 50; // Durchmesser Vertiefung
|
||||
socket_d = 60; // Durchmesser Vertiefung (nimmt Blanko-Scheibe Ø60 oder Action-Stein-Fuss auf)
|
||||
socket_depth = 4; // Tiefe
|
||||
fit_clear = 0.4; // Spielpassung
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ foot_w = 60;
|
|||
foot_d = 30;
|
||||
foot_h = 4;
|
||||
|
||||
/* [Rollen-Steckplaetze] */
|
||||
peg_d = 8.2; // Loch fuer Figuren-Pin (Ø7,5 + Passung)
|
||||
peg_count = 4;
|
||||
peg_depth = 6;
|
||||
/* [Rollen-Standfelder] (keine Loecher — Figuren werden gestellt) */
|
||||
spot_d = 8; // Durchmesser der eingravierten Standflaeche
|
||||
spot_count = 4; // 4 Pflicht-Figuren (SPM + SO + AL B&C + AL App)
|
||||
spot_depth = 0.6; // Gravurtiefe (reine Markierung)
|
||||
|
||||
/* [Kartenschlitz oben] */
|
||||
card_w = 65;
|
||||
|
|
@ -44,13 +44,12 @@ module feet() {
|
|||
cube([foot_w, foot_d, foot_h]);
|
||||
}
|
||||
|
||||
module peg_holes() {
|
||||
// Lochreihe entlang der Vorderkante der Fuesse
|
||||
spacing = (opening_w + post_w) / (peg_count - 1);
|
||||
for (i = [0 : peg_count - 1])
|
||||
translate([-(opening_w + post_w)/2 + i*spacing, foot_d/2 - peg_d, foot_h])
|
||||
rotate([180,0,0])
|
||||
cylinder(d = peg_d, h = peg_depth);
|
||||
module stand_spots() {
|
||||
// Flache Standfeld-Markierungen entlang der Vorderkante der Fuesse
|
||||
spacing = (opening_w + post_w) / (spot_count - 1);
|
||||
for (i = [0 : spot_count - 1])
|
||||
translate([-(opening_w + post_w)/2 + i*spacing, foot_d/2 - spot_d, foot_h - spot_depth])
|
||||
cylinder(d = spot_d, h = spot_depth + 0.1);
|
||||
}
|
||||
|
||||
module card_slot() {
|
||||
|
|
@ -63,8 +62,8 @@ difference() {
|
|||
translate([0,0,foot_h]) arch();
|
||||
translate([0,0,foot_h]) card_slot();
|
||||
}
|
||||
// Fuesse inkl. Rollen-Steckplaetze
|
||||
// Fuesse inkl. Rollen-Standfelder (flache Markierung)
|
||||
difference() {
|
||||
feet();
|
||||
peg_holes();
|
||||
stand_spots();
|
||||
}
|
||||
|
|
|
|||
94
01_3D-Druck/openscad/sor-tile.scad
Normal file
94
01_3D-Druck/openscad/sor-tile.scad
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// SOR-Sonder-Tile (Gremium) — Service Operations Runde
|
||||
// SLC-Workshop Tabletop · Einheiten: mm
|
||||
// Die SOR ist kein Einzel-Figur, sondern ein Gremium -> eigenes Tile:
|
||||
// - Gate-Tor wird am Eingang (Vorderkante) installiert -> Eingang ins Gremium
|
||||
// - Mitte: Platz fuer den Entscheidungs-Chip (Ø30); alternativ "Gremium" graviert
|
||||
// - rundherum: Standfelder fuer die teilnehmenden Figuren (gestellt, kein Pin)
|
||||
|
||||
/* [Tile] */
|
||||
tile_size = 120; // etwas groesser als Standardtile (Platz fuer Ring + Gate)
|
||||
tile_height = 6;
|
||||
corner_r = 4;
|
||||
|
||||
/* [Mitte: Chip oder Gravur] */
|
||||
use_chip = true; // true: Chip-Mulde Ø30 · false: "Gremium" eingraviert
|
||||
chip_d = 30;
|
||||
chip_recess_d = 0.6; // Spielpassung
|
||||
chip_depth = 1.5; // Mulden-Tiefe fuer den Chip
|
||||
gremium_text = "Gremium";
|
||||
gremium_size = 12;
|
||||
gremium_depth = 0.8;
|
||||
|
||||
/* [Ring aus Standfeldern] */
|
||||
ring_count = 6; // Plaetze fuer Gremiums-Figuren rund um die Mitte
|
||||
ring_d = 84; // Kreisdurchmesser, auf dem die Standfelder liegen
|
||||
spot_d = 8; // Standfeld-Durchmesser
|
||||
spot_depth = 0.5; // Gravurtiefe (Markierung, kein Loch)
|
||||
|
||||
/* [Gate-Eingang an der Vorderkante] */
|
||||
gate_seat_w = 116; // Breite der Aufsetzflaeche fuer das Gate (Fuesse 2x60)
|
||||
gate_seat_d = 30; // Tiefe (= Gate-Fusstiefe)
|
||||
gate_seat_depth = 1.5; // flache Mulde, in der die Gate-Fuesse stehen
|
||||
gate_label = "SOR";
|
||||
gate_label_size = 7;
|
||||
gate_label_depth= 0.8;
|
||||
|
||||
/* [Puzzle-Tab am Eingang -> Anschluss an die Bahn] */
|
||||
tab_w = 12; tab_d = 6;
|
||||
|
||||
$fn = 96;
|
||||
|
||||
module rounded_square(s, r, h) {
|
||||
linear_extrude(h) offset(r) offset(-r) square([s, s], center=true);
|
||||
}
|
||||
|
||||
module ring_spots() {
|
||||
for (i = [0 : ring_count - 1]) {
|
||||
a = 360/ring_count * i;
|
||||
x = (ring_d/2) * cos(a);
|
||||
y = (ring_d/2) * sin(a);
|
||||
translate([x, y, tile_height - spot_depth])
|
||||
cylinder(d = spot_d, h = spot_depth + 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
module center_feature() {
|
||||
if (use_chip) {
|
||||
// Mulde fuer den Entscheidungs-Chip
|
||||
translate([0, 0, tile_height - chip_depth])
|
||||
cylinder(d = chip_d + chip_recess_d, h = chip_depth + 0.1);
|
||||
} else {
|
||||
// "Gremium" eingraviert
|
||||
translate([0, 0, tile_height - gremium_depth])
|
||||
linear_extrude(gremium_depth + 0.1)
|
||||
text(gremium_text, size = gremium_size,
|
||||
halign = "center", valign = "center");
|
||||
}
|
||||
}
|
||||
|
||||
module gate_entrance() {
|
||||
// flache Mulde an der Vorderkante (Suedkante), in die die Gate-Fuesse gestellt werden
|
||||
translate([0, -tile_size/2 + gate_seat_d/2, tile_height - gate_seat_depth])
|
||||
cube([gate_seat_w, gate_seat_d, gate_seat_depth + 0.1], center = true);
|
||||
// Beschriftung "SOR" an der Vorderkante
|
||||
translate([0, -tile_size/2 + gate_seat_d + gate_label_size, tile_height - gate_label_depth])
|
||||
linear_extrude(gate_label_depth + 0.1)
|
||||
text(gate_label, size = gate_label_size, halign = "center", valign = "center");
|
||||
}
|
||||
|
||||
module sor_tile() {
|
||||
difference() {
|
||||
union() {
|
||||
rounded_square(tile_size, corner_r, tile_height);
|
||||
// Puzzle-Tab am Eingang (Suedkante) zum Anschluss an die Bahn
|
||||
translate([0, -tile_size/2 - tab_d, 0])
|
||||
cube([tab_w, tab_d*2, tile_height]);
|
||||
}
|
||||
center_feature();
|
||||
ring_spots();
|
||||
gate_entrance();
|
||||
}
|
||||
}
|
||||
|
||||
sor_tile();
|
||||
echo(tile_size = tile_size, ring_count = ring_count, use_chip = use_chip);
|
||||
Loading…
Add table
Add a link
Reference in a new issue