diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 92707e1..d4dc197 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -160,7 +160,8 @@
"Bash(where:*)",
"Read(//c/Users/Tellme/Pictures/Screenshots/**)",
"Bash(./deploy-plugin.bat)",
- "Read(//c/Users/Tellme/**)"
+ "Read(//c/Users/Tellme/**)",
+ "Bash(git push:*)"
],
"deny": [],
"additionalDirectories": [
diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj
index d2779bd..827997b 100644
--- a/NavisworksTransportPlugin.csproj
+++ b/NavisworksTransportPlugin.csproj
@@ -161,6 +161,7 @@
+
diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md
index 081d75c..18f3003 100644
--- a/doc/requirement/todo_features.md
+++ b/doc/requirement/todo_features.md
@@ -2,6 +2,10 @@
## 功能点
+### [2025/10/12]
+
+1. [x] (实验性功能)用体素网格实现3D路径规划
+
### [2025/10/11]
1. [x] (功能)实现系统配置管理,采用toml格式保存配置文件
diff --git a/src/Commands/VoxelGridTestCommand.cs b/src/Commands/VoxelGridTestCommand.cs
new file mode 100644
index 0000000..4dc9be9
--- /dev/null
+++ b/src/Commands/VoxelGridTestCommand.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Autodesk.Navisworks.Api;
+using NavisworksTransport.Core;
+using NavisworksTransport.PathPlanning;
+using NavisworksTransport.Utils;
+
+namespace NavisworksTransport.Commands
+{
+ ///
+ /// 体素网格测试命令
+ /// 用于测试体素网格的创建和可视化功能
+ ///
+ public class VoxelGridTestCommand : CommandBase
+ {
+ private readonly Document _document;
+ private readonly double _cellSize;
+ private readonly int _samplingRate;
+
+ public VoxelGridTestCommand(Document document, double cellSize = 0.5, int samplingRate = 2)
+ : base("VoxelGridTest", "体素网格测试", "测试体素网格的创建和可视化")
+ {
+ _document = document ?? throw new ArgumentNullException(nameof(document));
+ _cellSize = cellSize;
+ _samplingRate = samplingRate;
+ }
+
+ protected override PathPlanningResult ValidateParameters()
+ {
+ if (_document == null)
+ {
+ return PathPlanningResult.ValidationFailure("Navisworks 文档对象为空");
+ }
+
+ if (_document.CurrentSelection.SelectedItems.Count == 0)
+ {
+ return PathPlanningResult.ValidationFailure("请至少选择一个模型对象进行体素化测试");
+ }
+
+ if (_cellSize <= 0)
+ {
+ return PathPlanningResult.ValidationFailure("体素大小必须大于0");
+ }
+
+ return PathPlanningResult.Success("参数验证通过");
+ }
+
+ protected override async Task ExecuteInternalAsync(CancellationToken cancellationToken)
+ {
+ try
+ {
+ LogInfo("开始体素网格测试");
+ UpdateProgress(10, "正在提取选中对象的几何信息...");
+
+ // 1. 获取选中对象的包围盒
+ var selectedItems = _document.CurrentSelection.SelectedItems.ToList();
+ LogInfo($"选中了 {selectedItems.Count} 个对象");
+
+ // 计算总包围盒
+ BoundingBox3D totalBounds = null;
+ foreach (var item in selectedItems)
+ {
+ if (item.HasGeometry)
+ {
+ var itemBounds = item.BoundingBox();
+ if (totalBounds == null)
+ {
+ totalBounds = itemBounds;
+ }
+ else
+ {
+ // 扩展包围盒
+ var min = new Point3D(
+ Math.Min(totalBounds.Min.X, itemBounds.Min.X),
+ Math.Min(totalBounds.Min.Y, itemBounds.Min.Y),
+ Math.Min(totalBounds.Min.Z, itemBounds.Min.Z)
+ );
+ var max = new Point3D(
+ Math.Max(totalBounds.Max.X, itemBounds.Max.X),
+ Math.Max(totalBounds.Max.Y, itemBounds.Max.Y),
+ Math.Max(totalBounds.Max.Z, itemBounds.Max.Z)
+ );
+ totalBounds = new BoundingBox3D(min, max);
+ }
+ }
+ }
+
+ if (totalBounds == null)
+ {
+ return PathPlanningResult.Failure("选中对象没有有效的几何信息");
+ }
+
+ LogInfo($"总包围盒: Min={totalBounds.Min}, Max={totalBounds.Max}");
+
+ UpdateProgress(30, "正在创建体素网格...");
+
+ // 2. 创建体素网格
+ var voxelGrid = new VoxelGrid(totalBounds, _cellSize);
+ LogInfo($"创建了体素网格: {voxelGrid.SizeX}x{voxelGrid.SizeY}x{voxelGrid.SizeZ} = {voxelGrid.TotalVoxels} 个体素");
+
+ // 检查体素数量是否过大
+ if (voxelGrid.TotalVoxels > 1000000)
+ {
+ LogWarning($"体素数量过多 ({voxelGrid.TotalVoxels}),建议增大 cellSize 或减小选择范围");
+ return PathPlanningResult.Failure($"体素数量过多 ({voxelGrid.TotalVoxels}),请增大体素大小或减小选择范围");
+ }
+
+ UpdateProgress(50, "正在提取三角网格...");
+
+ // 3. 提取三角网格(用于后续 SDF 计算)
+ var triangles = new List();
+ foreach (var item in selectedItems)
+ {
+ if (item.HasGeometry)
+ {
+ var itemTriangles = GeometryHelper.ExtractTriangles(item);
+ triangles.AddRange(itemTriangles);
+ LogInfo($"从 {item.DisplayName} 提取了 {itemTriangles.Count} 个三角形");
+ }
+ }
+
+ LogInfo($"总共提取了 {triangles.Count} 个三角形");
+
+ UpdateProgress(70, "正在初始化体素类型(简单版本)...");
+
+ // 4. 简单的体素分类(先不使用 SDF,只是示例)
+ // 这里我们将包围盒内的体素都标记为 Free,边界标记为 Obstacle
+ for (int x = 0; x < voxelGrid.SizeX; x++)
+ {
+ for (int y = 0; y < voxelGrid.SizeY; y++)
+ {
+ for (int z = 0; z < voxelGrid.SizeZ; z++)
+ {
+ // 边界体素标记为障碍物
+ if (x == 0 || x == voxelGrid.SizeX - 1 ||
+ y == 0 || y == voxelGrid.SizeY - 1 ||
+ z == 0 || z == voxelGrid.SizeZ - 1)
+ {
+ var cell = voxelGrid.GetCell(x, y, z);
+ cell.SetAsObstacle();
+ }
+ else
+ {
+ // 内部体素标记为自由空间
+ var cell = voxelGrid.GetCell(x, y, z);
+ cell.SetAsFreeSpace();
+ }
+ }
+ }
+ }
+
+ var (total, passable, obstacle) = voxelGrid.GetStatistics();
+ LogInfo($"体素统计: Total={total}, Passable={passable}, Obstacle={obstacle}");
+
+ UpdateProgress(85, "正在生成可视化数据...");
+
+ // 5. 生成可视化
+ var voxelPoints = VoxelGridVisualizer.VisualizeAsPoints(
+ voxelGrid,
+ samplingRate: _samplingRate,
+ showPassableOnly: false
+ );
+
+ LogInfo($"生成了 {voxelPoints.Count} 个可视化点(采样率: {_samplingRate})");
+
+ // 6. 转换为 PathRoute 以便使用现有渲染系统
+ var visualRoute = VoxelGridVisualizer.ConvertToPathRoute(
+ voxelPoints,
+ $"VoxelGrid_Test_{DateTime.Now:HHmmss}"
+ );
+
+ // 7. 添加到渲染系统(假设有全局的路径管理器)
+ // 注意:这里需要你根据实际情况调整,可能需要通过 PathDataManager 来管理
+ LogInfo($"可视化路径已创建: {visualRoute.Name}");
+ LogInfo("提示:体素点已转换为 PathRoute,可以通过现有的 PathPointRenderPlugin 进行渲染");
+ LogInfo("提示:你需要刷新视图或触发渲染更新才能看到效果");
+
+ // 8. 生成文本报告
+ var report = VoxelGridVisualizer.GenerateVisualizationReport(voxelGrid);
+ LogInfo("=== 体素网格报告 ===");
+ LogInfo(report);
+
+ UpdateProgress(100, "体素网格测试完成");
+
+ return PathPlanningResult.Success($"体素网格测试完成\n\n{report}");
+ }
+ catch (Exception ex)
+ {
+ LogError($"体素网格测试失败: {ex.Message}", ex);
+ return PathPlanningResult.Failure($"体素网格测试失败: {ex.Message}", ex);
+ }
+ }
+ }
+}
diff --git a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
index 3519f1c..13d1b32 100644
--- a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
+++ b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
@@ -226,6 +226,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public ICommand GeneratePerformanceReportCommand { get; private set; }
public ICommand DiagnosticCommand { get; private set; }
+ // 功能测试命令
+ public ICommand TestVoxelGridCommand { get; private set; }
+
#endregion
#region 构造函数
@@ -325,6 +328,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
GeneratePerformanceReportCommand = new RelayCommand(() => ExecuteGeneratePerformanceReport());
DiagnosticCommand = new RelayCommand(() => ExecuteDiagnostic());
+ // 功能测试命令
+ TestVoxelGridCommand = new RelayCommand(() => ExecuteTestVoxelGrid());
+
LogManager.Info("系统管理命令初始化完成");
}
catch (Exception ex)
@@ -780,13 +786,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
var report = new System.Text.StringBuilder();
report.AppendLine("=== Navisworks API环境诊断报告 ===");
-
+
try
{
// 1. 线程状态
var apartmentState = System.Threading.Thread.CurrentThread.GetApartmentState();
report.AppendLine($"线程状态: {apartmentState} {(apartmentState == System.Threading.ApartmentState.STA ? "✓" : "✗")}");
-
+
// 2. API可用性
try
{
@@ -797,7 +803,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
report.AppendLine($"API可用性: 异常 - {apiEx.Message} ✗");
}
-
+
// 3. 文档状态
try
{
@@ -816,18 +822,18 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
report.AppendLine($"活动文档: 异常 - {docEx.Message} ✗");
}
-
+
// 4. 内存状态
long memoryMB = GC.GetTotalMemory(false) / 1024 / 1024;
report.AppendLine($"当前内存: {memoryMB} MB");
-
+
// 5. 系统信息
report.AppendLine($"插件版本: {PluginVersion}");
report.AppendLine($"Navisworks版本: {NavisworksVersion}");
report.AppendLine("系统状态: 正常");
-
+
report.AppendLine("=== 诊断完成 ===");
-
+
string result = report.ToString();
LogManager.Info($"[SystemManagement] 环境诊断报告:\n{result}");
return result;
@@ -841,6 +847,89 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
+ ///
+ /// 执行体素网格测试
+ ///
+ private async void ExecuteTestVoxelGrid()
+ {
+ await SafeExecuteAsync(async () =>
+ {
+ try
+ {
+ UpdateMainStatus("正在执行体素网格测试...");
+ LogManager.Info("开始体素网格测试");
+
+ // 获取当前文档
+ var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
+ if (document == null)
+ {
+ System.Windows.MessageBox.Show(
+ "未找到活动文档,请先打开一个 Navisworks 模型",
+ "体素网格测试",
+ System.Windows.MessageBoxButton.OK,
+ System.Windows.MessageBoxImage.Warning);
+ UpdateMainStatus("体素网格测试取消:无活动文档");
+ return;
+ }
+
+ // 检查是否有选中对象
+ if (document.CurrentSelection.SelectedItems.Count == 0)
+ {
+ System.Windows.MessageBox.Show(
+ "请先在模型中选择一个或多个对象进行体素化测试",
+ "体素网格测试",
+ System.Windows.MessageBoxButton.OK,
+ System.Windows.MessageBoxImage.Information);
+ UpdateMainStatus("体素网格测试取消:未选中对象");
+ return;
+ }
+
+ // 创建并执行体素网格测试命令
+ var testCommand = new VoxelGridTestCommand(
+ document,
+ cellSize: 0.5, // 体素大小 0.5 米
+ samplingRate: 2 // 采样率 2(显示 1/2 的体素)
+ );
+
+ var result = await testCommand.ExecuteAsync();
+
+ if (result.IsSuccess)
+ {
+ // 显示测试结果(简化版,不依赖Data属性)
+ System.Windows.MessageBox.Show(
+ $"体素网格测试成功!\n\n{result.Message}\n\n详细信息请查看日志。",
+ "体素网格测试结果",
+ System.Windows.MessageBoxButton.OK,
+ System.Windows.MessageBoxImage.Information);
+
+ UpdateMainStatus("体素网格测试完成");
+ LogManager.Info($"体素网格测试成功: {result.Message}");
+ }
+ else
+ {
+ System.Windows.MessageBox.Show(
+ $"体素网格测试失败:\n{result.Message}",
+ "体素网格测试",
+ System.Windows.MessageBoxButton.OK,
+ System.Windows.MessageBoxImage.Error);
+
+ UpdateMainStatus($"体素网格测试失败: {result.Message}");
+ LogManager.Error($"体素网格测试失败: {result.Message}");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error($"体素网格测试异常: {ex.Message}", ex);
+ System.Windows.MessageBox.Show(
+ $"体素网格测试出现异常:\n{ex.Message}",
+ "错误",
+ System.Windows.MessageBoxButton.OK,
+ System.Windows.MessageBoxImage.Error);
+ UpdateMainStatus($"体素网格测试异常: {ex.Message}");
+ }
+ }, "体素网格测试");
+ }
+
#endregion
#region 辅助方法
diff --git a/src/UI/WPF/Views/SystemManagementView.xaml b/src/UI/WPF/Views/SystemManagementView.xaml
index 94c3f0d..bd31d88 100644
--- a/src/UI/WPF/Views/SystemManagementView.xaml
+++ b/src/UI/WPF/Views/SystemManagementView.xaml
@@ -201,23 +201,53 @@ NavisworksTransport 系统管理页签视图 - 采用与其他页签一致的Nav
-
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file