diff options
Diffstat (limited to 'src/SomhairlesDream.Modeling')
| -rw-r--r-- | src/SomhairlesDream.Modeling/BlenderBridge.fs | 13 | ||||
| -rw-r--r-- | src/SomhairlesDream.Modeling/Definitions.fs | 65 | ||||
| -rw-r--r-- | src/SomhairlesDream.Modeling/Pipeline.fs | 13 |
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 |
