NavisworksTransport/src/Core/Config/ConfigManager.cs

375 lines
15 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 System;
using System.IO;
using System.Text;
using Tomlyn;
using Tomlyn.Model;
using NavisworksTransport.Utils;
namespace NavisworksTransport.Core.Config
{
/// <summary>
/// 系统配置管理器
/// 负责 TOML 配置文件的读取、保存和管理
/// </summary>
public class ConfigManager
{
private static ConfigManager _instance;
private static readonly object _lock = new object();
/// <summary>
/// 单例实例
/// </summary>
public static ConfigManager Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new ConfigManager();
}
}
}
return _instance;
}
}
/// <summary>
/// 配置文件路径
/// </summary>
public static string ConfigFilePath
{
get
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"Autodesk",
"Navisworks Manage 2026",
"plugins",
"NavisworksTransportPlugin",
"config.toml"
);
}
}
/// <summary>
/// 配置目录
/// </summary>
public static string ConfigDirectory
{
get { return Path.GetDirectoryName(ConfigFilePath); }
}
private SystemConfig _currentConfig;
private ConfigManager()
{
_currentConfig = LoadOrCreateDefault();
}
/// <summary>
/// 获取当前配置
/// </summary>
public SystemConfig Current
{
get { return _currentConfig; }
}
/// <summary>
/// 加载配置文件,如果不存在则创建默认配置
/// </summary>
public SystemConfig LoadOrCreateDefault()
{
try
{
if (!File.Exists(ConfigFilePath))
{
LogManager.Info($"配置文件不存在,创建默认配置: {ConfigFilePath}");
var defaultConfig = new SystemConfig();
SaveConfig(defaultConfig);
return defaultConfig;
}
LogManager.Info($"加载配置文件: {ConfigFilePath}");
var tomlContent = File.ReadAllText(ConfigFilePath, Encoding.UTF8);
var config = LoadFromToml(tomlContent);
LogManager.Info("配置文件加载成功");
return config;
}
catch (Exception ex)
{
LogManager.Error($"加载配置文件失败: {ex.Message}");
LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
// 加载失败时返回默认配置
LogManager.Info("使用默认配置");
return new SystemConfig();
}
}
/// <summary>
/// 从 TOML 字符串加载配置
/// </summary>
private SystemConfig LoadFromToml(string tomlContent)
{
var model = Toml.ToModel(tomlContent);
var config = new SystemConfig();
// 加载网格生成配置
if (model.ContainsKey("grid_generation"))
{
var gridGen = model["grid_generation"] as TomlTable;
if (gridGen != null)
{
config.GridGeneration.CellSizeMeters = GetDouble(gridGen, "cell_size_meters", 0.5);
config.GridGeneration.VehicleRadiusMeters = GetDouble(gridGen, "vehicle_radius_meters", 0.3);
config.GridGeneration.SafetyMarginMeters = GetDouble(gridGen, "safety_margin_meters", 0.2);
config.GridGeneration.InflationRadiusCells = GetInt(gridGen, "inflation_radius_cells", 2);
config.GridGeneration.ScanHeightMeters = GetDouble(gridGen, "scan_height_meters", 0.1);
}
}
// 加载路径规划配置
if (model.ContainsKey("path_planning"))
{
var pathPlan = model["path_planning"] as TomlTable;
if (pathPlan != null)
{
config.PathPlanning.MaxHeightDiffMeters = GetDouble(pathPlan, "max_height_diff_meters", 0.35);
config.PathPlanning.VehicleHeightMeters = GetDouble(pathPlan, "vehicle_height_meters", 2.0);
config.PathPlanning.VehicleLengthMeters = GetDouble(pathPlan, "vehicle_length_meters", 2.5);
config.PathPlanning.VehicleWidthMeters = GetDouble(pathPlan, "vehicle_width_meters", 1.8);
config.PathPlanning.DefaultPathStrategy = GetString(pathPlan, "default_path_strategy", "Straightest");
config.PathPlanning.EnablePathOptimization = GetBool(pathPlan, "enable_path_optimization", true);
}
}
// 加载可视化配置
if (model.ContainsKey("visualization"))
{
var visual = model["visualization"] as TomlTable;
if (visual != null)
{
config.Visualization.GridPointSize = GetDouble(visual, "grid_point_size", 5.0);
config.Visualization.PathLineWidth = GetDouble(visual, "path_line_width", 2.0);
config.Visualization.PathPointSize = GetDouble(visual, "path_point_size", 50.0);
config.Visualization.EnableGridVisualization = GetBool(visual, "enable_grid_visualization", false);
config.Visualization.EnableMultiLayerVisualization = GetBool(visual, "enable_multi_layer_visualization", true);
}
}
// 加载动画配置
if (model.ContainsKey("animation"))
{
var anim = model["animation"] as TomlTable;
if (anim != null)
{
config.Animation.DefaultSpeedMetersPerSecond = GetDouble(anim, "default_speed_meters_per_second", 1.5);
config.Animation.FrameRate = GetInt(anim, "frame_rate", 30);
config.Animation.StepIntervalMs = GetInt(anim, "step_interval_ms", 100);
config.Animation.EnableSmoothInterpolation = GetBool(anim, "enable_smooth_interpolation", true);
}
}
// 加载碰撞检测配置
if (model.ContainsKey("collision"))
{
var collision = model["collision"] as TomlTable;
if (collision != null)
{
config.Collision.DetectionStepMeters = GetDouble(collision, "detection_step_meters", 0.1);
config.Collision.CollisionToleranceMeters = GetDouble(collision, "collision_tolerance_meters", 0.01);
config.Collision.EnableRealtimeDetection = GetBool(collision, "enable_realtime_detection", true);
config.Collision.AutoGenerateReport = GetBool(collision, "auto_generate_report", true);
}
}
return config;
}
/// <summary>
/// 保存配置到文件
/// </summary>
public void SaveConfig(SystemConfig config)
{
try
{
// 确保目录存在
Directory.CreateDirectory(ConfigDirectory);
var tomlContent = ConvertToToml(config);
File.WriteAllText(ConfigFilePath, tomlContent, Encoding.UTF8);
_currentConfig = config;
LogManager.Info($"配置文件已保存: {ConfigFilePath}");
}
catch (Exception ex)
{
LogManager.Error($"保存配置文件失败: {ex.Message}");
LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
throw;
}
}
/// <summary>
/// 将配置转换为 TOML 字符串
/// </summary>
private string ConvertToToml(SystemConfig config)
{
var sb = new StringBuilder();
// 添加文件头注释
sb.AppendLine("# NavisworksTransport 系统配置文件");
sb.AppendLine("# 单位说明:长度单位均为米(m),时间单位为秒(s)");
sb.AppendLine("# 自动生成时间: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
sb.AppendLine();
// 网格生成配置
sb.AppendLine("[grid_generation]");
sb.AppendLine("# 网格单元大小(米)- 推荐值0.3-0.8");
sb.AppendLine($"cell_size_meters = {config.GridGeneration.CellSizeMeters}");
sb.AppendLine();
sb.AppendLine("# 车辆半径(米)- 用于障碍物膨胀计算");
sb.AppendLine($"vehicle_radius_meters = {config.GridGeneration.VehicleRadiusMeters}");
sb.AppendLine();
sb.AppendLine("# 安全间隙(米)- 额外的安全距离");
sb.AppendLine($"safety_margin_meters = {config.GridGeneration.SafetyMarginMeters}");
sb.AppendLine();
sb.AppendLine("# 膨胀半径(网格单元数)");
sb.AppendLine($"inflation_radius_cells = {config.GridGeneration.InflationRadiusCells}");
sb.AppendLine();
sb.AppendLine("# 扫描高度(米)");
sb.AppendLine($"scan_height_meters = {config.GridGeneration.ScanHeightMeters}");
sb.AppendLine();
// 路径规划配置
sb.AppendLine("[path_planning]");
sb.AppendLine("# 最大高度差(米)- 楼梯、坡道可接受的高度阈值");
sb.AppendLine($"max_height_diff_meters = {config.PathPlanning.MaxHeightDiffMeters}");
sb.AppendLine();
sb.AppendLine("# 车辆尺寸(米)");
sb.AppendLine($"vehicle_height_meters = {config.PathPlanning.VehicleHeightMeters}");
sb.AppendLine($"vehicle_length_meters = {config.PathPlanning.VehicleLengthMeters}");
sb.AppendLine($"vehicle_width_meters = {config.PathPlanning.VehicleWidthMeters}");
sb.AppendLine();
sb.AppendLine("# 默认路径策略:\"Shortest\" | \"Straightest\" | \"SafetyFirst\"");
sb.AppendLine($"default_path_strategy = \"{config.PathPlanning.DefaultPathStrategy}\"");
sb.AppendLine();
sb.AppendLine("# 启用路径优化(减少转弯点)");
sb.AppendLine($"enable_path_optimization = {config.PathPlanning.EnablePathOptimization.ToString().ToLower()}");
sb.AppendLine();
// 可视化配置
sb.AppendLine("[visualization]");
sb.AppendLine("# 网格点大小(像素)");
sb.AppendLine($"grid_point_size = {config.Visualization.GridPointSize}");
sb.AppendLine();
sb.AppendLine("# 路径线宽(像素)");
sb.AppendLine($"path_line_width = {config.Visualization.PathLineWidth}");
sb.AppendLine();
sb.AppendLine("# 路径点大小(模型单位)");
sb.AppendLine($"path_point_size = {config.Visualization.PathPointSize}");
sb.AppendLine();
sb.AppendLine("# 启用网格可视化");
sb.AppendLine($"enable_grid_visualization = {config.Visualization.EnableGridVisualization.ToString().ToLower()}");
sb.AppendLine();
sb.AppendLine("# 启用多层网格可视化");
sb.AppendLine($"enable_multi_layer_visualization = {config.Visualization.EnableMultiLayerVisualization.ToString().ToLower()}");
sb.AppendLine();
// 动画配置
sb.AppendLine("[animation]");
sb.AppendLine("# 默认动画速度(米/秒)");
sb.AppendLine($"default_speed_meters_per_second = {config.Animation.DefaultSpeedMetersPerSecond}");
sb.AppendLine();
sb.AppendLine("# 动画帧率(帧/秒)");
sb.AppendLine($"frame_rate = {config.Animation.FrameRate}");
sb.AppendLine();
sb.AppendLine("# 步进间隔(毫秒)");
sb.AppendLine($"step_interval_ms = {config.Animation.StepIntervalMs}");
sb.AppendLine();
sb.AppendLine("# 启用平滑插值");
sb.AppendLine($"enable_smooth_interpolation = {config.Animation.EnableSmoothInterpolation.ToString().ToLower()}");
sb.AppendLine();
// 碰撞检测配置
sb.AppendLine("[collision]");
sb.AppendLine("# 碰撞检测步长(米)");
sb.AppendLine($"detection_step_meters = {config.Collision.DetectionStepMeters}");
sb.AppendLine();
sb.AppendLine("# 碰撞容差(米)");
sb.AppendLine($"collision_tolerance_meters = {config.Collision.CollisionToleranceMeters}");
sb.AppendLine();
sb.AppendLine("# 启用实时碰撞检测");
sb.AppendLine($"enable_realtime_detection = {config.Collision.EnableRealtimeDetection.ToString().ToLower()}");
sb.AppendLine();
sb.AppendLine("# 自动生成碰撞报告");
sb.AppendLine($"auto_generate_report = {config.Collision.AutoGenerateReport.ToString().ToLower()}");
return sb.ToString();
}
/// <summary>
/// 重新加载配置
/// </summary>
public void Reload()
{
_currentConfig = LoadOrCreateDefault();
}
/// <summary>
/// 重置为默认配置
/// </summary>
public void ResetToDefault()
{
var defaultConfig = new SystemConfig();
SaveConfig(defaultConfig);
}
// 辅助方法:从 TomlTable 获取值
private double GetDouble(TomlTable table, string key, double defaultValue)
{
if (table.ContainsKey(key))
{
var value = table[key];
if (value is long longValue)
return (double)longValue;
if (value is double doubleValue)
return doubleValue;
}
return defaultValue;
}
private int GetInt(TomlTable table, string key, int defaultValue)
{
if (table.ContainsKey(key) && table[key] is long longValue)
{
return (int)longValue;
}
return defaultValue;
}
private bool GetBool(TomlTable table, string key, bool defaultValue)
{
if (table.ContainsKey(key) && table[key] 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;
}
}
}