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
}
}