diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 25be026..2f78982 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -323,6 +323,9 @@ NuGet 相依(自動還原):`CADability`、`HelixToolkit.Wpf`、`CommunityT **驗收:** 大組件手形拖曳流暢;放開後干涉/量測結果與拖曳位置一致;右鍵視角操作不受影響 +> v0.2.1 修正:拖曳放開時清除暫時位移誤用 `Transform = null`,導致下次 `FindHits` 命中該檔案時 +> HelixToolkit `GetTransform` 對 null transform `Add` 而 crash。改用 `Transform3D.Identity`。 + --- ## Future Extensions(下一輪) diff --git a/CLAUDE.md b/CLAUDE.md index 8a181a1..2081cc6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,6 +42,9 @@ dotnet publish src/STPViewer -c Release -o publish/STPViewer - 拖曳模式(`MeasureMode.Drag`):拖曳中只掛**暫時 `TranslateTransform3D`**(GPU 免費),放開才一次性 `TranslateRoot` 烘進 B-rep — **不要改成拖曳中逐幀 TransformRoot**(大檔每幀重建網格會卡死)。2D→3D 用 Helix `UnProject`(過錨點、法向=相機 LookDirection 的平面)。 合併網格的 hit-test 走 `_mergedMap`(合併 Model → leaf);拖曳中邊線用 `_edgesSuspended` 暫停 +- ⚠️ **`Visual3D.Transform` 永遠不要設成 `null`,清除要用 `Transform3D.Identity`**。HelixToolkit `Viewport3DHelper.GetTransform` + 對 `child.Transform` 沒做 null 檢查(`GeneralTransform3DGroup.Children.Add(null)` → 拋「無法新增空值到集合中」), + 之後任何 `FindHits` 都會 crash。v0.2.1 修的就是拖曳放開時把 BodyVisual.Transform 設 null(拖過一次後再點擊就炸) - 干涉/面距/對齊等運算在背景執行緒;`Freeze()` 幾何後才跨執行緒 - 匯入在背景執行緒;`Freeze()` 幾何後才跨執行緒 - Commit 格式:Conventional Commits(`feat:` / `fix:` / `docs:` …) diff --git a/src/STPViewer/ViewModels/MainViewModel.cs b/src/STPViewer/ViewModels/MainViewModel.cs index 43398d1..f7bd2d5 100644 --- a/src/STPViewer/ViewModels/MainViewModel.cs +++ b/src/STPViewer/ViewModels/MainViewModel.cs @@ -935,9 +935,11 @@ public partial class MainViewModel : ObservableObject ModelNodeViewModel root = _dragRoot; Vector3D delta = _dragApplied; + // 清除暫時位移:必須用 Identity,不可用 null —— HelixToolkit GetTransform 對 child.Transform + // 不做 null 檢查(Children.Add(null) 會拋「無法新增空值到集合中」),下次 FindHits 即 crash foreach (ModelNodeViewModel l in root.Leaves()) if (l.BodyVisual is not null) - l.BodyVisual.Transform = null; + l.BodyVisual.Transform = Transform3D.Identity; _dragRoot = null; _dragTransform = null; _dragApplied = default;