using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Input; using System.Linq; using Autodesk.Navisworks.Api; using NavisApplication = Autodesk.Navisworks.Api.Application; namespace NavisworksTransport.UI.WPF.ViewModels { /// /// 物流控制面板主ViewModel /// public class LogisticsControlViewModel : ViewModelBase { #region 私有字段 private string _selectedModelsText; private string _instructionText; private string _statusText; private ObservableCollection _logisticsModels; private LogisticsModel _selectedLogisticsModel; private ObservableCollection _pathRoutes; private PathRouteViewModel _selectedPathRoute; private bool _isPathEditMode; private string _animationStatus; private double _animationProgress; private ObservableCollection _availableCategories; private string _selectedCategory; private double _widthLimit; private string _pathFileStatus; private PathPlanningManager _pathPlanningManager; private bool _isLogisticsOnlyMode = false; // 动画参数相关字段 private double _animationSpeed = 1.0; private ObservableCollection _availableFrameRates; private int _selectedFrameRate = 30; private double _animationDuration = 10.0; private bool _isLoopEnabled = false; private bool _isSmoothTransition = true; private double _currentAnimationTime = 0.0; private bool _canStartAnimation = true; private bool _canPauseAnimation = false; private bool _canStopAnimation = false; // 碰撞检测相关字段 private bool _canRunCollisionDetection = true; private bool _hasCollisionResults = false; private string _collisionStatus = "就绪"; private string _collisionSummary = "尚未运行碰撞检测"; // 系统管理相关字段 private string _modelSplitterStatus = "就绪"; private ObservableCollection _logLevels; private string _selectedLogLevel = "Info"; private string _logStatus = "日志系统正常"; private bool _isAutoSaveEnabled = true; private bool _isDebugModeEnabled = false; private string _settingsStatus = "设置已加载"; private string _pluginVersion = "v1.0"; private string _navisworksVersion = "2026"; private string _systemStatus = "正常"; private string _systemStatusColor = "Green"; private string _memoryUsage = "0 MB"; private string _runningTime = "00:00:00"; private string _performanceInfo = "性能监控就绪"; // 自动路径规划相关字段 private string _autoPathStartPoint = "未选择"; private string _autoPathEndPoint = "未选择"; private double _autoPathVehicleSize = 1.0; private string _autoPathStatus = "就绪"; private Point3D _startPoint3D; private Point3D _endPoint3D; private bool _hasStartPoint = false; private bool _hasEndPoint = false; private bool _isSelectingStartPoint = false; private bool _isSelectingEndPoint = false; #endregion #region 公共属性 /// /// 选中模型文本 /// public string SelectedModelsText { get => _selectedModelsText; set => SetProperty(ref _selectedModelsText, value); } /// /// 指令文本 /// public string InstructionText { get => _instructionText; set => SetProperty(ref _instructionText, value); } /// /// 状态文本 /// public string StatusText { get => _statusText; set => SetProperty(ref _statusText, value); } /// /// 物流模型集合 /// public ObservableCollection LogisticsModels { get => _logisticsModels; set => SetProperty(ref _logisticsModels, value); } /// /// 选中的物流模型 /// public LogisticsModel SelectedLogisticsModel { get => _selectedLogisticsModel; set => SetProperty(ref _selectedLogisticsModel, value); } /// /// 路径集合 /// public ObservableCollection PathRoutes { get => _pathRoutes; set => SetProperty(ref _pathRoutes, value); } /// /// 选中的路径 /// public PathRouteViewModel SelectedPathRoute { get => _selectedPathRoute; set => SetProperty(ref _selectedPathRoute, value); } /// /// 是否处于路径编辑模式 /// public bool IsPathEditMode { get => _isPathEditMode; set => SetProperty(ref _isPathEditMode, value); } /// /// 动画状态 /// public string AnimationStatus { get => _animationStatus; set => SetProperty(ref _animationStatus, value); } /// /// 动画进度 /// public double AnimationProgress { get => _animationProgress; set => SetProperty(ref _animationProgress, value); } /// /// 可用类别集合 /// public ObservableCollection AvailableCategories { get => _availableCategories; set => SetProperty(ref _availableCategories, value); } /// /// 选中的类别 /// public string SelectedCategory { get => _selectedCategory; set => SetProperty(ref _selectedCategory, value); } /// /// 宽度限制(米) /// public double WidthLimit { get => _widthLimit; set => SetProperty(ref _widthLimit, value); } /// /// 路径文件状态 /// public string PathFileStatus { get => _pathFileStatus; set => SetProperty(ref _pathFileStatus, value); } /// /// 是否处于仅显示物流模式 /// public bool IsLogisticsOnlyMode { get => _isLogisticsOnlyMode; set { if (SetProperty(ref _isLogisticsOnlyMode, value)) { // 当开关状态改变时,自动应用可见性设置 ApplyVisibilityMode(); } } } #region 动画控制属性 /// /// 动画速度 /// public double AnimationSpeed { get => _animationSpeed; set => SetProperty(ref _animationSpeed, value); } /// /// 可用帧率集合 /// public ObservableCollection AvailableFrameRates { get => _availableFrameRates; set => SetProperty(ref _availableFrameRates, value); } /// /// 选中的帧率 /// public int SelectedFrameRate { get => _selectedFrameRate; set => SetProperty(ref _selectedFrameRate, value); } /// /// 动画持续时间(秒) /// public double AnimationDuration { get => _animationDuration; set => SetProperty(ref _animationDuration, value); } /// /// 是否启用循环播放 /// public bool IsLoopEnabled { get => _isLoopEnabled; set => SetProperty(ref _isLoopEnabled, value); } /// /// 是否启用平滑过渡 /// public bool IsSmoothTransition { get => _isSmoothTransition; set => SetProperty(ref _isSmoothTransition, value); } /// /// 当前动画时间 /// public double CurrentAnimationTime { get => _currentAnimationTime; set => SetProperty(ref _currentAnimationTime, value); } /// /// 是否可以开始动画 /// public bool CanStartAnimation { get => _canStartAnimation; set => SetProperty(ref _canStartAnimation, value); } /// /// 是否可以暂停动画 /// public bool CanPauseAnimation { get => _canPauseAnimation; set => SetProperty(ref _canPauseAnimation, value); } /// /// 是否可以停止动画 /// public bool CanStopAnimation { get => _canStopAnimation; set => SetProperty(ref _canStopAnimation, value); } #endregion #region 碰撞检测属性 /// /// 是否可以运行碰撞检测 /// public bool CanRunCollisionDetection { get => _canRunCollisionDetection; set => SetProperty(ref _canRunCollisionDetection, value); } /// /// 是否有碰撞检测结果 /// public bool HasCollisionResults { get => _hasCollisionResults; set => SetProperty(ref _hasCollisionResults, value); } /// /// 碰撞检测状态 /// public string CollisionStatus { get => _collisionStatus; set => SetProperty(ref _collisionStatus, value); } /// /// 碰撞检测摘要 /// public string CollisionSummary { get => _collisionSummary; set => SetProperty(ref _collisionSummary, value); } #endregion #region 系统管理属性 /// /// 模型分层拆分状态 /// public string ModelSplitterStatus { get => _modelSplitterStatus; set => SetProperty(ref _modelSplitterStatus, value); } /// /// 日志级别集合 /// public ObservableCollection LogLevels { get => _logLevels; set => SetProperty(ref _logLevels, value); } /// /// 选中的日志级别 /// public string SelectedLogLevel { get => _selectedLogLevel; set => SetProperty(ref _selectedLogLevel, value); } /// /// 日志状态 /// public string LogStatus { get => _logStatus; set => SetProperty(ref _logStatus, value); } /// /// 是否启用自动保存 /// public bool IsAutoSaveEnabled { get => _isAutoSaveEnabled; set => SetProperty(ref _isAutoSaveEnabled, value); } /// /// 是否启用调试模式 /// public bool IsDebugModeEnabled { get => _isDebugModeEnabled; set => SetProperty(ref _isDebugModeEnabled, value); } /// /// 设置状态 /// public string SettingsStatus { get => _settingsStatus; set => SetProperty(ref _settingsStatus, value); } /// /// 插件版本 /// public string PluginVersion { get => _pluginVersion; set => SetProperty(ref _pluginVersion, value); } /// /// Navisworks版本 /// public string NavisworksVersion { get => _navisworksVersion; set => SetProperty(ref _navisworksVersion, value); } /// /// 系统状态 /// public string SystemStatus { get => _systemStatus; set => SetProperty(ref _systemStatus, value); } /// /// 系统状态颜色 /// public string SystemStatusColor { get => _systemStatusColor; set => SetProperty(ref _systemStatusColor, value); } /// /// 内存使用情况 /// public string MemoryUsage { get => _memoryUsage; set => SetProperty(ref _memoryUsage, value); } /// /// 运行时间 /// public string RunningTime { get => _runningTime; set => SetProperty(ref _runningTime, value); } /// /// 性能信息 /// public string PerformanceInfo { get => _performanceInfo; set => SetProperty(ref _performanceInfo, value); } #endregion #region 自动路径规划属性 /// /// 自动路径规划起点文本 /// public string AutoPathStartPoint { get => _autoPathStartPoint; set => SetProperty(ref _autoPathStartPoint, value); } /// /// 自动路径规划终点文本 /// public string AutoPathEndPoint { get => _autoPathEndPoint; set => SetProperty(ref _autoPathEndPoint, value); } /// /// 自动路径规划车辆尺寸 /// public double AutoPathVehicleSize { get => _autoPathVehicleSize; set => SetProperty(ref _autoPathVehicleSize, value); } /// /// 自动路径规划状态 /// public string AutoPathStatus { get => _autoPathStatus; set => SetProperty(ref _autoPathStatus, value); } /// /// 是否正在选择起点 /// public bool IsSelectingStartPoint { get => _isSelectingStartPoint; set => SetProperty(ref _isSelectingStartPoint, value); } /// /// 是否正在选择终点 /// public bool IsSelectingEndPoint { get => _isSelectingEndPoint; set => SetProperty(ref _isSelectingEndPoint, value); } #endregion #endregion #region 命令 public ICommand NewPathCommand { get; } public ICommand DeletePathCommand { get; } public ICommand RenamePathCommand { get; } public ICommand StartEditCommand { get; } public ICommand EndEditCommand { get; } public ICommand ClearPathCommand { get; } public ICommand DeletePointCommand { get; } public ICommand ImportPathCommand { get; } public ICommand ExportPathCommand { get; } public ICommand SaveAsPathCommand { get; } public ICommand StartAnimationCommand { get; } public ICommand PauseAnimationCommand { get; } public ICommand StopAnimationCommand { get; } public ICommand RunCollisionDetectionCommand { get; } public ICommand ViewCollisionReportCommand { get; } public ICommand ModelSplitterCommand { get; } public ICommand SetLogisticsAttributeCommand { get; } public ICommand ViewLogCommand { get; } public ICommand ClearLogCommand { get; } public ICommand ExportLogCommand { get; } public ICommand OpenSettingsCommand { get; } public ICommand ResetSettingsCommand { get; } public ICommand ImportConfigCommand { get; } public ICommand CheckUpdateCommand { get; } public ICommand GeneratePerformanceReportCommand { get; } public ICommand SelectStartPointCommand { get; } public ICommand SelectEndPointCommand { get; } public ICommand AutoPlanPathCommand { get; } public ICommand ClearAutoPathCommand { get; } #endregion #region 构造函数 public LogisticsControlViewModel() { // 初始化集合 LogisticsModels = new ObservableCollection(); PathRoutes = new ObservableCollection(); AvailableCategories = new ObservableCollection(); AvailableFrameRates = new ObservableCollection(); LogLevels = new ObservableCollection(); // 初始化路径规划管理器 InitializePathPlanningManager(); // 初始化命令(移除了可见性控制相关的命令) NewPathCommand = new RelayCommand(ExecuteNewPath); DeletePathCommand = new RelayCommand(ExecuteDeletePath, CanExecuteDeletePath); RenamePathCommand = new RelayCommand(ExecuteRenamePath, CanExecuteRenamePath); StartEditCommand = new RelayCommand(ExecuteStartEdit, CanExecuteStartEdit); EndEditCommand = new RelayCommand(ExecuteEndEdit, CanExecuteEndEdit); ClearPathCommand = new RelayCommand(ExecuteClearPath, CanExecuteClearPath); DeletePointCommand = new RelayCommand(ExecuteDeletePoint); ImportPathCommand = new RelayCommand(ExecuteImportPath); ExportPathCommand = new RelayCommand(ExecuteExportPath, CanExecuteExportPath); SaveAsPathCommand = new RelayCommand(ExecuteSaveAsPath, CanExecuteSaveAsPath); StartAnimationCommand = new RelayCommand(ExecuteStartAnimation, () => CanStartAnimation); PauseAnimationCommand = new RelayCommand(ExecutePauseAnimation, () => CanPauseAnimation); StopAnimationCommand = new RelayCommand(ExecuteStopAnimation, () => CanStopAnimation); RunCollisionDetectionCommand = new RelayCommand(ExecuteRunCollisionDetection, () => CanRunCollisionDetection); ViewCollisionReportCommand = new RelayCommand(ExecuteViewCollisionReport, () => HasCollisionResults); ModelSplitterCommand = new RelayCommand(ExecuteModelSplitter); SetLogisticsAttributeCommand = new RelayCommand(ExecuteSetLogisticsAttribute); ViewLogCommand = new RelayCommand(ExecuteViewLog); ClearLogCommand = new RelayCommand(ExecuteClearLog); ExportLogCommand = new RelayCommand(ExecuteExportLog); OpenSettingsCommand = new RelayCommand(ExecuteOpenSettings); ResetSettingsCommand = new RelayCommand(ExecuteResetSettings); ImportConfigCommand = new RelayCommand(ExecuteImportConfig); CheckUpdateCommand = new RelayCommand(ExecuteCheckUpdate); GeneratePerformanceReportCommand = new RelayCommand(ExecuteGeneratePerformanceReport); SelectStartPointCommand = new RelayCommand(ExecuteSelectStartPoint); SelectEndPointCommand = new RelayCommand(ExecuteSelectEndPoint); AutoPlanPathCommand = new RelayCommand(ExecuteAutoPlanPath, CanExecuteAutoPlanPath); ClearAutoPathCommand = new RelayCommand(ExecuteClearAutoPath); // 初始化状态 InitializeViewModel(); } #endregion #region 初始化 private void InitializeViewModel() { SafeExecute(() => { UpdateInstructionText(); UpdateSelectionDisplay(); InitializeCategories(); StatusText = "插件已就绪"; AnimationStatus = "动画状态: 就绪"; AnimationProgress = 0; WidthLimit = 3.0; // 默认宽度限制3米 PathFileStatus = "未保存"; // 初始化动画参数 InitializeAnimationSettings(); // 初始化系统管理设置 InitializeSystemManagementSettings(); LogManager.Info("LogisticsControlViewModel 初始化完成"); }, "初始化ViewModel"); } /// /// 初始化动画设置 /// private void InitializeAnimationSettings() { SafeExecute(() => { // 初始化可用帧率 AvailableFrameRates.Clear(); var frameRates = new[] { 15, 24, 30, 60 }; foreach (var rate in frameRates) { AvailableFrameRates.Add(rate); } SelectedFrameRate = 30; // 默认30fps // 设置默认动画参数 AnimationSpeed = 1.0; AnimationDuration = 10.0; IsLoopEnabled = false; IsSmoothTransition = true; CurrentAnimationTime = 0.0; // 设置初始状态 CanStartAnimation = true; CanPauseAnimation = false; CanStopAnimation = false; CanRunCollisionDetection = true; HasCollisionResults = false; CollisionStatus = "就绪"; CollisionSummary = "尚未运行碰撞检测"; LogManager.Info("动画设置初始化完成"); }, "初始化动画设置"); } /// /// 初始化系统管理设置 /// private void InitializeSystemManagementSettings() { SafeExecute(() => { // 初始化日志级别 LogLevels.Clear(); var logLevels = new[] { "Debug", "Info", "Warning", "Error" }; foreach (var level in logLevels) { LogLevels.Add(level); } SelectedLogLevel = "Info"; // 初始化系统信息 ModelSplitterStatus = "就绪"; LogStatus = "日志系统正常"; SettingsStatus = "设置已加载"; PluginVersion = "v1.0"; NavisworksVersion = "2026"; SystemStatus = "正常"; SystemStatusColor = "Green"; // 启动性能监控 StartPerformanceMonitoring(); LogManager.Info("系统管理设置初始化完成"); }, "初始化系统管理设置"); } /// /// 启动性能监控 /// private void StartPerformanceMonitoring() { var startTime = DateTime.Now; // 使用定时器更新性能信息 var timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(5); timer.Tick += (s, e) => { try { // 更新内存使用 var process = System.Diagnostics.Process.GetCurrentProcess(); var memoryMB = process.WorkingSet64 / (1024 * 1024); MemoryUsage = $"{memoryMB} MB"; // 更新运行时间 var runTime = DateTime.Now - startTime; RunningTime = $"{runTime.Hours:D2}:{runTime.Minutes:D2}:{runTime.Seconds:D2}"; // 更新性能信息 PerformanceInfo = $"CPU: 正常, 内存: {memoryMB}MB, 运行时间: {RunningTime}"; } catch (Exception ex) { LogManager.Error($"性能监控更新失败: {ex.Message}"); } }; timer.Start(); } #endregion #region 命令实现 /// /// 应用可见性模式 /// private void ApplyVisibilityMode() { SafeExecute(() => { if (IsLogisticsOnlyMode) { // 仅显示物流模式 ShowLogisticsOnlyInternal(); } else { // 显示全部模式 ShowAllInternal(); } }, "应用可见性模式"); } /// /// 内部方法:显示所有元素 /// private void ShowAllInternal() { var result = VisibilityManager.ShowAllItems(); if (result.Success) { // 更新物流模型列表中的可见性状态 foreach (var model in LogisticsModels) { model.IsVisible = true; } StatusText = "显示所有元素"; LogManager.Info("切换到显示全部模式"); } else { StatusText = $"显示全部失败: {result.Message}"; LogManager.Error($"显示全部失败: {result.Message}"); } } /// /// 内部方法:仅显示物流元素 /// private void ShowLogisticsOnlyInternal() { var document = NavisApplication.ActiveDocument; if (document?.Models != null) { // 先重置所有隐藏状态 document.Models.ResetAllHidden(); // 获取所有具有物流属性的元素 var logisticsItems = new HashSet(); var allItems = GetAllModelItems(); foreach (var item in allItems) { if (CategoryAttributeManager.HasLogisticsAttributes(item)) { logisticsItems.Add(item); } } // 获取所有需要保持可见的元素 var itemsToKeepVisible = new HashSet(); foreach (var logisticsItem in logisticsItems) { // 添加物流元素本身 itemsToKeepVisible.Add(logisticsItem); // 添加所有父元素路径(向上) var parent = logisticsItem.Parent; while (parent != null) { itemsToKeepVisible.Add(parent); parent = parent.Parent; } // 添加所有子元素(向下)- 物流属性继承给子元素 AddAllChildren(logisticsItem, itemsToKeepVisible); } // 找出需要隐藏的元素(不在保持可见列表中的元素) var itemsToHide = new List(); foreach (var item in allItems) { if (!itemsToKeepVisible.Contains(item)) { itemsToHide.Add(item); } } // 执行隐藏操作 if (itemsToHide.Count > 0) { var collectionToHide = new ModelItemCollection(); collectionToHide.AddRange(itemsToHide); document.Models.SetHidden(collectionToHide, true); } // 更新物流模型列表中的可见性状态 foreach (var model in LogisticsModels) { model.IsVisible = true; } var totalVisibleItems = itemsToKeepVisible.Count; StatusText = $"仅显示物流元素 ({logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素)"; LogManager.Info($"切换到仅显示物流模式: 找到 {logisticsItems.Count} 个物流节点,{totalVisibleItems} 个可见元素"); } } /// /// 递归添加所有子元素到可见列表 /// private void AddAllChildren(ModelItem parent, HashSet visibleItems) { if (parent.Children != null) { foreach (ModelItem child in parent.Children) { visibleItems.Add(child); // 递归添加子元素的子元素 AddAllChildren(child, visibleItems); } } } private void ExecuteNewPath() { SafeExecute(() => { // 调用 PathPlanningManager 来启动新建路径流程 if (_pathPlanningManager != null) { var newRoute = _pathPlanningManager.StartCreatingNewRoute(); if (newRoute != null) { // 创建对应的 WPF ViewModel var newPathViewModel = new PathRouteViewModel { Name = newRoute.Name, Description = newRoute.Description, IsActive = true // 新建的路径默认是活动的 }; // 将 Core 层的 PathPoint 转换为 WPF 的 PathPointViewModel 并添加到 ViewModel foreach (var corePoint in newRoute.Points) { var wpfPoint = new PathPointViewModel { Name = corePoint.Name, X = corePoint.X, Y = corePoint.Y, Z = corePoint.Z // 注意:Type 属性在 corrected_old_string 中不存在,因此不添加 }; newPathViewModel.Points.Add(wpfPoint); } // 添加到 UI 列表并选中 PathRoutes.Add(newPathViewModel); SelectedPathRoute = newPathViewModel; StatusText = $"已进入新建路径模式: {newRoute.Name} - 请在3D视图中点击设置路径点"; LogManager.Info($"开始新建路径: {newRoute.Name}"); // 显示提示信息,告知用户进入新建路径模式 MessageBox.Show("已进入新建路径模式!\n\n请在3D视图中可通行的物流模型上来设置路径点。", "新建路径", MessageBoxButton.OK, MessageBoxImage.Information); } else { // StartCreatingNewRoute 已经通过 OnErrorOccurred 发送了错误信息 // 这里可以添加更具体的提示 StatusText = "创建新路径失败:没有可通行的物流模型"; LogManager.Error("创建新路径失败:没有可通行的物流模型"); MessageBox.Show("创建新路径失败:没有找到任何可通行的物流模型。\n请先为模型设置可通行的物流属性,然后再尝试创建路径。", "错误", MessageBoxButton.OK, MessageBoxImage.Warning); } } else { StatusText = "路径规划管理器未初始化"; LogManager.Error("路径规划管理器未初始化"); } }, "新建路径"); } private void ExecuteDeletePath() { SafeExecute(() => { if (SelectedPathRoute != null) { var pathName = SelectedPathRoute.Name; // 清理对应的3D可视化标记 if (PathPointRenderPlugin.Instance != null) { // 如果是自动生成的路径,清除对应的标记 if (pathName.StartsWith("自动路径_")) { // 清除所有自动路径标记(负序号-1000系列) var allMarkers = PathPointRenderPlugin.Instance.GetAllMarkers(); var autoPathMarkers = allMarkers.Where(m => m.SequenceNumber < -999).ToList(); foreach (var marker in autoPathMarkers) { PathPointRenderPlugin.Instance.RemoveMarkerAt(marker.Center, 1.0); } if (autoPathMarkers.Count > 0) { LogManager.Info($"删除路径时清除了 {autoPathMarkers.Count} 个自动路径3D标记"); } } else { // 对于手动路径,清除对应序号的标记(正序号) // 这里可以根据路径点来清除具体的标记 if (SelectedPathRoute.Points.Count > 0) { int removedMarkers = 0; foreach (var point in SelectedPathRoute.Points) { var pointLocation = new Point3D(point.X, point.Y, point.Z); bool removed = PathPointRenderPlugin.Instance.RemoveMarkerAt(pointLocation, 2.0); if (removed) removedMarkers++; } if (removedMarkers > 0) { LogManager.Info($"删除路径时清除了 {removedMarkers} 个手动路径3D标记"); } } } } // 通知PathPlanningManager删除对应的路径 if (_pathPlanningManager != null) { // 查找PathPlanningManager中对应的路径并删除 var coreRoute = _pathPlanningManager.Routes.FirstOrDefault(r => r.Name == pathName); if (coreRoute != null) { _pathPlanningManager.Routes.Remove(coreRoute); LogManager.Info($"已从PathPlanningManager中删除路径: {pathName}"); } // 如果删除的是当前路径,清除当前路径状态 if (_pathPlanningManager.CurrentRoute?.Name == pathName) { _pathPlanningManager.Clear3DPathMarkers(); LogManager.Info("已清除当前路径的3D标记"); } } // 从UI列表中删除路径 PathRoutes.Remove(SelectedPathRoute); SelectedPathRoute = null; StatusText = $"已完全删除路径: {pathName}(包括3D可视化)"; LogManager.Info($"完全删除路径: {pathName},包括UI列表和3D可视化"); } }, "删除路径"); } private bool CanExecuteDeletePath() { return SelectedPathRoute != null; } private void ExecuteRenamePath() { SafeExecute(() => { if (SelectedPathRoute != null) { // TODO: 实现重命名对话框 var newName = $"路径 {PathRoutes.Count}"; // 临时实现 var oldName = SelectedPathRoute.Name; SelectedPathRoute.Name = newName; StatusText = $"路径已重命名: {oldName} -> {newName}"; PathFileStatus = "未保存"; LogManager.Info($"路径重命名: {oldName} -> {newName}"); } }, "重命名路径"); } private bool CanExecuteRenamePath() { return SelectedPathRoute != null; } private void ExecuteStartEdit() { SafeExecute(() => { if (SelectedPathRoute != null) { // 查找或创建与 WPF ViewModel 对应的 Core PathRoute var coreRoute = _pathPlanningManager?.Routes.FirstOrDefault(r => r.Name == SelectedPathRoute.Name); if (coreRoute == null) { // 如果 Core 层没有,可能需要创建或同步 // 这里假设 Core 层应该已经包含了所有路径,如果没有,可能需要重新加载或同步 // 为简化,我们直接使用 SelectedPathRoute 的信息创建一个临时的 Core PathRoute coreRoute = new NavisworksTransport.PathRoute(SelectedPathRoute.Name) { Description = SelectedPathRoute.Description ?? "" }; // 注意:ViewModel 中的点是 PathPoint 对象,Core 中的是 NavisworksTransport.PathPoint 对象 // 这里没有直接转换,因为 StartEditing 通常是对已存在的路径操作 // 如果需要从 ViewModel 创建 Core Route,需要进行数据转换 // 为了保持逻辑清晰,这里假设路径已经在 Core 中存在 StatusText = $"路径 '{SelectedPathRoute.Name}' 在核心管理器中未找到,无法开始编辑。"; LogManager.Warning($"路径 '{SelectedPathRoute.Name}' 在核心管理器中未找到"); return; } // 通知 PathPlanningManager 开始编辑此路径 _pathPlanningManager?.SwitchToEditingState(coreRoute); // 更新 WPF ViewModel 状态 IsPathEditMode = true; SelectedPathRoute.IsActive = true; StatusText = $"已进入3D路径编辑模式: {SelectedPathRoute.Name}"; LogManager.Info($"开始3D路径编辑: {SelectedPathRoute.Name}"); } else { StatusText = "请先选择一个路径"; } }, "开始编辑"); } private bool CanExecuteStartEdit() { // 检查是否选择了路径以及 PathPlanningManager 是否处于非编辑状态 return SelectedPathRoute != null && (_pathPlanningManager?.PathEditState == PathEditState.Viewing); } private void ExecuteEndEdit() { SafeExecute(() => { // 通知 PathPlanningManager 结束编辑 bool success = _pathPlanningManager?.FinishEditing() ?? false; // 更新 WPF ViewModel 状态 IsPathEditMode = false; if (SelectedPathRoute != null) { SelectedPathRoute.IsActive = false; if (success) { StatusText = $"已退出3D路径编辑模式: {SelectedPathRoute.Name} (已保存)"; PathFileStatus = "未保存"; // 或者根据实际情况设置为"已保存" } else { StatusText = $"退出3D路径编辑模式失败: {SelectedPathRoute.Name}"; } } else { if (success) { StatusText = "已退出3D路径编辑模式 (已保存)"; } else { StatusText = "退出3D路径编辑模式失败"; } } LogManager.Info("结束3D路径编辑"); }, "结束编辑"); } private bool CanExecuteEndEdit() { // 检查 PathPlanningManager 是否处于编辑状态 (Creating 或 Editing) return (_pathPlanningManager?.PathEditState == PathEditState.Creating || _pathPlanningManager?.PathEditState == PathEditState.Editing); } private void ExecuteClearPath() { SafeExecute(() => { if (SelectedPathRoute != null) { var pointCount = SelectedPathRoute.Points.Count; // 通知 PathPlanningManager 清除当前路径点 // 这需要 PathPlanningManager 有对应的方法,或者直接操作 CurrentRoute var currentRoute = _pathPlanningManager?.CurrentRoute; if (currentRoute != null && currentRoute.Name == SelectedPathRoute.Name) { currentRoute.ClearPoints(); // 通知 PathPlanningManager 重绘/清除3D标记 _pathPlanningManager?.Clear3DPathMarkers(); // 假设有此方法 } // 更新 WPF ViewModel SelectedPathRoute.Points.Clear(); StatusText = $"已清空路径 {SelectedPathRoute.Name} 的 {pointCount} 个点"; PathFileStatus = "未保存"; LogManager.Info($"清空路径: {SelectedPathRoute.Name}, 删除了 {pointCount} 个点"); } }, "清空路径"); } private bool CanExecuteClearPath() { return SelectedPathRoute != null && SelectedPathRoute.Points.Count > 0; } private void ExecuteDeletePoint(PathPointViewModel point) { SafeExecute(() => { if (SelectedPathRoute != null && point != null) { // 通知 PathPlanningManager 删除路径点 // 这需要 PathPlanningManager 有对应的方法,或者直接操作 CurrentRoute var currentRoute = _pathPlanningManager?.CurrentRoute; if (currentRoute != null && currentRoute.Name == SelectedPathRoute.Name) { var corePoint = currentRoute.Points.FirstOrDefault(p => Math.Abs(p.X - point.X) < 0.001 && Math.Abs(p.Y - point.Y) < 0.001 && Math.Abs(p.Z - point.Z) < 0.001); if (corePoint != null) { // 通知 PathPlanningManager 从3D视图中移除此点 _pathPlanningManager?.RemovePathPointFrom3D(corePoint); // 假设有此方法 } } // 更新 WPF ViewModel SelectedPathRoute.Points.Remove(point); StatusText = $"已删除路径点: {point.Name}"; PathFileStatus = "未保存"; LogManager.Info($"删除路径点: {point.Name}"); } }, "删除路径点"); } private void ExecuteImportPath() { SafeExecute(() => { // TODO: 实现文件对话框和路径导入逻辑 StatusText = "路径导入功能待实现"; LogManager.Info("执行路径导入命令"); }, "导入路径"); } private void ExecuteExportPath() { SafeExecute(() => { if (SelectedPathRoute != null) { // TODO: 实现文件对话框和路径导出逻辑 StatusText = $"导出路径: {SelectedPathRoute.Name}"; PathFileStatus = "已保存"; LogManager.Info($"导出路径: {SelectedPathRoute.Name}"); } }, "导出路径"); } private bool CanExecuteExportPath() { return SelectedPathRoute != null && SelectedPathRoute.Points.Count > 0; } private void ExecuteSaveAsPath() { SafeExecute(() => { if (SelectedPathRoute != null) { // TODO: 实现另存为对话框和保存逻辑 StatusText = $"另存为路径: {SelectedPathRoute.Name}"; PathFileStatus = "已保存"; LogManager.Info($"另存为路径: {SelectedPathRoute.Name}"); } }, "另存为路径"); } private bool CanExecuteSaveAsPath() { return SelectedPathRoute != null && SelectedPathRoute.Points.Count > 0; } private void ExecuteStartAnimation() { SafeExecute(() => { if (SelectedPathRoute == null || SelectedPathRoute.Points.Count < 2) { StatusText = "请先选择包含至少2个点的路径"; return; } // 更新动画状态 AnimationStatus = "动画状态: 播放中"; AnimationProgress = 0; CurrentAnimationTime = 0.0; // 更新按钮状态 CanStartAnimation = false; CanPauseAnimation = true; CanStopAnimation = true; // TODO: 集成LogisticsAnimationManager开始动画 StatusText = $"动画已开始: {SelectedPathRoute.Name} (速度: {AnimationSpeed}x, 帧率: {SelectedFrameRate}fps)"; LogManager.Info($"开始动画播放: {SelectedPathRoute.Name}, 速度: {AnimationSpeed}x, 帧率: {SelectedFrameRate}fps"); }, "开始动画"); } private void ExecutePauseAnimation() { SafeExecute(() => { AnimationStatus = "动画状态: 已暂停"; // 更新按钮状态 CanStartAnimation = true; CanPauseAnimation = false; CanStopAnimation = true; StatusText = "动画已暂停"; LogManager.Info("暂停动画播放"); }, "暂停动画"); } private void ExecuteStopAnimation() { SafeExecute(() => { AnimationStatus = "动画状态: 已停止"; AnimationProgress = 0; CurrentAnimationTime = 0.0; // 更新按钮状态 CanStartAnimation = true; CanPauseAnimation = false; CanStopAnimation = false; StatusText = "动画已停止"; LogManager.Info("停止动画播放"); }, "停止动画"); } private void ExecuteRunCollisionDetection() { SafeExecute(() => { if (SelectedPathRoute == null || SelectedPathRoute.Points.Count < 2) { StatusText = "请先选择包含至少2个点的路径进行碰撞检测"; return; } CollisionStatus = "正在运行碰撞检测..."; CanRunCollisionDetection = false; // TODO: 集成ClashDetectiveIntegration运行碰撞检测 // 模拟碰撞检测结果 System.Threading.Tasks.Task.Run(() => { System.Threading.Thread.Sleep(2000); // 模拟检测时间 // 在UI线程上更新结果 System.Windows.Application.Current.Dispatcher.Invoke(() => { CollisionStatus = "碰撞检测完成"; CollisionSummary = "发现 3 个潜在碰撞点"; HasCollisionResults = true; CanRunCollisionDetection = true; StatusText = "碰撞检测已完成,发现 3 个潜在碰撞点"; }); }); LogManager.Info($"开始碰撞检测: {SelectedPathRoute.Name}"); }, "运行碰撞检测"); } private void ExecuteViewCollisionReport() { SafeExecute(() => { // TODO: 实现碰撞报告查看功能 StatusText = "打开碰撞检测报告"; LogManager.Info("查看碰撞检测报告"); }, "查看碰撞报告"); } private void ExecuteModelSplitter() { SafeExecute(() => { ModelSplitterStatus = "正在分析模型结构..."; // TODO: 集成ModelSplitterManager实现模型分层拆分功能 System.Threading.Tasks.Task.Run(() => { System.Threading.Thread.Sleep(3000); // 模拟分析时间 System.Windows.Application.Current.Dispatcher.Invoke(() => { ModelSplitterStatus = "模型分析完成,可进行拆分操作"; StatusText = "模型分层拆分分析完成"; }); }); StatusText = "正在分析模型结构..."; LogManager.Info("执行模型分层拆分命令"); }, "模型分层拆分"); } private void ExecuteViewLog() { SafeExecute(() => { // TODO: 实现日志查看功能 StatusText = "打开日志查看器"; LogManager.Info("查看日志"); }, "查看日志"); } private void ExecuteClearLog() { SafeExecute(() => { // TODO: 实现日志清空功能 LogStatus = "日志已清空"; StatusText = "日志已清空"; LogManager.Info("清空日志"); }, "清空日志"); } private void ExecuteExportLog() { SafeExecute(() => { // TODO: 实现日志导出功能 StatusText = "日志导出完成"; LogManager.Info("导出日志"); }, "导出日志"); } private void ExecuteOpenSettings() { SafeExecute(() => { // TODO: 实现设置对话框 StatusText = "打开插件设置"; LogManager.Info("打开设置"); }, "打开设置"); } private void ExecuteResetSettings() { SafeExecute(() => { // TODO: 实现设置重置功能 SettingsStatus = "设置已重置为默认值"; IsAutoSaveEnabled = true; IsDebugModeEnabled = false; StatusText = "设置已重置"; LogManager.Info("重置设置"); }, "重置设置"); } private void ExecuteImportConfig() { SafeExecute(() => { // TODO: 实现配置导入功能 StatusText = "配置导入完成"; LogManager.Info("导入配置"); }, "导入配置"); } private void ExecuteCheckUpdate() { SafeExecute(() => { StatusText = "正在检查更新..."; // 模拟检查更新 System.Threading.Tasks.Task.Run(() => { System.Threading.Thread.Sleep(2000); System.Windows.Application.Current.Dispatcher.Invoke(() => { StatusText = "当前版本已是最新版本"; }); }); LogManager.Info("检查更新"); }, "检查更新"); } private void ExecuteGeneratePerformanceReport() { SafeExecute(() => { StatusText = "正在生成性能报告..."; // 模拟生成报告 System.Threading.Tasks.Task.Run(() => { System.Threading.Thread.Sleep(1500); System.Windows.Application.Current.Dispatcher.Invoke(() => { StatusText = "性能报告生成完成"; PerformanceInfo = $"报告已生成 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}"; }); }); LogManager.Info("生成性能报告"); }, "生成性能报告"); } private void ExecuteSetLogisticsAttribute() { SafeExecute(() => { if (string.IsNullOrEmpty(SelectedCategory)) { StatusText = "请先选择物流类别"; return; } var selectedItems = NavisApplication.ActiveDocument?.CurrentSelection?.SelectedItems; if (selectedItems == null || selectedItems.Count == 0) { StatusText = "请先选择模型元素"; return; } // 解析选中的类别为枚举 if (Enum.TryParse(SelectedCategory, out var elementType)) { int successCount = CategoryAttributeManager.AddLogisticsAttributes( selectedItems, elementType, isTraversable: true, priority: 5, vehicleSize: "标准", speedLimit: 10.0, widthLimit: WidthLimit); StatusText = $"已为 {successCount} 个元素设置物流属性: {SelectedCategory} (宽度限制: {WidthLimit}m)"; LogManager.Info($"设置物流属性: {SelectedCategory}, 宽度限制: {WidthLimit}m, 影响元素: {successCount}"); // 刷新所有物流模型列表,显示所有具有物流属性的模型 RefreshAllLogisticsModels(); // 如果当前处于仅显示物流模式,重新应用可见性设置 if (IsLogisticsOnlyMode) { ApplyVisibilityMode(); } } else { StatusText = $"无效的物流类别: {SelectedCategory}"; } }, "设置物流属性"); } #region 自动路径规划命令实现 /// /// 执行选择起点命令 /// private void ExecuteSelectStartPoint() { SafeExecute(() => { if (_pathPlanningManager == null) { AutoPathStatus = "路径规划管理器未初始化"; return; } IsSelectingStartPoint = true; IsSelectingEndPoint = false; AutoPathStatus = "请在3D视图中点击选择起点..."; // 直接订阅PathClickToolPlugin的鼠标点击事件来获取自动路径规划的起点 PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; PathClickToolPlugin.MouseClicked += OnAutoPathMouseClicked; // 启动3D点击工具 if (!_pathPlanningManager.StartClickTool()) { AutoPathStatus = "无法激活3D点击工具"; LogManager.Error("启动3D点击工具失败"); return; } LogManager.Info("开始选择自动路径规划起点,已激活点击工具"); }, "选择起点"); } /// /// 执行选择终点命令 /// private void ExecuteSelectEndPoint() { SafeExecute(() => { if (_pathPlanningManager == null) { AutoPathStatus = "路径规划管理器未初始化"; return; } IsSelectingEndPoint = true; IsSelectingStartPoint = false; AutoPathStatus = "请在3D视图中点击选择终点..."; // 直接订阅PathClickToolPlugin的鼠标点击事件来获取自动路径规划的终点 PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; PathClickToolPlugin.MouseClicked += OnAutoPathMouseClicked; // 启动3D点击工具 if (!_pathPlanningManager.StartClickTool()) { AutoPathStatus = "无法激活3D点击工具"; LogManager.Error("启动3D点击工具失败"); return; } LogManager.Info("开始选择自动路径规划终点,已激活点击工具"); }, "选择终点"); } /// /// 执行自动路径规划命令 /// private void ExecuteAutoPlanPath() { SafeExecute(() => { if (!_hasStartPoint || !_hasEndPoint) { AutoPathStatus = "请先选择起点和终点"; return; } AutoPathStatus = "正在计算最优路径..."; // 在后台线程中执行路径规划 System.Threading.Tasks.Task.Run(() => { try { // 调用PathPlanningManager的自动路径规划功能 var pathRoute = _pathPlanningManager?.AutoPlanPath( _startPoint3D, _endPoint3D, AutoPathVehicleSize); // 在UI线程上更新结果 System.Windows.Application.Current.Dispatcher.Invoke(() => { if (pathRoute != null && pathRoute.Points.Count > 0) { // 创建新的路径视图模型 var autoPathViewModel = new PathRouteViewModel { Name = $"自动路径_{DateTime.Now:HHmmss}", Description = "自动生成的最优路径", IsActive = true }; // 转换路径点 foreach (var point in pathRoute.Points) { var pointViewModel = new PathPointViewModel { Name = point.Name, X = point.X, Y = point.Y, Z = point.Z, Type = point.Type }; autoPathViewModel.Points.Add(pointViewModel); } // 添加到路径列表并选中 PathRoutes.Add(autoPathViewModel); SelectedPathRoute = autoPathViewModel; AutoPathStatus = $"路径规划完成!共 {pathRoute.Points.Count} 个路径点"; StatusText = $"自动路径规划成功: {pathRoute.Points.Count} 个点"; LogManager.Info($"自动路径规划成功: {autoPathViewModel.Name}, {pathRoute.Points.Count} 个点"); } else { AutoPathStatus = "路径规划失败,未找到可行路径"; StatusText = "自动路径规划失败:未找到可行路径"; LogManager.Warning("自动路径规划失败:未找到可行路径"); } }); } catch (Exception ex) { System.Windows.Application.Current.Dispatcher.Invoke(() => { AutoPathStatus = $"路径规划出错: {ex.Message}"; StatusText = $"自动路径规划出错: {ex.Message}"; LogManager.Error($"自动路径规划出错: {ex.Message}"); }); } }); }, "自动路径规划"); } /// /// 检查是否可以执行自动路径规划 /// private bool CanExecuteAutoPlanPath() { return _hasStartPoint && _hasEndPoint && AutoPathVehicleSize > 0; } /// /// 执行清除自动路径命令 /// private void ExecuteClearAutoPath() { SafeExecute(() => { // 停止任何正在进行的点选择 if (_pathPlanningManager != null) { _pathPlanningManager.StopClickTool(); PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; // 清除PathPlanningManager中的自动路径标记 _pathPlanningManager.Clear3DPathMarkers(); LogManager.Info("已清除PathPlanningManager中的路径标记"); } // 清除可视化的起点、终点球体和自动路径连线 if (PathPointRenderPlugin.Instance != null) { // 方法1:精确清除起点和终点球体 if (_hasStartPoint) { PathPointRenderPlugin.Instance.RemoveMarkerAt(_startPoint3D, 2.0); } if (_hasEndPoint) { PathPointRenderPlugin.Instance.RemoveMarkerAt(_endPoint3D, 2.0); } // 方法2:清除所有自动路径相关的标记(负序号-1000系列) var allMarkers = PathPointRenderPlugin.Instance.GetAllMarkers(); var autoPathMarkers = allMarkers.Where(m => m.SequenceNumber < -999).ToList(); foreach (var marker in autoPathMarkers) { PathPointRenderPlugin.Instance.RemoveMarkerAt(marker.Center, 1.0); } if (autoPathMarkers.Count > 0) { LogManager.Info($"已清除 {autoPathMarkers.Count} 个自动路径标记和连线"); } else if (_hasStartPoint || _hasEndPoint) { LogManager.Info("已清除自动路径规划的起点终点球体"); } } // 清除自动生成的路径(从UI路径列表中移除以"自动路径_"开头的路径) var autoGeneratedPaths = PathRoutes.Where(r => r.Name.StartsWith("自动路径_")).ToList(); foreach (var autoPath in autoGeneratedPaths) { PathRoutes.Remove(autoPath); LogManager.Info($"已从路径列表中移除自动生成的路径: {autoPath.Name}"); } // 如果当前选中的是自动生成的路径,清除选择 if (SelectedPathRoute != null && SelectedPathRoute.Name.StartsWith("自动路径_")) { SelectedPathRoute = null; } // 重置所有自动路径规划状态 _hasStartPoint = false; _hasEndPoint = false; _startPoint3D = new Point3D(); _endPoint3D = new Point3D(); AutoPathStartPoint = "未选择"; AutoPathEndPoint = "未选择"; AutoPathVehicleSize = 1.0; AutoPathStatus = "就绪"; IsSelectingStartPoint = false; IsSelectingEndPoint = false; StatusText = "已完全清除自动路径规划设置和可视化"; LogManager.Info("完全清除自动路径规划:UI状态、3D可视化、自动生成的路径全部清理完毕"); }, "清除自动路径"); } /// /// 设置自动路径规划的起点(供外部调用) /// public void SetAutoPathStartPoint(Point3D point) { // 清除之前的起点标记(如果有的话) if (_hasStartPoint && PathPointRenderPlugin.Instance != null) { PathPointRenderPlugin.Instance.RemoveMarkerAt(_startPoint3D, 2.0); LogManager.Info("已清除之前的起点标记"); } _startPoint3D = point; _hasStartPoint = true; AutoPathStartPoint = $"({point.X:F2}, {point.Y:F2}, {point.Z:F2})"; IsSelectingStartPoint = false; // 可视化新的起点 - 使用绿色球体 if (PathPointRenderPlugin.Instance != null) { // 添加新的起点标记(使用负序号避免与手动路径连线) PathPointRenderPlugin.Instance.AddCircleMarker(point, PathPointType.StartPoint, -100); LogManager.Info("已可视化自动路径规划起点(绿色球体)"); } if (_hasEndPoint) { AutoPathStatus = "起点和终点已设置,可以开始路径规划"; } else { AutoPathStatus = "起点已设置,请选择终点"; } LogManager.Info($"设置自动路径规划起点: {AutoPathStartPoint}"); } /// /// 设置自动路径规划的终点(供外部调用) /// public void SetAutoPathEndPoint(Point3D point) { // 清除之前的终点标记(如果有的话) if (_hasEndPoint && PathPointRenderPlugin.Instance != null) { PathPointRenderPlugin.Instance.RemoveMarkerAt(_endPoint3D, 2.0); LogManager.Info("已清除之前的终点标记"); } _endPoint3D = point; _hasEndPoint = true; AutoPathEndPoint = $"({point.X:F2}, {point.Y:F2}, {point.Z:F2})"; IsSelectingEndPoint = false; // 可视化新的终点 - 使用红色球体 if (PathPointRenderPlugin.Instance != null) { // 添加新的终点标记(使用负序号避免与手动路径连线) PathPointRenderPlugin.Instance.AddCircleMarker(point, PathPointType.EndPoint, -200); LogManager.Info("已可视化自动路径规划终点(红色球体)"); } if (_hasStartPoint) { AutoPathStatus = "起点和终点已设置,可以开始路径规划"; } else { AutoPathStatus = "终点已设置,请选择起点"; } LogManager.Info($"设置自动路径规划终点: {AutoPathEndPoint}"); } /// /// 处理自动路径规划的鼠标点击事件(直接从PathClickToolPlugin获取) /// private void OnAutoPathMouseClicked(object sender, PickItemResult pickResult) { try { if (pickResult == null) { LogManager.Warning("收到空的点击结果事件"); return; } var point3D = pickResult.Point; LogManager.Info($"收到自动路径规划点击事件: ({point3D.X:F2}, {point3D.Y:F2}, {point3D.Z:F2})"); LogManager.Info($"点击对象: {pickResult.ModelItem?.DisplayName ?? "NULL"}"); if (IsSelectingStartPoint) { // 设置起点 SetAutoPathStartPoint(point3D); // 停止3D点击工具并取消事件订阅 _pathPlanningManager.StopClickTool(); PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; LogManager.Info("已设置自动路径规划起点"); } else if (IsSelectingEndPoint) { // 设置终点 SetAutoPathEndPoint(point3D); // 停止3D点击工具并取消事件订阅 _pathPlanningManager.StopClickTool(); PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; LogManager.Info("已设置自动路径规划终点"); } else { // 如果不在选择模式中,取消事件订阅 PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; LogManager.Warning("收到点击事件但未在选择模式中"); } } catch (Exception ex) { LogManager.Error($"处理自动路径规划点击事件时发生错误: {ex.Message}"); AutoPathStatus = $"获取点击位置失败: {ex.Message}"; // 确保清理状态 IsSelectingStartPoint = false; IsSelectingEndPoint = false; if (_pathPlanningManager != null) { _pathPlanningManager.StopClickTool(); PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; } } } #endregion #endregion #region PathPlanningManager 集成 /// /// 初始化路径规划管理器 /// private void InitializePathPlanningManager() { SafeExecute(() => { // 获取或创建PathPlanningManager实例 _pathPlanningManager = PathPlanningManager.GetActivePathManager() ?? new PathPlanningManager(); // 订阅 PathPlanningManager 的事件 if (_pathPlanningManager != null) { // 订阅路径编辑状态变更事件 _pathPlanningManager.PathEditStateChanged += OnPathEditStateChanged; // 订阅3D中路径点添加/移除事件 _pathPlanningManager.PathPointAddedIn3D += OnPathPointAddedIn3D; _pathPlanningManager.PathPointRemovedFrom3D += OnPathPointRemovedFrom3D; // 订阅路径点列表更新事件 _pathPlanningManager.PathPointsListUpdated += OnPathPointsListUpdated; // 订阅当前路径变更事件 _pathPlanningManager.CurrentRouteChanged += OnCurrentRouteChanged; // 订阅状态和错误事件 _pathPlanningManager.StatusChanged += OnPathManagerStatusChanged; _pathPlanningManager.ErrorOccurred += OnPathManagerErrorOccurred; LogManager.Info("PathPlanningManager事件订阅完成"); } LogManager.Info("PathPlanningManager已初始化并集成到ViewModel"); }, "初始化PathPlanningManager"); } #region PathPlanningManager 事件处理 /// /// 处理 PathEditStateChanged 事件 /// private void OnPathEditStateChanged(object sender, PathEditState newState) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { SafeExecute(() => { // 更新 ViewModel 的 IsPathEditMode 状态 // Creating 或 Editing 状态都视为编辑模式 IsPathEditMode = (newState == PathEditState.Creating || newState == PathEditState.Editing); // 如果有选中的路径,也更新其 IsActive 状态 if (SelectedPathRoute != null) { SelectedPathRoute.IsActive = IsPathEditMode; } LogManager.Info($"UI已更新 - 路径编辑状态已变更为: {newState}, IsPathEditMode: {IsPathEditMode}"); }, "处理路径编辑状态变更事件"); }); } /// /// 处理 PathPointAddedIn3D 事件 /// private void OnPathPointAddedIn3D(object sender, NavisworksTransport.PathPoint pathPoint) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { SafeExecute(() => { if (pathPoint != null && SelectedPathRoute != null) { // 创建 WPF ViewModel 对应的 PathPoint var newWpfPoint = new PathPointViewModel { Name = pathPoint.Name, X = pathPoint.X, Y = pathPoint.Y, Z = pathPoint.Z, Type = pathPoint.Type // 同步 Type 属性 }; SelectedPathRoute.Points.Add(newWpfPoint); LogManager.Info($"UI已更新 - 添加路径点: {pathPoint.Name}"); } }, "处理路径点添加事件"); }); } /// /// 处理 PathPointRemovedFrom3D 事件 /// private void OnPathPointRemovedFrom3D(object sender, NavisworksTransport.PathPoint pathPoint) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { SafeExecute(() => { if (pathPoint != null && SelectedPathRoute != null) { // 在 WPF ViewModel 中找到并移除对应的 PathPoint var pointToRemove = SelectedPathRoute.Points.FirstOrDefault(p => p.Name == pathPoint.Name); if (pointToRemove != null) { SelectedPathRoute.Points.Remove(pointToRemove); LogManager.Info($"UI已更新 - 移除路径点: {pathPoint.Name}"); } } }, "处理路径点移除事件"); }); } /// /// 处理 PathPointsListUpdated 事件 /// private void OnPathPointsListUpdated(object sender, NavisworksTransport.PathRoute updatedRoute) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { SafeExecute(() => { // 查找或创建对应的 WPF ViewModel var routeViewModel = PathRoutes.FirstOrDefault(r => r.Name == updatedRoute?.Name); if (routeViewModel == null && updatedRoute != null) { // 如果UI列表中没有,则创建一个新的 routeViewModel = new PathRouteViewModel { Name = updatedRoute.Name, Description = updatedRoute.Description, IsActive = true // 或根据实际情况设置 }; PathRoutes.Add(routeViewModel); } // 更新 ViewModel 的点列表 if (routeViewModel != null && updatedRoute != null) { routeViewModel.Points.Clear(); foreach (var corePoint in updatedRoute.Points) { var wpfPoint = new PathPointViewModel { Name = corePoint.Name, X = corePoint.X, Y = corePoint.Y, Z = corePoint.Z, Type = corePoint.Type // 同步 Type 属性 }; routeViewModel.Points.Add(wpfPoint); } LogManager.Info($"UI已更新 - 路径点列表已同步: {updatedRoute.Name}"); } }, "处理路径点列表更新事件"); }); } /// /// 处理 CurrentRouteChanged 事件 /// private void OnCurrentRouteChanged(object sender, NavisworksTransport.PathRoute newRoute) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { SafeExecute(() => { if (newRoute != null) { // 更新 SelectedPathRoute 为新的当前路径 SelectedPathRoute = PathRoutes.FirstOrDefault(r => r.Name == newRoute.Name) ?? SelectedPathRoute; StatusText = $"当前活动路径: {newRoute.Name}"; LogManager.Info($"UI已更新 - 当前活动路径变更为: {newRoute.Name}"); } }, "处理当前路径变更事件"); }); } /// /// 处理 PathManager 的 StatusChanged 事件 /// private void OnPathManagerStatusChanged(object sender, string statusMessage) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { StatusText = statusMessage; LogManager.Info($"PathManager状态更新: {statusMessage}"); }); } /// /// 处理 PathManager 的 ErrorOccurred 事件 /// private void OnPathManagerErrorOccurred(object sender, string errorMessage) { // 使用 Dispatcher 确保在 UI 线程上更新 System.Windows.Application.Current.Dispatcher.Invoke(() => { StatusText = $"错误: {errorMessage}"; LogManager.Error($"PathManager错误: {errorMessage}"); // 可以考虑显示一个错误对话框 // MessageBox.Show(errorMessage, "PathManager 错误", MessageBoxButton.OK, MessageBoxImage.Error); }); } #endregion /// /// 开始3D路径编辑 /// private void Start3DPathEditing() { SafeExecute(() => { if (SelectedPathRoute != null && _pathPlanningManager != null) { // 将WPF模型转换为PathPlanningManager的路径模型 var planningRoute = ConvertToPathPlanningRoute(SelectedPathRoute); // 开始编辑模式 _pathPlanningManager.SwitchToEditingState(planningRoute); StatusText = $"已开始3D编辑模式: {SelectedPathRoute.Name}"; LogManager.Info($"开始3D路径编辑: {SelectedPathRoute.Name}"); } }, "开始3D路径编辑"); } /// /// 结束3D路径编辑 /// private void End3DPathEditing() { SafeExecute(() => { if (_pathPlanningManager != null) { // 完成编辑并保存 bool success = _pathPlanningManager.FinishEditing(); if (success) { // 更新WPF模型 UpdatePathRouteFromPlanning(); StatusText = "3D路径编辑已完成"; PathFileStatus = "未保存"; } else { StatusText = "3D路径编辑完成失败"; } LogManager.Info("结束3D路径编辑"); } }, "结束3D路径编辑"); } /// /// 将WPF路径视图模型转换为Core层路径模型 /// private NavisworksTransport.PathRoute ConvertToPathPlanningRoute(PathRouteViewModel wpfRoute) { if (wpfRoute == null) return null; var planningRoute = new NavisworksTransport.PathRoute { Name = wpfRoute.Name, Description = wpfRoute.Description ?? "", Points = new List() }; // 转换路径点 foreach (var wpfPoint in wpfRoute.Points) { var planningPoint = new NavisworksTransport.PathPoint { Name = wpfPoint.Name, X = wpfPoint.X, Y = wpfPoint.Y, Z = wpfPoint.Z, Type = NavisworksTransport.PathPointType.WayPoint // 默认类型 }; planningRoute.Points.Add(planningPoint); } return planningRoute; } /// /// 从PathPlanningManager更新WPF路径模型 /// private void UpdatePathRouteFromPlanning() { SafeExecute(() => { if (_pathPlanningManager?.CurrentRoute != null && SelectedPathRoute != null) { var planningRoute = _pathPlanningManager.CurrentRoute; // 更新路径基本信息 SelectedPathRoute.Name = planningRoute.Name; SelectedPathRoute.Description = planningRoute.Description; // 清空并重新添加路径点 SelectedPathRoute.Points.Clear(); foreach (var planningPoint in planningRoute.Points) { var wpfPoint = new PathPointViewModel { Name = planningPoint.Name, X = planningPoint.X, Y = planningPoint.Y, Z = planningPoint.Z, Type = planningPoint.Type }; SelectedPathRoute.Points.Add(wpfPoint); } // 触发UI更新 OnPropertyChanged(nameof(SelectedPathRoute)); StatusText = $"已更新路径: {SelectedPathRoute.Name} ({SelectedPathRoute.Points.Count} 个点)"; } }, "更新路径模型"); } #endregion #region 辅助方法 /// /// 更新指令文本 /// public void UpdateInstructionText() { SafeExecute(() => { if (NavisApplication.ActiveDocument?.Models?.Count > 0) { InstructionText = "请在主界面中点击选择模型"; } else { InstructionText = "请先打开一个Navisworks模型文件"; } }, "更新指令文本"); } /// /// 更新选择显示 /// public void UpdateSelectionDisplay() { SafeExecute(() => { if (NavisApplication.ActiveDocument?.CurrentSelection?.SelectedItems?.Count > 0) { var selectedCount = NavisApplication.ActiveDocument.CurrentSelection.SelectedItems.Count; SelectedModelsText = $"选中模型: {selectedCount} 个"; } else { SelectedModelsText = "选中模型: 0 个"; } }, "更新选择显示"); } /// /// 初始化物流类别 /// private void InitializeCategories() { SafeExecute(() => { AvailableCategories.Clear(); // 添加所有物流元素类型 foreach (var elementType in Enum.GetValues(typeof(CategoryAttributeManager.LogisticsElementType))) { AvailableCategories.Add(elementType.ToString()); } // 设置默认选择 if (AvailableCategories.Count > 0) { SelectedCategory = AvailableCategories[0]; } LogManager.Info($"已初始化 {AvailableCategories.Count} 个物流类别"); }, "初始化物流类别"); } /// /// 更新物流模型列表(显示所有具有物流属性的模型) /// private void UpdateLogisticsModels() { // 直接调用刷新所有物流模型的方法 RefreshAllLogisticsModels(); } /// /// 刷新所有物流模型列表(显示所有具有物流属性的模型) /// private void RefreshAllLogisticsModels() { SafeExecute(() => { LogisticsModels.Clear(); // 查找所有具有物流属性的模型项 var allLogisticsItems = FindAllLogisticsModels(); foreach (var item in allLogisticsItems) { var logisticsType = GetLogisticsTypeFromItem(item); var attributes = GetLogisticsAttributesFromItem(item); var model = new LogisticsModel { Name = item.DisplayName ?? "未命名模型", Category = logisticsType ?? "未分类", Attributes = attributes ?? "无属性", IsVisible = !item.IsHidden, NavisworksItem = item }; LogisticsModels.Add(model); } LogManager.Info($"已刷新所有物流模型列表,共 {LogisticsModels.Count} 个模型"); }, "刷新所有物流模型列表"); } /// /// 从模型项获取物流类型 /// private string GetLogisticsTypeFromItem(ModelItem item) { try { // 查找物流属性类别 foreach (var category in item.PropertyCategories) { if (category.DisplayName == CategoryAttributeManager.LogisticsCategories.LOGISTICS) { foreach (var property in category.Properties) { if (property.DisplayName == CategoryAttributeManager.LogisticsProperties.TYPE) { return property.Value.ToDisplayString(); } } } } } catch (Exception ex) { LogManager.Error($"获取物流类型失败: {ex.Message}"); } return null; } /// /// 从模型项获取物流属性描述 /// private string GetLogisticsAttributesFromItem(ModelItem item) { try { var attributes = new System.Text.StringBuilder(); // 查找物流属性类别 foreach (var category in item.PropertyCategories) { if (category.DisplayName == CategoryAttributeManager.LogisticsCategories.LOGISTICS) { foreach (var property in category.Properties) { if (property.DisplayName != CategoryAttributeManager.LogisticsProperties.TYPE) { if (attributes.Length > 0) attributes.Append(", "); attributes.Append($"{property.DisplayName}: {property.Value.ToDisplayString()}"); } } break; } } return attributes.Length > 0 ? attributes.ToString() : null; } catch (Exception ex) { LogManager.Error($"获取物流属性失败: {ex.Message}"); return null; } } /// /// 查找所有具有物流属性的模型项 /// private ModelItemCollection FindAllLogisticsModels() { var logisticsItems = new ModelItemCollection(); try { var document = NavisApplication.ActiveDocument; if (document?.Models != null) { // 使用Search API查找所有具有物流属性的模型项 var search = new Search(); search.Selection.SelectAll(); // 查找具有物流属性类别的项目 search.SearchConditions.Add( SearchCondition.HasCategoryByDisplayName(CategoryAttributeManager.LogisticsCategories.LOGISTICS) ); logisticsItems = search.FindAll(document, false); LogManager.Info($"找到 {logisticsItems.Count} 个具有物流属性的模型项"); } } catch (Exception ex) { LogManager.Error($"查找物流模型失败: {ex.Message}"); } return logisticsItems; } /// /// 获取模型中的所有ModelItem /// private List GetAllModelItems() { var allItems = new List(); try { var document = NavisApplication.ActiveDocument; if (document?.Models != null) { foreach (var model in document.Models) { // 从根模型的子项开始收集,以避免包含不可见的根节点 foreach (var item in model.RootItem.Children) { CollectModelItems(item, allItems); } } } } catch (Exception ex) { LogManager.Error($"获取所有模型项失败: {ex.Message}"); } return allItems; } /// /// 递归收集ModelItem及其所有子项 /// private void CollectModelItems(ModelItem item, List collection) { if (item == null) return; collection.Add(item); // 递归添加子项目 if (item.Children != null && item.Children.Count() > 0) { foreach (ModelItem child in item.Children) { CollectModelItems(child, collection); } } } /// /// 检查模型项是否具有物流属性 /// private bool HasLogisticsAttributes(ModelItem item) { try { foreach (var category in item.PropertyCategories) { if (category.DisplayName == CategoryAttributeManager.LogisticsCategories.LOGISTICS) { return true; } } } catch (Exception ex) { LogManager.Error($"检查物流属性失败: {ex.Message}"); } return false; } #endregion } }