修复了路径编辑的事件分发问题。
This commit is contained in:
parent
0e20be9e86
commit
3012e4752f
Binary file not shown.
@ -184,11 +184,21 @@ namespace NavisworksTransport.Core.Animation
|
||||
var doc = NavisApplication.ActiveDocument;
|
||||
var modelItems = new ModelItemCollection { _animatedObject };
|
||||
|
||||
// 计算从部件原始中心到路径起点的偏移
|
||||
// 获取物体的包围盒
|
||||
var boundingBox = _animatedObject.BoundingBox();
|
||||
|
||||
// 计算物体底面中心点(而不是整体中心点)
|
||||
var objectBottomCenter = new Point3D(
|
||||
_originalCenter.X,
|
||||
_originalCenter.Y,
|
||||
boundingBox.Min.Z // 使用包围盒的最小Z值作为底面
|
||||
);
|
||||
|
||||
// 计算从物体底面中心到路径起点的偏移
|
||||
var startOffset = new Vector3D(
|
||||
_pathPoints[0].X - _originalCenter.X,
|
||||
_pathPoints[0].Y - _originalCenter.Y,
|
||||
_pathPoints[0].Z - _originalCenter.Z
|
||||
_pathPoints[0].X - objectBottomCenter.X,
|
||||
_pathPoints[0].Y - objectBottomCenter.Y,
|
||||
_pathPoints[0].Z - objectBottomCenter.Z
|
||||
);
|
||||
|
||||
// 创建变换并应用
|
||||
@ -198,9 +208,12 @@ namespace NavisworksTransport.Core.Animation
|
||||
// 更新当前位置为路径起点
|
||||
_currentPosition = _pathPoints[0];
|
||||
|
||||
LogManager.Info($"部件已移动到路径起点,偏移: ({startOffset.X:F2},{startOffset.Y:F2},{startOffset.Z:F2})");
|
||||
LogManager.Info($"物体已移动到路径起点,底面对齐地面");
|
||||
LogManager.Info($"物体包围盒: Min=({boundingBox.Min.X:F2},{boundingBox.Min.Y:F2},{boundingBox.Min.Z:F2}), Max=({boundingBox.Max.X:F2},{boundingBox.Max.Y:F2},{boundingBox.Max.Z:F2})");
|
||||
LogManager.Info($"物体原始中心: ({_originalCenter.X:F2},{_originalCenter.Y:F2},{_originalCenter.Z:F2})");
|
||||
LogManager.Info($"物体底面中心: ({objectBottomCenter.X:F2},{objectBottomCenter.Y:F2},{objectBottomCenter.Z:F2})");
|
||||
LogManager.Info($"路径起点坐标: ({_pathPoints[0].X:F2},{_pathPoints[0].Y:F2},{_pathPoints[0].Z:F2})");
|
||||
LogManager.Info($"原始中心坐标: ({_originalCenter.X:F2},{_originalCenter.Y:F2},{_originalCenter.Z:F2})");
|
||||
LogManager.Info($"应用的偏移量: ({startOffset.X:F2},{startOffset.Y:F2},{startOffset.Z:F2})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -40,6 +40,9 @@ namespace NavisworksTransport
|
||||
// ToolPlugin 集成
|
||||
private bool _isToolPluginActive = false;
|
||||
|
||||
// 自动路径规划模式标志
|
||||
private bool _isInAutoPathMode = false;
|
||||
|
||||
// 路径点3D标记管理
|
||||
private List<PathPointMarker> _pathPointMarkers;
|
||||
|
||||
@ -147,7 +150,7 @@ namespace NavisworksTransport
|
||||
|
||||
public bool IsInEditableState
|
||||
{
|
||||
get { return _pathEditState == PathEditState.Creating || _pathEditState == PathEditState.Editing; }
|
||||
get { return _pathEditState == PathEditState.Creating || _pathEditState == PathEditState.Editing || _pathEditState == PathEditState.AddingPoints; }
|
||||
}
|
||||
|
||||
public PathRoute CurrentRoute
|
||||
@ -177,6 +180,14 @@ namespace NavisworksTransport
|
||||
get { return _currentPointType; }
|
||||
private set { _currentPointType = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否在自动路径规划模式
|
||||
/// </summary>
|
||||
public bool IsInAutoPathMode
|
||||
{
|
||||
get { return _isInAutoPathMode; }
|
||||
private set { _isInAutoPathMode = value; }
|
||||
}
|
||||
|
||||
public ChannelBounds CombinedChannelBounds => _combinedChannelBounds;
|
||||
|
||||
@ -618,9 +629,14 @@ namespace NavisworksTransport
|
||||
try
|
||||
{
|
||||
CurrentPointType = pointType;
|
||||
ActivateToolPlugin();
|
||||
|
||||
// 检查是否在自动路径模式 - 如果是,则不订阅PathPlanningManager的事件
|
||||
bool shouldSubscribeToEvents = !IsInAutoPathMode;
|
||||
LogManager.Info($"StartClickTool - 自动路径模式: {IsInAutoPathMode}, 订阅事件: {shouldSubscribeToEvents}");
|
||||
|
||||
ActivateToolPlugin(shouldSubscribeToEvents);
|
||||
PathEditState = PathEditState.AddingPoints;
|
||||
LogManager.Info($"点击工具已启动,类型: {pointType}");
|
||||
LogManager.Info($"点击工具已启动,类型: {pointType},事件订阅: {shouldSubscribeToEvents}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -676,8 +692,7 @@ namespace NavisworksTransport
|
||||
LogManager.WriteLog($"[事件清理] 额外清理过程异常: {cleanupEx.Message}");
|
||||
}
|
||||
|
||||
// 3. 更新状态
|
||||
PathEditState = PathEditState.None;
|
||||
// 注意:移除了PathEditState设置,StopClickTool只管理工具插件状态,不修改业务逻辑状态
|
||||
LogManager.WriteLog("[事件清理] ===== StopClickTool执行完成,所有事件订阅已清理 =====");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -687,6 +702,47 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 禁用鼠标处理(用于自动路径规划模式)
|
||||
/// </summary>
|
||||
public void DisableMouseHandling()
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.Info("禁用PathPlanningManager鼠标处理,进入自动路径规划模式");
|
||||
IsInAutoPathMode = true;
|
||||
|
||||
// 取消PathPlanningManager的鼠标事件订阅
|
||||
PathClickToolPlugin.MouseClicked -= OnToolPluginMouseClicked;
|
||||
LogManager.Info("已取消PathPlanningManager的鼠标事件订阅");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"禁用鼠标处理失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启用鼠标处理(用于手动路径编辑模式)
|
||||
/// </summary>
|
||||
public void EnableMouseHandling()
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.Info("启用PathPlanningManager鼠标处理,退出自动路径规划模式");
|
||||
IsInAutoPathMode = false;
|
||||
|
||||
// 重新订阅PathPlanningManager的鼠标事件
|
||||
PathClickToolPlugin.MouseClicked -= OnToolPluginMouseClicked; // 先取消避免重复
|
||||
PathClickToolPlugin.MouseClicked += OnToolPluginMouseClicked;
|
||||
LogManager.Info("已重新订阅PathPlanningManager的鼠标事件");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"启用鼠标处理失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动路径规划(完整实现)
|
||||
/// </summary>
|
||||
@ -1631,18 +1687,27 @@ namespace NavisworksTransport
|
||||
/// <summary>
|
||||
/// 激活自定义ToolPlugin进行精确点击检测
|
||||
/// </summary>
|
||||
private bool ActivateToolPlugin()
|
||||
/// <param name="subscribeToEvents">是否订阅鼠标事件</param>
|
||||
private bool ActivateToolPlugin(bool subscribeToEvents = true)
|
||||
{
|
||||
// 如果已经激活,直接返回成功
|
||||
// 如果已经激活,检查是否需要订阅事件
|
||||
if (_isToolPluginActive)
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin] ToolPlugin已激活,无需重复激活");
|
||||
LogManager.WriteLog("[ToolPlugin] ToolPlugin已激活,检查事件订阅状态");
|
||||
if (subscribeToEvents)
|
||||
{
|
||||
// 确保事件订阅(避免重复订阅)
|
||||
PathClickToolPlugin.MouseClicked -= OnToolPluginMouseClicked;
|
||||
PathClickToolPlugin.MouseClicked += OnToolPluginMouseClicked;
|
||||
LogManager.WriteLog("[ToolPlugin] 已确保PathPlanningManager事件订阅");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin] ===== 开始激活ToolPlugin =====");
|
||||
LogManager.WriteLog($"[ToolPlugin] 订阅事件: {subscribeToEvents}");
|
||||
LogManager.WriteLog($"[ToolPlugin] 当前应用程序状态: {Application.IsAutomated}");
|
||||
LogManager.WriteLog($"[ToolPlugin] 当前文档状态: {Application.ActiveDocument?.Title ?? "NULL"}");
|
||||
|
||||
@ -1681,10 +1746,17 @@ namespace NavisworksTransport
|
||||
Application.MainDocument.Tool.SetCustomToolPlugin(loadedPlugin);
|
||||
LogManager.WriteLog("[ToolPlugin] ✓ 工具设置成功");
|
||||
|
||||
// 5. 订阅点击事件
|
||||
LogManager.WriteLog("[ToolPlugin] 步骤5: 订阅点击事件");
|
||||
PathClickToolPlugin.MouseClicked += OnToolPluginMouseClicked;
|
||||
LogManager.WriteLog("[ToolPlugin] ✓ 事件订阅成功");
|
||||
// 5. 根据参数决定是否订阅点击事件
|
||||
if (subscribeToEvents)
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin] 步骤5: 订阅点击事件");
|
||||
PathClickToolPlugin.MouseClicked += OnToolPluginMouseClicked;
|
||||
LogManager.WriteLog("[ToolPlugin] ✓ PathPlanningManager事件订阅成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin] 步骤5: 跳过事件订阅(由外部组件管理)");
|
||||
}
|
||||
|
||||
_isToolPluginActive = true;
|
||||
LogManager.WriteLog("[ToolPlugin] ===== ToolPlugin激活完成 =====");
|
||||
@ -1708,85 +1780,17 @@ namespace NavisworksTransport
|
||||
LogManager.WriteLog("[ToolPlugin事件-V2] ===== 收到精确点击坐标 =====");
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 精确坐标: ({pickResult.Point.X:F3}, {pickResult.Point.Y:F3}, {pickResult.Point.Z:F3})");
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 选中对象: {pickResult.ModelItem?.DisplayName ?? "NULL"}");
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 当前点类型: {CurrentPointType}");
|
||||
|
||||
// 检查当前选中的通道状态
|
||||
LogManager.WriteLog($"[ToolPlugin事件-V2] 当前_selectedChannels状态: {(_selectedChannels == null ? "NULL" : $"包含{_selectedChannels.Count}个项目")}");
|
||||
|
||||
// 如果没有选中的通道,尝试实时搜索
|
||||
if (_selectedChannels == null || _selectedChannels.Count == 0)
|
||||
// 如果在自动路径规划模式,则跳过处理(应该由PathEditingViewModel处理)
|
||||
if (IsInAutoPathMode)
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin事件] 没有预选通道,开始实时搜索可通行的物流模型");
|
||||
|
||||
try
|
||||
{
|
||||
var document = Application.ActiveDocument;
|
||||
if (document?.Models != null)
|
||||
{
|
||||
// 使用Search API实时搜索
|
||||
var logisticsItems = SearchLogisticsItemsUsingSearchAPI();
|
||||
LogManager.WriteLog($"[ToolPlugin事件] 实时搜索找到 {logisticsItems.Count} 个物流模型");
|
||||
|
||||
if (logisticsItems.Count > 0)
|
||||
{
|
||||
// 筛选出可通行的物流模型
|
||||
var modelCollection = new ModelItemCollection();
|
||||
modelCollection.AddRange(logisticsItems);
|
||||
var traversableItems = CategoryAttributeManager.FilterTraversableItems(modelCollection);
|
||||
LogManager.WriteLog($"[ToolPlugin事件] 筛选出 {traversableItems.Count} 个可通行的物流模型");
|
||||
|
||||
// 临时设置为选中通道
|
||||
if (_selectedChannels == null) _selectedChannels = new List<ModelItem>();
|
||||
_selectedChannels.Clear();
|
||||
|
||||
foreach (ModelItem item in traversableItems)
|
||||
{
|
||||
_selectedChannels.Add(item);
|
||||
LogManager.WriteLog($"[ToolPlugin事件] 添加可通行模型: '{item.DisplayName}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception searchEx)
|
||||
{
|
||||
LogManager.WriteLog($"[ToolPlugin事件] 实时搜索失败: {searchEx.Message}");
|
||||
}
|
||||
LogManager.WriteLog("[ToolPlugin事件] 当前在自动路径规划模式,跳过PathPlanningManager处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否在可通行的物流模型内
|
||||
if (_selectedChannels != null && _selectedChannels.Any())
|
||||
{
|
||||
bool isInTraversableLogisticsModel = IsItemInSelectedChannels(pickResult.ModelItem) ||
|
||||
IsItemChildOfSelectedChannels(pickResult.ModelItem);
|
||||
|
||||
LogManager.WriteLog($"[ToolPlugin事件] 在可通行的物流模型内: {isInTraversableLogisticsModel}");
|
||||
|
||||
if (isInTraversableLogisticsModel)
|
||||
{
|
||||
// 不再传递点类型,让AddPathPointIn3D方法内部自动判断
|
||||
LogManager.WriteLog("[ToolPlugin事件] 调用AddPathPointIn3D添加路径点");
|
||||
var pathPoint = AddPathPointIn3D(pickResult.Point);
|
||||
|
||||
if (pathPoint != null)
|
||||
{
|
||||
LogManager.WriteLog($"[ToolPlugin事件] ✓ 路径点添加成功: {pathPoint.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin事件] ✗ 路径点添加失败");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin事件] ✗ 点击位置不在可通行的物流模型内");
|
||||
// 可以考虑给用户一个提示
|
||||
OnStatusChanged("点击位置不是可通行的物流模型,请在可通行的物流模型上点击");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[ToolPlugin事件] ✗ 没有可通行的物流模型");
|
||||
OnStatusChanged("没有找到任何可通行的物流模型,请先为模型设置可通行的物流属性");
|
||||
}
|
||||
// 手动路径编辑处理
|
||||
ProcessManualPathEditing(pickResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -1795,6 +1799,98 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理手动路径编辑的鼠标点击
|
||||
/// </summary>
|
||||
private void ProcessManualPathEditing(PickItemResult pickResult)
|
||||
{
|
||||
// 检查当前选中的通道状态
|
||||
LogManager.WriteLog($"[手动编辑] 当前_selectedChannels状态: {(_selectedChannels == null ? "NULL" : $"包含{_selectedChannels.Count}个项目")}");
|
||||
|
||||
// 如果没有选中的通道,尝试实时搜索
|
||||
if (_selectedChannels == null || _selectedChannels.Count == 0)
|
||||
{
|
||||
LogManager.WriteLog("[手动编辑] 没有预选通道,开始实时搜索可通行的物流模型");
|
||||
SearchAndSetTraversableChannels();
|
||||
}
|
||||
|
||||
// 检查是否在可通行的物流模型内并添加路径点
|
||||
if (_selectedChannels != null && _selectedChannels.Any())
|
||||
{
|
||||
bool isInTraversableLogisticsModel = IsItemInSelectedChannels(pickResult.ModelItem) ||
|
||||
IsItemChildOfSelectedChannels(pickResult.ModelItem);
|
||||
|
||||
LogManager.WriteLog($"[手动编辑] 在可通行的物流模型内: {isInTraversableLogisticsModel}");
|
||||
|
||||
if (isInTraversableLogisticsModel)
|
||||
{
|
||||
// 手动路径编辑 - 添加路径点并绘制
|
||||
LogManager.WriteLog("[手动编辑] 调用AddPathPointIn3D添加路径点");
|
||||
var pathPoint = AddPathPointIn3D(pickResult.Point);
|
||||
|
||||
if (pathPoint != null)
|
||||
{
|
||||
LogManager.WriteLog($"[手动编辑] ✓ 路径点添加成功: {pathPoint.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[手动编辑] ✗ 路径点添加失败");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[手动编辑] ✗ 点击位置不在可通行的物流模型内");
|
||||
OnStatusChanged("点击位置不是可通行的物流模型,请在可通行的物流模型上点击");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[手动编辑] ✗ 没有可通行的物流模型");
|
||||
OnStatusChanged("没有找到任何可通行的物流模型,请先为模型设置可通行的物流属性");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 搜索并设置可通行的通道
|
||||
/// </summary>
|
||||
private void SearchAndSetTraversableChannels()
|
||||
{
|
||||
try
|
||||
{
|
||||
var document = Application.ActiveDocument;
|
||||
if (document?.Models != null)
|
||||
{
|
||||
// 使用Search API实时搜索
|
||||
var logisticsItems = SearchLogisticsItemsUsingSearchAPI();
|
||||
LogManager.WriteLog($"[搜索通道] 实时搜索找到 {logisticsItems.Count} 个物流模型");
|
||||
|
||||
if (logisticsItems.Count > 0)
|
||||
{
|
||||
// 筛选出可通行的物流模型
|
||||
var modelCollection = new ModelItemCollection();
|
||||
modelCollection.AddRange(logisticsItems);
|
||||
var traversableItems = CategoryAttributeManager.FilterTraversableItems(modelCollection);
|
||||
LogManager.WriteLog($"[搜索通道] 筛选出 {traversableItems.Count} 个可通行的物流模型");
|
||||
|
||||
// 临时设置为选中通道
|
||||
if (_selectedChannels == null) _selectedChannels = new List<ModelItem>();
|
||||
_selectedChannels.Clear();
|
||||
|
||||
foreach (ModelItem item in traversableItems)
|
||||
{
|
||||
_selectedChannels.Add(item);
|
||||
LogManager.WriteLog($"[搜索通道] 添加可通行模型: '{item.DisplayName}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception searchEx)
|
||||
{
|
||||
LogManager.WriteLog($"[搜索通道] 实时搜索失败: {searchEx.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用Navisworks Search API高效搜索具有物流属性的模型项
|
||||
/// </summary>
|
||||
|
||||
@ -268,6 +268,68 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只渲染点标记,不绘制连线(用于自动路径规划的起终点显示)
|
||||
/// </summary>
|
||||
public void RenderPointOnly(PathRoute pathRoute)
|
||||
{
|
||||
if (pathRoute == null)
|
||||
{
|
||||
LogManager.WriteLog("[点标记渲染] 路径数据为空");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var visualization = new PathVisualization
|
||||
{
|
||||
PathId = pathRoute.Id,
|
||||
PathRoute = pathRoute
|
||||
};
|
||||
|
||||
// 只构建点标记,不构建连线
|
||||
BuildPointMarkersOnly(visualization);
|
||||
|
||||
lock (_lockObject)
|
||||
{
|
||||
_pathVisualizations[pathRoute.Id] = visualization;
|
||||
}
|
||||
|
||||
LogManager.WriteLog($"[点标记渲染] 渲染点标记: {pathRoute.Name}, 点数: {pathRoute.Points.Count}");
|
||||
RequestViewRefresh();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.WriteLog($"[点标记渲染] 渲染点标记失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只构建点标记,不构建连线
|
||||
/// </summary>
|
||||
private void BuildPointMarkersOnly(PathVisualization visualization)
|
||||
{
|
||||
// 清空现有标记
|
||||
visualization.PointMarkers.Clear();
|
||||
visualization.LineMarkers.Clear(); // 确保没有连线
|
||||
|
||||
var points = visualization.PathRoute.Points;
|
||||
if (points.Count == 0) return;
|
||||
|
||||
// 按索引排序点
|
||||
var sortedPoints = points.OrderBy(p => p.Index).ToList();
|
||||
|
||||
// 只构建点标记,不构建连线
|
||||
foreach (var point in sortedPoints)
|
||||
{
|
||||
var pointMarker = CreatePointMarker(point);
|
||||
visualization.PointMarkers.Add(pointMarker);
|
||||
}
|
||||
|
||||
visualization.LastUpdated = DateTime.Now;
|
||||
LogManager.WriteLog($"[点标记构建] 已构建 {visualization.PointMarkers.Count} 个点标记,无连线");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新路径可视化
|
||||
/// </summary>
|
||||
|
||||
@ -357,8 +357,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
PathRoutes.Add(newPathViewModel);
|
||||
SelectedPathRoute = newPathViewModel;
|
||||
|
||||
// 强制重新初始化ToolPlugin以确保获得鼠标焦点,新建路径需要订阅事件
|
||||
if (!ForceReinitializeToolPlugin(subscribeToEvents: true))
|
||||
{
|
||||
AutoPathStatus = "ToolPlugin初始化失败,请重试";
|
||||
LogManager.Error("新建路径:ToolPlugin初始化失败");
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPathStatus = $"已进入新建路径模式: {newRoute.Name} - 请在3D视图中点击设置路径点";
|
||||
LogManager.Info($"开始新建路径: {newRoute.Name}");
|
||||
LogManager.Info($"开始新建路径: {newRoute.Name},已强制重新初始化ToolPlugin获取鼠标焦点");
|
||||
|
||||
// 不再显示对话框,状态文本已提供足够的反馈
|
||||
}
|
||||
@ -458,21 +466,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
IsSelectingEndPoint = false;
|
||||
AutoPathStatus = "请在3D视图中点击选择起点...";
|
||||
|
||||
// 强制重新初始化ToolPlugin以确保获得鼠标焦点
|
||||
if (!ForceReinitializeToolPlugin())
|
||||
// 进入自动路径规划模式 - 动态事件订阅
|
||||
LogManager.Info("进入自动路径规划模式,启用动态事件订阅");
|
||||
|
||||
// 1. 禁用PathPlanningManager的鼠标处理
|
||||
_pathPlanningManager.DisableMouseHandling();
|
||||
|
||||
// 2. 启用PathEditingViewModel的事件订阅
|
||||
PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; // 先取消避免重复
|
||||
PathClickToolPlugin.MouseClicked += OnAutoPathMouseClicked;
|
||||
LogManager.Info("已启用PathEditingViewModel的鼠标事件订阅");
|
||||
|
||||
// 强制重新初始化ToolPlugin以确保获得鼠标焦点,自动路径不需要PathPlanningManager订阅事件
|
||||
if (!ForceReinitializeToolPlugin(subscribeToEvents: false))
|
||||
{
|
||||
AutoPathStatus = "ToolPlugin初始化失败,请重试";
|
||||
return;
|
||||
}
|
||||
|
||||
// 订阅PathClickToolPlugin的鼠标点击事件来获取自动路径规划的起点
|
||||
LogManager.Info("订阅PathClickToolPlugin.MouseClicked事件");
|
||||
PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
|
||||
PathClickToolPlugin.MouseClicked += OnAutoPathMouseClicked;
|
||||
|
||||
// 在STA线程中调用Navisworks API
|
||||
_pathPlanningManager.StartClickTool(PathPointType.StartPoint);
|
||||
LogManager.Info("=== 选择起点命令设置完成,ToolPlugin已重新激活并获得鼠标焦点,等待用户点击 ===");
|
||||
LogManager.Info("=== 选择起点命令设置完成,已启用动态事件订阅,等待用户点击 ===");
|
||||
}, "选择起点");
|
||||
}
|
||||
|
||||
@ -494,21 +508,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
IsSelectingEndPoint = true;
|
||||
AutoPathStatus = "请在3D视图中点击选择终点...";
|
||||
|
||||
// 强制重新初始化ToolPlugin以确保获得鼠标焦点
|
||||
if (!ForceReinitializeToolPlugin())
|
||||
// 进入自动路径规划模式 - 动态事件订阅
|
||||
LogManager.Info("进入自动路径规划模式,启用动态事件订阅");
|
||||
|
||||
// 1. 禁用PathPlanningManager的鼠标处理
|
||||
_pathPlanningManager.DisableMouseHandling();
|
||||
|
||||
// 2. 启用PathEditingViewModel的事件订阅
|
||||
PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked; // 先取消避免重复
|
||||
PathClickToolPlugin.MouseClicked += OnAutoPathMouseClicked;
|
||||
LogManager.Info("已启用PathEditingViewModel的鼠标事件订阅");
|
||||
|
||||
// 强制重新初始化ToolPlugin以确保获得鼠标焦点,自动路径不需要PathPlanningManager订阅事件
|
||||
if (!ForceReinitializeToolPlugin(subscribeToEvents: false))
|
||||
{
|
||||
AutoPathStatus = "ToolPlugin初始化失败,请重试";
|
||||
return;
|
||||
}
|
||||
|
||||
// 订阅PathClickToolPlugin的鼠标点击事件来获取自动路径规划的终点
|
||||
LogManager.Info("订阅PathClickToolPlugin.MouseClicked事件");
|
||||
PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
|
||||
PathClickToolPlugin.MouseClicked += OnAutoPathMouseClicked;
|
||||
|
||||
// 在STA线程中调用Navisworks API
|
||||
_pathPlanningManager.StartClickTool(PathPointType.EndPoint);
|
||||
LogManager.Info("=== 选择终点命令设置完成,ToolPlugin已重新激活并获得鼠标焦点,等待用户点击 ===");
|
||||
LogManager.Info("=== 选择终点命令设置完成,已启用动态事件订阅,等待用户点击 ===");
|
||||
}, "选择终点");
|
||||
}
|
||||
|
||||
@ -568,6 +588,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
_pathPlanningManager.StopClickTool();
|
||||
}
|
||||
|
||||
// 清理临时的起点和终点标记
|
||||
ClearTemporaryAutoPathMarkers();
|
||||
|
||||
// 不在这里直接操作UI,让RouteGenerated事件处理UI更新
|
||||
// 这避免了重复的路径添加和UI更新冲突
|
||||
|
||||
@ -576,15 +599,28 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoPathStatus = "❌ 路径规划失败,未找到可行路径";
|
||||
LogManager.Warning("自动路径规划失败:未找到可行路径");
|
||||
// 检查是否已经通过ErrorOccurred事件设置了详细错误信息
|
||||
if (!AutoPathStatus.Contains("❌ 自动路径规划失败"))
|
||||
{
|
||||
// 如果没有详细错误信息,则设置通用错误提示
|
||||
AutoPathStatus = "❌ 路径规划失败,未找到可行路径";
|
||||
LogManager.Warning("自动路径规划失败:未找到可行路径");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果已有详细错误信息,保留不覆盖
|
||||
LogManager.Info("保留ErrorOccurred事件设置的详细错误信息,不覆盖AutoPathStatus");
|
||||
}
|
||||
|
||||
// 失败情况下也要清理事件订阅
|
||||
// 失败情况下也要清理事件订阅和临时标记
|
||||
CleanupAutoPathEventSubscriptions();
|
||||
if (_pathPlanningManager != null)
|
||||
{
|
||||
_pathPlanningManager.StopClickTool();
|
||||
}
|
||||
|
||||
// 清理临时的起点和终点标记
|
||||
ClearTemporaryAutoPathMarkers();
|
||||
}
|
||||
}, "自动路径规划");
|
||||
}
|
||||
@ -603,25 +639,26 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
PathClickToolPlugin.MouseClicked -= OnAutoPathMouseClicked;
|
||||
}
|
||||
|
||||
// 清除所有路径可视化(使用新的统一API)
|
||||
// 清除所有路径的可视化显示(与新建路径按钮保持一致)
|
||||
if (PathPointRenderPlugin.Instance != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 清除所有路径可视化,包括自动路径和手动路径
|
||||
PathPointRenderPlugin.Instance.ClearAllPaths();
|
||||
LogManager.Info("重置参数:已清除所有路径可视化显示");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"重置参数:清除路径可视化失败: {ex.Message}", ex);
|
||||
throw; // 重新抛出异常,让上层处理
|
||||
// 不抛出异常,继续执行状态重置
|
||||
}
|
||||
}
|
||||
|
||||
// 强制重新初始化ToolPlugin以重新获得鼠标焦点
|
||||
// 强制重新初始化ToolPlugin以重新获得鼠标焦点,重置时不需要订阅事件
|
||||
if (_pathPlanningManager != null)
|
||||
{
|
||||
ForceReinitializeToolPlugin();
|
||||
ForceReinitializeToolPlugin(subscribeToEvents: false);
|
||||
}
|
||||
|
||||
// 重置所有状态
|
||||
@ -638,7 +675,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 通知Can Execute属性更改
|
||||
OnPropertyChanged(nameof(CanExecuteAutoPlanPath));
|
||||
|
||||
LogManager.Info("自动路径规划参数和3D标记已完全重置,ToolPlugin已重新初始化");
|
||||
LogManager.Info("自动路径规划参数和起终点标记已完全重置,ToolPlugin已重新初始化");
|
||||
}, "重置自动路径规划");
|
||||
}
|
||||
|
||||
@ -820,7 +857,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
SetAutoPathStartPoint(point3D);
|
||||
await SafeExecuteAsync(() =>
|
||||
{
|
||||
// 退出自动路径规划模式 - 恢复事件订阅
|
||||
LogManager.Info("起点选择完成,恢复正常事件订阅状态");
|
||||
CleanupAutoPathEventSubscriptions();
|
||||
_pathPlanningManager?.EnableMouseHandling(); // 恢复PathPlanningManager的鼠标处理
|
||||
_pathPlanningManager?.StopClickTool();
|
||||
}, "停止起点选择工具");
|
||||
}
|
||||
@ -830,7 +870,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
SetAutoPathEndPoint(point3D);
|
||||
await SafeExecuteAsync(() =>
|
||||
{
|
||||
// 退出自动路径规划模式 - 恢复事件订阅
|
||||
LogManager.Info("终点选择完成,恢复正常事件订阅状态");
|
||||
CleanupAutoPathEventSubscriptions();
|
||||
_pathPlanningManager?.EnableMouseHandling(); // 恢复PathPlanningManager的鼠标处理
|
||||
_pathPlanningManager?.StopClickTool();
|
||||
}, "停止终点选择工具");
|
||||
}
|
||||
@ -838,6 +881,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
LogManager.WriteLog("[自动路径事件] 非选择状态,直接清理事件订阅");
|
||||
CleanupAutoPathEventSubscriptions();
|
||||
_pathPlanningManager?.EnableMouseHandling(); // 恢复PathPlanningManager的鼠标处理
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -848,10 +892,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
IsSelectingStartPoint = false;
|
||||
IsSelectingEndPoint = false;
|
||||
|
||||
// 异常情况下也要清理事件订阅
|
||||
// 异常情况下也要清理事件订阅并恢复状态
|
||||
try
|
||||
{
|
||||
CleanupAutoPathEventSubscriptions();
|
||||
_pathPlanningManager?.EnableMouseHandling(); // 恢复PathPlanningManager的鼠标处理
|
||||
_pathPlanningManager?.StopClickTool();
|
||||
}
|
||||
catch (Exception cleanupEx)
|
||||
@ -868,9 +913,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
await SafeExecuteAsync(() =>
|
||||
{
|
||||
// 如果已有起点,先移除之前的可视化
|
||||
if (_hasStartPoint && PathPointRenderPlugin.Instance != null)
|
||||
{
|
||||
PathPointRenderPlugin.Instance.RemoveMarkerAt(_startPoint3D, 2.0);
|
||||
// 移除之前的起点路径可视化
|
||||
PathPointRenderPlugin.Instance.RemovePath("AutoPathStartPoint");
|
||||
}
|
||||
|
||||
_startPoint3D = point;
|
||||
@ -881,9 +928,24 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 通知Can Execute属性更改
|
||||
OnPropertyChanged(nameof(CanExecuteAutoPlanPath));
|
||||
|
||||
// 使用新的RenderPointOnly API只渲染起点标记
|
||||
if (PathPointRenderPlugin.Instance != null)
|
||||
{
|
||||
PathPointRenderPlugin.Instance.AddCircleMarker(point, PathPointType.StartPoint, -100);
|
||||
// 创建临时路径只包含起点
|
||||
var startPointPathRoute = new PathRoute("AutoPathStartPoint")
|
||||
{
|
||||
Description = "自动路径规划起点"
|
||||
};
|
||||
var startPathPoint = new PathPoint
|
||||
{
|
||||
Name = "起点",
|
||||
Position = point,
|
||||
Type = PathPointType.StartPoint
|
||||
};
|
||||
startPointPathRoute.AddPoint(startPathPoint);
|
||||
|
||||
// 使用新的只渲染点的API,不绘制连线
|
||||
PathPointRenderPlugin.Instance.RenderPointOnly(startPointPathRoute);
|
||||
}
|
||||
|
||||
if (_hasEndPoint)
|
||||
@ -906,9 +968,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
await SafeExecuteAsync(() =>
|
||||
{
|
||||
// 如果已有终点,先移除之前的可视化
|
||||
if (_hasEndPoint && PathPointRenderPlugin.Instance != null)
|
||||
{
|
||||
PathPointRenderPlugin.Instance.RemoveMarkerAt(_endPoint3D, 2.0);
|
||||
// 移除之前的终点路径可视化
|
||||
PathPointRenderPlugin.Instance.RemovePath("AutoPathEndPoint");
|
||||
}
|
||||
|
||||
_endPoint3D = point;
|
||||
@ -919,9 +983,24 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 通知Can Execute属性更改
|
||||
OnPropertyChanged(nameof(CanExecuteAutoPlanPath));
|
||||
|
||||
// 使用新的RenderPointOnly API只渲染终点标记
|
||||
if (PathPointRenderPlugin.Instance != null)
|
||||
{
|
||||
PathPointRenderPlugin.Instance.AddCircleMarker(point, PathPointType.EndPoint, -200);
|
||||
// 创建临时路径只包含终点
|
||||
var endPointPathRoute = new PathRoute("AutoPathEndPoint")
|
||||
{
|
||||
Description = "自动路径规划终点"
|
||||
};
|
||||
var endPathPoint = new PathPoint
|
||||
{
|
||||
Name = "终点",
|
||||
Position = point,
|
||||
Type = PathPointType.EndPoint
|
||||
};
|
||||
endPointPathRoute.AddPoint(endPathPoint);
|
||||
|
||||
// 使用新的只渲染点的API,不绘制连线
|
||||
PathPointRenderPlugin.Instance.RenderPointOnly(endPointPathRoute);
|
||||
}
|
||||
|
||||
if (_hasStartPoint)
|
||||
@ -1003,6 +1082,33 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理临时的自动路径起点和终点标记
|
||||
/// </summary>
|
||||
private void ClearTemporaryAutoPathMarkers()
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.WriteLog("[临时标记清理] 开始清理自动路径临时标记");
|
||||
|
||||
if (PathPointRenderPlugin.Instance != null)
|
||||
{
|
||||
// 清除临时的起点和终点标记
|
||||
PathPointRenderPlugin.Instance.RemovePath("AutoPathStartPoint");
|
||||
PathPointRenderPlugin.Instance.RemovePath("AutoPathEndPoint");
|
||||
LogManager.WriteLog("[临时标记清理] 已清除AutoPathStartPoint和AutoPathEndPoint临时标记");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[临时标记清理] PathPointRenderPlugin实例为null,无法清理标记");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[临时标记清理] 清理临时标记失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PathPlanningManager事件处理
|
||||
@ -1037,7 +1143,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 订阅路径生成事件(用于处理自动路径)
|
||||
_pathPlanningManager.RouteGenerated += OnRouteGenerated;
|
||||
|
||||
LogManager.Info("*** PathEditingViewModel已成功订阅PathPlanningManager事件,包括RouteGenerated ***");
|
||||
// 添加错误事件订阅 - 用于处理自动路径规划失败等错误
|
||||
_pathPlanningManager.ErrorOccurred += OnPathPlanningError;
|
||||
|
||||
LogManager.Info("*** PathEditingViewModel已成功订阅PathPlanningManager事件,包括RouteGenerated和ErrorOccurred ***");
|
||||
|
||||
// 验证事件订阅是否成功
|
||||
var routeGeneratedField = _pathPlanningManager.GetType().GetEvent("RouteGenerated");
|
||||
@ -1070,8 +1179,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
_pathPlanningManager.CurrentRouteChanged -= OnCurrentRouteChanged;
|
||||
_pathPlanningManager.EditStateChanged -= OnEditStateChanged;
|
||||
_pathPlanningManager.RouteGenerated -= OnRouteGenerated;
|
||||
_pathPlanningManager.ErrorOccurred -= OnPathPlanningError;
|
||||
|
||||
LogManager.Info("PathEditingViewModel已取消订阅PathPlanningManager事件");
|
||||
LogManager.Info("PathEditingViewModel已取消订阅PathPlanningManager事件,包括ErrorOccurred");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -1337,6 +1447,41 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理路径规划错误事件
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 处理路径规划错误事件
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 处理路径规划错误事件
|
||||
/// </summary>
|
||||
private async void OnPathPlanningError(object sender, PathPlanningErrorOccurredEventArgs e)
|
||||
{
|
||||
LogManager.Info($"*** OnPathPlanningError被调用!Sender: {sender?.GetType().Name}, Error: {e?.ErrorMessage} ***");
|
||||
|
||||
try
|
||||
{
|
||||
await SafeExecuteAsync(async () =>
|
||||
{
|
||||
LogManager.Error($"自动路径规划失败: {e.ErrorMessage}");
|
||||
|
||||
// 使用UIStateManager确保UI更新在主线程执行
|
||||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
// 更新自动路径状态显示错误信息
|
||||
AutoPathStatus = $"❌ 自动路径规划失败: {e.ErrorMessage}";
|
||||
LogManager.Info($"*** AutoPathStatus已更新为: {AutoPathStatus} ***");
|
||||
});
|
||||
|
||||
}, "处理路径规划错误事件");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"*** OnPathPlanningError异常: {ex.Message} ***", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 清理资源
|
||||
@ -1344,10 +1489,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// <summary>
|
||||
/// 强制重新初始化ToolPlugin以确保获得鼠标焦点
|
||||
/// </summary>
|
||||
/// <param name="subscribeToEvents">是否订阅鼠标事件,新建路径需要true,自动路径选点需要false</param>
|
||||
/// <returns>初始化是否成功</returns>
|
||||
private bool ForceReinitializeToolPlugin()
|
||||
private bool ForceReinitializeToolPlugin(bool subscribeToEvents = false)
|
||||
{
|
||||
LogManager.Info("开始强制重新初始化ToolPlugin以确保获得鼠标焦点");
|
||||
LogManager.Info($"开始强制重新初始化ToolPlugin以确保获得鼠标焦点,订阅事件: {subscribeToEvents}");
|
||||
try
|
||||
{
|
||||
// 使用反射调用私有方法强制重新激活ToolPlugin
|
||||
@ -1368,13 +1514,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LogManager.Info("已重置ToolPlugin激活状态标志");
|
||||
}
|
||||
|
||||
// 重新激活ToolPlugin
|
||||
// 重新激活ToolPlugin,根据参数决定是否订阅事件
|
||||
var activateMethod = _pathPlanningManager.GetType().GetMethod("ActivateToolPlugin",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
if (activateMethod != null)
|
||||
{
|
||||
var result = activateMethod.Invoke(_pathPlanningManager, null);
|
||||
LogManager.Info($"ToolPlugin重新激活结果: {result}");
|
||||
// 调用带参数的方法,传递subscribeToEvents参数
|
||||
var result = activateMethod.Invoke(_pathPlanningManager, new object[] { subscribeToEvents });
|
||||
LogManager.Info($"ToolPlugin重新激活结果(事件订阅: {subscribeToEvents}): {result}");
|
||||
if (!(bool)result)
|
||||
{
|
||||
LogManager.Error("ToolPlugin激活失败");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user