a8a786d807
refactor: rename and reorder path creation buttons
...
- Rename '手动创建' to '地面路径'
- Rename '传统空轨路径' to '空轨路径'
- Move 空轨路径 after 吊装路径 (Ground → Hoisting → Rail order)
2026-06-03 20:07:33 +08:00
469f529fa0
tweak: increase path list DataGrid height from 200 to 340 (7→12 rows)
2026-06-03 20:02:51 +08:00
750559a560
refactor: collapsible test section with Grid layout in SystemManagement
...
- Wrap test buttons in Expander (default collapsed)
- Replace horizontal StackPanel with 3-column Grid layout
- Simplify button labels by removing redundant 'test' wording
2026-06-03 20:00:00 +08:00
6bc77672e9
fix: prevent crash when invalid characters typed in coordinate editor
...
EditableNumberConverter.ConvertBack was throwing FormatException
when users typed '=' or other non-numeric characters, causing
WPF binding validation to crash the application on focus change.
Changed to return Binding.DoNothing to silently reject invalid input.
2026-06-03 19:49:44 +08:00
0ed24b21a2
refactor: change virtual object RadioButton to CheckBox in AnimationControlView
2026-06-03 19:45:07 +08:00
c7a1eeebb8
feat: add FaceInferToolPlugin - single-click face normal inference tool
...
- New FaceInferToolPlugin: pixel-neighborhood method with {2,5,10}px offsets
- New FaceInferResult data class
- Test button in SystemManagement page
- Cursor: MarkupAutoPoly (arrow + dashed box)
- Uses project-standard tools: FindNamedParentContainer, viewpoint.Position
- Design doc at doc/design/2026/face-infer-tool-design.md
2026-06-02 23:11:11 +08:00
922864ce4f
style: 别名树字体 SemiBold → Bold
2026-06-02 13:02:16 +08:00
337ccbb43b
fix: OnTreeViewSelected NRE + 日志清理
...
- _isInternalSelection 为 true 时 OnTreeViewSelected 直接 return,阻断 NW→树→NW 循环
- 调试日志降为 Debug 级别
- doc.CurrentSelection 加空检查
2026-06-02 12:58:38 +08:00
8a8153dba0
fix: use ShouldUseReferenceBasedRealObjectPlanarPose to guard reference rotation capture
...
Ground and Hoisting paths don't consume fragment reference rotation, only Rail does.
Replace manual PathType checks with the existing semantic utility method.
Also fix GetPathRouteSync SELECT missing IsTwoPointVertical column.
2026-06-02 12:41:31 +08:00
2ff4cb1678
fix: 2-point vertical path point modification no longer constrained by hoisting height limits
...
- Skip height constraints, orthogonalization, and intermediate point insertion
- Auto-recalculate LiftHeight from elevation difference between the two points
2026-06-01 23:55:04 +08:00
a8c5681dfb
feat: separate 2-point vertical hoisting path from regular hoisting
...
- Add IsTwoPointVertical flag on PathRoute to distinguish pure vertical paths
- 2-point paths skip hoisting-specific logic: ResolveHoistingTrackedCenter,
TryCreatePlanarPathRotationForFrame, ground-contact segment classification
- Endpoint semantics: center reaches endpoint (not top-face constrained)
- Frame interpolation applies same ResolveGroundTrackedCenter as move-to-start
- Add database migration for IsTwoPointVertical column
- Update CHANGELOG for v0.15.4
2026-06-01 23:31:00 +08:00
64a27f4c29
feat: add 2-point vertical hoisting path support
...
- Add '2点路径' button in AerialHeightDialog for pure vertical lift
- Handle IsTwoPointMode on first click to create 2-point path directly
- Fix PathTargetFrameResolver to accept 2-point Hoisting paths
- Fix animation yaw for 2-point vertical paths (use _currentYaw)
- Fix TryApplyPlanarRealObjectStartIncrementalTransform to translate even
when no rotation change (was skipping translation for pure vertical)
- Guard _pathPoints[2] access in animation code for <3 points
2026-06-01 22:56:50 +08:00
a375e977d4
style: 别名树面板统一白色背景 + TreeView MinWidth=300
2026-06-01 11:04:18 +08:00
f8319438e9
fix: 无 DisplayName 的几何体节点显示为「几何对象」而非空字符
2026-06-01 10:39:57 +08:00
a5f9e4da24
feat: MaxFullDisplayDepth 改为从配置文件读取,支持实时生效
...
- SystemConfig 新增 AliasTreeConfig,含 MaxFullDisplayDepth 属性(默认 2)
- ConfigManager 添加 [alias_tree] 段的 TOML 解析和写入
- default_config.toml 添加 [alias_tree] 配置项
- AliasTreeControl 构造时读取配置 + 订阅 CategoryConfigurationChanged 实时重建
2026-06-01 10:30:21 +08:00
d670ae5c3c
perf: BuildNode 延迟 CreatePathId + DisplayPath 同名去重修复
...
- BuildNode 不再调 FromModelItem/CreatePathId,改用父节点 DisplayPath 拼接
- CreatePathId 只在保存别名时通过 EnsureFullNodeKey 触发
- LazyLoadChildren 用 nameCount 字典计算 siblingIndex,BuildNode 追加 #N 去重
- 子节点 DisplayPath 拼接时剥离父路径中的 ||前缀和#N后缀,与 FromModelItem 一致
- LazyLoadChildren 直接用 parentNode.ModelItem,不再调 FindModelItemByNodeKey
- 别名匹配去掉 fallback,精确到#N
- _dataStore.LoadAll() 提升到循环外
2026-06-01 10:21:02 +08:00
61318b450d
chore: DockPane 标题「别名导航树」→「别名树」
2026-06-01 09:12:28 +08:00
fddefde1ed
docs: 更新别名树实施方案 — 新增显示原则 + 修正标识/定位/联动描述
...
- 新增第7节「别名树显示原则」:二条件OR逻辑、深度限制、别名特殊规则、按需加载生命周期
- 第4节:标识改为 CreatePathId格式,定位改为 Models.ResolvePathId
- 第10节:JSON导出格式改为 key 字段
- 第11节:双向联动改为 ModelItem.Parent链 + ExpandAndSelect
- 清理 CleanupOnDemandNodes 逻辑文档化
2026-06-01 09:10:47 +08:00
6260c175d4
fix: 别名树 IndexPath 改用 Navisworks 官方 API CreatePathId/ResolvePathId
...
- AliasNodeIdentity.FromModelItem: 用 doc.Models.CreatePathId 替代 GetModelItemIndexPaths
- 存储格式统一为 'modelIndex:PathId'(冒号分隔,PathId 为斜杠分隔)
- FindModelItemByNodeKey: 用 Models.ResolvePathId 替代手写 LocateByIndexPath
- 删除 LocateByIndexPath、LocateByDisplayPath、LoadPathChild、EnsureChildLoaded
- 与 PathAnimationManager/BatchQueueManager 使用完全一致的 PathId 格式
2026-05-31 23:26:54 +08:00
f7544a2095
fix: 别名树深度超限节点导航 — 改用 ModelItem.Parent 链替代 IndexPath
...
- 移除 IndexPath 解析/偏移量等易错逻辑
- ExpandAndSelect 改为沿 ModelItem.Parent 链回溯,ModelItem.Equals 匹配
- 深层节点通过 BuildNode 直接创建,不依赖占位/懒加载通道
- 删除 LoadPathChild、EnsureChildLoaded 等废弃方法
- 清理约 10 行净代码
2026-05-31 22:30:54 +08:00
ea49774f39
fix: no silent catch - log all exceptions
2026-05-31 18:14:09 +08:00
6a3be184a6
fix: crash from VisualTreeHelper.GetParent during rapid clicks
...
- OnTreeViewItemLeftClick: use e.OriginalSource.DataContext directly,
not visual tree traversal (FindAncestor)
- _isProgrammaticExpand prevents Expanded event from triggering bulk
LazyLoadChildren during ExpandAndSelect
- OnNavisSelectionChanged: synchronous processing with _isInternalSelection
guard prevents feedback loop
- Try-catch wrappers on all COM API call sites (FromModelItem, BuildNode)
2026-05-31 18:12:34 +08:00
cba8e3f3b7
feat: depth-limited tree display for performance
...
- MaxFullDisplayDepth=2: only show full tree up to level 2
- Beyond max depth, nodes only expand if they have an alias
- AliasNodeViewModel.Depth tracks tree depth
- Reduces loaded nodes for large models with deep unaliased branches
2026-05-31 17:28:05 +08:00
7418fe28aa
feat: JSON import/export for aliases + crash protection
...
- Export: JavaScriptSerializer, .alias.json format matching path data pattern
- Import: merge mode (overwrites existing keys, adds new)
- Try-catch wraps on SetAlias, RefreshAliases, NW selection operations
- Prevents crashes from database inconsistency or API exceptions
2026-05-31 17:10:32 +08:00
4da6669707
refactor: lazy database creation - match path planning pattern
...
- TryConnectToDatabase: createIfMissing=false (only connect, don't create)
- New BeforeSaveAlias event + EnsureDatabaseCreated: creates DB on first save
- Matches MainPlugin.TryConnectPathDatabase pattern
2026-05-31 16:56:57 +08:00
af7099d682
fix: alias persistence - trigger DatabaseInitialize on connect
...
- TryConnectToDatabase calls DatabaseInitialize(createIfMissing:true)
- Alias saving now creates .db file if it doesn't exist
- Removed delayed retry code (no longer needed)
- Added diagnostic logging for SetDataStore/RefreshAliases
2026-05-31 16:40:54 +08:00
903ed856e3
feat: display alias with [original name] suffix, fix false alias detection
...
- Two stacked TextBlocks: alias (red, bold) + [原文] (black, bold)
- [原文] suffix only visible when HasAlias=true
- CommitEdit/toolbar: treat unchanged text as no alias (set to null)
- Fixes: nodes edited without actual changes no longer show false [原文] suffix
2026-05-31 16:29:17 +08:00
d358c31a7d
feat: inline editing with click-to-edit, TextBox overlay, Focus+SelectAll
...
- Grid overlay: TextBox covers TextBlock when editing (no more dual display)
- EditValue property: auto-initialized to DisplayName on edit start
- Click on already-selected node enters inline edit (PreviewMouseLeftButtonDown)
- Right-click auto-selects node before context menu
- TextBox IsVisibleChanged: Focus + SelectAll on Loaded priority
- XAML Visibility moved to Style setter (fix DataTrigger precedence)
- Light yellow background (#FFFFFDE6)
2026-05-31 15:52:03 +08:00
ad398652a7
feat: alias persistence via PathDatabase SQLite
...
- AliasTreePlugin 监听文档生命周期,连接 PathDatabase
- AliasDataStore 写入 PathDatabase.SQLiteConnection
- 编辑别名实时持久化,重启后自动恢复
- 修复 _isInternalSelection 阻塞 _currentSelectionItem 更新导致编辑写错节点
2026-05-31 14:59:54 +08:00
9a6859cdb5
style: match Navisworks Selection Tree font/color
...
- 别名用暗红色字体 (#C62828),原名用黑色
- 选中态:浅灰蓝底色 (#3A6EA5) + 白色字体,无焦点时也保持
- 字体加粗 SemiBold,字号 12px
- 移除斜体灰色样式和方块标记
2026-05-31 14:47:01 +08:00
b42cf02710
fix: bidirectional sync working for deep nodes + scroll-into-view
...
- 关掉 VirtualizingPanel 虚拟化(树是懒加载,虚拟化收益小但导致 ContainerFromItem 失败)
- ExpandAndSelect 重写为 IndexPath 纯 ViewModel 导航,不依赖 TreeViewItem
- 新增 GetTreeViewItemForNode:从 TreeView 根沿 parent 链找 Tvi
- IndexPath -1 修正(COM 路径从 1 开始计数,.NET Children 从 0)
- BringIntoView 延迟到 Dispatcher.Background
- 清理无用代码(ExpandAndSelectRecursive)
2026-05-31 14:21:50 +08:00
c002feee51
fix: ExpandAndSelect uses ModelItem.Equals for precise sibling matching
...
- 新增 AliasNodeViewModel.ModelItem 属性(持有 Navisworks 原生引用)
- BuildNode 中存储 ModelItem
- ExpandAndSelect 重写为 DFS 递归,用 ModelItem.Equals 精确匹配
(同 ModelItemAnalysisHelper.ModelItemEquals 逻辑,底层原生对象比较)
- 不再依赖 IndexPath 或 _nodeMap 做选中同步
2026-05-31 13:17:52 +08:00
4feb12f6b9
refactor: AliasNodeIdentity dual-field + reuse ModelItemAnalysisHelper
...
- 新增 IndexPath(COM 树索引路径),复用 ModelItemAnalysisHelper.GetModelItemIndexPaths
- 保留 DisplayPath(父链 DisplayName 拼接)作为降级匹配
- 序列化格式:"IndexPath||DisplayPath",向后兼容纯 DisplayPath
- FindModelItemByNodeKey: IndexPath 优先定位,DisplayPath 降级
- BuildNode: 新增旧格式兼容查找
- 单元测试全面更新覆盖新/旧格式、双字段解析、前缀匹配
2026-05-31 12:52:26 +08:00
56d18c696c
phase 2b: add AliasTreePlugin DockPanePlugin entry + wiring
...
- AliasTreePlugin.cs: DockPanePlugin with ElementHost wrapper
- XAML: wire Expanded/Selected event handlers via TreeViewItem
- Both projects compile, plugin deployed to Navisworks
2026-05-31 12:49:50 +08:00
f3392ddbf6
phase 2: VM + TreeView skeleton for alias tree
...
- AliasNodeViewModel: INotifyPropertyChanged, alias/display/editing state
- AliasTreeIcons.xaml: vector icon geometry + toolbar/button styles
- AliasTreeControl.xaml: TreeView with icon toolbar, status bar, context menu
- AliasTreeControl.xaml.cs: tree building, lazy loading, bidir selection sync,
inline editing, alias highlight (via ModelHighlightHelper)
- Both projects compile successfully
2026-05-31 12:49:14 +08:00
3f985aa235
phase 1: data layer for alias tree
...
- AliasNodeIdentity: stable composite node identifier (path + sibling index)
- AliasDataStore: CRUD operations on SQLite AliasMap table
- PathDatabase: add AliasMap table creation + index
- Unit tests: 30 tests for identity parsing/equality, store CRUD/batch/import
- Both projects compile successfully
2026-05-31 12:46:33 +08:00
56a1ef55f4
0.15.3: misc fixes - rail helper cleanup, screenshot + button, database version
2026-05-30 19:15:34 +08:00
7189e17e3d
fix indentation for AabbSx/Sy/Sz properties
2026-05-30 02:54:42 +08:00
1ca2a8e1bc
0.15.3: auto-adjust uses optimizer AABB directly for passage space visualization
...
- Optimizer now returns AABB extents (sx, sy, sz) from measured object
- UpdatePassageSpaceVisualization uses optimizer AABB directly:
Forward=sx, Width=sz, Height=sy - no cuboid projection needed
- Fixed negative passageNormalToPath when lift offset is negative
- Removed host-axis cuboid projection from TryCalculateCurrentRealObjectPlanarProjectedExtents
2026-05-30 02:48:39 +08:00
b25a3a04a1
0.15.3: fix auto-adjust rotation order mismatch in CreateCanonicalRotationCorrection / CreateHostRotationCorrection
...
- Rotation multiplication order was qz*qy*qx (Z*Y*X) which didn't match
MoveItemCombinedAxisRotationAndTranslation's up*nonUp*X order for YUp hosts.
Switched to qup * qnonUp * qx using canonical space axes, works for both YUp and ZUp without HostType branching.
- ComputedLiftOffsetMeters -> ComputedLiftOffsetModelUnits, removed intermediate meter conversions.
- EditRotationWindow auto-adjust button now shows wait cursor.
2026-05-30 00:22:42 +08:00
af141aa37c
自动调整:去掉米单位混用,内部统一模型单位;ComputedLiftOffsetMeters -> ComputedLiftOffsetModelUnits;EditRotationWindow 添加等待光标
2026-05-30 00:01:20 +08:00
90367db214
自动调整Info日志改为Debug
2026-05-29 01:49:39 +08:00
c67dee4f11
约束保留门型偏好,评估改用固定宿主X轴前向,结果加回路径yaw
2026-05-29 01:44:23 +08:00
649c7b50f1
0.15.2 WIP: 自动调整 — 门型偏好、物流车高、上下偏移自动计算、性能优化、日志清理
2026-05-28 23:58:27 +08:00
61b063d8c6
Y轴输入框添加旋转90°图标按钮; 窗口布局优化
...
- Y 轴输入框后增加 ↻ 按钮(IconButtonStyle + RotateIconGeometry),
点击使当前 Y 值增加 90°
- 角度超过 360° 自动归一化(NormalizeDisplayDegrees)
- 布局改为 3 列统一宽度,Y 轴第 3 列与 X/Z 一致
- 快捷角度按钮和底部操作按钮均居中分布
- 窗口宽度 440→470 适配按钮空间
2026-05-27 15:24:12 +08:00
16a81964f1
优化自动调整: 合并三次旋转为单次 OverridePermanentTransform,NW 调用减少 80%
...
旧代码在 TryApplyPlanarRealObjectStartIncrementalTransform 中通过三次
MoveItemIncrementallyByAxisRotationAndTranslation 依次施加 X、非-up、up 轴
旋转,每轴内部 3 步 (toOrigin→rotate→toTarget),合计 9 次 Override 调用。
新方法 MoveItemCombinedAxisRotationAndTranslation 将三个轴旋转用
四元数 (qYaw × qNonUp × qX) 合成一次,配合组合平移做单次 Reset+Override,
每轮 Evaluator 调用从 ~10 次 NW API 降至 ~3 次,自动调整整体从 5s 降至 <2s。
语义完全保留:三次旋转的轴/角度/顺序与原来一致(X→Z/Y→Yaw,
通过 q3×q2×q1 左乘合成),路径 yaw 加减抵消链路不变。实测结果与老版本一致。
2026-05-27 15:06:33 +08:00
bbb58c9634
调整物体窗口: 提升高度→上下偏移, 允许负值, 窗口加宽, 清理提示文字
...
- 字段名: 提升高度 → 上下偏移 (UI标签/日志/注释/状态栏)
- 移除负值校验,允许向下偏移 (EditRotationWindow.xaml.cs)
- 修复两处 <=0 拦截 (ApplyGroundPathObjectLiftOffset, ResolveGroundPathObjectLiftOffsetVector)
- 窗口宽度 400→440, 调低标题栏/去除副标题/去除提示文字行
2026-05-27 14:38:27 +08:00
3e43b20102
自动调整: 回调内扣除路径 yaw,使 correction 成为绝对角度
...
优化器通过 OptimizeWithEvaluator 传回调函数,回调接收 correction 后
经真实动画链路评估。动画链路 targetYaw = pathYaw + correctionY,
导致 correction.Y 被错误地当成额外增量而非绝对角度。
修复: 回调内从 correction 的 up 轴角度扣除路径 yaw,
使 targetYaw = pathYaw + (correctionY - pathYaw) = correctionY。
优化器现在正确地将 correction 作为从 CAD 出发的总 yaw 角度搜索。
2026-05-27 13:10:15 +08:00
7187bcf622
自动最优朝向: 黑盒实测模式
...
- 新增 ObjectPassageProjectionOptimizer(SO(3)粗搜索+Nelder-Mead)
- EditRotationWindow 加入"自动调整"按钮
- AnimationControlViewModel 实现黑盒实测评估(临时摆位→读BoundingBox→恢复)
- 设计文档和实现计划
2026-05-27 12:24:01 +08:00
19a38e5446
0.15.1: 修复角度输入崩溃、Y轴修正动画丢失、数据库连接缺失三个bug
...
- 修复编辑角度窗口空输入反复确认崩溃 (UpdateSourceTrigger LostFocus→Explicit)
- 修复Y轴角度修正在动画播放时双重叠加导致丢失 (删除 ApplyPlanarTrackedPose 中重复的 ResolvePlanarHostUpCorrectionRadians)
- 修复先开文档后加载插件时路径数据库未连接 (InitializePathPlanningManager 中加入数据库连接)
- 重构: TryConnectPathDatabase 辅助方法; TryUpdateNumberTextBox 拆分验证逻辑
- 更新 AGENTS.md 精简版; 更新 CHANGELOG.md 0.15.1; 更新 todo_features.md 5/18 条目
2026-05-26 21:02:48 +08:00