fix(ui): Use Transform3D.Identity instead of null after drag (v0.2.1)

Drag mode set BodyVisual.Transform = null when clearing the temporary
offset on release. HelixToolkit Viewport3DHelper.GetTransform adds
child.Transform to a GeneralTransform3DGroup without a null check, so
the next FindHits after any drag threw ArgumentException and crashed.

Clear the temporary transform with Transform3D.Identity instead.
Root cause confirmed by decompiling HelixToolkit.Wpf GetTransform.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 13:55:58 +08:00
co-authored by Claude Opus 4.8
parent dd15a83986
commit 9072842bba
3 changed files with 9 additions and 1 deletions
+3
View File
@@ -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(下一輪) ## Future Extensions(下一輪)
+3
View File
@@ -42,6 +42,9 @@ dotnet publish src/STPViewer -c Release -o publish/STPViewer
- 拖曳模式(`MeasureMode.Drag`):拖曳中只掛**暫時 `TranslateTransform3D`**GPU 免費),放開才一次性 `TranslateRoot` 烘進 B-rep — - 拖曳模式(`MeasureMode.Drag`):拖曳中只掛**暫時 `TranslateTransform3D`**GPU 免費),放開才一次性 `TranslateRoot` 烘進 B-rep —
**不要改成拖曳中逐幀 TransformRoot**(大檔每幀重建網格會卡死)。2D→3D 用 Helix `UnProject`(過錨點、法向=相機 LookDirection 的平面)。 **不要改成拖曳中逐幀 TransformRoot**(大檔每幀重建網格會卡死)。2D→3D 用 Helix `UnProject`(過錨點、法向=相機 LookDirection 的平面)。
合併網格的 hit-test 走 `_mergedMap`(合併 Model → leaf);拖曳中邊線用 `_edgesSuspended` 暫停 合併網格的 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()` 幾何後才跨執行緒
- 匯入在背景執行緒;`Freeze()` 幾何後才跨執行緒 - 匯入在背景執行緒;`Freeze()` 幾何後才跨執行緒
- Commit 格式:Conventional Commits`feat:` / `fix:` / `docs:` …) - Commit 格式:Conventional Commits`feat:` / `fix:` / `docs:` …)
+3 -1
View File
@@ -935,9 +935,11 @@ public partial class MainViewModel : ObservableObject
ModelNodeViewModel root = _dragRoot; ModelNodeViewModel root = _dragRoot;
Vector3D delta = _dragApplied; Vector3D delta = _dragApplied;
// 清除暫時位移:必須用 Identity,不可用 null —— HelixToolkit GetTransform 對 child.Transform
// 不做 null 檢查(Children.Add(null) 會拋「無法新增空值到集合中」),下次 FindHits 即 crash
foreach (ModelNodeViewModel l in root.Leaves()) foreach (ModelNodeViewModel l in root.Leaves())
if (l.BodyVisual is not null) if (l.BodyVisual is not null)
l.BodyVisual.Transform = null; l.BodyVisual.Transform = Transform3D.Identity;
_dragRoot = null; _dragRoot = null;
_dragTransform = null; _dragTransform = null;
_dragApplied = default; _dragApplied = default;