diff --git a/.kiro/specs/dockpane-migration/design.md b/.kiro/specs/dockpane-migration/design.md deleted file mode 100644 index e7592a9..0000000 --- a/.kiro/specs/dockpane-migration/design.md +++ /dev/null @@ -1,516 +0,0 @@ -# Design Document - -## Overview - -本设计文档详细描述了将Navisworks物流路径规划插件从AddInPlugin架构迁移到DockPanePlugin架构的技术实现方案。基于Navisworks 2026 API文档中的DockPanePlugin示例代码,我们将重新设计插件架构以提供可停靠的用户界面面板,并利用WPF技术栈实现更现代化的用户体验。 - -## Architecture - -### 插件架构变更 - -#### 当前架构 (AddInPlugin) -```csharp -[PluginAttribute("Basic", "Tian", ToolTip = "Transport Plugin", DisplayName = "Transport Plugin")] -[AddInPlugin(AddInLocation.AddIn)] -public class Main : AddInPlugin -{ - public override int Execute(params string[] parameters) - { - // 显示模态对话框 - ShowDockPane(); - return 0; - } -} -``` - -#### 目标架构 (DockPanePlugin) -```csharp -[Plugin("NavisworksTransport.Main", "Tian", - DisplayName = "物流路径规划", - ToolTip = "物流路径规划和动画仿真插件")] -[DockPanePlugin(420, 700)] // 宽度420, 高度700 -[Strings("NavisworksTransport.Tian.name")] -public class Main : DockPanePlugin -{ - public override Control CreateControlPane() - { - // 创建WPF用户控件并用ElementHost托管 - var wpfControl = new LogisticsControlPanel(); - var elementHost = new ElementHost - { - Dock = DockStyle.Fill, - Child = wpfControl - }; - return elementHost; - } - - public override void DestroyControlPane(Control pane) - { - // 清理资源和事件订阅 - if (pane is ElementHost host && host.Child is LogisticsControlPanel wpfControl) - { - wpfControl.Cleanup(); - } - pane.Dispose(); - } -} -``` - -### WPF用户控件架构 - -#### 主控件结构 -``` -LogisticsControlPanel (UserControl) -├── MainTabControl (TabControl) -│ ├── ModelSettingsTab (TabItem) -│ │ └── ModelSettingsView (UserControl) -│ ├── PathEditingTab (TabItem) -│ │ └── PathEditingView (UserControl) -│ ├── AnimationControlTab (TabItem) -│ │ └── AnimationControlView (UserControl) -│ └── SystemManagementTab (TabItem) -│ └── SystemManagementView (UserControl) -└── BottomPanel (StackPanel) - ├── HelpButton (Button) - ├── AboutButton (Button) - └── CloseButton (Button) -``` - -## Components and Interfaces - -### 1. 主插件类 (Main) - -**职责:** -- 实现DockPanePlugin接口 -- 管理插件生命周期 -- 创建和销毁控件面板 - -**关键方法:** -- `CreateControlPane()`: 创建ElementHost并托管WPF控件 -- `DestroyControlPane(Control pane)`: 清理资源和释放控件 - -### 2. WPF主控件 (LogisticsControlPanel) - -**职责:** -- 作为所有功能的容器 -- 管理Tab页面切换 -- 处理全局事件和状态 - -**关键属性和方法:** -```csharp -public partial class LogisticsControlPanel : UserControl -{ - // 子视图引用 - private ModelSettingsView _modelSettingsView; - private PathEditingView _pathEditingView; - private AnimationControlView _animationControlView; - private SystemManagementView _systemManagementView; - - // 管理器实例 - private PathPlanningManager _pathPlanningManager; - private static bool _isSessionInitialized = false; - - public LogisticsControlPanel() - { - InitializeComponent(); - InitializeSession(); - InitializeViews(); - SubscribeToEvents(); - } - - public void Cleanup() - { - UnsubscribeFromEvents(); - CleanupManagers(); - } -} -``` - -### 3. 子视图控件 - -#### ModelSettingsView -- 类别属性设置 -- 物流模型列表 -- 可见性控制 -- 统计信息显示 - -#### PathEditingView -- 路径列表管理 -- 当前路径编辑 -- 路径文件管理 - -#### AnimationControlView -- 动画参数设置 -- 播放控制 -- 碰撞检测 - -#### SystemManagementView -- 模型分层拆分 -- 日志管理 -- 插件设置 -- 系统信息 - -### 4. MVVM架构支持 - -#### ViewModel基类 -```csharp -public abstract class ViewModelBase : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = null) - { - if (EqualityComparer.Default.Equals(field, value)) return false; - field = value; - OnPropertyChanged(propertyName); - return true; - } -} -``` - -#### 主ViewModel -```csharp -public class LogisticsControlViewModel : ViewModelBase -{ - private string _selectedModelsText; - private string _instructionText; - private ObservableCollection _logisticsModels; - - public string SelectedModelsText - { - get => _selectedModelsText; - set => SetProperty(ref _selectedModelsText, value); - } - - public string InstructionText - { - get => _instructionText; - set => SetProperty(ref _instructionText, value); - } - - public ObservableCollection LogisticsModels - { - get => _logisticsModels; - set => SetProperty(ref _logisticsModels, value); - } - - // Commands - public ICommand RefreshCommand { get; } - public ICommand ClearSelectionCommand { get; } - public ICommand ShowAllCommand { get; } - public ICommand HideAllCommand { get; } -} -``` - -## Data Models - -### 1. 数据传输对象 - -#### LogisticsModel -```csharp -public class LogisticsModel : INotifyPropertyChanged -{ - private string _name; - private string _category; - private string _attributes; - private bool _isVisible; - - public string Name - { - get => _name; - set => SetProperty(ref _name, value); - } - - public string Category - { - get => _category; - set => SetProperty(ref _category, value); - } - - public string Attributes - { - get => _attributes; - set => SetProperty(ref _attributes, value); - } - - public bool IsVisible - { - get => _isVisible; - set => SetProperty(ref _isVisible, value); - } - - public ModelItem NavisworksItem { get; set; } - - // INotifyPropertyChanged implementation - public event PropertyChangedEventHandler PropertyChanged; - - private void SetProperty(ref T field, T value, [CallerMemberName] string propertyName = null) - { - if (EqualityComparer.Default.Equals(field, value)) return; - field = value; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } -} -``` - -#### PathRoute -```csharp -public class PathRoute : INotifyPropertyChanged -{ - private string _name; - private ObservableCollection _points; - private bool _isActive; - - public string Name - { - get => _name; - set => SetProperty(ref _name, value); - } - - public ObservableCollection Points - { - get => _points; - set => SetProperty(ref _points, value); - } - - public bool IsActive - { - get => _isActive; - set => SetProperty(ref _isActive, value); - } - - // INotifyPropertyChanged implementation - public event PropertyChangedEventHandler PropertyChanged; - - private void SetProperty(ref T field, T value, [CallerMemberName] string propertyName = null) - { - if (EqualityComparer.Default.Equals(field, value)) return; - field = value; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } -} -``` - -### 2. 业务逻辑管理器 - -现有的管理器类保持不变,但需要适配WPF的事件模型: -- `PathPlanningManager` -- `PathDataManager` -- `VisibilityManager` -- `ModelSplitterManager` -- `LogisticsAnimationManager` - -## Error Handling - -### 1. WPF异常处理 - -```csharp -public partial class LogisticsControlPanel : UserControl -{ - public LogisticsControlPanel() - { - InitializeComponent(); - - // 订阅WPF异常事件 - Dispatcher.UnhandledException += OnDispatcherUnhandledException; - } - - private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) - { - LogManager.Error($"[WPF异常] {e.Exception.Message}"); - LogManager.Error($"[WPF异常] 堆栈信息: {e.Exception.StackTrace}"); - - // 标记异常已处理,避免程序崩溃 - e.Handled = true; - - // 显示用户友好的错误信息 - MessageBox.Show($"界面操作发生错误: {e.Exception.Message}", - "错误", MessageBoxButton.OK, MessageBoxImage.Warning); - } -} -``` - -### 2. 线程安全处理 - -```csharp -public class ThreadSafeHelper -{ - public static void InvokeOnUIThread(Action action) - { - if (Application.Current?.Dispatcher?.CheckAccess() == true) - { - action(); - } - else - { - Application.Current?.Dispatcher?.Invoke(action); - } - } - - public static T InvokeOnUIThread(Func func) - { - if (Application.Current?.Dispatcher?.CheckAccess() == true) - { - return func(); - } - else - { - return Application.Current.Dispatcher.Invoke(func); - } - } -} -``` - -## Testing Strategy - -### 1. 单元测试 - -#### 插件生命周期测试 -```csharp -[TestClass] -public class MainPluginTests -{ - [TestMethod] - public void CreateControlPane_ShouldReturnElementHost() - { - // Arrange - var plugin = new Main(); - - // Act - var control = plugin.CreateControlPane(); - - // Assert - Assert.IsInstanceOfType(control, typeof(ElementHost)); - Assert.IsNotNull(((ElementHost)control).Child); - Assert.IsInstanceOfType(((ElementHost)control).Child, typeof(LogisticsControlPanel)); - } - - [TestMethod] - public void DestroyControlPane_ShouldDisposeControl() - { - // Arrange - var plugin = new Main(); - var control = plugin.CreateControlPane(); - - // Act - plugin.DestroyControlPane(control); - - // Assert - Assert.IsTrue(control.IsDisposed); - } -} -``` - -#### WPF控件测试 -```csharp -[TestClass] -public class LogisticsControlPanelTests -{ - [TestMethod] - public void Constructor_ShouldInitializeAllViews() - { - // Arrange & Act - var control = new LogisticsControlPanel(); - - // Assert - Assert.IsNotNull(control.FindName("MainTabControl")); - Assert.IsNotNull(control.FindName("ModelSettingsTab")); - Assert.IsNotNull(control.FindName("PathEditingTab")); - Assert.IsNotNull(control.FindName("AnimationControlTab")); - Assert.IsNotNull(control.FindName("SystemManagementTab")); - } -} -``` - -### 2. 集成测试 - -#### Navisworks API集成测试 -```csharp -[TestClass] -public class NavisworksIntegrationTests -{ - [TestMethod] - public void SelectionChanged_ShouldUpdateViewModel() - { - // 需要在Navisworks环境中运行 - // 测试选择变更事件是否正确更新WPF界面 - } - - [TestMethod] - public void PathPlanning_ShouldCreateVisualPath() - { - // 测试路径规划功能是否在WPF界面中正确显示 - } -} -``` - -### 3. 用户界面测试 - -#### WPF自动化测试 -```csharp -[TestClass] -public class UIAutomationTests -{ - [TestMethod] - public void TabSwitching_ShouldWorkCorrectly() - { - // 使用WPF测试框架测试Tab切换功能 - } - - [TestMethod] - public void DataBinding_ShouldUpdateUI() - { - // 测试数据绑定是否正确更新界面 - } -} -``` - -## Performance Considerations - -### 1. WPF渲染优化 - -- 使用虚拟化ListView和TreeView处理大量数据 -- 实现延迟加载避免界面卡顿 -- 使用异步操作处理耗时任务 - -### 2. 内存管理 - -- 正确实现IDisposable接口 -- 及时取消事件订阅避免内存泄漏 -- 使用WeakReference处理长期引用 - -### 3. 线程优化 - -- 将Navisworks API调用保持在主线程 -- 使用BackgroundWorker处理后台任务 -- 合理使用Dispatcher.BeginInvoke避免界面阻塞 - -## Migration Strategy - -### 阶段1:基础架构迁移 -1. 创建DockPanePlugin基础结构 -2. 实现ElementHost托管机制 -3. 创建基本的WPF用户控件框架 - -### 阶段2:功能模块迁移 -1. 迁移模型设置功能到WPF -2. 迁移路径编辑功能到WPF -3. 迁移动画控制功能到WPF -4. 迁移系统管理功能到WPF - -### 阶段3:优化和测试 -1. 实现MVVM模式和数据绑定 -2. 优化性能和用户体验 -3. 完善错误处理和异常管理 -4. 进行全面测试和调试 - -### 阶段4:部署和验证 -1. 更新部署配置 -2. 验证插件注册和加载 -3. 进行用户验收测试 -4. 文档更新和培训 \ No newline at end of file diff --git a/.kiro/specs/dockpane-migration/requirements.md b/.kiro/specs/dockpane-migration/requirements.md deleted file mode 100644 index e65119d..0000000 --- a/.kiro/specs/dockpane-migration/requirements.md +++ /dev/null @@ -1,96 +0,0 @@ -# Requirements Document - -## Introduction - -本需求文档定义了将现有的Navisworks物流路径规划插件从AddInPlugin架构迁移到DockPanePlugin架构的功能需求。根据技术方案文档,DockPanePlugin能够提供更好的用户体验,允许创建可停靠的面板,并支持WPF技术栈以实现更丰富的交互式导航控件。 - -## Requirements - -### Requirement 1 - -**User Story:** 作为插件开发者,我希望将现有的AddInPlugin改为DockPanePlugin,以便提供可停靠的用户界面面板。 - -#### Acceptance Criteria - -1. WHEN 插件加载时 THEN 系统应创建一个可停靠的面板而不是模态对话框 -2. WHEN 用户关闭面板时 THEN 面板应能够被重新打开而不重启Navisworks -3. WHEN 面板显示时 THEN 用户应能够将面板停靠到Navisworks界面的不同位置 -4. WHEN 面板创建时 THEN 系统应正确实现CreateControlPane和DestroyControlPane方法 - -### Requirement 2 - -**User Story:** 作为用户,我希望插件界面使用WPF技术,以便获得更现代化和响应式的用户体验。 - -#### Acceptance Criteria - -1. WHEN 面板显示时 THEN 界面应使用WPF而不是Windows Forms -2. WHEN 用户与界面交互时 THEN 界面应提供流畅的响应和现代化的视觉效果 -3. WHEN 面板调整大小时 THEN WPF控件应正确响应布局变化 -4. WHEN 面板内容更新时 THEN WPF数据绑定应正确工作 - -### Requirement 3 - -**User Story:** 作为开发者,我希望保持现有的所有功能,以便用户在迁移后不会丢失任何特性。 - -#### Acceptance Criteria - -1. WHEN 迁移完成时 THEN 所有现有的类别设置功能应正常工作 -2. WHEN 迁移完成时 THEN 所有现有的路径编辑功能应正常工作 -3. WHEN 迁移完成时 THEN 所有现有的动画控制功能应正常工作 -4. WHEN 迁移完成时 THEN 所有现有的系统管理功能应正常工作 -5. WHEN 迁移完成时 THEN 所有事件处理和数据管理逻辑应保持不变 - -### Requirement 4 - -**User Story:** 作为开发者,我希望正确处理DockPanePlugin的生命周期管理,以便避免内存泄漏和资源冲突。 - -#### Acceptance Criteria - -1. WHEN CreateControlPane被调用时 THEN 系统应正确创建并返回WPF用户控件 -2. WHEN DestroyControlPane被调用时 THEN 系统应正确释放所有资源和事件订阅 -3. WHEN 面板重复创建时 THEN 系统应避免重复订阅事件或创建重复实例 -4. WHEN Navisworks关闭时 THEN 所有插件资源应被正确清理 - -### Requirement 5 - -**User Story:** 作为开发者,我希望利用ElementHost控件来托管WPF内容,以便在Navisworks的.NET Framework环境中正确运行。 - -#### Acceptance Criteria - -1. WHEN 创建面板时 THEN 系统应使用ElementHost控件托管WPF用户控件 -2. WHEN WPF控件需要与Navisworks API交互时 THEN ElementHost应正确处理线程调用 -3. WHEN 面板大小改变时 THEN ElementHost应正确调整WPF内容的大小 -4. WHEN 处理用户输入时 THEN ElementHost应正确转发鼠标和键盘事件 - -### Requirement 6 - -**User Story:** 作为开发者,我希望更新插件属性和注册方式,以便正确注册为DockPanePlugin。 - -#### Acceptance Criteria - -1. WHEN 插件编译时 THEN 系统应使用正确的DockPanePlugin属性而不是AddInPlugin属性 -2. WHEN 插件加载时 THEN Navisworks应将插件识别为可停靠面板插件 -3. WHEN 插件在Navisworks中显示时 THEN 插件应出现在正确的菜单位置 -4. WHEN 插件属性设置时 THEN DisplayName、ToolTip等属性应正确显示 - -### Requirement 7 - -**User Story:** 作为开发者,我希望创建合适的WPF用户控件结构,以便替换现有的Windows Forms界面。 - -#### Acceptance Criteria - -1. WHEN 创建WPF控件时 THEN 系统应创建包含所有现有功能的用户控件 -2. WHEN WPF控件布局时 THEN 应使用适当的WPF布局容器(如Grid、StackPanel等) -3. WHEN WPF控件绑定数据时 THEN 应使用MVVM模式或适当的数据绑定机制 -4. WHEN WPF控件处理事件时 THEN 应正确处理WPF事件模型 - -### Requirement 8 - -**User Story:** 作为开发者,我希望确保API调用的兼容性,以便所有Navisworks API调用在新架构下正常工作。 - -#### Acceptance Criteria - -1. WHEN 从WPF控件调用Navisworks API时 THEN 所有API调用应在正确的线程上执行 -2. WHEN 处理Navisworks事件时 THEN 事件处理应正确更新WPF界面 -3. WHEN 访问Document和Selection对象时 THEN 应正确处理跨线程访问 -4. WHEN 使用Graphics类绘制时 THEN 绘制操作应与WPF界面正确协调 \ No newline at end of file diff --git a/.kiro/specs/dockpane-migration/tasks.md b/.kiro/specs/dockpane-migration/tasks.md deleted file mode 100644 index 20055fd..0000000 --- a/.kiro/specs/dockpane-migration/tasks.md +++ /dev/null @@ -1,253 +0,0 @@ -# Implementation Plan - -- [x] 1. 创建DockPanePlugin基础架构 - - - - - 修改Main类继承DockPanePlugin而不是AddInPlugin - - 更新插件属性为[Plugin]和[DockPanePlugin] - - 实现CreateControlPane()和DestroyControlPane()方法 - - 创建ElementHost托管机制 - - _Requirements: 1.1, 1.2, 1.3, 1.4_ - - - - - - - -- [ ] 2. 创建WPF用户控件框架 -- [x] 2.1 创建主WPF用户控件LogisticsControlPanel - - - 创建LogisticsControlPanel.xaml和.xaml.cs文件 - - - 实现基本的TabControl布局结构 - - 添加底部操作按钮面板 - - 实现Cleanup()方法用于资源清理 - - _Requirements: 2.1, 2.2, 2.3_ - -- [x] 2.2 创建MVVM基础架构 - - - 实现ViewModelBase基类支持INotifyPropertyChanged - - 创建LogisticsControlViewModel主视图模型 - - 实现ThreadSafeHelper线程安全辅助类 - - 创建数据模型类LogisticsModel和PathRoute - - - - - _Requirements: 2.2, 2.4, 5.2_ - -- [x] 2.3 创建子视图用户控件 - - - - 创建ModelSettingsView.xaml用户控件 - - 创建PathEditingView.xaml用户控件 - - 创建AnimationControlView.xaml用户控件 - - 创建SystemManagementView.xaml用户控件 - - _Requirements: 2.1, 2.3, 7.1, 7.2_ - -- [x] 3. 迁移模型设置功能到WPF - - -- [x] 3.1 实现类别属性设置界面 - - - 将类别下拉框转换为WPF ComboBox - - 实现数据绑定连接CategoryAttributeManager - - 添加选择提示和状态显示标签 - - 测试类别选择功能 - - _Requirements: 3.1, 3.2, 7.3, 8.2_ - -- [x] 3.2 实现物流模型列表界面 - - - 将ListView转换为WPF ListView - - 实现ObservableCollection数据绑定 - - 添加模型属性编辑功能 - - 实现选择同步机制 - - _Requirements: 3.1, 3.2, 7.3, 8.1_ - - - -- [x] 3.3 实现可见性控制界面 - - - 转换可见性控制按钮为WPF Button - - 实现Command模式处理按钮点击 - - 连接VisibilityManager业务逻辑 - - 添加统计信息显示 - - _Requirements: 3.1, 3.2, 7.4, 8.2_ - -- [ ] 4. 迁移路径编辑功能到WPF -- [x] 4.1 实现路径列表管理界面 - - - - 转换路径列表ListView为WPF版本 - - 实现路径创建、删除、重命名功能 - - 连接PathPlanningManager业务逻辑 - - 添加路径状态显示 - - _Requirements: 3.3, 7.3, 8.1, 8.2_ - -- [x] 4.2 实现当前路径编辑界面 - - - - - 转换路径点列表为WPF ListView - - 实现路径点添加、删除、编辑功能 - - 添加3D交互支持 - - 实现路径可视化更新 - - _Requirements: 3.3, 7.4, 8.1, 8.3_ - -- [x] 4.3 实现路径文件管理界面 - - - - 添加路径导入导出按钮 - - 实现文件对话框集成 - - 连接PathDataManager文件操作 - - 添加操作状态反馈 - - _Requirements: 3.3, 8.1_ - -- [ ] 5. 迁移动画控制功能到WPF -- [x] 5.1 实现动画参数设置界面 - - - - 转换动画参数控件为WPF版本 - - 实现数据绑定和验证 - - 连接LogisticsAnimationManager - - 添加参数预览功能 - - _Requirements: 3.4, 7.3, 8.1_ - -- [x] 5.2 实现播放控制界面 - - - 转换播放控制按钮为WPF版本 - - 实现进度条和状态显示 - - 添加播放速度控制 - - 连接动画播放逻辑 - - _Requirements: 3.4, 7.4, 8.2_ - -- [x] 5.3 实现碰撞检测界面 - - - 转换碰撞检测控件为WPF版本 - - 连接ClashDetectiveIntegration - - 实现碰撞结果显示 - - 添加碰撞报告功能 - - _Requirements: 3.4, 8.1, 8.2_ - -- [ ] 6. 迁移系统管理功能到WPF -- [x] 6.1 实现模型分层拆分界面 - - - - 转换ModelSplitterDialog为WPF版本 - - 实现楼层选择和属性筛选 - - 连接ModelSplitterManager业务逻辑 - - 添加拆分进度显示 - - _Requirements: 3.5, 7.1, 8.1_ - -- [x] 6.2 实现日志管理界面 - - - 创建日志查看和管理控件 - - 实现日志级别筛选 - - 添加日志导出功能 - - 连接LogManager - - _Requirements: 3.5, 7.3_ - -- [x] 6.3 实现插件设置界面 - - - - 创建设置选项控件 - - 实现设置保存和加载 - - 添加设置验证 - - 实现设置重置功能 - - _Requirements: 3.5, 7.3_ - -- [ ] 7. 实现生命周期管理和资源清理 -- [ ] 7.1 实现插件生命周期管理 - - 完善CreateControlPane()方法 - - 实现DestroyControlPane()资源清理 - - 添加重复创建保护机制 - - 测试面板创建和销毁 - - _Requirements: 4.1, 4.2, 4.3, 4.4_ - -- [ ] 7.2 实现事件订阅管理 - - 创建事件订阅管理器 - - 实现自动取消订阅机制 - - 添加事件处理异常保护 - - 测试事件生命周期 - - _Requirements: 4.3, 4.4, 8.2_ - -- [ ] 7.3 实现ElementHost集成 - - 完善ElementHost配置 - - 实现WPF与WinForms的交互 - - 添加大小调整处理 - - 测试跨技术栈事件传递 - - _Requirements: 5.1, 5.2, 5.3, 5.4_ - -- [ ] 8. 实现错误处理和线程安全 -- [ ] 8.1 实现WPF异常处理 - - 添加Dispatcher.UnhandledException处理 - - 实现用户友好的错误提示 - - 连接GlobalExceptionHandler - - 测试异常恢复机制 - - _Requirements: 4.4, 8.1, 8.2_ - -- [ ] 8.2 实现线程安全机制 - - 完善ThreadSafeHelper实现 - - 确保Navisworks API调用线程安全 - - 实现UI更新线程调度 - - 测试跨线程操作 - - _Requirements: 5.2, 8.1, 8.3, 8.4_ - -- [ ] 8.3 实现内存管理 - - 添加IDisposable实现 - - 实现WeakReference长期引用 - - 添加内存泄漏检测 - - 优化大对象处理 - - _Requirements: 4.4, 7.3_ - -- [ ] 9. 更新插件注册和部署配置 -- [ ] 9.1 更新插件属性和注册 - - 修改Plugin属性配置 - - 更新DisplayName和ToolTip - - 创建本地化字符串文件 - - 测试插件识别和加载 - - _Requirements: 6.1, 6.2, 6.3, 6.4_ - -- [ ] 9.2 更新项目配置 - - 添加WPF相关引用 - - 更新编译配置 - - 修改输出路径设置 - - 测试编译和部署 - - _Requirements: 6.1, 6.4_ - -- [ ] 9.3 创建本地化支持 - - 创建字符串资源文件 - - 实现多语言支持 - - 添加本地化测试 - - 验证字符串显示 - - _Requirements: 6.4_ - -- [ ] 10. 进行全面测试和优化 -- [ ] 10.1 创建单元测试 - - 编写插件生命周期测试 - - 创建WPF控件测试 - - 实现ViewModel测试 - - 添加业务逻辑测试 - - _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_ - -- [ ] 10.2 进行集成测试 - - 测试Navisworks API集成 - - 验证事件处理机制 - - 测试数据绑定功能 - - 验证线程安全性 - - _Requirements: 8.1, 8.2, 8.3, 8.4_ - -- [ ] 10.3 进行性能优化 - - 优化WPF渲染性能 - - 实现虚拟化列表 - - 添加延迟加载机制 - - 优化内存使用 - - _Requirements: 2.3, 7.3_ - -- [ ] 10.4 进行用户验收测试 - - 验证所有现有功能正常工作 - - 测试新的可停靠面板体验 - - 收集用户反馈 - - 修复发现的问题 - - _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_ \ No newline at end of file diff --git a/.kiro/specs/ui-scaling-enhancement/design.md b/.kiro/specs/ui-scaling-enhancement/design.md deleted file mode 100644 index 477a877..0000000 --- a/.kiro/specs/ui-scaling-enhancement/design.md +++ /dev/null @@ -1,221 +0,0 @@ -# 设计文档:UI缩放增强 - -## 概述 - -本设计文档描述了如何改善Navisworks插件在4K高分辨率显示器上的用户界面显示效果。根据用户反馈,插件在2K显示器上显示正常,但在4K显示器上(使用150%缩放,实际显示为2560*1440)显示过小,导致按钮中的文字显示不全、组件高度不足等问题。模型分层拆分工具的弹出对话框在4K显示器上已经能够正常显示,因此本设计将参考该实现来调整MainPlugin中的按钮尺寸、分组区域高度和主窗口大小。 - -## 设计方案 - -本设计采用最简单直接的方案,只调整MainPlugin中的按钮尺寸、分组区域高度和主窗口大小,不修改其他任何代码。主要调整内容包括: - -1. **增加主窗口尺寸**:参考ModelSplitterDialog的尺寸,适当增加MainPlugin主窗口的宽度和高度。 -2. **调整按钮尺寸**:参考ModelSplitterDialog中的按钮尺寸,增加MainPlugin中所有按钮的宽度和高度。 -3. **调整分组区域高度**:增加GroupBox的高度,确保能容纳调整后的按钮并有合理间距。 -4. **增加路径列表和表格高度**:特别增加路径编辑标签页中的路径列表和当前路径编辑表格的高度,使其能容纳的行数从3行增加到4行。 - -### 参考ModelSplitterDialog的实现 - -通过分析ModelSplitterDialog.cs,我们发现以下关键设置: - -```csharp -// 窗口大小设置 -this.Size = new Size(800, 720); - -// 按钮大小设置 -Size = new Size(100, 30) // 主要按钮 -Size = new Size(80, 30) // 次要按钮 - -// GroupBox高度设置 -Size = new Size(350, 160) // 较大的分组区域 -Size = new Size(350, 80) // 较小的分组区域 -``` - -## 具体实现方案 - -### 1. 主窗口尺寸调整 - -将MainPlugin中的主窗口从当前尺寸调整为更大的尺寸: - -```csharp -// 原始尺寸 -_controlPanelForm = new Form -{ - Text = "物流路径规划控制面板", - Size = new Size(420, 700), - // 其他属性... -}; - -// 调整后的尺寸 -_controlPanelForm = new Form -{ - Text = "物流路径规划控制面板", - Size = new Size(500, 820), // 增加宽度和高度,以容纳更大的路径列表和表格 - // 其他属性... -}; -``` - -### 2. 按钮尺寸调整 - -增加MainPlugin中所有按钮的宽度和高度,参考ModelSplitterDialog中的按钮尺寸: - -```csharp -// 原始按钮尺寸 -Button button = new Button -{ - Text = "按钮文本", - Size = new Size(60, 25), - // 其他属性... -}; - -// 调整后的按钮尺寸 - 主要按钮 -Button mainButton = new Button -{ - Text = "主要按钮", - Size = new Size(100, 30), // 参考ModelSplitterDialog的主要按钮尺寸 - // 其他属性... -}; - -// 调整后的按钮尺寸 - 次要按钮 -Button secondaryButton = new Button -{ - Text = "次要按钮", - Size = new Size(80, 30), // 参考ModelSplitterDialog的次要按钮尺寸 - // 其他属性... -}; -``` - -### 3. 分组区域高度调整 - -增加GroupBox的高度,确保能容纳调整后的按钮并有合理间距: - -```csharp -// 原始GroupBox尺寸 -GroupBox groupBox = new GroupBox -{ - Text = "分组标题", - Size = new Size(350, 70), // 或其他高度 - // 其他属性... -}; - -// 调整后的GroupBox尺寸 -GroupBox groupBox = new GroupBox -{ - Text = "分组标题", - Size = new Size(350, 90), // 增加高度,确保有足够空间容纳更大的按钮 - // 其他属性... -}; -``` - -### 4. 路径列表和表格高度调整 - -特别增加路径编辑标签页中的路径列表和当前路径编辑表格的高度: - -```csharp -// 原始路径列表尺寸 -_pathListView = new ListView -{ - // 其他属性... - Size = new Size(350, 100), // 假设原始高度为100 -}; - -// 调整后的路径列表尺寸 -_pathListView = new ListView -{ - // 其他属性... - Size = new Size(350, 140), // 增加高度,使其能容纳4行 -}; - -// 原始路径点列表尺寸 -_currentPathPointsListView = new ListView -{ - // 其他属性... - Size = new Size(350, 100), // 假设原始高度为100 -}; - -// 调整后的路径点列表尺寸 -_currentPathPointsListView = new ListView -{ - // 其他属性... - Size = new Size(350, 140), // 增加高度,使其能容纳4行 -}; -``` - -## 需要修改的位置 - -### 1. MainPlugin.cs中的ShowCategorySelectionDialog方法 - -修改主窗口尺寸: - -```csharp -_controlPanelForm = new Form -{ - Text = "物流路径规划控制面板", - Size = new Size(500, 820), // 从(420, 700)调整为(500, 820) - // 其他属性保持不变... -}; -``` - -### 2. 各个标签页中的分组区域和按钮 - -在以下方法中找到所有GroupBox和Button的Size属性,并进行调整: - -- CreateModelSettingsTab -- CreatePathEditingTab -- CreateAnimationControlTab -- CreateSystemManagementTab - -例如: - -```csharp -// 原始代码 -GroupBox groupBox = new GroupBox -{ - Text = "分组标题", - Size = new Size(350, 70), - // 其他属性... -}; - -Button button = new Button -{ - Text = "按钮文本", - Size = new Size(60, 25), - // 其他属性... -}; - -// 修改为 -GroupBox groupBox = new GroupBox -{ - Text = "分组标题", - Size = new Size(350, 90), // 增加高度 - // 其他属性保持不变... -}; - -Button button = new Button -{ - Text = "按钮文本", - Size = new Size(100, 30), // 或 Size = new Size(80, 30),根据按钮重要性 - // 其他属性保持不变... -}; -``` - -### 3. 路径编辑标签页中的列表 - -特别关注CreatePathEditingTab方法中的路径列表和当前路径编辑表格: - -```csharp -// 找到路径列表和当前路径编辑表格的定义 -_pathListView.Size = new Size(350, 140); // 增加高度 -_currentPathPointsListView.Size = new Size(350, 140); // 增加高度 - -// 同时调整包含这些列表的GroupBox高度 -pathListGroupBox.Size = new Size(350, 200); // 从160增加到200 -currentPathGroupBox.Size = new Size(350, 290); // 从250增加到290 -``` - -## 实现注意事项 - -1. **只修改尺寸数据**:只调整窗口、分组区域、列表和按钮的Size属性,不修改其他任何代码。 -2. **保持一致性**:确保所有按钮的调整保持一致,主要按钮使用(100, 30),次要按钮使用(80, 30)。 -3. **合理间距**:确保增加GroupBox高度后,内部控件有足够的间距,不会显得拥挤。 -4. **路径列表特别关注**:确保路径列表和当前路径编辑表格能容纳4行数据,提高用户体验。 -5. **最小化修改**:只针对MainPlugin.cs文件进行修改,不涉及其他文件。 diff --git a/.kiro/specs/ui-scaling-enhancement/requirements.md b/.kiro/specs/ui-scaling-enhancement/requirements.md deleted file mode 100644 index 96c71ab..0000000 --- a/.kiro/specs/ui-scaling-enhancement/requirements.md +++ /dev/null @@ -1,67 +0,0 @@ -# 需求文档 - -## 简介 - -UI缩放增强功能旨在改善插件在高分辨率(4K)显示器上的用户界面显示效果。目前,插件的UI元素(按钮、文本、间距)在2K显示器上显示正常,但在4K显示器上显示过小,导致按钮中的文字显示不全、组件高度不足等问题。模型分层拆分工具的弹出对话框在4K显示器上已经能够正常显示,因此本功能将参考该实现来调整插件主窗口及其标签页。 - -## 需求 - -### 需求1:插件主窗口的UI缩放 - -**用户故事:** 作为使用4K显示器的插件用户,我希望插件主窗口能够适当缩放,以便我能清晰地看到所有UI元素,而不会出现文字被截断的情况。 - -#### 验收标准1 - -1. 当插件在4K显示器上启动时,插件主窗口应自动调整其大小以保持可读性。 -2. 当插件在4K显示器上显示时,按钮和标签中的所有文本应完全可见,不会被截断。 -3. 当插件在4K显示器上显示时,UI元素之间的间距应按比例调整,以保持视觉层次结构。 -4. 当插件在2K显示器上显示时,UI应保持其当前的适当大小。 -5. 当插件窗口大小改变时,所有UI元素应保持其相对比例和可读性。 - -### 需求2:标签页控件的UI缩放 - -**用户故事:** 作为使用4K显示器的插件用户,我希望所有标签页及其控件能够适当缩放,以便我能有效地与它们交互。 - -#### 验收标准2 - -1. 当任何标签页在4K显示器上显示时,标签页内的所有控件应具有适当的大小和间距。 -2. 当"类别设置"标签页在4K显示器上显示时,所有列表视图、组合框和按钮应具有适当的大小。 -3. 当"路径编辑"标签页在4K显示器上显示时,所有路径编辑控件应具有适当的大小并完全可用。 -4. 当"检测动画"标签页在4K显示器上显示时,所有动画控件应具有适当的大小并完全可用。 -5. 当"系统管理"标签页在4K显示器上显示时,所有系统管理控件应具有适当的大小并完全可用。 - -### 需求3:字体缩放 - -**用户故事:** 作为使用4K显示器的插件用户,我希望插件中的所有文本都能适当调整大小,以便我能够轻松阅读。 - -#### 验收标准3 - -1. 当插件在4K显示器上显示时,所有字体应按比例缩放以保持可读性。 -2. 当按钮在4K显示器上显示文本时,字体大小应按比例增加,以确保文本完全可见。 -3. 当标签在4K显示器上显示文本时,字体大小应按比例增加,以确保可读性。 -4. 当列表视图在4K显示器上显示文本时,字体大小应按比例增加,以确保可读性。 -5. 当插件在2K显示器上显示时,字体大小应保持其当前的适当大小。 - -### 需求4:DPI感知实现 - -**用户故事:** 作为插件开发人员,我希望在插件中实现适当的DPI感知功能,以便它能够自动适应不同的显示分辨率。 - -#### 验收标准4 - -1. 当插件启动时,它应检测当前显示器的DPI设置。 -2. 当插件检测到高DPI设置时,它应自动调整UI缩放因子。 -3. 当插件在具有不同DPI设置的显示器之间移动时,它应相应地调整其缩放。 -4. 当系统DPI设置更改时,插件应在下次启动时适当响应。 -5. 如果插件无法确定DPI设置,则应默认为标准缩放,不会出现错误。 - -### 需求5:一致的UI元素比例 - -**用户故事:** 作为插件用户,我希望UI元素在不同显示分辨率下保持一致的比例,以便界面保持熟悉和可用。 - -#### 验收标准5 - -1. 当插件针对不同分辨率进行缩放时,UI元素的相对大小应保持一致。 -2. 当插件针对不同分辨率进行缩放时,UI元素的布局和定位应保持一致。 -3. 当列表视图在不同分辨率上显示时,列宽应按比例缩放。 -4. 当分组框在不同分辨率上显示时,其内容应适当排列,不会重叠。 -5. 当插件在任何支持的分辨率上显示时,滚动条应仅在必要时出现。 diff --git a/.serena/memories/coding_standards.md b/.serena/memories/coding_standards.md deleted file mode 100644 index 38a26ba..0000000 --- a/.serena/memories/coding_standards.md +++ /dev/null @@ -1,82 +0,0 @@ -# 编码规范和约定 - -## 语言和注释 -- **主要语言**: 中文用于所有交流和代码注释 -- **注释风格**: 详细的中文注释解释功能和目的 -- **文档**: 技术文档使用中文 - -## 命名约定 -- **类名**: PascalCase (如PathPlanningManager) -- **方法名**: PascalCase (如UpdateAnimationUI) -- **私有字段**: _camelCase前缀下划线 (如_animationStatusLabel) -- **公共属性**: PascalCase (如IsAnimationRunning) -- **常量**: UPPER_CASE或PascalCase - -## 线程安全模式(重要) -### 标准UI更新模式 -```csharp -if (control.InvokeRequired) -{ - control.BeginInvoke(new Action(() => - { - try - { - // UI更新逻辑 - control.Property = newValue; - } - catch (Exception ex) - { - LogManager.Error($"UI更新失败: {ex.Message}"); - } - })); -} -else -{ - // 直接执行UI更新逻辑 - control.Property = newValue; -} -``` - -### 批量更新模式(ListView等) -```csharp -// 1. 后台准备数据 -var items = new List(); -// ... 准备数据 ... - -// 2. 线程安全批量更新 -if (listView.InvokeRequired) -{ - listView.BeginInvoke(new Action(() => - { - try - { - if (listView != null && !listView.IsDisposed) - { - listView.Items.Clear(); - listView.Items.AddRange(items.ToArray()); - } - } - catch (Exception ex) - { - LogManager.Error($"ListView更新失败: {ex.Message}"); - } - })); -} -``` - -## 插件注册模式 -```csharp -[Plugin("NavisworksTransport.MainPlugin", "YourDeveloperID")] -[AddInPlugin(AddInLocation.AddIn)] -public class MainPlugin : AddInPlugin { } -``` - -## 异常处理 -- 使用GlobalExceptionHandler进行应用级异常处理 -- 在UI更新中使用try-catch保护 -- 详细的错误日志记录使用LogManager - -## API使用原则 -- **优先使用**: Navisworks Native API (Autodesk.Navisworks.Api) -- **辅助使用**: COM API (Autodesk.Navisworks.ComApi) 用于属性持久化 -- **避免**: 直接使用未检查的API调用 \ No newline at end of file diff --git a/.serena/memories/current_thread_safety_issues.md b/.serena/memories/current_thread_safety_issues.md deleted file mode 100644 index 94e460f..0000000 --- a/.serena/memories/current_thread_safety_issues.md +++ /dev/null @@ -1,28 +0,0 @@ -# 当前线程安全问题分析 - -## 问题背景 -项目存在严重的UI线程安全问题,导致Navisworks频繁崩溃。主要原因是在非UI线程中直接操作UI控件。 - -## 已知问题模式 -1. **直接UI控件操作**: 后台线程直接设置UI属性 -2. **缺少InvokeRequired检查**: 未检查线程上下文 -3. **同步调用风险**: 可能导致死锁 -4. **批量操作不原子**: ListView等控件更新不原子 - -## 修复策略 -1. **实现UIStateManager**: 统一的线程安全UI更新管理器 -2. **异步UI更新**: 使用BeginInvoke避免死锁 -3. **批量原子更新**: 一次性完成复杂UI更新操作 -4. **防重入机制**: 避免重复的UI更新操作 - -## 关键技术要求 -- SynchronizationContext管理 -- UI更新队列和状态跟踪 -- 异常处理和恢复机制 -- 性能优化避免过度线程切换 - -## 预期效果 -- 消除UI线程安全崩溃 -- 提高UI响应性 -- 确保UI状态一致性 -- 为后续重构提供稳定基础 \ No newline at end of file diff --git a/.serena/memories/project_overview.md b/.serena/memories/project_overview.md deleted file mode 100644 index 5caadd1..0000000 --- a/.serena/memories/project_overview.md +++ /dev/null @@ -1,35 +0,0 @@ -# NavisworksTransport 项目概览 - -## 项目目标 -NavisworksTransport是一个Navisworks 2026插件,专门用于在3D建筑模型中进行物流路径规划和运输冲突检测。主要功能包括: -- 路径优化和规划 -- 碰撞检测 -- 沿定义路径的动画对象移动 -- A*寻路算法集成 -- 时间轴动画集成 - -## 技术栈 -- **平台**: Navisworks 2026 (.NET 4.8, x64) -- **语言**: C# -- **UI框架**: WPF + WinForms混合架构 -- **API**: Navisworks Native API + COM API -- **项目格式**: 旧式csproj (使用Reference Include,非PackageReference) -- **包管理**: packages.config手动管理 -- **寻路算法**: RoyT.AStar库 -- **数据序列化**: JSON - -## 核心架构模式 -### 三重插件架构 -1. **MainPlugin.cs**: 主AddInPlugin,包含Ribbon UI和DockPane集成 -2. **PathClickToolPlugin.cs**: ToolPlugin,处理3D鼠标交互和点击 -3. **PathPointRenderPlugin.cs**: RenderPlugin,提供3D可视化覆盖 - -### UI架构 -- **WPF组件**: 现代MVVM控件在`src\UI\WPF\` -- **WinForms对话框**: 传统属性编辑界面 -- **ElementHost集成**: WPF嵌入Navisworks环境 - -## 当前状态 -- 专注Navisworks 2026开发,无需向后兼容 -- 存在严重UI线程安全问题导致频繁崩溃 -- 正在进行UI架构重构以解决线程安全问题 \ No newline at end of file diff --git a/.serena/memories/suggested_commands.md b/.serena/memories/suggested_commands.md deleted file mode 100644 index d413b62..0000000 --- a/.serena/memories/suggested_commands.md +++ /dev/null @@ -1,59 +0,0 @@ -# 推荐开发命令 - -## 编译命令 -```bash -# 主要编译命令 (在项目根目录) -./compile.bat - -# 注意: 必须使用./ 前缀,不要使用cmd /c compile.bat -``` - -## 部署命令 -```bash -# 部署插件到Navisworks -./deploy-plugin.bat -# 或使用PowerShell版本 -./deploy-plugin.ps1 -``` - -## 测试和调试 -```bash -# 查看日志 (需要LogViewer工具) -tool\LogViewer.bat - -# 测试需要重启Navisworks Manage 2026来加载新版本插件 -``` - -## 包管理 (重要) -- **不要使用**: `dotnet add package` -- **使用**: 手动下载.nupkg文件并解压到packages/目录 -- **路径格式**: `packages\{PackageId}.{Version}\lib\{TargetFramework}\{Assembly}.dll` - -## Git操作 -```bash -git status -git add . -git commit -m "功能描述" -git push origin 2026 # 当前开发分支 -``` - -## Windows系统命令 -```bash -# 文件查找 -dir /s /b *.cs -find . -name "*.cs" - -# 文本搜索 -findstr /s /i "关键词" *.cs -grep -r "关键词" --include="*.cs" . - -# 目录导航 -cd src\Core -ls (使用LS工具而非ls命令) -``` - -## MSBuild路径(编译脚本使用) -1. Visual Studio 2022 Community -2. Visual Studio 2022 Professional -3. Visual Studio 2019 Professional -4. 回退到dotnet build \ No newline at end of file diff --git a/.serena/memories/task_completion_checklist.md b/.serena/memories/task_completion_checklist.md deleted file mode 100644 index d47b9f4..0000000 --- a/.serena/memories/task_completion_checklist.md +++ /dev/null @@ -1,38 +0,0 @@ -# 任务完成检查清单 - -## 代码质量检查 -- [ ] 所有代码注释使用中文 -- [ ] 遵循项目命名约定 -- [ ] UI操作包含线程安全检查 (InvokeRequired/BeginInvoke) -- [ ] 添加适当的异常处理和日志记录 -- [ ] 空引用检查 (null和IsDisposed) - -## 编译和测试 -- [ ] 运行 `./compile.bat` 确保编译成功 -- [ ] 检查编译输出无警告或错误 -- [ ] 如果修改UI,测试基本UI交互功能 -- [ ] 验证插件能正常加载到Navisworks 2026 - -## API使用验证 -- [ ] 优先使用Navisworks Native API -- [ ] 正确的插件注册属性 -- [ ] 正确的线程上下文 (UI线程 vs 后台线程) -- [ ] 避免阻塞UI线程的长时间操作 - -## 文档和提交 -- [ ] 更新相关技术文档(如有需要) -- [ ] Git提交信息包含清晰的功能描述 -- [ ] 检查是否破坏现有功能 -- [ ] 确认符合Navisworks 2026专用开发要求 - -## 部署验证 -- [ ] 插件文件正确复制到Navisworks插件目录 -- [ ] 重启Navisworks后插件正常加载 -- [ ] 主要功能工作正常 -- [ ] 无明显的内存泄漏或崩溃 - -## 特殊注意事项 -- [ ] 不破坏现有A*路径规划功能 -- [ ] 保持WPF+WinForms混合UI架构 -- [ ] 维护与TimeLiner的集成 -- [ ] 确保物流分类系统正常工作 \ No newline at end of file diff --git a/.serena/memories/threadsafe_observable_collection_implementation.md b/.serena/memories/threadsafe_observable_collection_implementation.md deleted file mode 100644 index 3f7ae65..0000000 --- a/.serena/memories/threadsafe_observable_collection_implementation.md +++ /dev/null @@ -1,91 +0,0 @@ -# ThreadSafeObservableCollection实现总结 - -## T1.2任务完成状态 -✅ **任务完成** - ThreadSafeObservableCollection线程安全集合组件实现完成 - -## 实现的文件 -1. **核心实现**: `src/UI/WPF/Collections/ThreadSafeObservableCollection.cs` -2. **单元测试**: `tests/ThreadSafeObservableCollectionTests.cs` -3. **集成测试**: `tests/ThreadSafeObservableCollectionIntegrationTest.cs` -4. **使用示例**: `src/UI/WPF/Collections/ThreadSafeObservableCollectionUsageExample.cs` - -## 核心特性实现 - -### 1. 线程安全机制 -- 使用`lock`机制保护所有集合操作 -- `BindingOperations.EnableCollectionSynchronization`启用WPF集合同步 -- 集成UIStateManager进行线程安全的UI更新 - -### 2. 批量操作接口 -- `AddRange()` - 批量添加,只触发一次UI更新 -- `RemoveRange()` - 批量移除,优化性能 -- `ClearAndAddRange()` - 原子性替换操作 -- `ExecuteBatchUpdate()` - 复杂批量操作,禁用期间通知 - -### 3. 事件处理优化 -- 重写`OnCollectionChanged`确保UI线程通知 -- 重写`OnPropertyChanged`确保UI线程通知 -- 批量操作期间使用`_suppressNotification`标志 - -### 4. 线程安全查询 -- `ToSnapshot()` - 获取当前集合的线程安全快照 -- `FirstOrDefault()`, `Count()`, `Any()`, `Where()` - 线程安全查询方法 -- `Contains()`, `IndexOf()` - 线程安全基础查询 - -## 与UIStateManager集成 -- 自动检测UI线程状态 -- 非UI线程操作自动使用UIStateManager进行线程调度 -- 支持优先级队列的UI更新操作 - -## 性能优化 -- 批量操作减少UI更新频率(1000次操作 → 1次UI更新) -- 快照机制避免重复锁定 -- 事件抑制机制减少不必要的UI刷新 - -## WPF数据绑定兼容性 -- 完全兼容WPF数据绑定机制 -- 支持INotifyCollectionChanged和INotifyPropertyChanged -- 自动启用WPF集合同步功能 - -## 单元测试覆盖 -- **基础功能测试**: Add, Remove, Insert, Clear操作 -- **批量操作测试**: AddRange, RemoveRange, ClearAndAddRange, ExecuteBatchUpdate -- **线程安全测试**: 并发添加、并发添加删除、并发批量操作 -- **查询操作测试**: FirstOrDefault, Count, Any, Where, ToSnapshot -- **异常处理测试**: 空参数验证、索引越界保护 -- **性能测试**: 大量元素操作、并发访问性能 -- **WPF兼容性测试**: 数据绑定集成、事件线程安全 - -## 使用场景 -1. **路径规划结果更新** - 后台计算完成后安全更新UI集合 -2. **物流模型分类管理** - 从Navisworks API异步加载数据 -3. **实时状态监控** - 多线程环境下的状态集合更新 -4. **批量数据操作** - 减少UI更新频率,提升性能 - -## 迁移指南 -提供了完整的从ObservableCollection到ThreadSafeObservableCollection的迁移指南,包括: -- 类型声明替换 -- 构造函数更新 -- 批量操作优化 -- 线程调度代码移除 -- 功能验证步骤 - -## 编译验证 -✅ 所有文件编译通过 -✅ 无编译警告或错误 -✅ 与现有代码兼容 -✅ 单元测试和集成测试实现完整 - -## 技术要求达成 -- ✅ 继承ObservableCollection -- ✅ 使用BindingOperations.EnableCollectionSynchronization -- ✅ 重写OnCollectionChanged确保UI线程通知 -- ✅ 实现批量操作接口(AddRange, RemoveRange, ClearAndAddRange) -- ✅ 并发访问保护机制(lock) -- ✅ 集成UIStateManager -- ✅ WPF集合同步机制 -- ✅ 多线程并发测试 -- ✅ 性能优化验证 - -## 下一步 -ThreadSafeObservableCollection已准备好在项目中使用,可以替换现有的ObservableCollection使用,特别是在LogisticsControlViewModel等需要后台线程更新UI的场景中。 \ No newline at end of file diff --git a/.serena/project.yml b/.serena/project.yml deleted file mode 100644 index 6affd3b..0000000 --- a/.serena/project.yml +++ /dev/null @@ -1,68 +0,0 @@ -# language of the project (csharp, python, rust, java, typescript, go, cpp, or ruby) -# * For C, use cpp -# * For JavaScript, use typescript -# Special requirements: -# * csharp: Requires the presence of a .sln file in the project folder. -language: csharp - -# whether to use the project's gitignore file to ignore files -# Added on 2025-04-07 -ignore_all_files_in_gitignore: true -# list of additional paths to ignore -# same syntax as gitignore, so you can use * and ** -# Was previously called `ignored_dirs`, please update your config if you are using that. -# Added (renamed) on 2025-04-07 -ignored_paths: [] - -# whether the project is in read-only mode -# If set to true, all editing tools will be disabled and attempts to use them will result in an error -# Added on 2025-04-18 -read_only: false - - -# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details. -# Below is the complete list of tools for convenience. -# To make sure you have the latest list of tools, and to view their descriptions, -# execute `uv run scripts/print_tool_overview.py`. -# -# * `activate_project`: Activates a project by name. -# * `check_onboarding_performed`: Checks whether project onboarding was already performed. -# * `create_text_file`: Creates/overwrites a file in the project directory. -# * `delete_lines`: Deletes a range of lines within a file. -# * `delete_memory`: Deletes a memory from Serena's project-specific memory store. -# * `execute_shell_command`: Executes a shell command. -# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced. -# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type). -# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type). -# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes. -# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file. -# * `initial_instructions`: Gets the initial instructions for the current project. -# Should only be used in settings where the system prompt cannot be set, -# e.g. in clients you have no control over, like Claude Desktop. -# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol. -# * `insert_at_line`: Inserts content at a given line in a file. -# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol. -# * `list_dir`: Lists files and directories in the given directory (optionally with recursion). -# * `list_memories`: Lists memories in Serena's project-specific memory store. -# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building). -# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context). -# * `read_file`: Reads a file within the project directory. -# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store. -# * `remove_project`: Removes a project from the Serena configuration. -# * `replace_lines`: Replaces a range of lines within a file with new content. -# * `replace_symbol_body`: Replaces the full definition of a symbol. -# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen. -# * `search_for_pattern`: Performs a search for a pattern in the project. -# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase. -# * `switch_modes`: Activates modes by providing a list of their names -# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information. -# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task. -# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed. -# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store. -excluded_tools: [] - -# initial prompt for the project. It will always be given to the LLM upon activating the project -# (contrary to the memories, which are loaded on demand). -initial_prompt: "" - -project_name: "NavisworksTransport" diff --git a/TestRunner.cs b/TestRunner.cs deleted file mode 100644 index d590258..0000000 --- a/TestRunner.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using NavisworksTransport.UnitTests; - -namespace TestRunner -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("开始运行A*算法调试测试..."); - - var tester = new AStarDebuggingTest(); - - try - { - Console.WriteLine("=== 基础障碍物避让测试 ==="); - tester.TestBasicObstacleAvoidance(); - Console.WriteLine("✅ 基础障碍物避让测试通过"); - } - catch (Exception ex) - { - Console.WriteLine($"❌ 基础障碍物避让测试失败: {ex.Message}"); - } - - try - { - Console.WriteLine("\n=== 坐标映射验证测试 ==="); - tester.TestCoordinateMapping(); - Console.WriteLine("✅ 坐标映射验证测试通过"); - } - catch (Exception ex) - { - Console.WriteLine($"❌ 坐标映射验证测试失败: {ex.Message}"); - } - - try - { - Console.WriteLine("\n=== 实际问题场景重现测试 ==="); - tester.TestActualProblemScenario(); - Console.WriteLine("✅ 实际问题场景重现测试通过"); - } - catch (Exception ex) - { - Console.WriteLine($"❌ 实际问题场景重现测试失败: {ex.Message}"); - } - - try - { - Console.WriteLine("\n=== 网格连接状态检查测试 ==="); - tester.TestGridConnectionState(); - Console.WriteLine("✅ 网格连接状态检查测试通过"); - } - catch (Exception ex) - { - Console.WriteLine($"❌ 网格连接状态检查测试失败: {ex.Message}"); - } - - try - { - Console.WriteLine("\n=== 真实坐标系统A*算法测试 ==="); - tester.TestWithRealCoordinateSystem(); - Console.WriteLine("✅ 真实坐标系统A*算法测试通过"); - } - catch (Exception ex) - { - Console.WriteLine($"❌ 真实坐标系统A*算法测试失败: {ex.Message}"); - Console.WriteLine($"详细错误信息: {ex}"); - } - - try - { - Console.WriteLine("\n=== 通道路径查找测试 ==="); - tester.TestChannelPathfinding(); - Console.WriteLine("✅ 通道路径查找测试通过"); - } - catch (Exception ex) - { - Console.WriteLine($"❌ 通道路径查找测试失败: {ex.Message}"); - Console.WriteLine($"详细错误信息: {ex}"); - } - - Console.WriteLine("\n测试完成!按任意键退出..."); - Console.ReadKey(); - } - } -} \ No newline at end of file diff --git a/doc/design/2026/体素网格路径规划方案.md b/doc/design/2026/体素网格路径规划方案.md index f817093..1a51e03 100644 --- a/doc/design/2026/体素网格路径规划方案.md +++ b/doc/design/2026/体素网格路径规划方案.md @@ -91,7 +91,7 @@ public class VoxelGrid #### 核心功能模块 -**1. 体素化与距离场** +1.体素化与距离场 ```csharp // 核心类 @@ -120,7 +120,7 @@ BiGrid3 // 两层稀疏网格(优化大规模场景) - 适合大规模场景(仅存储非空体素) - 基于字典或哈希表实现 -**2. 空间查询与距离计算** +2.空间查询与距离计算 ```csharp // 距离查询 @@ -135,7 +135,7 @@ PointHashGrid3d // 3D 点哈希网格 PointAABBTree3 // 点云 AABB 树 ``` -**3. 网格操作与处理** +3.网格操作与处理 ```csharp // 等值面提取 @@ -152,7 +152,7 @@ BoundsUtil // 包围盒计算 MeshMeasurements // 体积、质心、惯性张量 ``` -**4. 数学与几何工具** +4.数学与几何工具 ```csharp // 向量数学(完整的 struct 实现) @@ -213,7 +213,7 @@ IntrRay3Triangle3, IntrTriangle3Triangle3 geometry4Sharp 提供**空间表示**,Roy-T.AStar 提供**路径算法**: -``` +```graph ┌────────────────────────────────────────┐ │ Navisworks BIM 模型 │ │ (三角网格、包围盒) │ @@ -254,7 +254,7 @@ geometry4Sharp 提供**空间表示**,Roy-T.AStar 提供**路径算法**: ### 3.1 整体架构 -``` +```graph ┌──────────────────────────────────────────────────────────┐ │ Navisworks API │ │ (ModelItem, BoundingBox, Geometry) │ diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index ee5e535..5ee1e45 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -431,15 +431,6 @@ namespace NavisworksTransport.Core.Animation _animationFrames.Add(frame); - // 进度报告 - if (i % 30 == 0) // 每秒报告一次(30fps) - { - LogManager.Info($"预计算进度: 帧 {i}/{totalFrames} ({progress*100:F1}%)"); - if (frame.HasCollision) - { - LogManager.Debug($" 帧 {i} 检测到 {frame.Collisions.Count} 个碰撞"); - } - } } // 统计碰撞信息 diff --git a/src/PathPlanning/OptimizedHeightCalculator.cs b/src/PathPlanning/OptimizedHeightCalculator.cs index 693338b..7683e85 100644 --- a/src/PathPlanning/OptimizedHeightCalculator.cs +++ b/src/PathPlanning/OptimizedHeightCalculator.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; using Autodesk.Navisworks.Api; -using NavisworksTransport.Utils; namespace NavisworksTransport.PathPlanning { diff --git a/src/UI/WPF/ViewModels/LayerManagementViewModel.cs b/src/UI/WPF/ViewModels/LayerManagementViewModel.cs index 7592041..d687df7 100644 --- a/src/UI/WPF/ViewModels/LayerManagementViewModel.cs +++ b/src/UI/WPF/ViewModels/LayerManagementViewModel.cs @@ -1380,7 +1380,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Info($"[LayerManagementViewModel] 开始执行分层,输出目录: {selectedDirectory}"); // 直接调用 ModelSplitterManager 的方法处理选中的分层 - await ExecuteSelectedLayersAsync(_modelSplitterManager, config, previewResultsForSave, _cancellationTokenSource.Token); + await ExecuteSelectedLayersAsync(config, previewResultsForSave, _cancellationTokenSource.Token); LogManager.Info($"[LayerManagementViewModel] 分层执行完成"); @@ -1420,7 +1420,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// 执行选中的分层保存 /// private async Task ExecuteSelectedLayersAsync( - ModelSplitterManager modelSplitterManager, ModelSplitterManager.SplitConfiguration config, List previewResultsForSave, CancellationToken cancellationToken)