清理多余文件
This commit is contained in:
parent
ca8bcc0bba
commit
1a3d1e7f49
@ -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<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (EqualityComparer<T>.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<LogisticsModel> _logisticsModels;
|
||||
|
||||
public string SelectedModelsText
|
||||
{
|
||||
get => _selectedModelsText;
|
||||
set => SetProperty(ref _selectedModelsText, value);
|
||||
}
|
||||
|
||||
public string InstructionText
|
||||
{
|
||||
get => _instructionText;
|
||||
set => SetProperty(ref _instructionText, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<LogisticsModel> 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<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(field, value)) return;
|
||||
field = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### PathRoute
|
||||
```csharp
|
||||
public class PathRoute : INotifyPropertyChanged
|
||||
{
|
||||
private string _name;
|
||||
private ObservableCollection<PathPoint> _points;
|
||||
private bool _isActive;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty(ref _name, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<PathPoint> 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<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (EqualityComparer<T>.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<T>(Func<T> 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. 文档更新和培训
|
||||
@ -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界面正确协调
|
||||
@ -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_
|
||||
@ -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文件进行修改,不涉及其他文件。
|
||||
@ -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. 当插件在任何支持的分辨率上显示时,滚动条应仅在必要时出现。
|
||||
@ -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<ListViewItem>();
|
||||
// ... 准备数据 ...
|
||||
|
||||
// 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调用
|
||||
@ -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状态一致性
|
||||
- 为后续重构提供稳定基础
|
||||
@ -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架构重构以解决线程安全问题
|
||||
@ -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
|
||||
@ -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的集成
|
||||
- [ ] 确保物流分类系统正常工作
|
||||
@ -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<T>
|
||||
- ✅ 使用BindingOperations.EnableCollectionSynchronization
|
||||
- ✅ 重写OnCollectionChanged确保UI线程通知
|
||||
- ✅ 实现批量操作接口(AddRange, RemoveRange, ClearAndAddRange)
|
||||
- ✅ 并发访问保护机制(lock)
|
||||
- ✅ 集成UIStateManager
|
||||
- ✅ WPF集合同步机制
|
||||
- ✅ 多线程并发测试
|
||||
- ✅ 性能优化验证
|
||||
|
||||
## 下一步
|
||||
ThreadSafeObservableCollection已准备好在项目中使用,可以替换现有的ObservableCollection使用,特别是在LogisticsControlViewModel等需要后台线程更新UI的场景中。
|
||||
@ -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"
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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) │
|
||||
|
||||
@ -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} 个碰撞");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 统计碰撞信息
|
||||
|
||||
@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisworksTransport.Utils;
|
||||
|
||||
namespace NavisworksTransport.PathPlanning
|
||||
{
|
||||
|
||||
@ -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
|
||||
/// 执行选中的分层保存
|
||||
/// </summary>
|
||||
private async Task ExecuteSelectedLayersAsync(
|
||||
ModelSplitterManager modelSplitterManager,
|
||||
ModelSplitterManager.SplitConfiguration config,
|
||||
List<ModelSplitterManager.SplitPreviewResult> previewResultsForSave,
|
||||
CancellationToken cancellationToken)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user