docs: document i18n conventions and Phase 17 (v0.8.0)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 09:50:03 +08:00
co-authored by Claude Opus 5.5
parent c65fc4e67f
commit fb46da29cf
2 changed files with 46 additions and 6 deletions
+31 -1
View File
@@ -100,8 +100,12 @@ STPViewer/
├── STPViewer.csproj # net8.0-windows, UseWPF
├── App.xaml / App.xaml.cs # 全域例外處理(log + 訊息框存活;%LOCALAPPDATA%\STPViewer\error.log)
├── MainWindow.xaml / .cs # 版面 + 滑鼠拾取事件
├── i18n/ # 語言包 en / zh_tw / zh_cn.json(輸出到 exe 旁;啟動時掃描,免重編)
├── Localization/
│ └── LocExtension.cs # XAML {loc:Loc Key} → 綁定 LocalizationService[Key](切語言即時更新)
│
├── Models/
│ ├── LanguageDefinition.cs # 一個語言包(Id = 檔名、Key = 顯示名、Data = 翻譯表)
│ ├── FaceInfo.cs # GeometryModel3D ↔ B-rep Face 對照(STL 為 null)
│ ├── MeasureMode.cs # enum: None/Point/Distance/Edge/Face/Circle/Angle/FaceDistance/Align/Align3/Drag/Interference/Volume
│ ├── MeasurementResult.cs # 量測結果(雙單位 lambda、3D 標籤同步)
@@ -112,6 +116,8 @@ STPViewer/
│
├── Services/
│ ├── StepImportService.cs # STEP/STL/DXF 讀檔 + 三角化 + 裝配樹
│ ├── StlMeshReader.cs # STL 直接解析(binary/ASCII,不經 CADability;v0.7.1)
│ ├── LocalizationService.cs # 語言包載入、目前語言、[key] 查詢(缺字回退英文)、LanguageChanged
│ ├── MeasurementService.cs # 點/線/面/圓/角度/面距/體積質心 幾何計算(吸附含圓心)
│ ├── InterferenceService.cs # 干涉檢查:三角形-三角形相交(區間法)+均勻網格加速;無干涉時近似最小間隙
│ ├── RigidAlign.cs # 三點對齊/旋轉的剛體變換數學(Matrix3D列向量 ↔ ModOp行向量 轉換)
@@ -126,6 +132,8 @@ STPViewer/
├── MainViewModel.Section.cs # 剖面(v0.4.0 起背景平行裁切)
├── MainViewModel.Interference.cs # 干涉檢查指令
├── MainViewModel.Export.cs # CSV / 截圖 / STEP / STL 匯出
├── MainViewModel.Localization.cs # 語言切換指令 + 切換後刷新量測/樹/狀態列文字
├── QuickBarViewModel.cs # 快速列按鈕註冊表(key/文字 key/預設值)
├── StlExportViewModel.cs # STL 匯出對話框 VM(選項 + 即時摘要)
└── ModelNodeViewModel.cs # 裝配樹節點(可見性/顏色 cascade)
```
@@ -201,7 +209,8 @@ class MeasurementResult
| 快速鍵 | P 點 / D 距離 / E 邊 / F 面 / C 圓 / A 角度 / M 面距;同鍵再按=退出;Esc=取消進行中量測→退出模式 | |
| 樹操作 | 搜尋框過濾節點名稱;右鍵:只顯示此節點 / 反轉顯示 / 全部顯示 / 量體積質心 | tooltip 含外形尺寸 L×W×H |
| 體積/質心 | 樹節點右鍵「⚖ 量體積/質心」 | signed volume(封閉實體)+ 質心標記 + AABB 外形尺寸 |
| 設定/MRU | 自動記住視窗位置大小、單位;「▾」最近 10 個檔案 | %LOCALAPPDATA%\STPViewer\settings.json |
| 語言 | 視圖 → 語言 / 快速列下拉:English、繁體中文、简体中文(v0.8.0) | 即時切換(含既有量測文字)並記住;`i18n/*.json` 加檔即新增語言,缺字回退英文 |
| 設定/MRU | 自動記住視窗位置大小、單位、語言;「▾」最近 10 個檔案 | %LOCALAPPDATA%\STPViewer\settings.json |
支援格式:`.stp` / `.step`(B-rep + 裝配樹)、`.stl`(純網格,僅點/距離/角度/面距量測)、
`.dxf`(線架構檢視)。**IGES 不支援**(CADability 無 IGES reader)。
@@ -489,6 +498,27 @@ WPF retained-mode 每幀重走 visual tree → frame rate 崩。瀏覽模式因
---
## Development Phases — 第九輪(多語系 v0.8.0)
### Phase 17 — 執行期語言包 + 即時切換(工作量:L;外部貢獻 PR #1 by @CarmJos)
**問題:** 介面字串全部寫死繁中,非中文使用者無法使用;新增語言要改程式重編。
- [x] **語言包**:`i18n/*.json`(`key` = 選單顯示名、`data` = key → 譯文)複製到 exe 旁;
啟動時 `LocalizationService` 掃描,檔名即語言 Id(`zh_cn.json` → `zh_cn`);壞檔/重複 Id 略過記 Trace
- [x] **查詢與回退**:`LocalizationService[key]` → 目前語言 → 英文 → key 本身;`Format` 格式錯誤時回退英文格式
- [x] **XAML**:`{loc:Loc Key}`(`LocExtension` = 綁 `LocalizationService.Instance[Key]`,`Item[]` 變更即時刷新)
- [x] **程式內文字**:狀態列 `SetStatus(() => Get/Format(...))`、量測/樹節點文字延後產生,
`LanguageChanged` → `RefreshLocalizedText()` 重算(與 mm⇄inch 同一套延後產生模式)
- [x] **初始語言**:settings.json `Language`,null → 依系統 UI 語系(zh-Hant/TW/HK/MO → zh_tw,其他 zh → zh_cn)
- [x] 關於視窗版本紀錄改為 key(`Ui.About.ReleaseXYZ.Title/ChangeN`),三語各一份
- [x] SmokeTest `--localization-test`:語系解析(zh-Hans/Hant/TW…)、缺字/格式錯回退英文、壞檔容錯、
內建語言包格式參數一致、VM 切語言後既有量測/3D 標籤/快速列即時更新
**驗收:** 三語切換即時生效(含已存在的量測結果與狀態列)、重開保留;刪掉某語言檔中的 key 時顯示英文不崩潰
---
## Future Extensions(下一輪)
- **大檔重開快取** — 匯入成功後把三角網格 + 裝配樹序列化成 sidecar 快取檔(以來源檔 hash 驗證),
+15 -5
View File
@@ -5,7 +5,7 @@
CAD 3D 檢視器(Windows 桌面 WPF, .NET 8):STEP/STL/DXF 匯入、STEP 裝配樹(搜尋/隔離顯示)、
點/距離/邊/面/圓/角度/面距/體積質心量測(吸附含圓心)、兩點對齊(平移)、三點對齊(旋轉+平移)、
軸向旋轉 90°、拖曳模式、干涉檢查(≥2 檔兩兩配對)、剖面(X/Y/Z + 3點任意平面)、
標準視圖+正交投影、量測快速鍵+Esc、mm⇄inch、CSV/截圖/STEP/STL 匯出(STL 有參數對話框)、設定與 MRU 保存。
標準視圖+正交投影、量測快速鍵+Esc、mm⇄inch、多語系(英/繁/簡,執行期語言包)、CSV/截圖/STEP/STL 匯出(STL 有參數對話框)、設定與 MRU 保存。
詳細設計見 [ARCHITECTURE.md](ARCHITECTURE.md)。
## 技術棧
@@ -49,8 +49,8 @@ dotnet publish src/STPViewer -c Release -o publish/STPViewer
(樹搜尋框、剖面數值框要能打字),新增輸入控件不用再各自處理
- UI 三層(v0.7.0):**選單列**(全部功能,分類下拉)+ **快速列**(`QuickBarViewModel` 註冊表,
使用者勾選常用按鈕,XAML 索引子綁定 `QuickBar[Key].IsChecked` 控 Visibility,按鈕本體維持靜態綁定)+
**剖面參數列**(只在 SectionEnabled 顯示)。新增功能要三處都接:選單分類、快速列註冊表
(含預設值)+ 對應 XAML 按鈕;勾選清單存 settings.json `QuickBarKeys`(null = 預設)
**剖面參數列**(只在 SectionEnabled 顯示)。新增功能要四處都接:選單分類、快速列註冊表
(含預設值)+ 對應 XAML 按鈕、**三個語言包的文字 key**;勾選清單存 settings.json `QuickBarKeys`(null = 預設)
- 使用者設定 `SettingsService`(%LOCALAPPDATA%\STPViewer\settings.json):視窗(MainWindow 管)+
單位/MRU(VM `LoadSettings`/`SaveSettingsInto`);壞檔回預設、儲存失敗靜默
- 匯出 STEP 走 `CADability.ExportStep.WriteToFile(file, Project.CreateSimpleProject()+Model.Add)`;
@@ -65,6 +65,13 @@ dotnet publish src/STPViewer -c Release -o publish/STPViewer
OnViewportClick 最前面攔點擊);換軸/關剖面/Esc 會重置。平面位置一律用「AABB 8 角投影到法向」內插,
軸向與任意法向共用同一段程式,不要改回逐軸特化
- 量測文字一律 `Func<UnitSystem,string>` 延後產生(mm⇄inch 即時切換);內部數值永遠存 mm
- 🌐 **多語系(v0.8.0,PR #1 by @CarmJos)**:介面文字**一律走 key,不可寫死字串**。語言包 `src/STPViewer/i18n/{en,zh_tw,zh_cn}.json`
(`key` = 選單顯示名、`data` = key → 譯文;建置時複製到 exe 旁,啟動掃描,加檔即新增語言免重編)。
XAML 用 `{loc:Loc Ui.Xxx}`;程式用 `LocalizationService.Get(key)` / `Format(key, args)`;
狀態列用 `SetStatus(() => Get(...))`(延後產生,切語言時 `RefreshLocalizedText()` 重算 — 直接設 `StatusText` 切語言不會更新)。
新增文字 key **三個 json 都要加**(`en.json` 是 key 清單正本;缺字執行期回退英文、再缺顯示 key 本身)。
key 命名:`Ui.Main.*`(主視窗)/ `Ui.StlExport.*` / `Ui.About.*` / `QuickBar.*` / `Runtime.*`(狀態列訊息)/ `App.*`。
選用語言存 settings.json `Language`(null = 依系統 UI 語系)。**程式碼註解維持中文**(設計理由與「不要改回 X」都寫在註解,勿精簡掉)
- 裝配樹節點(`ModelNodeViewModel`)的可見性/邊線/顏色向下 cascade
- 剖面只換 `GeometryModel3D.Geometry`(`FaceInfo.Mesh` 保留原始 frozen mesh 供還原與量測)
- ⚡ 剖面裁切是**背景平行**(v0.4.0):`ApplySection` 在 UI 快照 (model, frozen mesh) → `Task.Run`+`Parallel.For`
@@ -98,7 +105,8 @@ dotnet publish src/STPViewer -c Release -o publish/STPViewer
- 干涉/面距/對齊等運算在背景執行緒;`Freeze()` 幾何後才跨執行緒
- 匯入在背景執行緒;`Freeze()` 幾何後才跨執行緒
- 發新版:升 csproj `<Version>` 之外,記得在 `AboutDialog.xaml.cs` 的 `Changelog` 陣列**頂端**加一筆
(口吻寫給一般使用者:「你會感覺到什麼」,不是技術 changelog)。
(口吻寫給一般使用者:「你會感覺到什麼」,不是技術 changelog)。v0.8.0 起內容是 key
(`Ui.About.ReleaseXYZ.Title` / `.ChangeN`),**三個語言包都要寫**。
⚠️ WPF **頂層 MenuItem 直接掛 Click 不會觸發**(實測滑鼠/鍵盤都沒反應),要開視窗的入口一律放子選單(如 說明 → 關於)
- Commit 格式:Conventional Commits(`feat:` / `fix:` / `docs:` …)
@@ -133,7 +141,9 @@ dotnet publish src/STPViewer -c Release -o publish/STPViewer
`--align-test`(三點對齊剛體變換 + ModOp↔Matrix3D 一致性)、`--make-dxf`(產測試檔)、
`--export-test <in.stp> <out.stp>`(STEP 匯出往返:寫出→回讀比對實體數)、
`--stl-export-test [file.stp]`(STL binary/ASCII 往返 + 退化濾除;給 stp 加測 B-rep 精細重算)、
`--make-stl <out.stl> [triCount]`(產測試用 binary STL,預設 150 萬三角形,量 STL 匯入效能用)
`--make-stl <out.stl> [triCount]`(產測試用 binary STL,預設 150 萬三角形,量 STL 匯入效能用)、
`--localization-test`(語言包載入/回退/壞檔容錯 + VM 即時切換;改 i18n 或加文字要跑)
- Linux 也能編 Windows 版:`~/.dotnet/dotnet build/publish ... -p:EnableWindowsTargeting=true`(SmokeTest 是 net8.0-windows,只能在 Windows 跑)
- **絕不要用 PowerShell regex/Set-Content 改 .cs 檔** — Windows PowerShell 5.1 預設編碼會把 UTF-8 中文弄成亂碼(已踩過,靠反編譯 DLL 救回)。文字取代一律用 Edit 工具
## For_AI/