From d336f8302a5a665b89028ed29d97ffd4d10c5166 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Thu, 19 Feb 2026 15:45:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E7=89=A9=E6=B5=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E7=AE=80=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E8=B0=83=E6=95=B4=E9=83=A8=E5=88=86=E7=B1=BB=E5=88=AB?= =?UTF-8?q?=E5=90=8D=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/default_custom_categories.toml | 119 ++++++++++-------- src/Core/Config/CustomCategoryConfig.cs | 45 +++---- src/Core/PathPlanningManager.cs | 2 +- src/Core/PathPointRenderPlugin.cs | 6 +- .../Properties/CategoryAttributeManager.cs | 4 +- src/PathPlanning/AutoPathFinder.cs | 2 +- src/PathPlanning/GridCellBuilder.cs | 2 +- src/PathPlanning/GridMap.cs | 10 +- src/PathPlanning/GridMapGenerator.cs | 4 +- .../WPF/ViewModels/ModelSettingsViewModel.cs | 14 ++- 10 files changed, 116 insertions(+), 92 deletions(-) diff --git a/resources/default_custom_categories.toml b/resources/default_custom_categories.toml index 9cb8ff0..6fd9379 100644 --- a/resources/default_custom_categories.toml +++ b/resources/default_custom_categories.toml @@ -2,76 +2,85 @@ # 位置: %ProgramData%/Autodesk/Navisworks Manage 2026/plugins/TransportPlugin/custom_categories.toml # 说明: 本文件定义用户自定义的物流类别,与模型文件无关,可跨项目共享 -# 类别属性说明: +# ============================================================ +# 类别属性说明 +# ============================================================ +# +# 【必填属性】 # id: 唯一标识(英文,用于存储和内部识别) +# - 不能与内置类别名称重复(如 door, elevator 等) +# - 建议使用小写和下划线,如: "ramp", "clean_room" +# # display_name: 显示名称(中文) -# icon: 图标标识(可选,默认 Box) -# traversable: 是否默认可通行(可选,默认 true) -# priority: 优先级 1-10(可选,默认 5) -# weight: 寻路权重(可选,默认 1.0,越低越优先) -# color: UI显示颜色(可选,默认 #9E9E9E) -# height_limit_meters: 默认高度限制米数(可选,默认 3.0) -# speed_limit_meters_per_second: 默认速度限制米/秒(可选,默认 1.0) -# width_limit_meters: 默认宽度限制米数(可选,默认 3.0) - -# 示例自定义类别(可根据需要添加更多) +# - 在UI类别下拉框和物流模型列表中显示 +# +# 【可选属性 - 有特殊需求时才设置】 +# traversable: 是否默认可通行 +# - 默认: true(可通行) +# - 仅当类别不可通行时设置为 false(如限制区域) +# +# weight: 寻路权重 +# - 默认: 1.0 +# - 值越小优先级越高,越大越难走 +# - 不可通行区域建议设为极大值如 999999.0 +# +# 【预留属性 - 当前未使用,可不设置】 +# icon: 图标标识(默认 Box) +# priority: 优先级 1-10(默认 5) +# color: UI显示颜色(默认 #9E9E9E) +# height_limit_meters: 默认高度限制米数(默认 3.0) +# speed_limit_meters_per_second: 默认速度限制米/秒(默认 1.0) +# width_limit_meters: 默认宽度限制米数(默认 3.0) +# +# ============================================================ +# 配置示例 +# ============================================================ +# -------------------------------------------------- +# 示例1: 最简配置(只有必填,其他用默认) +# -------------------------------------------------- +# 坡道:默认可通行(weight=1.0),无需设置其他属性 [[category]] id = "ramp" display_name = "坡道" -icon = "Ramp" -traversable = true -priority = 4 -weight = 1.5 -color = "#FF9800" -height_limit_meters = 3.0 -speed_limit_meters_per_second = 0.5 -width_limit_meters = 4.0 - -[[category]] -id = "tunnel" -display_name = "隧道" -icon = "Tunnel" -traversable = true -priority = 3 -weight = 1.8 -color = "#795548" -height_limit_meters = 2.5 -speed_limit_meters_per_second = 0.3 -width_limit_meters = 2.5 +# -------------------------------------------------- +# 示例2: 不可通行区域(必须设置特殊属性) +# -------------------------------------------------- +# 限制区域:不可通行,寻路时避开 [[category]] id = "restricted_area" display_name = "限制区域" -icon = "Warning" traversable = false -priority = 1 weight = 999999.0 -color = "#F44336" -height_limit_meters = 0.0 -speed_limit_meters_per_second = 0.0 -width_limit_meters = 0.0 +# -------------------------------------------------- +# 示例3: 优先选择的通道(设置更小weight) +# -------------------------------------------------- +# 快速通道:比默认值(1.0)优先,寻路时优先走这里 +[[category]] +id = "express_lane" +display_name = "快速通道" +weight = 0.6 + +# -------------------------------------------------- +# 示例4: 较难的通行区域(设置更大weight) +# -------------------------------------------------- +# 狭窄通道:比默认值难走,只有必要时才走 +[[category]] +id = "narrow_passage" +display_name = "狭窄通道" +weight = 2.5 + +# -------------------------------------------------- +# 示例5: 完整配置(展示所有可用属性) +# -------------------------------------------------- +# 一般不需要这么多,按需设置即可 [[category]] id = "temporary_storage" display_name = "临时堆放区" +# 可通行但较慢(weight > 1.0) +weight = 1.5 +# 预留属性(当前未使用) icon = "Package" -traversable = true -priority = 6 -weight = 1.2 color = "#FFC107" -height_limit_meters = 5.0 -speed_limit_meters_per_second = 0.8 -width_limit_meters = 5.0 - -[[category]] -id = "cleanroom" -display_name = "洁净室" -icon = "Shield" -traversable = true -priority = 2 -weight = 2.0 -color = "#E1F5FE" -height_limit_meters = 3.5 -speed_limit_meters_per_second = 0.4 -width_limit_meters = 3.0 diff --git a/src/Core/Config/CustomCategoryConfig.cs b/src/Core/Config/CustomCategoryConfig.cs index b7819e6..9919928 100644 --- a/src/Core/Config/CustomCategoryConfig.cs +++ b/src/Core/Config/CustomCategoryConfig.cs @@ -255,7 +255,7 @@ namespace NavisworksTransport.Core.Config } /// - /// 生成 TOML 内容 + /// 生成 TOML 内容(只输出非默认值的属性) /// private string GenerateTomlContent() { @@ -264,17 +264,21 @@ namespace NavisworksTransport.Core.Config sb.AppendLine("# 位置: %ProgramData%/Autodesk/Navisworks Manage 2026/plugins/TransportPlugin/custom_categories.toml"); sb.AppendLine("# 说明: 本文件定义用户自定义的物流类别,与模型文件无关,可跨项目共享"); sb.AppendLine(); - sb.AppendLine("# 类别属性说明:"); - sb.AppendLine("# id: 唯一标识(英文,用于存储和内部识别)"); + sb.AppendLine("# ============================================================"); + sb.AppendLine("# 类别属性说明"); + sb.AppendLine("# ============================================================"); + sb.AppendLine("#"); + sb.AppendLine("# 【必填】"); + sb.AppendLine("# id: 唯一标识(英文)"); sb.AppendLine("# display_name: 显示名称(中文)"); - sb.AppendLine("# icon: 图标标识(可选,默认 Box)"); - sb.AppendLine("# traversable: 是否默认可通行(可选,默认 true)"); - sb.AppendLine("# priority: 优先级 1-10(可选,默认 5)"); - sb.AppendLine("# weight: 寻路权重(可选,默认 1.0,越低越优先)"); - sb.AppendLine("# color: UI显示颜色(可选,默认 #9E9E9E)"); - sb.AppendLine("# height_limit_meters: 默认高度限制米数(可选,默认 3.0)"); - sb.AppendLine("# speed_limit_meters_per_second: 默认速度限制米/秒(可选,默认 1.0)"); - sb.AppendLine("# width_limit_meters: 默认宽度限制米数(可选,默认 3.0)"); + sb.AppendLine("#"); + sb.AppendLine("# 【可选 - 有特殊需求才设置】"); + sb.AppendLine("# traversable: 是否可通行(默认 true)"); + sb.AppendLine("# weight: 寻路权重(默认 1.0)"); + sb.AppendLine("#"); + sb.AppendLine("# 【预留 - 当前未使用】"); + sb.AppendLine("# icon, priority, color, height_limit_meters 等"); + sb.AppendLine("#"); sb.AppendLine(); foreach (var category in Categories) @@ -282,14 +286,13 @@ namespace NavisworksTransport.Core.Config sb.AppendLine("[[category]]"); sb.AppendLine($"id = \"{EscapeTomlString(category.Id)}\""); sb.AppendLine($"display_name = \"{EscapeTomlString(category.DisplayName)}\""); - sb.AppendLine($"icon = \"{EscapeTomlString(category.Icon)}\""); - sb.AppendLine($"traversable = {category.Traversable.ToString().ToLower()}"); - sb.AppendLine($"priority = {category.Priority}"); - sb.AppendLine($"weight = {category.Weight:F2}"); - sb.AppendLine($"color = \"{ColorToHex(category.DisplayColor)}\""); - sb.AppendLine($"height_limit_meters = {category.Defaults.HeightLimitMeters:F2}"); - sb.AppendLine($"speed_limit_meters_per_second = {category.Defaults.SpeedLimitMetersPerSecond:F2}"); - sb.AppendLine($"width_limit_meters = {category.Defaults.WidthLimitMeters:F2}"); + + // 只输出非默认值的属性 + if (category.Traversable != true) + sb.AppendLine($"traversable = {category.Traversable.ToString().ToLower()}"); + if (category.Weight != 1.0) + sb.AppendLine($"weight = {category.Weight:F2}"); + sb.AppendLine(); } @@ -437,7 +440,7 @@ namespace NavisworksTransport.Core.Config switch (type) { case CategoryAttributeManager.LogisticsElementType.障碍物: - case CategoryAttributeManager.LogisticsElementType.Unknown: + case CategoryAttributeManager.LogisticsElementType.空洞: case CategoryAttributeManager.LogisticsElementType.无关项: return false; default: @@ -477,7 +480,7 @@ namespace NavisworksTransport.Core.Config case CategoryAttributeManager.LogisticsElementType.电梯: return 2.0; case CategoryAttributeManager.LogisticsElementType.楼梯: return 3.0; case CategoryAttributeManager.LogisticsElementType.障碍物: - case CategoryAttributeManager.LogisticsElementType.Unknown: + case CategoryAttributeManager.LogisticsElementType.空洞: return double.MaxValue; default: return 1.0; } diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs index b10c6f0..44e7ad7 100644 --- a/src/Core/PathPlanningManager.cs +++ b/src/Core/PathPlanningManager.cs @@ -4693,7 +4693,7 @@ namespace NavisworksTransport } } } - else if (cell.CellType == "Unknown") + else if (cell.CellType == "空洞") { // Unknown网格没有高度层,用于调试 if (_showUnknownGrid) diff --git a/src/Core/PathPointRenderPlugin.cs b/src/Core/PathPointRenderPlugin.cs index 9f20d33..4f7986e 100644 --- a/src/Core/PathPointRenderPlugin.cs +++ b/src/Core/PathPointRenderPlugin.cs @@ -2032,7 +2032,7 @@ namespace NavisworksTransport if (isGridVisualization) { // 根据网格类型确定样式 - if (point.Name.Contains("空洞") || point.Name.Contains("Unknown")) + if (point.Name.Contains("空洞")) { gridStyle = GetRenderStyle(RenderStyleName.GridUnknown); } @@ -2048,9 +2048,9 @@ namespace NavisworksTransport else if (!string.IsNullOrEmpty(point.Notes) && point.Notes.StartsWith("GridType:")) { var gridTypeStr = point.Notes.Substring(9); // 去掉"GridType:"前缀 - if (gridTypeStr == "Unknown") + if (gridTypeStr == "空洞") gridStyle = GetRenderStyle(RenderStyleName.GridUnknown); - else if (gridTypeStr == "Obstacle") + else if (gridTypeStr == "障碍物") gridStyle = GetRenderStyle(RenderStyleName.GridObstacle); else gridStyle = GetRenderStyle(RenderStyleName.GridChannel); diff --git a/src/Core/Properties/CategoryAttributeManager.cs b/src/Core/Properties/CategoryAttributeManager.cs index 267bbea..82fb1f2 100644 --- a/src/Core/Properties/CategoryAttributeManager.cs +++ b/src/Core/Properties/CategoryAttributeManager.cs @@ -41,9 +41,9 @@ namespace NavisworksTransport public enum LogisticsElementType { /// - /// 未知/空洞 - 没有任何几何覆盖,不可通行(默认值) + /// 空洞 - 没有任何几何覆盖,不可通行(默认值) /// - Unknown = 0, + 空洞 = 0, /// /// 障碍物 - 墙体、柱子、设备等,不可通行 diff --git a/src/PathPlanning/AutoPathFinder.cs b/src/PathPlanning/AutoPathFinder.cs index 26087b6..d21cf5a 100644 --- a/src/PathPlanning/AutoPathFinder.cs +++ b/src/PathPlanning/AutoPathFinder.cs @@ -2916,7 +2916,7 @@ namespace NavisworksTransport.PathPlanning // 统计网格类型 if (cell.CellType == "障碍物") obstacleCount++; - else if (cell.CellType == "Unknown") + else if (cell.CellType == "空洞") unknownCount++; else if (cell.HasAnyWalkableLayer()) walkableCount++; diff --git a/src/PathPlanning/GridCellBuilder.cs b/src/PathPlanning/GridCellBuilder.cs index 0b3e5f4..d2a72fb 100644 --- a/src/PathPlanning/GridCellBuilder.cs +++ b/src/PathPlanning/GridCellBuilder.cs @@ -125,7 +125,7 @@ namespace NavisworksTransport.PathPlanning { return new GridCell { - CellType = "Unknown", + CellType = "空洞", IsInChannel = false, ChannelType = ChannelType.Other, RelatedModelItem = null, diff --git a/src/PathPlanning/GridMap.cs b/src/PathPlanning/GridMap.cs index a0ab9c0..458f317 100644 --- a/src/PathPlanning/GridMap.cs +++ b/src/PathPlanning/GridMap.cs @@ -166,7 +166,7 @@ namespace NavisworksTransport.PathPlanning { var cell = new GridCell { - CellType = CategoryAttributeManager.LogisticsElementType.Unknown.ToString(), // 修改:默认为未知/空洞类型 + CellType = CategoryAttributeManager.LogisticsElementType.空洞.ToString(), // 修改:默认为未知/空洞类型 IsInChannel = false, HeightLayers = new List(), ChannelType = ChannelType.Other @@ -393,7 +393,7 @@ namespace NavisworksTransport.PathPlanning private void ApplyCellValidationRules(ref GridCell cell, double originalCost) { // 🔥 关键验证:确保Unknown和障碍物类型永远不可通行 - if (cell.CellType == "Unknown" || + if (cell.CellType == "空洞" || cell.CellType == "障碍物") { // Unknown和障碍物没有可通行层,HasAnyWalkableLayer()自动返回false @@ -613,7 +613,7 @@ namespace NavisworksTransport.PathPlanning int walkable_Other = 0; // 按类型统计 - 不可通行的 - int nonWalkable_Unknown = 0; + int nonWalkable_空洞 = 0; int nonWalkable_障碍物 = 0; int nonWalkable_楼板 = 0; int nonWalkable_门 = 0; @@ -644,7 +644,7 @@ namespace NavisworksTransport.PathPlanning { totalNonWalkable++; // 使用字符串比较(支持自定义类别) - if (cell.CellType == "Unknown") nonWalkable_Unknown++; + if (cell.CellType == "空洞") nonWalkable_空洞++; else if (cell.CellType == "障碍物") nonWalkable_障碍物++; else if (cell.CellType == "楼板") nonWalkable_楼板++; else if (cell.CellType == "门") nonWalkable_门++; @@ -664,7 +664,7 @@ namespace NavisworksTransport.PathPlanning stats += $" 楼梯: {walkable_楼梯}, 电梯: {walkable_电梯}, 其他: {walkable_Other}\n"; stats += $"【不可通行单元格详细统计】\n"; - stats += $" Unknown/空洞: {nonWalkable_Unknown}, 障碍物: {nonWalkable_障碍物}\n"; + stats += $" 空洞: {nonWalkable_空洞}, 障碍物: {nonWalkable_障碍物}\n"; stats += $" 不可通行楼板: {nonWalkable_楼板}, 不可通行门: {nonWalkable_门}\n"; stats += $" 不可通行通道: {nonWalkable_通道}, 其他不可通行: {nonWalkable_Other}\n"; diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs index 284b2f9..934c945 100644 --- a/src/PathPlanning/GridMapGenerator.cs +++ b/src/PathPlanning/GridMapGenerator.cs @@ -492,7 +492,7 @@ namespace NavisworksTransport.PathPlanning int neighborLayerCount = (neighbor.HeightLayers != null) ? neighbor.HeightLayers.Count : 0; // 情况2:邻居是Unknown - 标记当前网格所有层为边界 - if (neighbor.CellType == "Unknown") + if (neighbor.CellType == "空洞") { for (int li = 0; li < currentLayerCount; li++) { @@ -986,7 +986,7 @@ namespace NavisworksTransport.PathPlanning distanceMap[x, y] = double.MaxValue; // Unknown网格 → distance=0(整个网格无法通行) - if (cell.CellType == "Unknown") + if (cell.CellType == "空洞") { distanceMap[x, y] = 0.0; continue; diff --git a/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs b/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs index 7386f59..a5a165e 100644 --- a/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs +++ b/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs @@ -875,10 +875,22 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 直接使用 CategoryAttributeManager 的 API var info = CategoryAttributeManager.GetLogisticsAttributeInfo(item); + // 将类别ID转换为显示名称 + string categoryId = info?.ElementType ?? "未分类"; + string displayName = categoryId; + if (categoryId != "未分类") + { + var categoryDef = CategoryAttributeManager.GetCategoryDefinition(categoryId); + if (categoryDef != null) + { + displayName = categoryDef.DisplayName; + } + } + var model = new LogisticsModel { Name = item.DisplayName ?? "未命名模型", - Category = info?.ElementType ?? "未分类", + Category = displayName, Attributes = FormatLogisticsAttributes(info), IsVisible = !item.IsHidden, NavisworksItem = item