105061bade
feat: 贴合地面功能 + 通行空间尺寸准确化 + UI修复 (0.16.0)
...
贴合地面:点选物体表面自动贴地+搜索最小截面对齐路径
- AlignToGroundMinCrossSectionYawSearcher 搜索yaw
- ComposeHostCorrection 扣除CAD yaw+pathYaw避免重复旋转
- ComputeGroundLiftForCorrection 实测底边算lift
通行空间尺寸:实际旋转物体到X轴方向测AABB再转回
- MeasureXAlignedAabbAndSetCache 自动调整和贴合地面共用
- ObjectRotationCorrection setter 清空缓存修复手动改角度不同步
UI:调整物体窗口按钮区改Grid布局真正居中
版本号 0.15.8 -> 0.16.0
2026-06-26 09:17:46 +08:00
3cb5d8d423
fix: 贴地后用实际旋转物体到X轴方向测AABB获取准确通行空间尺寸
...
路径斜向时世界AABB投影偏大,纯数学旋转AABB也会膨胀。
改为用Navisworks API实际旋转物体到X轴方向测量AABB,再转回来:
- 算路径方向相对X轴的夹角 angleToX
- 绕hostUp旋转物体 -angleToX 使路径对齐X轴
- 测AABB:X=沿路径长度,up轴=高度,非up轴=宽度
- 转回来恢复姿态
清理STEP1-STEP6诊断日志,保留STEP7为正式日志。
2026-06-25 08:53:14 +08:00
5308552b40
修改贴合后,路径宽度和通行空间高度不正确的问题
2026-06-24 20:42:51 +08:00
66e68c6bd1
fix: 贴合地面后正确回写 correction 和 lift,确认/动画不再偏移
...
贴地后 overrideQ 是绝对旋转,但 _objectRotationCorrection 语义是
相对于 baseline(pathYaw) 的增量,且 PathAnimationManager 增量链从
CAD 姿态出发:finalQ = qup(pathYaw-currentYaw) * correctionHostQ * cadQ。
之前直接转 overrideQ 导致确认/动画时重复旋转。
核心改动:
- ComposeHostCorrection 接受 cadQ,从中提取 currentYaw,
correctionHostQ = qup(currentYaw - pathYaw) * overrideQ
- HostQuaternionToCanonical 用相似变换 R_canon = M^-1 * R_host * M
(非列向量映射,保证 Identity 不变性)
- CanonicalQuaternionToHostEulerCorrection 加 hostType 参数重载,
去除全局 CoordinateSystemManager 依赖
- ComputeGroundLiftForCorrection:与自动调整同方法实测底边算 lift,
finally 用新 correction+lift 完整重建(skipCadRestore=false),
使物体停留在贴地等价姿态
- 新增 5 个增量链闭环单测(含 CAD 歪斜场景)
2026-06-24 08:24:38 +08:00
cf6b2ef959
fix: 修复 7 个 pre-existing 单测失败(optimizer 初始候选 + ZUp 测试语义)
...
ObjectPassageProjectionOptimizer.OptimizeWithEvaluator:
- 初始化 bestScore 评估 correction=Zero 作为初始候选
- 旧逻辑 bestScore=Invalid 导致 Zero 从未被评估,
当 baseline 已对齐路径时随机采样必然替换它,refine 收敛不回 0
- 影响 3 个 Optimize 测试:baseline 已对齐时找不到 correction=0
ZUp 测试语义修正(4 个):
- LocalEulerRotationCorrection 语义:Y=up轴/yaw, Z=non-up轴
- ZUp 下 up=Z, non-up=Y,绕 Z(up) 转应使用 YDegrees 不是 ZDegrees
- 旧测试在 ZUp 下把 ZDegrees 当字面 Z 轴,与实现语义矛盾
2026-06-23 23:18:42 +08:00
7f3be8495c
fix(tests): 修复 AliasTreeTests 编译错误并更新过时旧格式兼容测试
...
- SetAlias 调用补全缺失的 alias 参数(DeleteByPathPrefix 测试)
- 移除 4 个旧格式兼容测试,改为期望抛 FormatException
(FromKey 已按 AGENTS.md "不向后兼容" 原则移除旧格式支持)
2026-06-23 23:12:40 +08:00
f86e8c8bf4
fix: 贴合地面后绕垂直轴搜索最小截面 yaw,对齐路径方向
...
贴地旋转已固定俯仰/翻滚,只剩绕宿主 Up 的 yaw 自由度。
对 CAD 姿态天然歪斜的物体,假设 local +X 是长轴会失败,
改为搜索 [0,360) 使物体在路径方向的截面投影面积最小,
与自动调整同目标但单自由度搜索更稳定。
- 新增 AlignToGroundMinCrossSectionYawSearcher(粗搜5°+细搜1°)
- 复用 ObjectPassageProjectionOptimizer.ProjectExtent 的 AABB 投影公式
- 新增 7 个单测覆盖平地/倾斜/CAD歪斜/垂直退化/立方体
- 经多物体实测验证:Chair Lounge Couch / Chair Sitting Square 均正确对齐
2026-06-23 23:09:59 +08:00
75afba7670
docs: 去掉UTF-8显式设置,已配好pwsh profile
2026-06-10 17:48:48 +08:00
020e265918
docs: pwsh 命令加 UTF-8 输出编码设置
2026-06-10 17:45:16 +08:00
e9fb47d9ad
docs: shell命令统一用pwsh执行
2026-06-10 17:44:43 +08:00
82caa3e155
feat: 贴合地面加入路径yaw补偿,物体旋转后长边对齐路径方向
2026-06-09 11:37:03 +08:00
63b59890e4
refactor: 贴合地面改为独立操作(选面即生效),确认按钮去分支,上下偏移默认物流车高度
2026-06-09 11:25:50 +08:00
999fffcaa7
fix: 贴合地面:恢复git版本旋转逻辑 + 底边贴地高度修正
2026-06-09 10:06:12 +08:00
034acb1d65
fix: 贴合地面旋转修正 — 路径起点法向量→CAD空间算对齐,直接 OverridePermanentTransform 施压
...
- 读路径起点 ActiveTransform 取 psQ,复位 CAD 后取 cadQ
- 路径起点世界法向量→inv(psQ)→局部→cadQ→CAD 世界法向量
- CAD 世界法向量→-hostUp 算 overrideQ
- 直接 OverridePermanentTransform 施加,不走 ApplyRotationCorrectionInPlace
- 待加平移
2026-06-09 08:42:42 +08:00
f75dcb1f50
refactor: use PathAnimationManager.ApplyQuaternionRotationInPlace
...
- New method mirrors proven ApplyRotationCorrectionInPlace pattern
- ViewModel only calls existing project APIs, no raw OverridePermanentTransform
2026-06-09 03:39:56 +08:00
3634551e53
fix: use incremental transform to preserve path start position
...
- Don't ResetPermanentTransform (keeps path placement)
- Apply rotation around object center as incremental transform
- T(-center) * R * T(center) via Transform3D.Multiply
2026-06-09 03:37:35 +08:00
c8d48755db
fix: apply face-to-ground rotation directly via quaternion, skip Euler decomposition
...
- Use existing OverridePermanentTransform pattern from PathAnimationManager
- Compute quaternion from face normal → ground direction
- Apply directly as Rotation3D with center-preserving translation
- Sync tracked state after application
2026-06-09 03:32:26 +08:00
10a0ad754c
fix: move face-to-ground mate logic from modal dialog to ViewModel
...
- Modal ShowDialog blocks Navisworks ToolPlugin message loop
- Now: '贴地面' sets MateToGroundRequested flag, closes dialog
- AnimationControlViewModel handles FaceInferToolPlugin activation
- OnFaceToGroundInferred computes rotation and applies directly
2026-06-09 03:22:50 +08:00
2f16ec0d43
fix: add debug log, use NavisApplication alias in EditRotationWindow
2026-06-09 03:18:20 +08:00
9ea3cc0e02
feat: add '贴地面' face-to-ground mate in EditRotationWindow
...
- New button activates FaceInferToolPlugin to pick face on object
- Computes rotation from face normal to ground direction
- Decomposes to ZYX Euler angles, fills X/Y/Z fields
- User can preview and confirm as usual
2026-06-09 03:12:22 +08:00
2e959c16c9
chore: bump version to 0.15.8, update changelog
2026-06-09 03:01:18 +08:00
ea0ea1c3ca
refactor: remove old 2-click installation point code
...
- Remove ExecuteSelectAssemblyInstallationPointAsync
- Remove OnAssemblyInstallationMouseClicked
- Remove BeginAssemblyInstallationSelection
- Remove BuildAndRenderAssemblyInstallationReference
- Single-click '选安装面' is now the only way
2026-06-09 02:57:45 +08:00
d3b2906169
feat: add FailureReason to FaceInferResult for specific error messages
...
- FaceInferToolPlugin now returns specific reasons: '未命中模型' or '表面过窄'
- ViewModel handlers show FailureReason instead of generic '未命中有效表面'
- Catch exceptions still pass through BuildFromFaceNormal error messages
2026-06-09 02:53:41 +08:00
cd05553dd9
fix: remove all generic/instructional text from error dialogs
...
- Keep only the actual error reason, no '请先...' guidance
- Each condition shows its specific cause, exceptions pass through raw
2026-06-09 02:48:33 +08:00
5be6dfdaf3
fix: split ambiguous failure message in OnInstallationFaceInferred
...
- Separate 'no terminal object' from 'invalid pick' case
- Remove misleading '请先取端面' from surface pick failure
2026-06-09 02:42:51 +08:00
6a1318602e
fix: pass through exception message directly instead of generic wrapper
...
- BuildFromFaceNormal already provides specific error like '面法向与光轴平行'
- Catch now shows raw ex.Message instead of prefixing with generic text
2026-06-09 02:40:35 +08:00
9e1056b92c
feat: add DialogHelper.ShowStatusAndDialog for unified status+dialog feedback
...
- Replaces scattered UpdateMainStatus + ShowAutoClosingMessageBox calls
- Accepts Action<string> callback for ViewModel status bar update
- Applied to all end face and installation face failure handlers
2026-06-09 02:36:21 +08:00
6b78b851db
refactor: rename to remove 'Quick' prefix after old method removal
...
- QuickAnalyzeAssemblyEndFaceCommand → AnalyzeAssemblyEndFaceCommand
- CanQuickAnalyzeAssemblyEndFace → CanAnalyzeAssemblyEndFace
- BeginAssemblyEndFaceQuickPick → BeginAssemblyEndFacePick
- OnQuickEndFaceInferred → OnEndFaceInferred
2026-06-09 02:06:44 +08:00
0fe7179494
refactor: replace 3-click end face detection with single-click FaceInferTool
...
- Remove '找端面' button and all 3-click logic
- Keep single-click '取端面' button only
- Remove: AnalyzeCurrentAssemblyEndFace, BeginAssemblyEndFaceSelection,
OnAssemblyEndFaceMouseClicked, ExecuteAnalyzeAssemblyTerminalFaceAsync
- Retain CleanupAssemblyEndFaceSelection (shared with quick pick)
2026-06-09 02:04:54 +08:00
01195434b7
fix: use ancestor chain check for pick item matching terminal object
...
- PickItemFromPoint returns leaf geometry, not the parent container
- Check if pickItem is terminalObject or its descendant via AncestorsAndSelf
2026-06-09 01:58:09 +08:00
e485629360
tweak: rename quick end-face button to '取端面'
2026-06-09 01:53:53 +08:00
16bf5cc10e
feat: integrate FaceInferToolPlugin with Rail assembly end face detection
...
- Add '快速取端面' button in Rail assembly workflow
- Single click → FaceInferToolPlugin → AssemblyEndFaceAnalyzer.Analyze(hitPoint, normal)
- Replaces 3-click manual seed point workflow
2026-06-09 01:53:36 +08:00
e7b5206198
feat: add single-point+normal overload to AssemblyEndFaceAnalyzer
...
- New Analyze(triangles, hitPoint, normal) bypasses 3-point seed plane construction
- New Analyze(modelItem, hitPoint, normal) for Navisworks types
- Same triangle extraction and centroid computation as 3-point version
- Enables single-click end face detection via FaceInferToolPlugin
2026-06-09 01:51:05 +08:00
1e45546aed
chore: 更新 CHANGELOG 和 VERSION 至 0.15.7
2026-06-08 04:20:59 +08:00
b533153234
chore: 删除废弃的 PatternSearchDeltas 和 NormalizeDegrees
2026-06-08 03:36:16 +08:00
b17df9aa31
fix: 四元数均匀采样替代欧拉角网格,模式搜索改为四元数邻域
...
- 网格搜索: S³ 均匀随机四元数 → canonical→host Euler,512→256 采样点
- 模式搜索: 7轴×2方向四元数乘法搜索,替代欧拉角 delta
- 去掉 CandidateAngles/Euler 网格+PatternSearchDeltas/NormalizeDegrees
- canonical 空间桥接保证 YUp/ZUp 兼容
2026-06-08 03:35:33 +08:00
51453df037
chore: 更新 CHANGELOG 和 VERSION 至 0.15.6
...
- 记录自动调整评测与姿态对准修正、skipCadRestore 重构
- 记录别名树 DisplayPath 重名修复
- 版本号 0.15.4 → 0.15.6
2026-06-06 13:12:18 +08:00
f5387c8699
fix: 自动调整评测与姿态对准修正
...
1. GetYawFromRotation: 通过 canonical space 转换计算 yaw,修复 YUp 下 atan2(Y,X) 用错平面
2. ApplyRotationCorrectionInPlace: 新增 CAD 原位纯旋转,评测旋转顺序与增量链一致
3. 评测器两轮优化: 先无约束找最小面积,不满足约束再带约束重搜
4. ApplyAutoAdjustedPoseAndMoveToPathStart: 确认时先校正再偏航,不读 CAD yaw
5. OnAutoAdjustClick: 去掉 Y 轴 yaw 叠加
2026-06-06 12:47:12 +08:00
f38fba6506
fix: DisplayPath 所有层级加#N去重 + 移除旧格式兼容
...
- BuildNode 不再剥离父路径#N后缀
- FromModelItem 对每层祖先计算 siblingIndex 追加#N,与树加载一致
- 解决复制子树中节点别名泄露给其他子树的问题
- FromKey 移除纯 DisplayPath 旧格式兼容
2026-06-06 10:05:35 +08:00
7dec26b1ac
fix: replace RowStyle IsSelected binding with SelectionChanged event
...
- RowStyle TwoWay binding on IsSelected is unreliable with virtualizing DataGrid
- Switched to DataGrid.SelectionChanged event handler in code-behind
- Syncs RemovedItems/AddedItems to ViewModel.IsSelected reliably
2026-06-04 21:42:07 +08:00
6b8bae2afc
fix: clear all IsSelected flags after export to prevent stale selections
...
- Added finally block to reset IsSelected on all PathRoutes
- Prevents multi-select state from leaking into subsequent single exports
2026-06-04 21:36:52 +08:00
897280bb3f
fix: show concatenated path names as dialog filename for multi-select export
...
- Single: path name as default filename (unchanged)
- Multi: semicolon-separated names as hint, each file still saved individually
2026-06-03 21:16:52 +08:00
1beaa7b24d
Revert "fix: use folder dialog for multi-select export, file dialog for single"
...
This reverts commit 6d14d1d26f .
2026-06-03 21:16:28 +08:00
6d14d1d26f
fix: use folder dialog for multi-select export, file dialog for single
...
- Single selection: SaveFileDialog with path name as default filename
- Multi selection: FolderBrowserDialog to pick output directory
- Export format: XML for multi (simpler UX), selectable for single
2026-06-03 21:11:41 +08:00
ac2de23e32
feat: support multi-select and batch export in path list
...
- DataGrid: SelectionMode Extended with RowStyle IsSelected binding
- PathRouteViewModel: add IsSelected property
- Export: iterates selected paths, saves each to separate file
- Ctrl/Shift+click to multi-select, then Export button batches them
2026-06-03 21:06:32 +08:00
c0714a5180
fix: regenerate path point IDs and rebuild edges on import rename
...
- Also regenerate all PathPoint.Id to avoid UNIQUE constraint on PathPoints.Id
- Call RecalculateRoute() to rebuild edges with new point references
- Edge constructor auto-generates new Id, so edges are fresh too
2026-06-03 20:58:49 +08:00
c6afef13de
fix: generate new GUID when renaming imported path to avoid DB conflict
...
- Imported routes with same Id would overwrite each other in DB
- Now assign route.Id = Guid.NewGuid() on rename, ensuring unique DB entry
2026-06-03 20:54:08 +08:00
0cff495331
fix: prevent duplicate database save during XML import deserialization
...
- ParseRouteElement used route.AddPoint() which called RecalculateAndSaveRoute
- This saved the path to DB with original name before ImportPathCommand could rename it
- Changed to route.Points.Add() + route.RecalculateRoute() to skip DB save
- Only ImportPathCommand → AddRoute → SavePathToDatabase now persists renamed path
2026-06-03 20:44:52 +08:00
c2a37fe007
fix: only count rename when name actually changed during import
...
- Capture original name before GenerateUniqueName
- Skip RenamedCount increment if names are identical
- Fix misleading log showing same name twice
2026-06-03 20:34:49 +08:00
0967f7a9bc
feat: show renamed count in import result dialog
...
- Add RenamedCount to ImportPathResult
- Track per-file and aggregate across multi-file imports
- Dialog now shows '重名自动重命名: N 个路径' when applicable
2026-06-03 20:29:28 +08:00