| … | … | @@ -870,7 +870,12 @@ and modal keys only (GPL: clean-room, no code or assets). Decided by the user: |
| 870 | 870 | - **Custom profile** = a closed CURVE the cable names, live; plus strands / spread |
| 871 | 871 | (Cablerator's multi-profile). |
| 872 | 872 | |
| 873 | ### 14.1 Strands (every profile) | |
| 873 | ### 14.1 Strands (every profile) — TABLED | |
| 874 | ||
| 875 | **Tabled 2026-10-19** (user: "table strands until we do a performance review … also | |
| 876 | creating high poly faceted spheres suffers the same performance issues"). The params are | |
| 877 | `hidden`, so the Shape panel offers no Strands / Spread / Twist row (`gate_cable_gen` S9); | |
| 878 | the generator and S1–S8 stay, so the review can measure them. See step 7's numbers. | |
| 874 | 879 | |
| 875 | 880 | Cablerator's multi-profile repeats the profile around the cable's axis. Ours, on |
| 876 | 881 | `param_cable.gd`: |
| … | … | @@ -82,12 +82,15 @@ func params() -> Array: |
| 82 | 82 | {"id": "connectors", "label": "Connectors", "type": "bool", "default": false, "hidden": true}, |
| 83 | 83 | {"id": "ring_every", "label": "Rings every", "type": "float", "default": 0.0, "min": 0.0, "max": 20.0, |
| 84 | 84 | "step": 0.1, "unit": "m", "tip": "0 = none"}, |
| 85 | # STRANDS ARE TABLED (user 2026-10-19: "table strands until we do a performance | |
| 86 | # review"): hidden, so no Shape panel row sets them; the fold still reads them. | |
| 87 | # A 20-cable bundle at 7 strands is ~3 s per curve edit (§14.8 step 7). | |
| 85 | 88 | {"id": "strands", "label": "Strands", "type": "int", "default": 1, "min": 1, "max": 12, "step": 1, |
| 86 | "tip": "Copies of the profile around the axis"}, | |
| 89 | "tip": "Copies of the profile around the axis", "hidden": true}, | |
| 87 | 90 | {"id": "spread", "label": "Spread", "type": "float", "default": 1.0, "min": 0.0, "max": 8.0, |
| 88 | "step": 0.05, "tip": "Strands only: each strand's centre, x the radius off the axis"}, | |
| 91 | "step": 0.05, "tip": "Strands only: each strand's centre, x the radius off the axis", "hidden": true}, | |
| 89 | 92 | {"id": "twist", "label": "Twist", "type": "float", "default": 0.0, "min": -720.0, "max": 720.0, |
| 90 | "step": 5.0, "unit": "°/m", "tip": "Strands only: how far they turn per metre (a rope)"}, | |
| 93 | "step": 5.0, "unit": "°/m", "tip": "Strands only: how far they turn per metre (a rope)", "hidden": true}, | |
| 91 | 94 | ] |
| 92 | 95 | |
| 93 | 96 |
| … | … | @@ -28,10 +28,13 @@ extends Node |
| 28 | 28 | ## S6 a plug covers every strand: 1.6 x the radius x (1 + spread) |
| 29 | 29 | ## S7 a ring covers every strand: 1.3 x the radius x (1 + spread) |
| 30 | 30 | ## S8 a closed loop with twist: the twist rounds so every strand closes |
| 31 | ## S9 strands are TABLED (user 2026-10-19): the Shape panel offers no Strands / Spread / | |
| 32 | ## Twist row | |
| 31 | 33 | ## |
| 32 | 34 | ## RUN AS A SCENE: CI=true "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_cable_gen.tscn |
| 33 | 35 | |
| 34 | 36 | const Cable := preload("res://scenes/maps/shapes/param/param_cable.gd") |
| 37 | const ParamShapes := preload("res://scenes/maps/shapes/param/param_shapes.gd") | |
| 35 | 38 | |
| 36 | 39 | var fails := 0 |
| 37 | 40 | var checks := 0 |
| … | … | @@ -323,3 +326,8 @@ func _run() -> void: |
| 323 | 326 | closes = closes and (d >= 0.0 and d < 1.0e-3 if m == (j + 1) % 3 else d > 0.05) |
| 324 | 327 | _ok("S8 closed + twist 480°: strand j's last piece ends on strand j+1's first ring (< 1 mm), not another's", |
| 325 | 328 | closes, meets) |
| 329 | var ids: Array = [] | |
| 330 | for r: Dictionary in ParamShapes.rows(gen, gen.resolve({})): | |
| 331 | ids.append(String(r["id"])) | |
| 332 | _ok("S9 strands tabled: no Strands / Spread / Twist row in the Shape panel", not ids.has("p.strands") | |
| 333 | and not ids.has("p.spread") and not ids.has("p.twist") and ids.has("p.radius"), ids) |