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