Advance AXIS-style Three.js simulation UI

This commit is contained in:
2026-06-17 09:59:22 +08:00
parent d6a623308b
commit 656cddf73a
24 changed files with 84658 additions and 75 deletions

View File

@@ -302,6 +302,10 @@ Start with "OPFS Program Persistence" because the page can now load, edit, and
run real G-code text/files, but programs are not yet saved to or restored from
OPFS from within the AXIS shell.
Updated after batch 9: compact run summary is implemented. The next recommended
batch is adding machine/session run summaries to saved OPFS/session artifacts or
making the preview controls more AXIS-like with fit-state persistence.
## Execution Record
### 一、2026-06-16 Real G-code Editor Pane
@@ -343,3 +347,835 @@ real_simulation_programs_node_smoke=ok
- editor 只保存和显示 G-code 文本;
- G-code 执行仍通过 LinuxCNC-backed WASM
- JS 不解释 G-code、不规划刀路、不推导 modal/machine semantics。
### 二、2026-06-16 AXIS DRO/Modal State and Preview Controls
继续按 AXIS 实现文档推进,完成 Phase 3/4 的可落地部分。
本批新增实质能力:
- `runtime/ui/simulation/simulation-app.js` 新增:
- `createModalState(resultText)`
- `createDroState(frame)`
- `zoomToolpathViewBox(viewBox, zoom)`
- modal display 不再使用硬编码 active G-code 文本,改为显示 LinuxCNC
`canon_event=UPDATE_TAG` 字段;
- DRO 显示:
- actual X/Y/Z/A/B/C 来自 LinuxCNC canonical motion playback frame
- DTG/G54/G92/TLO/velocity 在当前 canonical 输出不可用时明确显示 `n/a`
- `window.linuxCncRealSimulationApi` 新增:
- `getDroState()`
- `getModalState()`
- `fitPreview()`
- `zoomPreview(factor)`
- `resetPreview()`
- preview toolbar 新增 Fit / Zoom In / Zoom Out / Reset
- SVG preview 保留 full path、executed path、toolhead并支持 viewBox 缩放/恢复。
测试覆盖:
- Node smoke 验证:
- modal state 来自 `UPDATE_TAG`
- unavailable DRO 字段保持显式 `n/a`
- viewBox zoom 会收窄;
- browser smoke 验证:
- API 暴露;
- modal DOM 显示 LinuxCNC 字段;
- DRO 不伪造 DTG/G54/G92/TLO/velocity
- preview zoom 改变 viewBoxreset 恢复 fit viewBox
- 现有 built-in/custom/file/editor G-code 执行继续走 LinuxCNC WASM。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
```
语义边界:
- JS 只解析 LinuxCNC canonical text 中已经输出的 `UPDATE_TAG` 字段用于显示;
- JS 不解释 G-code不推导 modal 语义,不计算 DTG/G54/G92/TLO/velocity
- preview zoom/reset 只改变 SVG viewBox不改变 LinuxCNC 生成的 motion events。
### 三、2026-06-16 AXIS OPFS Program Persistence
继续按 AXIS 实现文档推进,完成 Phase 2 的 OPFS program persistence 闭环。
本批新增实质能力:
- AXIS editable G-code pane 新增:
- OPFS G-code filename 输入;
- `Save OPFS`
- `Load OPFS`
- 页面复用既有 OPFS helpers
- `saveGcodeProgram()`
- `loadGcodeProgram()`
- `gcodeProgramPath()`
- `window.linuxCncRealSimulationApi` 新增:
- `getOpfsProgramState()`
- `saveProgramToOpfs(filename)`
- `loadProgramFromOpfs(filename)`
- OPFS load 会调用现有 `runProgramText()`,因此 reloaded program 仍通过
LinuxCNC-backed WASM 执行;
- OPFS metadata 写入 program state
- `program.source = "opfs"`
- `program.opfsPath = "linuxcnc/gcode/<filename>"`
- statusbar 显示 `Loaded OPFS: ...`。
browser smoke 新增验证:
- 设置 editor G-code
- 保存到 `linuxcnc/gcode/axis-opfs-roundtrip.ngc`
- 修改 editor 为不同内容;
- 从 OPFS 重新加载保存的程序;
- 验证 reloaded canonical output 出现保存内容的坐标;
- 验证 editor、body dataset、statusbar 和 OPFS state metadata 同步。
关键验证:
```text
browser_real_simulation_page_smoke=ok
real_simulation_programs_node_smoke=ok
```
语义边界:
- OPFS 只持久化 G-code 文本;
- OPFS load 后仍走 LinuxCNC-backed WASM interpreter
- JS 不解释 G-code不推导机床状态不绕过 canonical output。
### 四、2026-06-16 AXIS Machine/Session Readiness
继续按 AXIS 实现文档推进,完成 Phase 5 的 readiness 前半段。
本批新增实质能力:
- Manual Control panel 新增 `data-axis-shell="machine-session"` 区域:
- machine id
- session id
- G-code filename
- `Check Session`
- readiness phase/missing/path readout
- 页面复用既有 OPFS/session helper
- `readMachineSessionReadiness()`
- `window.linuxCncRealSimulationApi` 新增:
- `getMachineReadiness()`
- `checkMachineSessionReadiness(options)`
- readiness DOM 同步:
- `document.body.dataset.machineSessionReady`
- `data-machine-readiness-phase`
- `data-machine-readiness-missing`
- `data-machine-readiness-path="ini"`
- `data-machine-readiness-path="gcode"`。
browser smoke 新增验证:
- 检查不存在的 machine/session确认 readiness 为 blocked并报告 missing
`ini` 和 `gcode`
- 通过既有 OPFS helpers 写入:
- machine INI
- parameter file
- tool table
- G-code
- machine session snapshot
- 再次调用 AXIS API 检查 readiness确认 phase 为 `ready`missing 为空;
- 验证 readiness paths 与 OPFS path model 一致,并同步到 API/body/DOM。
关键验证:
```text
browser_real_simulation_page_smoke=ok
```
语义边界:
- readiness 只检查 OPFS 文件存在和 snapshot envelope
- JS 不合成 INI/tool/parameter/G-code 语义;
- 本批不加载或执行完整 machine session只把可运行前置条件暴露给 AXIS shell。
### 五、2026-06-16 AXIS Machine/Session WASM Staging
继续按 AXIS 实现文档推进,完成 Phase 5 的 ready session load/stage 能力。
本批新增实质能力:
- Manual Control panel 的 machine-session 区域新增:
- `Load Session`
- loaded INI WASM path
- loaded parameter WASM path
- loaded tool-table WASM path
- 页面复用既有 LinuxCNC-backed helpers
- `createLinuxCncInterpSdk()`
- `createLinuxCncIniSdk()`
- `loadMachineSessionFromOpfs()`
- `window.linuxCncRealSimulationApi` 新增:
- `getMachineSessionLoadState()`
- `loadReadyMachineSession(options)`
- `loadReadyMachineSession()` 先调用 readiness checkblocked 时返回 blocked
load state不 stage
- ready 时创建 LinuxCNC interp/INI SDK调用 `loadMachineSessionFromOpfs()`
把 OPFS INI/parameter/tool-table staged 到 WASM filesystem
- DOM 同步:
- `document.body.dataset.machineSessionLoaded`
- `data-machine-session-loaded-path="ini"`
- `data-machine-session-loaded-path="parameters"`
- `data-machine-session-loaded-path="toolTable"`。
browser smoke 新增验证:
- 在 ready machine/session 基础上调用 `loadReadyMachineSession()`
- 使用显式 WASM paths
- `/work/axis-smoke/machine.ini`
- `/work/axis-smoke/linuxcnc.var`
- `/work/axis-smoke/tool.tbl`
- 验证 API 返回 loaded state
- 验证 API/body/DOM 中 loaded paths 同步。
关键验证:
```text
browser_real_simulation_page_smoke=ok
```
语义边界:
- session load/stage 完全通过既有 LinuxCNC-backed SDK 和 OPFS bridge
- JS 不解释 INI/tool-table/parameter/G-code
- 本批只 stage machine session不改变 program execution semantics。
### 六、2026-06-16 AXIS Loaded-Session Program Execution
继续按 AXIS 实现文档推进,让 loaded machine session 真正参与程序执行。
本批新增实质能力:
- `simulation-app.js` 新增:
- `runLinuxCncProgram(interp, programText, options)`
- `runRealBrowserSimulation({ interp, iniPath })`
- state.execution
- `mode: "linuxcnc-wasm"`
- `mode: "linuxcnc-wasm-with-ini"`
- `iniPath`
- AXIS page 在 `loadReadyMachineSession()` 成功后保留 staged interpreter
- 后续 built-in/custom/editor/OPFS text execution 自动使用:
- staged interpreter
- loaded session INI WASM path
- LinuxCNC-backed `runProgramWithIni()`
- program source label 会显示 `Session INI: <wasm path>`。
browser smoke 新增验证:
- 在 ready session staged 后设置 editor G-code
- 调用 `runEditorProgramText()`
- 验证 returned state
- `execution.mode === "linuxcnc-wasm-with-ini"`
- `execution.iniPath === "/work/axis-smoke/machine.ini"`
- canonical output 包含修改后的 G-code 坐标;
- source label 包含 loaded session INI path。
Node smoke 新增验证:
- `runLinuxCncProgram()` 无 INI 时调用 `runProgram()`
- 有 INI 时调用 `runProgramWithIni()`
- `runRealBrowserSimulation({ interp, iniPath })` 返回
`linuxcnc-wasm-with-ini` execution metadata。
关键验证:
```text
real_simulation_programs_node_smoke=ok
browser_real_simulation_page_smoke=ok
```
语义边界:
- JS 只选择 LinuxCNC-backed interpreter SDK 方法;
- G-code 解释仍由 LinuxCNC WASM 执行;
- INI/tool/parameter state 仍由 existing OPFS bridge 和 LinuxCNC SDK staged/loaded。
### 七、2026-06-16 AXIS Run Mode Status and OPFS Session-Backed Execution
继续按 AXIS 实现文档推进,补齐 visible run-mode 状态,并扩展 OPFS program
在 loaded session 下的执行覆盖。
本批新增实质能力:
- toolbar status strip 新增:
- `Run mode Standalone`
- loaded session 执行后显示 `Session-backed: <iniPath>`
- statusbar 同步显示 run mode
- body dataset 新增:
- `data-run-mode="standalone"`
- `data-run-mode="session-backed"`
- `window.linuxCncRealSimulationApi` 新增:
- `getRunMode()`
- 每次 program render 后同步 run-mode UI/API 状态。
browser smoke 新增验证:
- 初始页面 run mode 为 standalone
- loaded session editor run 后 run mode 切换为 session-backed
- OPFS-loaded G-code 在 session-backed 模式下执行:
- 保存 `axis-session-opfs.ngc` 到 OPFS
- 修改 editor 为不同内容;
- 从 OPFS load/run
- 验证 `execution.mode === "linuxcnc-wasm-with-ini"`
- 验证 canonical output 来自 OPFS 保存内容;
- 验证 source label 同时包含 OPFS path 和 Session INI path。
关键验证:
```text
real_simulation_programs_node_smoke=ok
browser_real_simulation_page_smoke=ok
```
语义边界:
- run mode 只反映当前 LinuxCNC-backed execution path
- OPFS program load/run 仍通过 LinuxCNC-backed `runProgramWithIni()`
- JS 不解释 G-code也不实现 session semantics。
### 八、2026-06-16 AXIS Run Mode Session Toggle
继续按 AXIS 实现文档推进,补齐 standalone/session-backed 显式切换。
本批新增实质能力:
- Manual Control machine-session actions 新增:
- `Use Session` checkbox
- run mode 逻辑新增:
- loaded session 存在且 Use Session 开启时,程序执行走 loaded session INI
- Use Session 关闭时,即使 session staged也回到 standalone execution
- `window.linuxCncRealSimulationApi` 新增:
- `setUseLoadedSession(value)`
- `getRunMode()` 返回:
- `mode`
- `label`
- `iniPath`
- `useLoadedSession`
- `sessionLoaded`。
browser smoke 新增验证:
- loaded session editor run 后为 session-backed
- 调用 `setUseLoadedSession(false)` 后 checkbox 同步关闭;
- 再次运行 editor G-code确认
- `execution.mode === "linuxcnc-wasm"`
- `execution.iniPath === null`
- body run mode 维持 standalone
- 调用 `setUseLoadedSession(true)` 后 checkbox 同步开启;
- 后续 OPFS program load/run 再次使用 loaded session INI。
关键验证:
```text
real_simulation_programs_node_smoke=ok
browser_real_simulation_page_smoke=ok
```
语义边界:
- Use Session 只选择 LinuxCNC-backed execution method
- 不修改 staged machine session 内容;
- JS 不解释 G-code/INI/tool/parameter semantics。
### 九、2026-06-16 AXIS Run Summary
继续按 AXIS 实现文档推进,增加 compact run summary方便操作时判断当前运行上下文。
本批新增实质能力:
- Machine State readout 新增:
- Execution Mode
- Session INI
- OPFS Program
- Session State
- `window.linuxCncRealSimulationApi` 新增:
- `getRunSummary()`
- run summary 字段:
- `apiName: "real-browser-simulation-run-summary"`
- `executionMode`
- `runMode`
- `sessionIniPath`
- `opfsProgramPath`
- `readinessPhase`
- `sessionLoadPhase`
- `programSource`
- readiness/load/run/toggle 后都会同步 run summary DOM。
browser smoke 新增验证:
- 初始 summary 为 standalone `linuxcnc-wasm`
- session ready/load 后 summary 显示 `ready / loaded`
- session-backed editor run 后 summary 显示:
- `linuxcnc-wasm-with-ini`
- `/work/axis-smoke/machine.ini`
- Use Session 关闭后 standalone run summary 回到:
- `linuxcnc-wasm`
- Session INI `n/a`
- session-backed OPFS run 后 summary 显示:
- OPFS program path `linuxcnc/gcode/axis-session-opfs.ngc`。
关键验证:
```text
real_simulation_programs_node_smoke=ok
browser_real_simulation_page_smoke=ok
```
语义边界:
- run summary 只汇总已有 LinuxCNC-backed execution/session/readiness state
- 不推导 CNC semantics
- 不改变 execution path。
### 十、2026-06-17 AXIS MDI Text and Preview Pan
继续按 AXIS 实现文档推进,补齐 MDI scratch 文本路径和 preview pan 控制。
本批新增实质能力:
- AXIS MDI panel 新增:
- `data-mdi-program-text` scratch G-code textarea
- `Load MDI Text`
- `Run MDI Text`
- `data-mdi-status`
- `window.linuxCncRealSimulationApi` 新增:
- `loadProgramText(text, metadata)`
- `runMdiProgramText(text)`
- `loadProgramText()` 只把 operator text staging 到 AXIS G-code pane
不执行、不解释 G-code
- `runMdiProgramText()` 复用既有 `runProgramText()`,继续走 LinuxCNC-backed
WASM execution
- preview controls 新增 pan left/right/up/down
- `simulation-app.js` 新增纯显示 helper
- `panToolpathViewBox(viewBox, offset)`
- browser API 新增:
- `panPreview(dx, dy)`
- `fitPreview()` / `resetPreview()` 清除 pan offsetzoom/pan 不改变 canonical
motion state。
browser smoke 新增验证:
- MDI 控件存在;
- `loadProgramText()` 可以 staging 文本到 editor/statusbar
- MDI scratch 文本执行后 canonical output 包含 LinuxCNC-produced
`STRAIGHT_FEED`
- `panPreview()` 会移动已填充 toolpath viewBox
- `fitPreview()` 会清除 pan offset 并恢复 fit viewBox。
Node smoke 新增验证:
- `panToolpathViewBox()` 只平移 viewBox不改变 width/height
- existing zoom helper 仍围绕 fit viewBox 缩放。
文档同步:
- `wasm-port/docs/axis-style-simulation-implementation.md` 将
`loadProgramText()` 从 future API 移入 required API
- Phase 2 增补 MDI text execution
- Phase 4 增补 preview pan
- Immediate Next Batch 更新为当前后续方向run-control blocked/ready
messaging 和 preview state readback。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- MDI text 只是 operator-provided program text仍由 LinuxCNC WASM 解释;
- preview pan/zoom 只改变 SVG viewBox
- JS 不实现 G-code、modal、planner、kinematics 或 machine runtime semantics。
### 十一、2026-06-17 AXIS Run-Control State and Preview State Readback
继续按“页面样式和功能对标 LinuxCNC AXIS”的方向推进补齐 operator-facing
状态反馈,避免 session-backed/standalone 执行路径不透明。
本批新增实质能力:
- toolbar status strip 新增 run-control 状态行:
- `data-run-control-state`
- `document.body.dataset.runControlPhase`
- 初始显示 `fallback`,说明 Use Session 开启但尚无 loaded machine session
- Machine State readout 新增:
- Run Control
- Preview
- browser API 新增:
- `getRunControlState()`
- `getPreviewState()`
- run-control state 字段:
- `apiName: "real-browser-simulation-run-control-state"`
- `phase`
- `requestedMode`
- `executionMode`
- `reason`
- `canUseSession`
- `loadedIniPath`
- preview state 字段:
- `apiName: "real-browser-simulation-preview-state"`
- `zoom`
- `pan`
- `fitViewBox`
- `viewBox`
- preview controls 的 pan/zoom 状态同步到:
- `data-preview-zoom`
- `data-preview-pan`
- Machine State Preview
- Manual Control 新增 explicit blocked LED
- `data-axis-machine-control-state`
- 明确 jog/spindle/coolant 未绑定真实 machine runtime。
AXIS visual polish
- preview pan controls 从长文字改为更接近工具按钮的 `< > ^ v`
- 保留 `aria-label` 和原有 `data-preview-pan-*` selectors
- 控件仍保持密集、灰色、边框式 AXIS 风格。
browser smoke 新增验证:
- 初始 run-control 为 fallback
- run-control DOM 解释 standalone fallback 原因;
- preview pan 后 API/DOM 同步;
- fit 后 pan offset 清零;
- session load 后 run-control 显示 loaded INI 可用;
- session-backed run 后 run-control 为 ready
- Use Session 关闭后 run-control 说明 loaded session 被 bypass
- real-machine controls 必须显示 `not bound` blocked 状态。
文档同步:
- `wasm-port/docs/axis-style-simulation-implementation.md` 增补:
- `getRunControlState()`
- `getPreviewState()`
- real jog/spindle/coolant unbound blocked state
- run-control ready/fallback 状态。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- run-control 只反映当前 LinuxCNC-backed execution path
- preview state 只反映 SVG viewBox
- unbound machine-control 状态不伪造真实 jog/spindle/coolant 行为。
### 十二、2026-06-17 AXIS Canonical Machine Status Panel
继续推进 AXIS 对标,把左侧和 Machine State 中的 spindle/coolant/tool/override
状态从静态 UI 升级为 LinuxCNC canonical output 派生状态。
本批新增实质能力:
- `simulation-app.js` 新增:
- `createMachineStatusState(resultText)`
- simulation state 新增:
- `machineStatus`
- browser API 新增:
- `getMachineStatusState()`
- machine status 字段:
- `apiName: "real-browser-simulation-machine-status-state"`
- `source: "linuxcnc-canonical-events"`
- `spindle.state` / `spindle.direction` / `spindle.speed`
- `coolant.mist` / `coolant.flood`
- `tool.selected` / `tool.current` / `tool.pocket` / `tool.lengthOffset`
- `overrides.feed` / `overrides.speed` / `overrides.adaptiveFeed` /
`overrides.feedHold`
- AXIS UI 新增/同步:
- Manual Control Spindle status LED
- Manual Control Coolant status LED
- Machine State Spindle row
- Machine State Coolant row
- Machine State Tool row
- Machine State Overrides row
- 没有 LinuxCNC canonical event 的字段保持 `n/a`。
canonical event mapping
- `SET_SPINDLE_SPEED` -> spindle speed
- `START_SPINDLE_CLOCKWISE` / `START_SPINDLE_COUNTERCLOCKWISE` -> spindle
direction/state
- `STOP_SPINDLE_TURNING` -> spindle off
- `MIST_ON/OFF`、`FLOOD_ON/OFF` -> coolant state
- `SELECT_TOOL`、`CHANGE_TOOL_NUMBER`、`USE_TOOL_LENGTH_OFFSET` -> tool/TLO
- `ENABLE/DISABLE_*_OVERRIDE`、`ENABLE/DISABLE_FEED_HOLD` -> override rows。
browser smoke 新增验证:
- 初始 built-in program 未产生 machine-status events 时spindle/coolant
明确显示 `n/a`
- 执行包含 `S1200 M3/M5/M7/M8/M9/M48/M50/T2/M6/G43/G49/M61` 的 program
- 验证 API 和 DOM 中 spindle/coolant/tool/override 状态均来自 LinuxCNC
canonical output。
Node smoke 新增验证:
- `createMachineStatusState()` 对 unavailable canonical output 返回 `n/a`
- spindle/coolant/override canonical events 可正确折叠为最终状态;
- tool/TLO canonical events 可正确折叠为当前 tool/pocket/TLO。
文档同步:
- `wasm-port/docs/axis-style-simulation-implementation.md` 增补:
- machine status canonical event display
- `getMachineStatusState()` required API。
关键验证:
```text
real_simulation_programs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- machine status 只显示 LinuxCNC canonical output 已产生的事件;
- 前端不推断真实 spindle/coolant/tool runtime
- 缺失字段继续显示 `n/a`。
### 十三、2026-06-17 AXIS Preview Extents, Origin, and Legend
继续推进 AXIS preview 对标,补齐更接近 LinuxCNC AXIS 的预览覆盖层。
本批新增实质能力:
- SVG preview 新增:
- `data-preview-extents` extents rectangle
- `data-preview-origin-x` / `data-preview-origin-y` origin axes
- `data-preview-origin` origin marker
- `data-axis-shell="preview-legend"` legend
- `data-preview-extents-label` extents text
- `renderToolpath()` 现在基于 LinuxCNC canonical motion 生成的
`createToolpathViewBox(motion)` 同步:
- extents rectangle
- origin axes
- origin marker size
- extents label
- preview legend 显示:
- Extents
- Full path
- Executed path
- Origin。
browser smoke 新增验证:
- AXIS shell 必须存在 preview legend
- SVG extents rectangle width/height > 0
- origin marker 位于 `0,0`
- extents label 同时包含 X/Y 范围;
- zoom/pan/fit 仍保持原有行为。
文档同步:
- `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 记录:
- motion-derived extents rectangle
- origin axes/marker
- preview legend。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- extents 只来自 LinuxCNC canonical motion path
- origin marker/axes 只是 preview display overlay
- 不新增浏览器端 CNC 几何、planner 或 kinematics 语义。
### 十四、2026-06-17 AXIS Three.js Toolpath Preview
按用户要求,刀具轨迹预览区改用 Three.js版本要求为
```json
"three": "^0.183.2"
```
本批新增实质能力:
- 新增 `wasm-port/runtime/ui/simulation/package.json`
- `dependencies.three = "^0.183.2"`
- 新增 `package-lock.json` 记录 resolved dependency
- 新增 vendored runtime build
- `runtime/ui/simulation/vendor/three/three.module.js`
- `runtime/ui/simulation/vendor/three/three.core.js`
- `runtime/ui/simulation/vendor/three/LICENSE`
- `simulation-app.js` 直接 import
- `./vendor/three/three.module.js`
- preview 主视图新增:
- `<canvas data-toolpath-three>`
- 原 SVG preview 改为 hidden fallback/state surface
- 保留 `data-toolpath-svg`
- 保留 polyline/head/extents selectors兼容既有 tests/API。
Three.js 渲染内容:
- orthographic camera
- dark AXIS-like background
- motion-derived extents outline
- origin X/Y axes
- full canonical path
- executed canonical path
- origin marker
- active tool marker
- camera fit/zoom/pan 与现有 `fitPreview()` / `zoomPreview()` /
`panPreview()` 同步。
browser smoke 新增验证:
- `data-toolpath-three.dataset.threeReady === "true"`
- Three.js revision 为 `183`
- Three path point count 等于 LinuxCNC canonical motion count
- playback step 后 Three executed point count 前进;
- SVG fallback viewBox/polyline 继续保持兼容。
docs smoke 新增验证:
- AXIS implementation docs 记录 Three.js `^0.183.2`
- simulation package 声明 `three: ^0.183.2`
- vendored `three.core.js` revision 为 `183`
- real-browser priority docs smoke 确认页面包含 `data-toolpath-three`。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
real_browser_simulation_priority_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- Three.js 只负责显示 LinuxCNC canonical motion
- 不在 Three.js/浏览器端实现 G-code、planner、kinematics 或 compensation
- SVG fallback 仅作为 state/compatibility surface 保留。
### 十五、2026-06-17 AXIS Three.js Preview View Modes
继续按用户“预览区使用 threejs、对标 LinuxCNC AXIS”的要求推进补齐 AXIS
常见预览视图模式。
本批新增实质能力:
- Preview toolbar 新增:
- `Top`
- `Front`
- `Side`
- `Iso`
- `window.linuxCncRealSimulationApi` 新增:
- `setPreviewViewMode(mode)`
- `getPreviewState()` 新增:
- `viewMode`
- Three.js preview canvas 新增/同步:
- `data-three-view-mode`
- UI 新增:
- `data-preview-view-label`
- active view-mode button state。
Three.js camera behavior
- `top`:正交 top view
- `front`:正交 front-style view
- `side`:正交 side-style view
- `iso`isometric-like angled view
- zoom/pan/fit 继续复用现有 viewBox 状态;
- Three.js 仅显示 LinuxCNC canonical motion不改变 motion semantics。
browser smoke 新增验证:
- API 必须存在 `setPreviewViewMode()`
- 切换 `iso` 后:
- `getPreviewState().viewMode === "iso"`
- Three canvas `data-three-view-mode === "iso"`
- UI label 显示 `Iso`
- 切换 `side` 后:
- active button state 为 true
- 切回 `top` 后继续执行 fit/zoom/pan smoke。
文档同步:
- `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 增补
Top/Front/Side/Iso view modes
- Required APIs 增补 `setPreviewViewMode(mode)`。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- view modes 只改变 Three.js camera
- 不改变 LinuxCNC canonical motion path
- 不实现浏览器端 kinematics 或 G-code 几何语义。
### 十六、2026-06-17 AXIS Three.js Grid, Axis Labels, and Pixel Smoke
继续按“预览区使用 threejs、对标 LinuxCNC AXIS”推进补齐 Three.js 预览的
网格、轴标签和 canvas 非空验证。
本批新增实质能力:
- Three.js preview 新增动态 grid
- `chooseGridStep(span)` 按 viewBox 尺寸选择 1/2/5/10 系列步距;
- `addThreeGrid(scene, viewBox)` 生成 viewBox 覆盖范围内的 grid lines
- canvas dataset
- `data-three-grid-step`
- `data-three-grid-lines`
- Three.js preview 新增 X/Y/Z axis labels
- `createTextSprite(text, color)`
- `addThreeAxisLabels(scene, viewBox)`
- canvas dataset
- `data-three-axis-labels="3"`
- Three.js preview smoke 新增 WebGL pixel readback
- 获取 `webgl2` / `webgl` context
- `readPixels()` 检查 canvas 中心像素非透明空白;
- 继续验证 Three.js revision/path points/executed points。
文档同步:
- `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 增补:
- dynamic grid lines
- X/Y/Z axis labels
- browser smoke canvas pixel check。
关键验证:
```text
real_simulation_programs_node_smoke=ok
axis_style_simulation_docs_node_smoke=ok
browser_real_simulation_page_smoke=ok
git diff --check ok
```
语义边界:
- grid 和 labels 只使用当前 preview viewBox
- Three.js 仍只显示 LinuxCNC canonical motion
- pixel smoke 只验证渲染非空,不推导 CNC 语义。