From aa0557c9e6894a7b966b47af225fc511773b3a3c Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Wed, 31 Dec 2025 11:29:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B3=BB=E7=BB=9F=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NavisworksTransportPlugin.csproj | 10 +- config.toml.example => default_config.toml | 2 - deploy-plugin.bat | 3 +- src/Core/Config/ConfigManager.cs | 409 +++++++++++------- src/Core/Config/SystemConfig.cs | 63 ++- src/Core/PathCurveEngine.cs | 5 +- src/Core/PathPlanningManager.cs | 23 +- ...txt => NavisworksTransportPlugin.name.txt} | 0 src/UI/WPF/Views/ConfigEditorDialog.xaml.cs | 2 +- 9 files changed, 312 insertions(+), 205 deletions(-) rename config.toml.example => default_config.toml (98%) rename src/Resources/{NavisworksTransport.Tian.name.txt => NavisworksTransportPlugin.name.txt} (100%) diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj index 7bcd54f..b39b774 100644 --- a/NavisworksTransportPlugin.csproj +++ b/NavisworksTransportPlugin.csproj @@ -355,12 +355,18 @@ - + PreserveNewest - NavisworksTransport.Tian.name.txt + NavisworksTransportPlugin.name.txt + + + + PreserveNewest + + \ No newline at end of file diff --git a/config.toml.example b/default_config.toml similarity index 98% rename from config.toml.example rename to default_config.toml index 21e157e..8b1d0e7 100644 --- a/config.toml.example +++ b/default_config.toml @@ -20,8 +20,6 @@ vehicle_height_meters = 2.0 # 安全间隙(米) safety_margin_meters = 0.05 -# 路径曲线化配置 - # 路径默认转弯半径(米)- 表示路径允许的最大转弯半径 default_path_turn_radius = 2.5 diff --git a/deploy-plugin.bat b/deploy-plugin.bat index bc0ebd8..98dd30d 100644 --- a/deploy-plugin.bat +++ b/deploy-plugin.bat @@ -4,6 +4,7 @@ set "TARGET_DIR=C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\Naviswork if not exist "%TARGET_DIR%" mkdir "%TARGET_DIR%" copy "bin\x64\Release\NavisworksTransportPlugin.dll" "%TARGET_DIR%\" >nul -if exist "bin\x64\Release\NavisworksTransport.Tian.name.txt" copy "bin\x64\Release\NavisworksTransport.Tian.name.txt" "%TARGET_DIR%\" >nul +if exist "bin\x64\Release\NavisworksTransportPlugin.name.txt" copy "bin\x64\Release\NavisworksTransportPlugin.name.txt" "%TARGET_DIR%\" >nul +if exist "bin\x64\Release\default_config.toml" copy "bin\x64\Release\default_config.toml" "%TARGET_DIR%\" >nul echo Plugin deployed successfully! \ No newline at end of file diff --git a/src/Core/Config/ConfigManager.cs b/src/Core/Config/ConfigManager.cs index 58801e5..3a151f8 100644 --- a/src/Core/Config/ConfigManager.cs +++ b/src/Core/Config/ConfigManager.cs @@ -1,8 +1,9 @@ using System; using System.IO; -using System.Text; +using System.Reflection; using Tomlyn; using Tomlyn.Model; +using Tomlyn.Syntax; namespace NavisworksTransport.Core.Config { @@ -62,11 +63,25 @@ namespace NavisworksTransport.Core.Config get { return Path.GetDirectoryName(ConfigFilePath); } } + /// + /// 配置模板文件路径 + /// + private static string ConfigTemplatePath + { + get + { + // 从插件当前目录获取模板文件 + var pluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + return Path.Combine(pluginDirectory, "default_config.toml"); + } + } + private SystemConfig _currentConfig; + private string _cachedTemplateContent; private ConfigManager() { - _currentConfig = LoadOrCreateDefault(); + _currentConfig = LoadConfigFile(); } /// @@ -78,23 +93,37 @@ namespace NavisworksTransport.Core.Config } /// - /// 加载配置文件,如果不存在则创建默认配置 + /// 读取配置模板文件内容 /// - public SystemConfig LoadOrCreateDefault() + private string ReadConfigTemplate() + { + if (!File.Exists(ConfigTemplatePath)) + { + throw new FileNotFoundException($"配置模板文件不存在: {ConfigTemplatePath}"); + } + + LogManager.Info($"使用配置模板文件: {ConfigTemplatePath}"); + return File.ReadAllText(ConfigTemplatePath); + } + + /// + /// 加载配置文件,如果不存在则从模板创建 + /// + private SystemConfig LoadConfigFile() { try { if (!File.Exists(ConfigFilePath)) { - LogManager.Info($"配置文件不存在,创建默认配置: {ConfigFilePath}"); - var defaultConfig = new SystemConfig(); - SaveConfig(defaultConfig); - return defaultConfig; + LogManager.Info($"配置文件不存在,从模板创建: {ConfigFilePath}"); + var templateContent = ReadConfigTemplate(); + WriteConfigFileDirect(templateContent); + return ParseTomlToConfig(templateContent); } LogManager.Info($"加载配置文件: {ConfigFilePath}"); - var tomlContent = File.ReadAllText(ConfigFilePath, Encoding.UTF8); - var config = LoadFromToml(tomlContent); + var tomlContent = File.ReadAllText(ConfigFilePath); + var config = ParseTomlToConfig(tomlContent); LogManager.Info("配置文件加载成功"); return config; @@ -104,74 +133,109 @@ namespace NavisworksTransport.Core.Config LogManager.Error($"加载配置文件失败: {ex.Message}"); LogManager.Error($"堆栈跟踪: {ex.StackTrace}"); - // 加载失败时返回默认配置 - LogManager.Info("使用默认配置"); - return new SystemConfig(); + // 加载失败时使用模板中的默认配置 + LogManager.Info("使用模板中的默认配置"); + var templateContent = ReadConfigTemplate(); + return ParseTomlToConfig(templateContent); } } /// - /// 从 TOML 字符串加载配置 + /// 将 TOML 字符串解析为配置对象 /// - private SystemConfig LoadFromToml(string tomlContent) + private SystemConfig ParseTomlToConfig(string tomlContent) { var model = Toml.ToModel(tomlContent); - var config = new SystemConfig(); + var config = CreateEmptyConfigObject(); // 加载路径编辑配置 - if (model.ContainsKey("path_editing")) + if (!model.ContainsKey("path_editing")) { - var pathEdit = model["path_editing"] as TomlTable; - if (pathEdit != null) - { - config.PathEditing.CellSizeMeters = GetDouble(pathEdit, "cell_size_meters", 0.5); - config.PathEditing.MaxHeightDiffMeters = GetDouble(pathEdit, "max_height_diff_meters", 0.35); - config.PathEditing.VehicleLengthMeters = GetDouble(pathEdit, "vehicle_length_meters", 1.0); - config.PathEditing.VehicleWidthMeters = GetDouble(pathEdit, "vehicle_width_meters", 1.0); - config.PathEditing.VehicleHeightMeters = GetDouble(pathEdit, "vehicle_height_meters", 2.0); - config.PathEditing.SafetyMarginMeters = GetDouble(pathEdit, "safety_margin_meters", 0.05); - } + throw new InvalidOperationException("配置文件缺少 [path_editing] 部分"); } + var pathEdit = model["path_editing"] as TomlTable; + if (pathEdit == null) + { + throw new InvalidOperationException("[path_editing] 部分格式错误"); + } + + config.PathEditing.CellSizeMeters = GetRequiredDoubleValue(pathEdit, "cell_size_meters"); + config.PathEditing.MaxHeightDiffMeters = GetRequiredDoubleValue(pathEdit, "max_height_diff_meters"); + config.PathEditing.VehicleLengthMeters = GetRequiredDoubleValue(pathEdit, "vehicle_length_meters"); + config.PathEditing.VehicleWidthMeters = GetRequiredDoubleValue(pathEdit, "vehicle_width_meters"); + config.PathEditing.VehicleHeightMeters = GetRequiredDoubleValue(pathEdit, "vehicle_height_meters"); + config.PathEditing.SafetyMarginMeters = GetRequiredDoubleValue(pathEdit, "safety_margin_meters"); + config.PathEditing.DefaultPathTurnRadius = GetRequiredDoubleValue(pathEdit, "default_path_turn_radius"); + config.PathEditing.ArcSamplingStep = GetRequiredDoubleValue(pathEdit, "arc_sampling_step"); + // 加载可视化配置 - if (model.ContainsKey("visualization")) + if (!model.ContainsKey("visualization")) { - var visual = model["visualization"] as TomlTable; - if (visual != null) - { - config.Visualization.MarginRatio = GetDouble(visual, "margin_ratio", 0.1); - } + throw new InvalidOperationException("配置文件缺少 [visualization] 部分"); } + var visual = model["visualization"] as TomlTable; + if (visual == null) + { + throw new InvalidOperationException("[visualization] 部分格式错误"); + } + + config.Visualization.MarginRatio = GetRequiredDoubleValue(visual, "margin_ratio"); + // 加载动画配置 - if (model.ContainsKey("animation")) + if (!model.ContainsKey("animation")) { - var anim = model["animation"] as TomlTable; - if (anim != null) - { - config.Animation.FrameRate = GetInt(anim, "frame_rate", 30); - config.Animation.DurationSeconds = GetDouble(anim, "duration_seconds", 10.0); - config.Animation.DetectionGapMeters = GetDouble(anim, "detection_gap_meters", 0.05); - } + throw new InvalidOperationException("配置文件缺少 [animation] 部分"); } + var anim = model["animation"] as TomlTable; + if (anim == null) + { + throw new InvalidOperationException("[animation] 部分格式错误"); + } + + config.Animation.FrameRate = GetRequiredIntValue(anim, "frame_rate"); + config.Animation.DurationSeconds = GetRequiredDoubleValue(anim, "duration_seconds"); + config.Animation.DetectionGapMeters = GetRequiredDoubleValue(anim, "detection_gap_meters"); + // 加载物流属性配置 - if (model.ContainsKey("logistics")) + if (!model.ContainsKey("logistics")) { - var logistics = model["logistics"] as TomlTable; - if (logistics != null) - { - config.Logistics.Traversable = GetBool(logistics, "traversable", true); - config.Logistics.Priority = GetInt(logistics, "priority", 5); - config.Logistics.HeightLimitMeters = GetDouble(logistics, "height_limit_meters", 3.0); - config.Logistics.SpeedLimitMetersPerSecond = GetDouble(logistics, "speed_limit_meters_per_second", 0.8); - config.Logistics.WidthLimitMeters = GetDouble(logistics, "width_limit_meters", 3.0); - } + throw new InvalidOperationException("配置文件缺少 [logistics] 部分"); } + var logistics = model["logistics"] as TomlTable; + if (logistics == null) + { + throw new InvalidOperationException("[logistics] 部分格式错误"); + } + + config.Logistics.Traversable = GetRequiredBoolValue(logistics, "traversable"); + config.Logistics.Priority = GetRequiredIntValue(logistics, "priority"); + config.Logistics.HeightLimitMeters = GetRequiredDoubleValue(logistics, "height_limit_meters"); + config.Logistics.SpeedLimitMetersPerSecond = GetRequiredDoubleValue(logistics, "speed_limit_meters_per_second"); + config.Logistics.WidthLimitMeters = GetRequiredDoubleValue(logistics, "width_limit_meters"); + return config; } + /// + /// 创建空的配置对象(初始化所有嵌套对象) + /// + private SystemConfig CreateEmptyConfigObject() + { + return new SystemConfig + { + GridGeneration = new GridGenerationConfig(), + PathPlanning = new PathPlanningConfig(), + PathEditing = new PathEditingConfig(), + Visualization = new VisualizationConfig(), + Animation = new AnimationConfig(), + Logistics = new LogisticsConfig() + }; + } + /// /// 保存配置到文件 /// @@ -182,8 +246,8 @@ namespace NavisworksTransport.Core.Config // 确保目录存在 Directory.CreateDirectory(ConfigDirectory); - var tomlContent = ConvertToToml(config); - File.WriteAllText(ConfigFilePath, tomlContent, Encoding.UTF8); + var tomlContent = GenerateTomlFromConfig(config); + File.WriteAllText(ConfigFilePath, tomlContent); _currentConfig = config; LogManager.Info($"配置文件已保存: {ConfigFilePath}"); @@ -197,133 +261,178 @@ namespace NavisworksTransport.Core.Config } /// - /// 将配置转换为 TOML 字符串 + /// 直接写入配置文件内容(不经过模板转换) /// - private string ConvertToToml(SystemConfig config) + private void WriteConfigFileDirect(string tomlContent) { - var sb = new StringBuilder(); + try + { + // 确保目录存在 + Directory.CreateDirectory(ConfigDirectory); - // 添加文件头注释 - sb.AppendLine("# NavisworksTransport 系统配置文件"); - sb.AppendLine("# 单位说明:长度单位均为米(m)"); - sb.AppendLine("# 自动生成时间: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); - sb.AppendLine(); - - // 路径编辑配置 - sb.AppendLine("[path_editing]"); - sb.AppendLine("# 网格单元大小(米)- 推荐值:0.3-1.0"); - sb.AppendLine($"cell_size_meters = {config.PathEditing.CellSizeMeters:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 最大高度差(米)- 楼梯、坡道可接受的高度阈值"); - sb.AppendLine($"max_height_diff_meters = {config.PathEditing.MaxHeightDiffMeters:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 车辆长度(米)"); - sb.AppendLine($"vehicle_length_meters = {config.PathEditing.VehicleLengthMeters:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 车辆宽度(米)"); - sb.AppendLine($"vehicle_width_meters = {config.PathEditing.VehicleWidthMeters:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 车辆高度(米)"); - sb.AppendLine($"vehicle_height_meters = {config.PathEditing.VehicleHeightMeters:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 安全间隙(米)"); - sb.AppendLine($"safety_margin_meters = {config.PathEditing.SafetyMarginMeters:0.00###}"); - sb.AppendLine(); - - // 可视化配置 - sb.AppendLine("[visualization]"); - sb.AppendLine("# 地图边距比例(0-1之间)"); - sb.AppendLine($"margin_ratio = {config.Visualization.MarginRatio:0.0###}"); - sb.AppendLine(); - - // 动画配置 - sb.AppendLine("[animation]"); - sb.AppendLine("# 动画帧率(帧/秒)"); - sb.AppendLine($"frame_rate = {config.Animation.FrameRate}"); - sb.AppendLine(); - sb.AppendLine("# 动画持续时间(秒)"); - sb.AppendLine($"duration_seconds = {config.Animation.DurationSeconds:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 检测间隙(米)"); - sb.AppendLine($"detection_gap_meters = {config.Animation.DetectionGapMeters:0.00###}"); - sb.AppendLine(); - - // 物流属性配置 - sb.AppendLine("[logistics]"); - sb.AppendLine("# 可通行性(默认值:true)"); - sb.AppendLine($"traversable = {config.Logistics.Traversable.ToString().ToLower()}"); - sb.AppendLine(); - sb.AppendLine("# 优先级(默认值:5,范围:1-5)"); - sb.AppendLine($"priority = {config.Logistics.Priority}"); - sb.AppendLine(); - sb.AppendLine("# 高度限制(默认值:3.0米)"); - sb.AppendLine($"height_limit_meters = {config.Logistics.HeightLimitMeters:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 速度限制(默认值:0.8米/秒)"); - sb.AppendLine($"speed_limit_meters_per_second = {config.Logistics.SpeedLimitMetersPerSecond:0.0###}"); - sb.AppendLine(); - sb.AppendLine("# 宽度限制(默认值:3.0米)"); - sb.AppendLine($"width_limit_meters = {config.Logistics.WidthLimitMeters:0.0###}"); - - return sb.ToString(); + File.WriteAllText(ConfigFilePath, tomlContent); + LogManager.Info($"配置文件已创建: {ConfigFilePath}"); + } + catch (Exception ex) + { + LogManager.Error($"写入配置文件失败: {ex.Message}"); + LogManager.Error($"堆栈跟踪: {ex.StackTrace}"); + throw; + } } /// - /// 重新加载配置 + /// 从配置对象生成 TOML 字符串(使用模板格式) + /// + private string GenerateTomlFromConfig(SystemConfig config) + { + // 加载模板内容(缓存) + if (_cachedTemplateContent == null) + { + _cachedTemplateContent = ReadConfigTemplate(); + } + + // 解析模板 + var syntax = Toml.Parse(_cachedTemplateContent); + var model = syntax.ToModel(); + + // 更新配置值到模型 + ApplyConfigValuesToModel(model, config); + + // 转换回 TOML 字符串 + return Toml.FromModel(model); + } + + /// + /// 将配置对象的值应用到 TOML 模型 + /// + private void ApplyConfigValuesToModel(TomlTable model, SystemConfig config) + { + // 更新路径编辑配置 + if (model.ContainsKey("path_editing")) + { + var pathEdit = model["path_editing"] as TomlTable; + if (pathEdit != null) + { + pathEdit["cell_size_meters"] = config.PathEditing.CellSizeMeters; + pathEdit["max_height_diff_meters"] = config.PathEditing.MaxHeightDiffMeters; + pathEdit["vehicle_length_meters"] = config.PathEditing.VehicleLengthMeters; + pathEdit["vehicle_width_meters"] = config.PathEditing.VehicleWidthMeters; + pathEdit["vehicle_height_meters"] = config.PathEditing.VehicleHeightMeters; + pathEdit["safety_margin_meters"] = config.PathEditing.SafetyMarginMeters; + pathEdit["default_path_turn_radius"] = config.PathEditing.DefaultPathTurnRadius; + pathEdit["arc_sampling_step"] = config.PathEditing.ArcSamplingStep; + } + } + + // 更新可视化配置 + if (model.ContainsKey("visualization")) + { + var visual = model["visualization"] as TomlTable; + if (visual != null) + { + visual["margin_ratio"] = config.Visualization.MarginRatio; + } + } + + // 更新动画配置 + if (model.ContainsKey("animation")) + { + var anim = model["animation"] as TomlTable; + if (anim != null) + { + anim["frame_rate"] = config.Animation.FrameRate; + anim["duration_seconds"] = config.Animation.DurationSeconds; + anim["detection_gap_meters"] = config.Animation.DetectionGapMeters; + } + } + + // 更新物流属性配置 + if (model.ContainsKey("logistics")) + { + var logistics = model["logistics"] as TomlTable; + if (logistics != null) + { + logistics["traversable"] = config.Logistics.Traversable; + logistics["priority"] = config.Logistics.Priority; + logistics["height_limit_meters"] = config.Logistics.HeightLimitMeters; + logistics["speed_limit_meters_per_second"] = config.Logistics.SpeedLimitMetersPerSecond; + logistics["width_limit_meters"] = config.Logistics.WidthLimitMeters; + } + } + } + + /// + /// 重新加载配置文件 /// public void Reload() { - _currentConfig = LoadOrCreateDefault(); + _currentConfig = LoadConfigFile(); } /// - /// 重置为默认配置 + /// 恢复为模板中的默认配置 /// - public void ResetToDefault() + public void RestoreToDefaults() { - var defaultConfig = new SystemConfig(); - SaveConfig(defaultConfig); + LogManager.Info("开始恢复默认配置..."); + var templateContent = ReadConfigTemplate(); + LogManager.Info($"模板内容长度: {templateContent.Length}"); + LogManager.Info($"模板内容前200字符: {templateContent.Substring(0, Math.Min(200, templateContent.Length))}"); + + WriteConfigFileDirect(templateContent); + + var newConfig = ParseTomlToConfig(templateContent); + LogManager.Info($"解析后的配置 - CellSizeMeters: {newConfig.PathEditing.CellSizeMeters}"); + LogManager.Info($"解析后的配置 - VehicleLengthMeters: {newConfig.PathEditing.VehicleLengthMeters}"); + + _currentConfig = newConfig; + LogManager.Info("默认配置恢复完成"); } - // 辅助方法:从 TomlTable 获取值 - private double GetDouble(TomlTable table, string key, double defaultValue) + // 辅助方法:从 TomlTable 获取必需值 + private double GetRequiredDoubleValue(TomlTable table, string key) { - if (table.ContainsKey(key)) + if (!table.ContainsKey(key)) { - var value = table[key]; - if (value is long longValue) - return (double)longValue; - if (value is double doubleValue) - return doubleValue; + throw new InvalidOperationException($"配置项 '{key}' 不存在"); } - return defaultValue; + + var value = table[key]; + if (value is long longValue) + return (double)longValue; + if (value is double doubleValue) + return doubleValue; + + throw new InvalidOperationException($"配置项 '{key}' 的类型错误,应为数值类型"); } - private int GetInt(TomlTable table, string key, int defaultValue) + private int GetRequiredIntValue(TomlTable table, string key) { - if (table.ContainsKey(key) && table[key] is long longValue) + if (!table.ContainsKey(key)) { + throw new InvalidOperationException($"配置项 '{key}' 不存在"); + } + + var value = table[key]; + if (value is long longValue) return (int)longValue; - } - return defaultValue; + + throw new InvalidOperationException($"配置项 '{key}' 的类型错误,应为整数类型"); } - private bool GetBool(TomlTable table, string key, bool defaultValue) + private bool GetRequiredBoolValue(TomlTable table, string key) { - if (table.ContainsKey(key) && table[key] is bool boolValue) + if (!table.ContainsKey(key)) { + throw new InvalidOperationException($"配置项 '{key}' 不存在"); + } + + var value = table[key]; + if (value is bool boolValue) return boolValue; - } - return defaultValue; - } - private string GetString(TomlTable table, string key, string defaultValue) - { - if (table.ContainsKey(key) && table[key] is string stringValue) - { - return stringValue; - } - return defaultValue; + throw new InvalidOperationException($"配置项 '{key}' 的类型错误,应为布尔类型"); } } } diff --git a/src/Core/Config/SystemConfig.cs b/src/Core/Config/SystemConfig.cs index e607d9e..14b5080 100644 --- a/src/Core/Config/SystemConfig.cs +++ b/src/Core/Config/SystemConfig.cs @@ -9,32 +9,32 @@ namespace NavisworksTransport.Core.Config /// /// 网格生成配置 /// - public GridGenerationConfig GridGeneration { get; set; } = new GridGenerationConfig(); + public GridGenerationConfig GridGeneration { get; set; } /// /// 路径规划配置 /// - public PathPlanningConfig PathPlanning { get; set; } = new PathPlanningConfig(); + public PathPlanningConfig PathPlanning { get; set; } /// /// 路径编辑配置 /// - public PathEditingConfig PathEditing { get; set; } = new PathEditingConfig(); + public PathEditingConfig PathEditing { get; set; } /// /// 可视化配置 /// - public VisualizationConfig Visualization { get; set; } = new VisualizationConfig(); + public VisualizationConfig Visualization { get; set; } /// /// 动画配置 /// - public AnimationConfig Animation { get; set; } = new AnimationConfig(); + public AnimationConfig Animation { get; set; } /// /// 物流属性配置 /// - public LogisticsConfig Logistics { get; set; } = new LogisticsConfig(); + public LogisticsConfig Logistics { get; set; } } /// @@ -58,49 +58,43 @@ namespace NavisworksTransport.Core.Config { /// /// 网格单元大小(米) - /// 推荐值:0.3-1.0 /// - public double CellSizeMeters { get; set; } = 0.5; + public double CellSizeMeters { get; set; } /// /// 最大高度差(米) - /// 楼梯、坡道可接受的高度阈值 /// - public double MaxHeightDiffMeters { get; set; } = 0.35; + public double MaxHeightDiffMeters { get; set; } /// /// 车辆长度(米) /// - public double VehicleLengthMeters { get; set; } = 1.0; + public double VehicleLengthMeters { get; set; } /// /// 车辆宽度(米) /// - public double VehicleWidthMeters { get; set; } = 1.0; + public double VehicleWidthMeters { get; set; } /// /// 车辆高度(米) /// - public double VehicleHeightMeters { get; set; } = 2.0; + public double VehicleHeightMeters { get; set; } /// /// 安全间隙(米) /// - public double SafetyMarginMeters { get; set; } = 0.05; - - // 路径曲线化配置 + public double SafetyMarginMeters { get; set; } /// /// 路径默认转弯半径(米) - /// 表示路径允许的最大转弯半径,车辆的最小转弯半径必须小于等于此值 /// - public double DefaultPathTurnRadius { get; set; } = 2.5; + public double DefaultPathTurnRadius { get; set; } /// /// 圆弧采样步长(米) - /// 推荐值:0.02-0.1 /// - public double ArcSamplingStep { get; set; } = 0.05; + public double ArcSamplingStep { get; set; } } /// @@ -110,9 +104,8 @@ namespace NavisworksTransport.Core.Config { /// /// 地图边距比例 - /// 地图显示时的边距占比(0-1之间) /// - public double MarginRatio { get; set; } = 0.1; + public double MarginRatio { get; set; } } /// @@ -123,17 +116,17 @@ namespace NavisworksTransport.Core.Config /// /// 动画帧率(帧/秒) /// - public int FrameRate { get; set; } = 30; + public int FrameRate { get; set; } /// /// 动画持续时间(秒) /// - public double DurationSeconds { get; set; } = 10.0; + public double DurationSeconds { get; set; } /// /// 检测间隙(米) /// - public double DetectionGapMeters { get; set; } = 0.05; + public double DetectionGapMeters { get; set; } } /// @@ -142,28 +135,28 @@ namespace NavisworksTransport.Core.Config public class LogisticsConfig { /// - /// 可通行性(默认值:true) + /// 可通行性 /// - public bool Traversable { get; set; } = true; + public bool Traversable { get; set; } /// - /// 优先级(默认值:5,范围:1-5) + /// 优先级 /// - public int Priority { get; set; } = 5; + public int Priority { get; set; } /// - /// 高度限制(默认值:3.0米) + /// 高度限制(米) /// - public double HeightLimitMeters { get; set; } = 3.0; + public double HeightLimitMeters { get; set; } /// - /// 速度限制(默认值:0.8米/秒) + /// 速度限制(米/秒) /// - public double SpeedLimitMetersPerSecond { get; set; } = 0.8; + public double SpeedLimitMetersPerSecond { get; set; } /// - /// 宽度限制(默认值:3.0米) + /// 宽度限制(米) /// - public double WidthLimitMeters { get; set; } = 3.0; + public double WidthLimitMeters { get; set; } } } diff --git a/src/Core/PathCurveEngine.cs b/src/Core/PathCurveEngine.cs index 3eacc68..90c8ee9 100644 --- a/src/Core/PathCurveEngine.cs +++ b/src/Core/PathCurveEngine.cs @@ -307,7 +307,8 @@ namespace NavisworksTransport var p2 = sortedPoints[i + 1]; // 判断是否为转折点(需要圆弧过渡) - bool needsArc = (i > 0 && i < sortedPoints.Count - 1); + // 需要满足:不是第一段,不是最后一段,且还有下一个点用于计算圆弧 + bool needsArc = (i > 0 && i < sortedPoints.Count - 2); if (needsArc) { @@ -326,7 +327,7 @@ namespace NavisworksTransport } else { - // 直线边 + // 直线边(第一段、最后一段或只有两个点时) var edge = BuildStraightEdge(p1, p2, samplingStep); route.Edges.Add(edge); } diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs index db9ec7d..5f3db25 100644 --- a/src/Core/PathPlanningManager.cs +++ b/src/Core/PathPlanningManager.cs @@ -1399,6 +1399,17 @@ namespace NavisworksTransport { try { + // 自动选择所有可通行的物流模型(先检查是否有可通行的模型) + AutoSelectLogisticsChannels(); + + // 检查是否有可通行的物流模型 + if (_walkableAreas == null || _walkableAreas.Count == 0) + { + RaiseErrorOccurred("没有找到任何可通行的物流模型,请先为模型设置可通行的物流属性"); + // 不需要重置状态,因为还没有进入创建状态 + return null; + } + // 设置为创建状态 PathEditState = PathEditState.Creating; @@ -1407,18 +1418,6 @@ namespace NavisworksTransport _editingRoute = newRoute; SetCurrentRouteInternal(newRoute, triggerEvent: true); - // 自动选择所有可通行的物流模型 - AutoSelectLogisticsChannels(); - - // 检查是否有可通行的物流模型 - if (_walkableAreas == null || _walkableAreas.Count == 0) - { - RaiseErrorOccurred("没有找到任何可通行的物流模型,请先为模型设置可通行的物流属性"); - // 重置状态 - SwitchToViewingState(); - return null; - } - // 智能管理ToolPlugin状态 ManageToolPluginForEditState(); diff --git a/src/Resources/NavisworksTransport.Tian.name.txt b/src/Resources/NavisworksTransportPlugin.name.txt similarity index 100% rename from src/Resources/NavisworksTransport.Tian.name.txt rename to src/Resources/NavisworksTransportPlugin.name.txt diff --git a/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs b/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs index e571f7e..5de2318 100644 --- a/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs +++ b/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs @@ -173,7 +173,7 @@ namespace NavisworksTransport.UI.WPF.Views { try { - ConfigManager.Instance.ResetToDefault(); + ConfigManager.Instance.RestoreToDefaults(); LoadConfigContent(); StatusLabel.Content = "已恢复默认配置"; StatusLabel.Foreground = System.Windows.Media.Brushes.Green;