summaryrefslogtreecommitdiff
path: root/src/SomhairlesDream.Modeling
diff options
context:
space:
mode:
Diffstat (limited to 'src/SomhairlesDream.Modeling')
-rw-r--r--src/SomhairlesDream.Modeling/BlenderBridge.fs13
-rw-r--r--src/SomhairlesDream.Modeling/Definitions.fs65
-rw-r--r--src/SomhairlesDream.Modeling/Pipeline.fs13
3 files changed, 82 insertions, 9 deletions
diff --git a/src/SomhairlesDream.Modeling/BlenderBridge.fs b/src/SomhairlesDream.Modeling/BlenderBridge.fs
index c0795e9..c4215ae 100644
--- a/src/SomhairlesDream.Modeling/BlenderBridge.fs
+++ b/src/SomhairlesDream.Modeling/BlenderBridge.fs
@@ -101,8 +101,13 @@ type BlenderProcessBridge(python: string, stageRoot: string, ?timeout: TimeSpan)
File.WriteAllText(path, content)
- member private _.StartInfo(request: BridgeRequest) =
- let scriptPath = Path.GetFullPath(Path.Combine(stageRoot, "blender", "fixture.py"))
+ member private _.ScriptPath(stepId: string) =
+ let scriptName = if stepId.StartsWith("probe-") then "probe.py" else "fixture.py"
+
+ Path.GetFullPath(Path.Combine(stageRoot, "blender", scriptName))
+
+ member private this.StartInfo(request: BridgeRequest) =
+ let scriptPath = this.ScriptPath(request.Step.StepId)
let info = ProcessStartInfo()
info.FileName <- python
info.UseShellExecute <- false
@@ -128,10 +133,10 @@ type BlenderProcessBridge(python: string, stageRoot: string, ?timeout: TimeSpan)
interface IArtifactBridge with
member this.Export(request, heartbeat) =
try
- let scriptPath = Path.GetFullPath(Path.Combine(stageRoot, "blender", "fixture.py"))
+ let scriptPath = this.ScriptPath(request.Step.StepId)
if not (File.Exists(scriptPath)) then
- Error(bridgeError $"fixture is missing: {scriptPath}")
+ Error(bridgeError $"blender script is missing: {scriptPath}")
else
match Path.GetDirectoryName(request.GlbPath) with
| null -> ()
diff --git a/src/SomhairlesDream.Modeling/Definitions.fs b/src/SomhairlesDream.Modeling/Definitions.fs
index 64e6bc6..9a9256e 100644
--- a/src/SomhairlesDream.Modeling/Definitions.fs
+++ b/src/SomhairlesDream.Modeling/Definitions.fs
@@ -29,3 +29,68 @@ module Design =
Changes =
[| { ObjectId = "heritage.cabin"; Kind = "add"; Summary = "Add cabin volume" }
{ ObjectId = "heritage.crossbeam"; Kind = "add"; Summary = "Add cabin crossbeam" } |] } |]
+
+ // YJ-01 Voyager-class current-tech probe (source: interstellar-dual-track/current-tech-probe
+ // scripts/build_probe.py, line ranges cited per step). Object ids map the legacy
+ // UPPER_SNAKE names onto lowercase dotted ids via documented rule
+ // (probe.bus.bay.panel.00 <- BUS_BAY_PANEL_00, probe.rtg.01.fin.00 <- RTG_01_FIN_0).
+ // Display plinth, information card and MODEL_LABEL are intentionally excluded.
+ let probeSteps : DesignStep array =
+ let bus =
+ [| "probe.bus.electronics.decagon"; "probe.bus.ring.front"; "probe.bus.ring.rear"
+ "probe.bus.bay.panel.00"; "probe.bus.bay.panel.01"; "probe.bus.bay.panel.02"
+ "probe.bus.bay.panel.03"; "probe.bus.bay.panel.04"; "probe.bus.bay.panel.05"
+ "probe.bus.bay.panel.06"; "probe.bus.bay.panel.07"; "probe.bus.bay.panel.08"
+ "probe.bus.bay.panel.09"
+ "probe.bus.mli.top"; "probe.bus.mli.bottom"
+ "probe.bus.radiator.port"; "probe.bus.radiator.starboard"
+ "probe.aacs"
+ "probe.thruster.01"; "probe.thruster.02"; "probe.thruster.03"; "probe.thruster.04" |]
+ let booms =
+ [| "probe.rtg.boom"
+ "probe.mag.boom"; "probe.mag.head"; "probe.mag.sensor.a"; "probe.mag.sensor.b"
+ "probe.pws.antenna.left"; "probe.pws.antenna.right"
+ "probe.pws.tip.left"; "probe.pws.tip.right" |]
+ let rtgs =
+ [| "probe.rtg.01"; "probe.rtg.01.fin.00"; "probe.rtg.01.fin.01"; "probe.rtg.01.fin.02"
+ "probe.rtg.02"; "probe.rtg.02.fin.00"; "probe.rtg.02.fin.01"; "probe.rtg.02.fin.02"
+ "probe.rtg.03"; "probe.rtg.03.fin.00"; "probe.rtg.03.fin.01"; "probe.rtg.03.fin.02" |]
+ let hga =
+ [| "probe.hga.reflector"; "probe.hga.feed"
+ "probe.hga.strut.00"; "probe.hga.strut.01"; "probe.hga.strut.02"; "probe.hga.strut.03" |]
+ let instruments =
+ [| "probe.scan.pivot"; "probe.scan.platform"
+ "probe.crs"; "probe.plasma"; "probe.optical"; "probe.optical.aperture" |]
+ let mast = [| "probe.science.boom" |]
+ let prior (prefix: string array) (current: string array) =
+ Array.append prefix current
+
+ let busChanges = bus |> Array.map (fun id -> { ObjectId = id; Kind = "add"; Summary = "Add ten-sided bus with bay panels, MLI and radiators" })
+ let boomChanges = booms |> Array.map (fun id -> { ObjectId = id; Kind = "add"; Summary = "Add fields-and-particles and RTG support booms" })
+ let rtgChanges = rtgs |> Array.map (fun id -> { ObjectId = id; Kind = "add"; Summary = "Add three RTGs with heat-rejection fins" })
+ let hgaChanges = hga |> Array.map (fun id -> { ObjectId = id; Kind = "add"; Summary = "Add high-gain antenna, feed and struts" })
+ let instrumentChanges = instruments |> Array.map (fun id -> { ObjectId = id; Kind = "add"; Summary = "Add articulated scan platform with science instruments" })
+ let mastChanges = mast |> Array.map (fun id -> { ObjectId = id; Kind = "add"; Summary = "Add deployable science mast" })
+ let liveryChanges =
+ [| { ObjectId = "probe.hga.reflector"; Kind = "update"; Summary = "Livery pass: reflector white finish" }
+ { ObjectId = "probe.bus.mli.top"; Kind = "update"; Summary = "Livery pass: MLI gold foil finish" }
+ { ObjectId = "probe.bus.bay.panel.01"; Kind = "update"; Summary = "Livery pass: restrained red accents on bay panels" }
+ { ObjectId = "probe.pws.tip.left"; Kind = "update"; Summary = "Livery pass: red antenna tip markers" }
+ { ObjectId = "probe.bus.electronics.decagon"; Kind = "update"; Summary = "Livery pass: body blue basecoat" }
+ { ObjectId = "probe.rtg.01"; Kind = "update"; Summary = "Livery pass: graphite RTG housings" } |]
+
+ [| { StepId = "probe-01-bus"; Index = 0; ObjectIds = bus; Changes = busChanges }
+ { StepId = "probe-02-boom"; Index = 1; ObjectIds = prior bus booms; Changes = boomChanges }
+ { StepId = "probe-03-rtg"; Index = 2; ObjectIds = prior (prior bus booms) rtgs; Changes = rtgChanges }
+ { StepId = "probe-04-hga"; Index = 3; ObjectIds = prior (prior (prior bus booms) rtgs) hga; Changes = hgaChanges }
+ { StepId = "probe-05-instruments"; Index = 4
+ ObjectIds = prior (prior (prior (prior bus booms) rtgs) hga) instruments; Changes = instrumentChanges }
+ { StepId = "probe-06-mast"; Index = 5
+ ObjectIds = prior (prior (prior (prior (prior bus booms) rtgs) hga) instruments) mast
+ Changes = mastChanges }
+ { StepId = "probe-07-livery"; Index = 6
+ ObjectIds = prior (prior (prior (prior (prior (prior bus booms) rtgs) hga) instruments) mast) [||]
+ Changes = liveryChanges } |]
+
+ let forProject (projectId: string) : DesignStep array =
+ if projectId.StartsWith("probe-") then probeSteps else steps
diff --git a/src/SomhairlesDream.Modeling/Pipeline.fs b/src/SomhairlesDream.Modeling/Pipeline.fs
index 3f1f105..d9db5f6 100644
--- a/src/SomhairlesDream.Modeling/Pipeline.fs
+++ b/src/SomhairlesDream.Modeling/Pipeline.fs
@@ -33,6 +33,7 @@ type IArtifactBridge =
type PipelineOptions =
{ ArtifactRoot: string
Ids: RunIds
+ Steps: DesignStep array
Render: bool
Bridge: IArtifactBridge
Clock: unit -> DateTimeOffset
@@ -214,10 +215,12 @@ module Pipeline =
let emit event = appendEvent log options.OnEvent event
let ids = options.Ids
- emit (RunEvent.Start { Ids = ids; At = startedAt; TotalSteps = Design.steps.Length })
+ let steps = options.Steps
+
+ emit (RunEvent.Start { Ids = ids; At = startedAt; TotalSteps = steps.Length })
let artifacts =
- [| for step in Design.steps do
+ [| for step in steps do
currentStep <- Some step.StepId
emit (RunEvent.Heartbeat { Ids = ids; At = options.Clock(); Message = $"starting {step.StepId}" })
@@ -275,7 +278,7 @@ module Pipeline =
At = options.Clock()
StepId = step.StepId
StepIndex = step.Index
- TotalSteps = Design.steps.Length
+ TotalSteps = steps.Length
Message = "artifact verified"
ArtifactPath = relativePath }
@@ -424,12 +427,12 @@ module ArtifactVerifier =
|| Ids.validateResourceId manifest.BaseId |> Result.isError
|| Ids.validateResourceId manifest.TargetId |> Result.isError then
Error "manifest contains an invalid resource id"
- elif manifest.Steps.Length <> Design.steps.Length then
+ elif manifest.Steps.Length <> (Design.forProject manifest.ProjectId).Length then
Error "manifest step count does not match design"
else
let mutable failure: string option = None
- for expected, actual in Array.zip Design.steps manifest.Steps do
+ for expected, actual in Array.zip (Design.forProject manifest.ProjectId) manifest.Steps do
if failure.IsNone && actual.StepId <> expected.StepId then
failure <- Some $"manifest step id mismatch: {expected.StepId}"
elif failure.IsNone && actual.StepIndex <> expected.Index then