NavisworksTransport/MainPlugin.cs

1144 lines
48 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using NavisApplication = Autodesk.Navisworks.Api.Application;
namespace NavisworksTransport
{
/// <summary>
/// 全局异常处理工具类
/// </summary>
public static class GlobalExceptionHandler
{
private static bool _isInitialized = false;
/// <summary>
/// 初始化全局异常处理器
/// </summary>
public static void Initialize()
{
if (_isInitialized) return;
try
{
// 捕获未处理的异常
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
System.Windows.Forms.Application.ThreadException += OnThreadException;
_isInitialized = true;
LogManager.Info("[全局异常] 全局异常处理器已初始化");
}
catch (Exception ex)
{
LogManager.Error($"[全局异常] 初始化异常处理器失败: {ex.Message}");
}
}
/// <summary>
/// 处理未捕获的异常
/// </summary>
private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = e.ExceptionObject as Exception;
string message = ex?.Message ?? "未知异常";
string stackTrace = ex?.StackTrace ?? "无堆栈信息";
LogManager.Error($"[全局异常] 未处理异常: {message}");
LogManager.Error($"[全局异常] 堆栈信息: {stackTrace}");
LogManager.Error($"[全局异常] 异常类型: {ex?.GetType().Name ?? "Unknown"}");
LogManager.Error($"[全局异常] 是否终止: {e.IsTerminating}");
// 显示用户友好的错误信息
ShowErrorDialog("程序发生未预期的错误", message, ex);
// 尝试恢复关键组件
TryRecoverComponents();
}
catch
{
// 异常处理中的异常,保持静默
}
}
/// <summary>
/// 处理线程异常
/// </summary>
private static void OnThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
try
{
Exception ex = e.Exception;
LogManager.Error($"[全局异常] 线程异常: {ex.Message}");
LogManager.Error($"[全局异常] 堆栈信息: {ex.StackTrace}");
LogManager.Error($"[全局异常] 异常类型: {ex.GetType().Name}");
// 显示用户友好的错误信息
ShowErrorDialog("程序发生线程错误", ex.Message, ex);
// 尝试恢复关键组件
TryRecoverComponents();
}
catch
{
// 异常处理中的异常,保持静默
}
}
/// <summary>
/// 安全执行方法,捕获所有异常
/// </summary>
public static T SafeExecute<T>(Func<T> action, T defaultValue = default(T), string operationName = "操作")
{
try
{
return action();
}
catch (Exception ex)
{
LogManager.Error($"[安全执行] {operationName}失败: {ex.Message}");
LogManager.Error($"[安全执行] 堆栈信息: {ex.StackTrace}");
LogManager.Error($"[安全执行] 异常类型: {ex.GetType().Name}");
// 对于用户操作,显示简短的错误提示
if (!string.IsNullOrEmpty(operationName) && operationName != "操作")
{
ShowErrorToast($"{operationName}失败: {ex.Message}");
}
return defaultValue;
}
}
/// <summary>
/// 安全执行方法(无返回值)
/// </summary>
public static void SafeExecute(Action action, string operationName = "操作")
{
SafeExecute(() => { action(); return true; }, false, operationName);
}
/// <summary>
/// 显示错误对话框
/// </summary>
private static void ShowErrorDialog(string title, string message, Exception ex = null)
{
try
{
string detailMessage = message;
if (ex != null)
{
detailMessage += $"\n\n技术详情: {ex.GetType().Name}";
if (!string.IsNullOrEmpty(ex.Message))
{
detailMessage += $"\n错误信息: {ex.Message}";
}
}
MessageBox.Show(detailMessage, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch
{
// 如果连错误对话框都显示不了,就保持静默
}
}
/// <summary>
/// 显示简短的错误提示
/// </summary>
private static void ShowErrorToast(string message)
{
try
{
MessageBox.Show(message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch
{
// 保持静默
}
}
/// <summary>
/// 尝试恢复关键组件
/// </summary>
private static void TryRecoverComponents()
{
try
{
LogManager.Info("[全局异常] 尝试恢复关键组件...");
// 尝试重置路径编辑模式
var activeManager = PathPlanningManager.GetActivePathManager();
if (activeManager != null && activeManager.IsPathEditMode)
{
activeManager.ExitPathEditMode();
LogManager.Info("[全局异常] 已退出路径编辑模式");
}
// 尝试清除临时高亮
if (NavisApplication.ActiveDocument?.Models != null)
{
NavisApplication.ActiveDocument.Models.ResetAllTemporaryMaterials();
LogManager.Info("[全局异常] 已清除临时材质");
}
LogManager.Info("[全局异常] 组件恢复完成");
}
catch (Exception ex)
{
LogManager.Error($"[全局异常] 组件恢复失败: {ex.Message}");
}
}
}
[PluginAttribute("Basic", "Tian", ToolTip = "Transport Plugin", DisplayName = "Transport Plugin")]
[AddInPlugin(AddInLocation.AddIn)] // 将插件显示在Navisworks的"附加模块"选项卡中
public class Main : AddInPlugin
{
/// <summary>
/// 会话初始化标志用于确保在同一Navisworks会话中只清空一次日志
/// </summary>
private static bool _isSessionInitialized = false;
public override int Execute(params string[] parameters)
{
return GlobalExceptionHandler.SafeExecute(() =>
{
// 初始化全局异常处理器
GlobalExceptionHandler.Initialize();
// 根据会话状态决定日志处理方式
if (!_isSessionInitialized)
{
// 首次启动:清空旧日志
LogManager.ClearLog();
LogManager.Info("=== NavisworksTransport 插件启动 ===");
LogManager.Info("=== 路径点计算日志功能已加载 ===");
_isSessionInitialized = true;
}
else
{
// 后续打开:添加会话分隔符,保留历史记录
LogManager.WriteSessionSeparator();
LogManager.Info("=== 重新打开插件界面 ===");
}
// 显示类别选择对话框
ShowCategorySelectionDialog();
return 0;
}, -1, "插件初始化");
}
/// <summary>
/// 显示主控制面板
/// </summary>
private void ShowCategorySelectionDialog()
{
GlobalExceptionHandler.SafeExecute(() =>
{
// 获取当前选中的模型项数量
int selectedCount = NavisApplication.ActiveDocument.CurrentSelection.SelectedItems.Count;
// 创建对话框
Form dialog = new Form
{
Text = "物流路径规划插件 - 3D交互模式",
Size = new Size(380, 700), // 增加高度以容纳新的详情显示区域
StartPosition = FormStartPosition.CenterParent,
FormBorderStyle = FormBorderStyle.FixedDialog,
MaximizeBox = false,
MinimizeBox = false
};
// 创建主面板,启用自动滚动
Panel mainPanel = new Panel
{
Dock = DockStyle.Fill,
Padding = new Padding(15),
AutoScroll = true
};
dialog.Controls.Add(mainPanel);
int currentY = 0;
// 状态信息标签
Label statusLabel = new Label
{
Text = $"当前选中: {selectedCount} 个模型项",
Font = new Font("微软雅黑", 9, FontStyle.Bold),
ForeColor = selectedCount > 0 ? System.Drawing.Color.Blue : System.Drawing.Color.Red,
AutoSize = true,
Location = new Point(0, currentY)
};
mainPanel.Controls.Add(statusLabel);
currentY += 35;
// 创建类别设置GroupBox
GroupBox categoryGroupBox = new GroupBox
{
Text = "★ 类别设置",
Location = new Point(0, currentY),
Size = new Size(320, 65),
Font = new Font("微软雅黑", 9, FontStyle.Bold)
};
mainPanel.Controls.Add(categoryGroupBox);
CreateCategoryDropdown(categoryGroupBox);
currentY += 85;
// 创建3D交互模式GroupBox
GroupBox mode3DGroupBox = new GroupBox
{
Text = "★ 3D路径编辑",
Location = new Point(0, currentY),
Size = new Size(320, 300), // 减少高度20像素
Font = new Font("微软雅黑", 9, FontStyle.Bold),
BackColor = System.Drawing.Color.LightBlue
};
mainPanel.Controls.Add(mode3DGroupBox);
Create3DInteractionControls(mode3DGroupBox);
currentY += 320; // 调整间距以适应减少的GroupBox高度
// 创建可见性控制GroupBox
GroupBox visibilityGroupBox = new GroupBox
{
Text = "可见性控制",
Location = new Point(0, currentY),
Size = new Size(320, 85),
Font = new Font("微软雅黑", 9, FontStyle.Bold)
};
mainPanel.Controls.Add(visibilityGroupBox);
CreateVisibilityControls(visibilityGroupBox);
currentY += 105;
// 创建路径管理GroupBox
GroupBox pathManagementGroupBox = new GroupBox
{
Text = "路径管理",
Location = new Point(0, currentY),
Size = new Size(320, 85),
Font = new Font("微软雅黑", 9, FontStyle.Bold)
};
mainPanel.Controls.Add(pathManagementGroupBox);
CreatePathManagementControls(pathManagementGroupBox);
currentY += 105;
// 创建关闭按钮
Button closeButton = new Button
{
Text = "关闭",
Size = new Size(80, 30),
Location = new Point(240, currentY),
DialogResult = DialogResult.OK,
Font = new Font("微软雅黑", 9)
};
mainPanel.Controls.Add(closeButton);
// 显示对话框
dialog.ShowDialog();
}, "显示主控制面板");
}
/// <summary>
/// 创建3D交互控制界面
/// </summary>
/// <param name="parent">父容器</param>
private void Create3DInteractionControls(GroupBox parent)
{
// 进入3D编辑模式按钮
Button enterEditModeButton = new Button
{
Text = "进入路径编辑",
Location = new Point(20, 25),
Size = new Size(110, 30),
Font = new Font("微软雅黑", 9),
BackColor = System.Drawing.Color.LightGreen,
UseVisualStyleBackColor = false
};
// 退出3D编辑模式按钮
Button exitEditModeButton = new Button
{
Text = "退出路径编辑",
Location = new Point(140, 25),
Size = new Size(110, 30),
Font = new Font("微软雅黑", 9),
BackColor = System.Drawing.Color.LightCoral,
UseVisualStyleBackColor = false,
Enabled = false
};
// 检查全局编辑模式状态并更新按钮状态
bool isGlobalEditMode = PathPlanningManager.GlobalIsPathEditMode;
enterEditModeButton.Enabled = !isGlobalEditMode;
exitEditModeButton.Enabled = isGlobalEditMode;
// 当前状态显示
Label statusLabel = new Label
{
Text = "状态: 未进入编辑模式",
Location = new Point(20, 65),
Size = new Size(200, 20),
Font = new Font("微软雅黑", 9),
ForeColor = System.Drawing.Color.Gray
};
// 下一个点类型显示
Label nextPointTypeLabel = new Label
{
Text = "下一个点: 起点",
Location = new Point(230, 65),
Size = new Size(80, 20),
Font = new Font("微软雅黑", 9),
ForeColor = System.Drawing.Color.Blue
};
// 路径点列表
Label pointListLabel = new Label
{
Text = "路径点列表:",
Location = new Point(20, 90),
Size = new Size(80, 20),
Font = new Font("微软雅黑", 9)
};
ListBox pointListBox = new ListBox
{
Location = new Point(20, 110),
Size = new Size(280, 64), // 4行高度每行约16px
Font = new Font("微软雅黑", 8),
ScrollAlwaysVisible = true, // 按需显示滚动条
};
// 路径点详情显示区域
Label detailLabel = new Label
{
Text = "路径点详情:",
Location = new Point(20, 165), // 调整位置适应列表高度变化
Size = new Size(80, 15),
Font = new Font("微软雅黑", 9)
};
Label pointDetailLabel = new Label
{
Text = "请选择一个路径点查看详情",
Location = new Point(20, 185),
Size = new Size(280, 50), // 增加高度到50px以容纳3行文本
Font = new Font("微软雅黑", 8),
ForeColor = System.Drawing.Color.DarkBlue,
BorderStyle = BorderStyle.FixedSingle,
BackColor = System.Drawing.Color.LightCyan
};
// 路径点操作按钮(调整位置到详情下方)
Button deletePointButton = new Button
{
Text = "删除选中点",
Location = new Point(110, 235), // 调整位置以适应减少的GroupBox高度
Size = new Size(90, 25),
Font = new Font("微软雅黑", 8),
Enabled = false
};
Button clearAllPointsButton = new Button
{
Text = "清除所有点",
Location = new Point(210, 235), // 调整位置以适应减少的GroupBox高度
Size = new Size(90, 25),
Font = new Font("微软雅黑", 8),
Enabled = false
};
// 操作说明标签
Label instructionLabel = new Label
{
Text = "说明: 第一个点自动设为起点,退出编辑时最后一个点自动设为终点",
Location = new Point(20, 265), // 调整位置以适应减少的GroupBox高度
Size = new Size(280, 15),
Font = new Font("微软雅黑", 8),
ForeColor = System.Drawing.Color.Gray
};
// 事件处理
enterEditModeButton.Click += (sender, e) =>
{
GlobalExceptionHandler.SafeExecute(() =>
{
// 获取当前选中的模型项
ModelItemCollection selectedItems = NavisApplication.ActiveDocument.CurrentSelection.SelectedItems;
if (selectedItems.Count == 0)
{
MessageBox.Show("请先选择要作为通道的模型项", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 添加测试日志
LogManager.Info("[测试] 用户点击了进入路径编辑按钮");
// 获取或创建路径规划管理器(确保使用同一个实例)
PathPlanningManager pathManager = PathPlanningManager.GetActivePathManager();
if (pathManager == null)
{
pathManager = new PathPlanningManager();
LogManager.Info("[测试] 创建了新的PathPlanningManager实例");
}
else
{
LogManager.Info("[测试] 使用现有的PathPlanningManager实例");
}
// 设置选中的通道
var channelList = new List<ModelItem>();
foreach (ModelItem item in selectedItems)
{
channelList.Add(item);
}
LogManager.Info($"[测试] 设置通道,选中了 {selectedItems.Count} 个对象");
pathManager.SelectedChannels.Clear();
pathManager.SelectedChannels.AddRange(channelList);
LogManager.Info($"[测试] 通道设置完成PathManager中有 {pathManager.SelectedChannels.Count} 个通道");
// 进入路径编辑模式
bool success = pathManager.EnterPathEditMode();
if (success)
{
// 更新按钮状态
enterEditModeButton.Enabled = false;
exitEditModeButton.Enabled = true;
statusLabel.Text = "状态: 已进入编辑模式";
statusLabel.ForeColor = System.Drawing.Color.Green;
// 更新路径点列表
UpdatePointsList(pointListBox, nextPointTypeLabel, pathManager);
// 关闭当前对话框以释放焦点,让用户能在主界面操作
var parentForm = enterEditModeButton.FindForm();
MessageBox.Show("已进入3D路径编辑模式\n\n请在高亮的通道上点击设置路径点。\n\n完成后重新打开插件面板点击'退出路径编辑'。", "模式切换",
MessageBoxButtons.OK, MessageBoxIcon.Information);
// 完全关闭对话框,释放焦点
if (parentForm != null)
{
parentForm.DialogResult = DialogResult.OK;
parentForm.Close();
}
}
else
{
MessageBox.Show("进入3D路径编辑模式失败", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}, "进入路径编辑模式");
};
exitEditModeButton.Click += (sender, e) =>
{
GlobalExceptionHandler.SafeExecute(() =>
{
var activeManager = PathPlanningManager.GetActivePathManager();
if (activeManager != null)
{
bool success = activeManager.ExitPathEditMode();
if (success)
{
// 更新按钮状态
enterEditModeButton.Enabled = true;
exitEditModeButton.Enabled = false;
statusLabel.Text = "状态: 未进入编辑模式";
statusLabel.ForeColor = System.Drawing.Color.Gray;
nextPointTypeLabel.Text = "下一个点: 起点";
// 清空路径点列表
pointListBox.Items.Clear();
MessageBox.Show("已退出3D路径编辑模式", "模式切换",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("退出3D路径编辑模式失败", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
// 强制更新UI状态
enterEditModeButton.Enabled = true;
exitEditModeButton.Enabled = false;
statusLabel.Text = "状态: 未进入编辑模式";
statusLabel.ForeColor = System.Drawing.Color.Gray;
}
}, "退出路径编辑模式");
};
deletePointButton.Click += (sender, e) =>
{
try
{
if (pointListBox.SelectedIndex >= 0)
{
var activeManager = PathPlanningManager.GetActivePathManager();
if (activeManager != null && activeManager.CurrentRoute != null)
{
var selectedIndex = pointListBox.SelectedIndex;
if (selectedIndex < activeManager.CurrentRoute.Points.Count)
{
activeManager.CurrentRoute.Points.RemoveAt(selectedIndex);
UpdatePointsList(pointListBox, nextPointTypeLabel, activeManager);
MessageBox.Show("已删除选中的路径点", "操作成功",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"删除路径点失败: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
clearAllPointsButton.Click += (sender, e) =>
{
try
{
var activeManager = PathPlanningManager.GetActivePathManager();
if (activeManager != null && activeManager.CurrentRoute != null)
{
var result = MessageBox.Show("确定要清除所有路径点吗?", "确认操作",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
activeManager.CurrentRoute.Points.Clear();
activeManager.Clear3DPathMarkers();
UpdatePointsList(pointListBox, nextPointTypeLabel, activeManager);
MessageBox.Show("已清除所有路径点", "操作成功",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show($"清除路径点失败: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
// 添加路径点选择事件处理
pointListBox.SelectedIndexChanged += (sender, e) =>
{
try
{
if (pointListBox.SelectedIndex >= 0)
{
var activeManager = PathPlanningManager.GetActivePathManager();
if (activeManager?.CurrentRoute?.Points != null &&
pointListBox.SelectedIndex < activeManager.CurrentRoute.Points.Count)
{
var selectedPoint = activeManager.CurrentRoute.Points[pointListBox.SelectedIndex];
var selectedIndex = pointListBox.SelectedIndex;
// 显示路径点详情
string pointType = selectedPoint.Type == PathPointType.StartPoint ? "🚀 起点" :
selectedPoint.Type == PathPointType.EndPoint ? "🎯 终点" : "📍 路径点";
pointDetailLabel.Text = $"序号: {selectedIndex + 1:D2} / {activeManager.CurrentRoute.Points.Count}\n" +
$"名称: {selectedPoint.Name} 类型: {pointType}\n" +
$"3D坐标: X={selectedPoint.Position.X:F2}, Y={selectedPoint.Position.Y:F2}, Z={selectedPoint.Position.Z:F2}";
deletePointButton.Enabled = true;
}
}
else
{
pointDetailLabel.Text = "请选择一个路径点查看详情";
deletePointButton.Enabled = false;
}
}
catch (Exception ex)
{
pointDetailLabel.Text = $"获取路径点详情失败: {ex.Message}";
}
};
// 添加控件到父容器
parent.Controls.Add(enterEditModeButton);
parent.Controls.Add(exitEditModeButton);
parent.Controls.Add(statusLabel);
// parent.Controls.Add(nextPointTypeLabel); // 隐藏显示,但保留逻辑
parent.Controls.Add(pointListLabel);
parent.Controls.Add(pointListBox);
parent.Controls.Add(detailLabel);
parent.Controls.Add(pointDetailLabel);
parent.Controls.Add(deletePointButton);
parent.Controls.Add(clearAllPointsButton);
parent.Controls.Add(instructionLabel);
// 如果当前处于编辑模式,更新界面状态和路径点列表
if (isGlobalEditMode)
{
statusLabel.Text = "状态: 3D编辑模式已激活";
statusLabel.ForeColor = System.Drawing.Color.Green;
clearAllPointsButton.Enabled = true;
deletePointButton.Enabled = true;
// 获取活动的路径管理器并更新列表
var activeManager = PathPlanningManager.GetActivePathManager();
if (activeManager != null)
{
UpdatePointsList(pointListBox, nextPointTypeLabel, activeManager);
}
}
}
/// <summary>
/// 更新路径点列表显示
/// </summary>
/// <param name="listBox">列表框控件</param>
/// <param name="nextPointLabel">下一个点类型标签</param>
/// <param name="pathManager">路径规划管理器</param>
private void UpdatePointsList(ListBox listBox, Label nextPointLabel, PathPlanningManager pathManager)
{
try
{
listBox.Items.Clear();
if (pathManager?.CurrentRoute?.Points != null)
{
// 使用改进的显示格式
for (int i = 0; i < pathManager.CurrentRoute.Points.Count; i++)
{
var point = pathManager.CurrentRoute.Points[i];
string pointIcon = point.Type == PathPointType.StartPoint ? "🚀" :
point.Type == PathPointType.EndPoint ? "🎯" : "📍";
string pointTypeText = point.Type == PathPointType.StartPoint ? "起点" :
point.Type == PathPointType.EndPoint ? "终点" : "路径点";
listBox.Items.Add($"{i + 1:D2}. {pointIcon} {point.Name} [{pointTypeText}]");
}
// 默认选中第一个点
if (pathManager.CurrentRoute.Points.Count > 0)
{
listBox.SelectedIndex = 0;
}
// 更新下一个点类型提示
if (pathManager.CurrentRoute.Points.Count == 0)
{
nextPointLabel.Text = "下一个点: 起点";
nextPointLabel.ForeColor = System.Drawing.Color.Green;
}
else
{
nextPointLabel.Text = "下一个点: 路径点";
nextPointLabel.ForeColor = System.Drawing.Color.Blue;
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新路径点列表失败: {ex.Message}");
}
}
/// <summary>
/// 创建路径管理控制界面
/// </summary>
/// <param name="parent">父容器</param>
private void CreatePathManagementControls(GroupBox parent)
{
// 打开2D地图按钮
Button open2DMapButton = new Button
{
Text = "打开2D地图",
Size = new Size(100, 30),
Location = new Point(20, 25),
Font = new Font("微软雅黑", 9),
UseVisualStyleBackColor = true
};
// 导入路径按钮
Button importPathButton = new Button
{
Text = "导入路径",
Size = new Size(90, 30),
Location = new Point(130, 25),
Font = new Font("微软雅黑", 9),
UseVisualStyleBackColor = true
};
// 导出路径按钮
Button exportPathButton = new Button
{
Text = "导出路径",
Size = new Size(90, 30),
Location = new Point(230, 25),
Font = new Font("微软雅黑", 9),
UseVisualStyleBackColor = true
};
// 事件处理
open2DMapButton.Click += (sender, e) =>
{
try
{
var pathPlanningManager = new PathPlanningManager();
pathPlanningManager.ShowPathPlanningInterface();
MessageBox.Show("2D导航地图已打开", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"打开2D地图失败: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
importPathButton.Click += (sender, e) =>
{
try
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Title = "选择路径文件",
Filter = "XML文件 (*.xml)|*.xml|JSON文件 (*.json)|*.json|所有文件 (*.*)|*.*",
FilterIndex = 1
};
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
var dataManager = new PathDataManager();
var routes = new List<PathRoute>();
string extension = System.IO.Path.GetExtension(openFileDialog.FileName).ToLower();
if (extension == ".xml")
{
routes = dataManager.ImportFromXml(openFileDialog.FileName);
}
else if (extension == ".json")
{
routes = dataManager.ImportFromJson(openFileDialog.FileName);
}
if (routes.Count > 0)
{
MessageBox.Show($"成功导入 {routes.Count} 条路径", "导入成功",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("文件中未找到有效的路径数据", "导入提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show($"导入路径失败: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
exportPathButton.Click += (sender, e) =>
{
MessageBox.Show("导出功能正在开发中", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
};
// 添加控件到父容器
parent.Controls.Add(open2DMapButton);
parent.Controls.Add(importPathButton);
parent.Controls.Add(exportPathButton);
}
/// <summary>
/// 创建类别选择下拉框
/// </summary>
/// <param name="parent">父容器</param>
private void CreateCategoryDropdown(GroupBox parent)
{
// 类别标签
Label categoryLabel = new Label
{
Text = "设为类型:",
Location = new Point(20, 30),
Size = new Size(80, 20),
Font = new Font("微软雅黑", 9)
};
parent.Controls.Add(categoryLabel);
// 类别下拉框
ComboBox categoryComboBox = new ComboBox
{
Location = new Point(100, 28),
Size = new Size(120, 25),
Font = new Font("微软雅黑", 9),
DropDownStyle = ComboBoxStyle.DropDownList
};
// 添加类别选项
categoryComboBox.Items.Add("门");
categoryComboBox.Items.Add("电梯");
categoryComboBox.Items.Add("楼梯");
categoryComboBox.Items.Add("通道");
categoryComboBox.Items.Add("障碍物");
categoryComboBox.Items.Add("装卸区");
categoryComboBox.Items.Add("停车位");
categoryComboBox.Items.Add("检查点");
categoryComboBox.SelectedIndex = 3; // 默认选择"通道"
parent.Controls.Add(categoryComboBox);
// 应用按钮
Button applyButton = new Button
{
Text = "应用类别",
Location = new Point(230, 27),
Size = new Size(80, 27),
Font = new Font("微软雅黑", 9),
UseVisualStyleBackColor = true
};
// 应用按钮点击事件
applyButton.Click += (sender, e) =>
{
try
{
if (categoryComboBox.SelectedIndex < 0)
{
MessageBox.Show("请先选择一个类别", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 获取当前选中的模型项
ModelItemCollection selectedItems = NavisApplication.ActiveDocument.CurrentSelection.SelectedItems;
if (selectedItems.Count == 0)
{
MessageBox.Show("请先选择要设置属性的模型项", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 将下拉框选择转换为枚举类型
CategoryAttributeManager.LogisticsElementType elementType;
switch (categoryComboBox.SelectedIndex)
{
case 0: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 1: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 2: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 3: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 4: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 5: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 6: elementType = CategoryAttributeManager.LogisticsElementType.; break;
case 7: elementType = CategoryAttributeManager.LogisticsElementType.; break;
default: elementType = CategoryAttributeManager.LogisticsElementType.; break;
}
// 执行属性添加操作
int successCount = CategoryAttributeManager.AddLogisticsAttributes(
selectedItems,
elementType,
elementType != CategoryAttributeManager.LogisticsElementType., // 障碍物默认不可通行
5, // 默认优先级
"标准", // 默认车辆尺寸
10.0 // 默认速度限制
);
// 显示结果
if (successCount > 0)
{
MessageBox.Show($"成功为 {successCount} 个模型项设置了'{categoryComboBox.SelectedItem}'属性", "操作成功",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("未能为任何模型项设置属性,请检查选择的模型项", "操作失败",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show($"设置属性时发生错误: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
parent.Controls.Add(applyButton);
}
/// <summary>
/// 创建类别按钮(已弃用,保留以防向后兼容)
/// </summary>
/// <param name="parent">父容器</param>
/// <param name="elementType">元素类型</param>
/// <param name="index">按钮索引</param>
private void CreateCategoryButton(GroupBox parent, CategoryAttributeManager.LogisticsElementType elementType, int index)
{
Button button = new Button
{
Text = $"设为{elementType}",
Size = new Size(200, 35),
Location = new Point(45, 30 + index * 35),
Font = new Font("微软雅黑", 10),
UseVisualStyleBackColor = true
};
// 添加点击事件
button.Click += (sender, e) =>
{
try
{
// 获取当前选中的模型项
ModelItemCollection selectedItems = NavisApplication.ActiveDocument.CurrentSelection.SelectedItems;
if (selectedItems.Count == 0)
{
MessageBox.Show("请先选择要设置属性的模型项", "提示",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// 执行属性添加操作
int successCount = CategoryAttributeManager.AddLogisticsAttributes(
selectedItems,
elementType,
elementType != CategoryAttributeManager.LogisticsElementType., // 障碍物默认不可通行
5, // 默认优先级
"标准", // 默认车辆尺寸
10.0 // 默认速度限制
);
// 显示结果
if (successCount > 0)
{
MessageBox.Show($"成功为 {successCount} 个模型项设置了物流属性", "操作成功",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("未能为任何模型项设置属性,请检查选择的模型项", "操作失败",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
MessageBox.Show($"设置属性时发生错误: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
parent.Controls.Add(button);
}
/// <summary>
/// 创建可见性控制界面
/// </summary>
/// <param name="parent">父容器</param>
private void CreateVisibilityControls(GroupBox parent)
{
// 只显示物流分类项目复选框
CheckBox logisticsOnlyCheckBox = new CheckBox
{
Text = "只显示物流分类项目",
Size = new Size(200, 20),
Location = new Point(20, 30),
Font = new Font("微软雅黑", 9),
Checked = false,
UseVisualStyleBackColor = true
};
// 状态标签
Label statusLabel = new Label
{
Text = "状态: 显示所有项目",
Location = new Point(20, 70),
Size = new Size(250, 20),
Font = new Font("微软雅黑", 9),
ForeColor = System.Drawing.Color.DarkGreen
};
// 复选框事件处理
logisticsOnlyCheckBox.CheckedChanged += (sender, e) =>
{
try
{
logisticsOnlyCheckBox.Enabled = false;
statusLabel.Text = "状态: 正在处理...";
statusLabel.ForeColor = System.Drawing.Color.Orange;
VisibilityOperationResult result;
if (logisticsOnlyCheckBox.Checked)
{
// 勾选时:隐藏非物流分类项目
result = VisibilityManager.HideNonLogisticsItems();
if (result.Success)
{
statusLabel.Text = $"状态: 已隐藏 {result.HiddenCount} 个非物流项目";
statusLabel.ForeColor = System.Drawing.Color.DarkGreen;
}
else
{
statusLabel.Text = "状态: 隐藏操作失败";
statusLabel.ForeColor = System.Drawing.Color.Red;
logisticsOnlyCheckBox.Checked = false; // 回滚状态
}
}
else
{
// 取消勾选时:显示所有项目
result = VisibilityManager.ShowAllItems();
if (result.Success)
{
statusLabel.Text = "状态: 显示所有项目";
statusLabel.ForeColor = System.Drawing.Color.DarkGreen;
}
else
{
statusLabel.Text = "状态: 显示操作失败";
statusLabel.ForeColor = System.Drawing.Color.Red;
logisticsOnlyCheckBox.Checked = true; // 回滚状态
}
}
// 如果操作失败,显示错误信息
if (!result.Success)
{
MessageBox.Show(result.Message, "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
catch (Exception ex)
{
statusLabel.Text = "状态: 发生错误";
statusLabel.ForeColor = System.Drawing.Color.Red;
logisticsOnlyCheckBox.Checked = !logisticsOnlyCheckBox.Checked; // 回滚状态
MessageBox.Show($"操作出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
logisticsOnlyCheckBox.Enabled = true;
}
};
// 添加控件到父容器
parent.Controls.Add(logisticsOnlyCheckBox);
parent.Controls.Add(statusLabel);
}
}
}