对代码进行审查并优化
This commit is contained in:
parent
2fb883ae18
commit
178aa995ff
115
AGENTS.md
115
AGENTS.md
@ -217,6 +217,121 @@ using NavisworksTransport.Utils;
|
|||||||
| 常量 | PascalCase | `MaxHeightDiff` |
|
| 常量 | PascalCase | `MaxHeightDiff` |
|
||||||
| 枚举 | PascalCase | `GridGenerationMode` |
|
| 枚举 | PascalCase | `GridGenerationMode` |
|
||||||
|
|
||||||
|
### 代码开发原则
|
||||||
|
|
||||||
|
#### 1. 禁止硬编码默认值
|
||||||
|
|
||||||
|
函数的参数和初始化时不要使用硬编码的默认值,应从配置读取或使用命名常量:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ❌ 错误:硬编码默认值
|
||||||
|
public GridMap Generate(double cellSize = 0.5) { }
|
||||||
|
|
||||||
|
// ❌ 错误:构造函数中硬编码
|
||||||
|
public PathPlanner() {
|
||||||
|
_cellSize = 0.5;
|
||||||
|
_maxSlope = 15.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 正确:从配置读取
|
||||||
|
public GridMap Generate(double cellSize) {
|
||||||
|
cellSize = cellSize > 0 ? cellSize : ConfigManager.Instance.Current.PathEditing.CellSizeMeters;
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 正确:使用命名常量
|
||||||
|
private const double DEFAULT_CELL_SIZE_METERS = 0.5;
|
||||||
|
public PathPlanner(double cellSize = DEFAULT_CELL_SIZE_METERS) { }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 不向后兼容
|
||||||
|
|
||||||
|
本项目专门针对 Navisworks 2026 开发,**程序中不要写向后兼容代码**:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ❌ 错误:向后兼容代码
|
||||||
|
#if NAVISWORKS_2025
|
||||||
|
// 2025 specific code
|
||||||
|
#elif NAVISWORKS_2026
|
||||||
|
// 2026 specific code
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ❌ 错误:运行时版本检查
|
||||||
|
if (NavisworksVersion.Major < 2026) {
|
||||||
|
// 兼容旧版本的代码
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 正确:直接针对2026编写
|
||||||
|
var clashResult = Autodesk.Navisworks.Api.Clash.ClashResult.GetAllResults();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. 不随意加回退逻辑
|
||||||
|
|
||||||
|
程序中不要随意加回退逻辑,避免过度防御性编程导致隐藏问题:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ❌ 错误:过度回退逻辑
|
||||||
|
public double GetCellSize() {
|
||||||
|
try {
|
||||||
|
return ConfigManager.Instance.Current.PathEditing.CellSizeMeters;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return 0.5; // 隐藏了配置读取失败的问题!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ 错误:静默回退
|
||||||
|
double value = GetConfigValue("cellSize");
|
||||||
|
if (value <= 0) value = 0.5; // 为什么<=0?配置验证应该保证这一点
|
||||||
|
|
||||||
|
// ✅ 正确:让问题暴露出来
|
||||||
|
public double GetCellSize() {
|
||||||
|
return ConfigManager.Instance.Current.PathEditing.CellSizeMeters;
|
||||||
|
// 如果配置有问题,让它抛出异常,在源头解决
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. 代码复用优先
|
||||||
|
|
||||||
|
规划和编写新功能或新模块时,**尽量复用项目中的代码,尤其是工具和辅助类**:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ❌ 错误:重复造轮子
|
||||||
|
public static double MyConvertUnits(double value) {
|
||||||
|
// 自己写一套单位转换逻辑...
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 正确:复用现有的 UnitsConverter
|
||||||
|
using NavisworksTransport.Utils;
|
||||||
|
double meters = UnitsConverter.ConvertToMeters(distance);
|
||||||
|
|
||||||
|
// ❌ 错误:自己实现集合通知
|
||||||
|
public class MyCollection : ObservableCollection<T> {
|
||||||
|
// 重写一大堆线程安全代码...
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 正确:复用 ThreadSafeObservableCollection
|
||||||
|
using NavisworksTransport.UI.WPF.Collections;
|
||||||
|
var collection = new ThreadSafeObservableCollection<Item>();
|
||||||
|
|
||||||
|
// ❌ 错误:自己写几何计算
|
||||||
|
public double Distance(Point3D a, Point3D b) {
|
||||||
|
return Math.Sqrt(Math.Pow(a.X - b.X, 2) + ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 正确:复用 GeometryHelper
|
||||||
|
using NavisworksTransport.Utils;
|
||||||
|
double distance = GeometryHelper.Distance(pointA, pointB);
|
||||||
|
```
|
||||||
|
|
||||||
|
**复用检查清单:**
|
||||||
|
- 需要单位转换?→ 使用 `UnitsConverter`
|
||||||
|
- 需要几何计算?→ 使用 `GeometryHelper`
|
||||||
|
- 需要日志记录?→ 使用 `LogManager`
|
||||||
|
- 需要线程安全的集合?→ 使用 `ThreadSafeObservableCollection`
|
||||||
|
- 需要坐标转换?→ 使用 `CoordinateConverter`
|
||||||
|
- 需要路径相关工具?→ 使用 `PathHelper`
|
||||||
|
|
||||||
### 单位系统 - 极其重要
|
### 单位系统 - 极其重要
|
||||||
|
|
||||||
**所有网格地图和路径规划计算必须使用模型单位,严禁混用米制单位。**
|
**所有网格地图和路径规划计算必须使用模型单位,严禁混用米制单位。**
|
||||||
|
|||||||
@ -628,7 +628,10 @@ namespace NavisworksTransport
|
|||||||
var pathId = doc.Models.CreatePathId(precomputed.Item2);
|
var pathId = doc.Models.CreatePathId(precomputed.Item2);
|
||||||
precomputedPathIds.Add((pathId.ModelIndex, pathId.PathId));
|
precomputedPathIds.Add((pathId.ModelIndex, pathId.PathId));
|
||||||
}
|
}
|
||||||
catch { /* 忽略获取PathId失败的记录 */ }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Warning($"[PathId匹配] 获取PathId失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -898,6 +898,29 @@ namespace NavisworksTransport.Core.Config
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 float 配置值(带默认值,不抛出异常)
|
||||||
|
/// </summary>
|
||||||
|
private float GetFloatValueWithDefault(TomlTable table, string key, float defaultValue, List<string> missingItems)
|
||||||
|
{
|
||||||
|
if (!table.ContainsKey(key))
|
||||||
|
{
|
||||||
|
missingItems.Add($"{key}");
|
||||||
|
LogManager.Debug($"配置项 '{key}' 不存在,使用默认值: {defaultValue}");
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = table[key];
|
||||||
|
if (value is long longValue)
|
||||||
|
return (float)longValue;
|
||||||
|
if (value is double doubleValue)
|
||||||
|
return (float)doubleValue;
|
||||||
|
|
||||||
|
missingItems.Add($"{key} (类型错误)");
|
||||||
|
LogManager.Warning($"配置项 '{key}' 类型错误,使用默认值: {defaultValue}");
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取 int 配置值(带默认值,不抛出异常)
|
/// 获取 int 配置值(带默认值,不抛出异常)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -200,7 +200,12 @@ namespace NavisworksTransport.Core.Database
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// 重新打开连接
|
// 重新打开连接
|
||||||
try { _database.Connection.Open(); } catch { }
|
try { _database.Connection.Open(); }
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[数据库恢复] 重新打开连接失败: {ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogManager.Info($"数据库恢复完成: {backupFilePath}");
|
LogManager.Info($"数据库恢复完成: {backupFilePath}");
|
||||||
|
|||||||
@ -237,7 +237,10 @@ namespace NavisworksTransport.Core
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[楼层管理器] 检查类别失败: {ex.Message}");
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1216,7 +1216,10 @@ namespace NavisworksTransport
|
|||||||
fileSizeInfo = $" ({sizeMB:F1}MB)";
|
fileSizeInfo = $" ({sizeMB:F1}MB)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[分层管理器] 获取文件大小失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
// 更新状态:导出成功
|
// 更新状态:导出成功
|
||||||
string successProgressInfo = (currentIndex > 0 && totalCount > 0) ? $" ({currentIndex}/{totalCount})" : "";
|
string successProgressInfo = (currentIndex > 0 && totalCount > 0) ? $" ({currentIndex}/{totalCount})" : "";
|
||||||
|
|||||||
@ -1015,7 +1015,10 @@ namespace NavisworksTransport
|
|||||||
{
|
{
|
||||||
ExecuteNonQuery("DELETE FROM sqlite_sequence");
|
ExecuteNonQuery("DELETE FROM sqlite_sequence");
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[数据库] 重置自增ID失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
LogManager.Info("已清空所有数据表");
|
LogManager.Info("已清空所有数据表");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1463,7 +1463,10 @@ namespace NavisworksTransport
|
|||||||
// 这里可以添加更详细的属性读取逻辑
|
// 这里可以添加更详细的属性读取逻辑
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[通道列表] 获取物流属性失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
// 获取尺寸信息
|
// 获取尺寸信息
|
||||||
double length = 0, width = 0, height = 0;
|
double length = 0, width = 0, height = 0;
|
||||||
@ -1477,7 +1480,10 @@ namespace NavisworksTransport
|
|||||||
height = Math.Abs(boundingBox.Max.Z - boundingBox.Min.Z);
|
height = Math.Abs(boundingBox.Max.Z - boundingBox.Min.Z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[通道列表] 获取包围盒失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
// 添加子项
|
// 添加子项
|
||||||
item.SubItems.Add(channelType);
|
item.SubItems.Add(channelType);
|
||||||
@ -1601,7 +1607,10 @@ namespace NavisworksTransport
|
|||||||
{
|
{
|
||||||
ModelHighlightHelper.ClearCategory(ChannelPreviewHighlightCategory);
|
ModelHighlightHelper.ClearCategory(ChannelPreviewHighlightCategory);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[通道预览] 清除高亮失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -2456,7 +2465,10 @@ namespace NavisworksTransport
|
|||||||
if (content.StartsWith("{") && content.EndsWith("}"))
|
if (content.StartsWith("{") && content.EndsWith("}"))
|
||||||
return "JSON";
|
return "JSON";
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[路径格式检测] 读取文件失败: {ex.Message}");
|
||||||
|
}
|
||||||
return "未知";
|
return "未知";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,31 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AutoPathFinder
|
public class AutoPathFinder
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 缓坡速度系数 - 当坡度在 3cm 到 25cm 之间时使用
|
||||||
|
/// </summary>
|
||||||
|
private const float SLOPE_SPEED_FACTOR_GENTLE = 0.8f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 楼梯速度系数 - 当坡度在 25cm 到 50cm 之间时使用
|
||||||
|
/// </summary>
|
||||||
|
private const float SLOPE_SPEED_FACTOR_STAIR = 0.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 陡坡速度系数 - 当坡度超过 50cm 时使用
|
||||||
|
/// </summary>
|
||||||
|
private const float SLOPE_SPEED_FACTOR_STEEP = 0.1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A*高度惩罚因子 - 用于计算距离目标高度的速度扣减
|
||||||
|
/// </summary>
|
||||||
|
private const double HEIGHT_PENALTY_FACTOR = 0.1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转弯角度阈值(弧度)- 用于检测路径转弯
|
||||||
|
/// </summary>
|
||||||
|
private const double TURN_ANGLE_THRESHOLD_RADIANS = 0.1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取水平边连接允许的最大高度差(米)
|
/// 获取水平边连接允许的最大高度差(米)
|
||||||
/// 从配置文件读取,足以支持台阶连接(约0.15米)和地面到楼梯底部的连接(约0.3米)
|
/// 从配置文件读取,足以支持台阶连接(约0.15米)和地面到楼梯底部的连接(约0.3米)
|
||||||
@ -382,9 +407,9 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
double heightRatio = heightDiff / maxHeightDiff;
|
double heightRatio = heightDiff / maxHeightDiff;
|
||||||
|
|
||||||
if (heightRatio < 0.06) return (float)baseSpeed; // 平地 (<3cm,即<0.06*0.5m)
|
if (heightRatio < 0.06) return (float)baseSpeed; // 平地 (<3cm,即<0.06*0.5m)
|
||||||
if (heightRatio <= 0.5) return (float)(baseSpeed * 0.8); // 缓坡 (≤0.25m)
|
if (heightRatio <= 0.5) return (float)(baseSpeed * SLOPE_SPEED_FACTOR_GENTLE); // 缓坡 (≤0.25m)
|
||||||
if (heightRatio <= 1.0) return (float)(baseSpeed * 0.5); // 楼梯 (≤0.5m)
|
if (heightRatio <= 1.0) return (float)(baseSpeed * SLOPE_SPEED_FACTOR_STAIR); // 楼梯 (≤0.5m)
|
||||||
return (float)(baseSpeed * 0.1); // 过陡 (>0.5m)
|
return (float)(baseSpeed * SLOPE_SPEED_FACTOR_STEEP); // 过陡 (>0.5m)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1404,8 +1429,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
// 距离目标高度越近,速度越快(A*成本越低)
|
// 距离目标高度越近,速度越快(A*成本越低)
|
||||||
// 公式:速度 = 1 / (1 + 距离 * 惩罚系数)
|
// 公式:速度 = 1 / (1 + 距离 * 惩罚系数)
|
||||||
// 例如:距离0m → 速度1.0x, 距离3m → 速度0.77x, 距离6m → 速度0.625x
|
// 例如:距离0m → 速度1.0x, 距离3m → 速度0.77x, 距离6m → 速度0.625x
|
||||||
const double penaltyFactor = 0.1;
|
return (float)(1.0 / (1.0 + distanceToTarget * HEIGHT_PENALTY_FACTOR));
|
||||||
return (float)(1.0 / (1.0 + distanceToTarget * penaltyFactor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1962,7 +1986,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int turns = 0;
|
int turns = 0;
|
||||||
const double angleThreshold = 0.1; // 弧度
|
const double angleThreshold = TURN_ANGLE_THRESHOLD_RADIANS; // 弧度
|
||||||
|
|
||||||
for (int i = 1; i < path.Count - 1; i++)
|
for (int i = 1; i < path.Count - 1; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,6 +14,11 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ChannelHeightDetector
|
public class ChannelHeightDetector
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认射线投射容差(米)- 与配置中的安全间隙一致
|
||||||
|
/// </summary>
|
||||||
|
private const double DEFAULT_RAYCAST_TOLERANCE_METERS = 0.1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前使用的坐标系
|
/// 当前使用的坐标系
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -25,7 +30,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// 构造函数(自动使用当前坐标系)
|
/// 构造函数(自动使用当前坐标系)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="raycastTolerance">射线投射容差(米)</param>
|
/// <param name="raycastTolerance">射线投射容差(米)</param>
|
||||||
public ChannelHeightDetector(double raycastTolerance = 0.1)
|
public ChannelHeightDetector(double raycastTolerance = DEFAULT_RAYCAST_TOLERANCE_METERS)
|
||||||
: this(CoordinateSystemManager.Instance.Current, raycastTolerance)
|
: this(CoordinateSystemManager.Instance.Current, raycastTolerance)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -35,7 +40,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="coordinateSystem">坐标系</param>
|
/// <param name="coordinateSystem">坐标系</param>
|
||||||
/// <param name="raycastTolerance">射线投射容差(米)</param>
|
/// <param name="raycastTolerance">射线投射容差(米)</param>
|
||||||
public ChannelHeightDetector(ICoordinateSystem coordinateSystem, double raycastTolerance = 0.1)
|
public ChannelHeightDetector(ICoordinateSystem coordinateSystem, double raycastTolerance = DEFAULT_RAYCAST_TOLERANCE_METERS)
|
||||||
{
|
{
|
||||||
_coordinateSystem = coordinateSystem ?? throw new ArgumentNullException(nameof(coordinateSystem));
|
_coordinateSystem = coordinateSystem ?? throw new ArgumentNullException(nameof(coordinateSystem));
|
||||||
_heightCache = new Dictionary<string, ChannelHeightInfo>();
|
_heightCache = new Dictionary<string, ChannelHeightInfo>();
|
||||||
|
|||||||
@ -13,6 +13,11 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GridMap
|
public class GridMap
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认高度层查找容差(米)- 与配置中的安全间隙一致
|
||||||
|
/// </summary>
|
||||||
|
private const double DEFAULT_LAYER_TOLERANCE_METERS = 0.1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前使用的坐标系
|
/// 当前使用的坐标系
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -339,7 +344,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// <param name="z">Z坐标(米)</param>
|
/// <param name="z">Z坐标(米)</param>
|
||||||
/// <param name="tolerance">容差(米),默认0.1m</param>
|
/// <param name="tolerance">容差(米),默认0.1m</param>
|
||||||
/// <returns>符合条件的高度层,如果没有则返回null</returns>
|
/// <returns>符合条件的高度层,如果没有则返回null</returns>
|
||||||
public HeightLayer? FindLayerContainingZ(GridPoint2D gridPosition, double z, double tolerance = 0.1)
|
public HeightLayer? FindLayerContainingZ(GridPoint2D gridPosition, double z, double tolerance = DEFAULT_LAYER_TOLERANCE_METERS)
|
||||||
{
|
{
|
||||||
if (!IsValidGridPosition(gridPosition))
|
if (!IsValidGridPosition(gridPosition))
|
||||||
return null;
|
return null;
|
||||||
@ -436,7 +441,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// <param name="zCoord">Z坐标(模型单位)</param>
|
/// <param name="zCoord">Z坐标(模型单位)</param>
|
||||||
/// <param name="tolerance">Z坐标容差(模型单位),默认0.1</param>
|
/// <param name="tolerance">Z坐标容差(模型单位),默认0.1</param>
|
||||||
/// <returns>是否可通行</returns>
|
/// <returns>是否可通行</returns>
|
||||||
public bool IsPassableAt3DPoint(GridPoint2D gridPosition, double zCoord, double tolerance = 0.1)
|
public bool IsPassableAt3DPoint(GridPoint2D gridPosition, double zCoord, double tolerance = DEFAULT_LAYER_TOLERANCE_METERS)
|
||||||
{
|
{
|
||||||
if (!IsValidGridPosition(gridPosition))
|
if (!IsValidGridPosition(gridPosition))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -11,6 +11,16 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PathOptimizer
|
public class PathOptimizer
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 共线检测容差(米)
|
||||||
|
/// </summary>
|
||||||
|
private const double COLLINEAR_TOLERANCE_METERS = 0.1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重复点检测容差(米)- 用于检测坐标完全相同的点
|
||||||
|
/// </summary>
|
||||||
|
private const double DUPLICATE_POINT_TOLERANCE_METERS = 0.001;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 路径优化配置参数
|
/// 路径优化配置参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -387,7 +397,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
/// <returns>如果三点在同一直线上且方向一致返回true</returns>
|
/// <returns>如果三点在同一直线上且方向一致返回true</returns>
|
||||||
private bool IsCollinear(Point3D p1, Point3D p2, Point3D p3)
|
private bool IsCollinear(Point3D p1, Point3D p2, Point3D p3)
|
||||||
{
|
{
|
||||||
const double tolerance = 0.1; // 容差值,单位:模型单位
|
const double tolerance = COLLINEAR_TOLERANCE_METERS; // 容差值,单位:模型单位
|
||||||
|
|
||||||
// 🔥 修复:使用统一的高度检查函数
|
// 🔥 修复:使用统一的高度检查函数
|
||||||
if (HasHeightChange(p1, p2, p3))
|
if (HasHeightChange(p1, p2, p3))
|
||||||
@ -406,7 +416,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
double dy23 = p3.Y - p2.Y;
|
double dy23 = p3.Y - p2.Y;
|
||||||
|
|
||||||
// 🔥 修复:使用更严格的容差检查真正的重复点(坐标完全相同)
|
// 🔥 修复:使用更严格的容差检查真正的重复点(坐标完全相同)
|
||||||
const double duplicatePointTolerance = 0.001; // 用很小的值检查真正的重复点
|
const double duplicatePointTolerance = DUPLICATE_POINT_TOLERANCE_METERS; // 用很小的值检查真正的重复点
|
||||||
bool isSegment1Zero = Math.Abs(dx12) < duplicatePointTolerance && Math.Abs(dy12) < duplicatePointTolerance;
|
bool isSegment1Zero = Math.Abs(dx12) < duplicatePointTolerance && Math.Abs(dy12) < duplicatePointTolerance;
|
||||||
bool isSegment2Zero = Math.Abs(dx23) < duplicatePointTolerance && Math.Abs(dy23) < duplicatePointTolerance;
|
bool isSegment2Zero = Math.Abs(dx23) < duplicatePointTolerance && Math.Abs(dy23) < duplicatePointTolerance;
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,9 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
LogManager.Info($"[空间哈希] 开始构建空间索引:{triangles.Count} 个三角形");
|
LogManager.Info($"[空间哈希] 开始构建空间索引:{triangles.Count} 个三角形");
|
||||||
|
|
||||||
_totalTriangles = triangles.Count;
|
_totalTriangles = triangles.Count;
|
||||||
_cellSize = Math.Max(gridSize * 2, 0.1); // 使用稍大的单元格减少重复
|
if (gridSize <= 0)
|
||||||
|
throw new ArgumentException("gridSize 必须大于0", nameof(gridSize));
|
||||||
|
_cellSize = gridSize * 2; // 使用稍大的单元格减少重复
|
||||||
_spatialHash.Clear();
|
_spatialHash.Clear();
|
||||||
|
|
||||||
// 计算或使用提供的边界框
|
// 计算或使用提供的边界框
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Autodesk.Navisworks.Api;
|
using Autodesk.Navisworks.Api;
|
||||||
using NavisworksTransport.Utils;
|
using NavisworksTransport.Utils;
|
||||||
|
using NavisworksTransport.Core.Config;
|
||||||
using static NavisworksTransport.CategoryAttributeManager;
|
using static NavisworksTransport.CategoryAttributeManager;
|
||||||
using g4;
|
using g4;
|
||||||
|
|
||||||
@ -340,7 +341,7 @@ namespace NavisworksTransport.PathPlanning
|
|||||||
new Point3D(10 * metersToModelUnits, 10 * metersToModelUnits, 3 * metersToModelUnits)
|
new Point3D(10 * metersToModelUnits, 10 * metersToModelUnits, 3 * metersToModelUnits)
|
||||||
);
|
);
|
||||||
|
|
||||||
double voxelSize = 0.5 * metersToModelUnits; // 0.5米体素
|
double voxelSize = ConfigManager.Instance.Current.PathEditing.CellSizeMeters * metersToModelUnits; // 使用配置的网格大小作为体素大小
|
||||||
|
|
||||||
var grid = new VoxelGrid(bounds, voxelSize);
|
var grid = new VoxelGrid(bounds, voxelSize);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using NavisworksTransport.Core.Models;
|
using NavisworksTransport.Core.Models;
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
|
||||||
namespace NavisworksTransport.UI.WPF.Converters
|
namespace NavisworksTransport.UI.WPF.Converters
|
||||||
@ -22,7 +23,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("IsNotNullToBoolConverter不支持反向转换");
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("CountToVisibilityConverter不支持反向转换");
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
|
||||||
namespace NavisworksTransport.UI.WPF.Converters
|
namespace NavisworksTransport.UI.WPF.Converters
|
||||||
@ -30,7 +31,7 @@ namespace NavisworksTransport.UI.WPF.Converters
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2820,7 +2820,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
if (volume > 1000) // 大于1000立方米
|
if (volume > 1000) // 大于1000立方米
|
||||||
return "大型物体 - 包围盒很大,容易与路径相交";
|
return "大型物体 - 包围盒很大,容易与路径相交";
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[碰撞分析] 获取物体包围盒失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
return "未知原因 - 建议手动检查";
|
return "未知原因 - 建议手动检查";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,10 +87,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
private bool _showControlVisualization = true; // 默认显示控制点连线
|
private bool _showControlVisualization = true; // 默认显示控制点连线
|
||||||
private bool _showPathLines = true; // 默认显示路径线(地面连线)
|
private bool _showPathLines = true; // 默认显示路径线(地面连线)
|
||||||
private bool _showObjectSpace = false; // 默认不显示通行空间
|
private bool _showObjectSpace = false; // 默认不显示通行空间
|
||||||
// 兼容旧代码的互斥属性(已废弃,使用独立开关)
|
// 渲染模式已改为独立开关(_showControlVisualization, _showPathLines, _showObjectSpace)
|
||||||
private bool _isStandardLineMode = false;
|
// 下面的互斥属性已废弃并删除
|
||||||
private bool _isRibbonLineMode = true;
|
|
||||||
private bool _isObjectSpaceMode = false;
|
|
||||||
|
|
||||||
// 路径策略参数
|
// 路径策略参数
|
||||||
private PathStrategyOption _selectedPathStrategy;
|
private PathStrategyOption _selectedPathStrategy;
|
||||||
|
|||||||
@ -1746,7 +1746,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Warning($"[坐标系探索] 设置视图状态失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
resultDialog.ShowDialog();
|
resultDialog.ShowDialog();
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace NavisworksTransport.UI.WPF.Views
|
namespace NavisworksTransport.UI.WPF.Views
|
||||||
@ -68,7 +69,10 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
{
|
{
|
||||||
dialog.Owner = System.Windows.Application.Current?.MainWindow;
|
dialog.Owner = System.Windows.Application.Current?.MainWindow;
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[坐标系对话框] 设置Owner失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.ShowDialog();
|
dialog.ShowDialog();
|
||||||
|
|||||||
@ -198,7 +198,10 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
System.Windows.Clipboard.SetText(coordinate);
|
System.Windows.Clipboard.SetText(coordinate);
|
||||||
ShowButtonFeedback(CopyCenterButton);
|
ShowButtonFeedback(CopyCenterButton);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[坐标窗口] 复制到剪贴板失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -212,7 +215,10 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
System.Windows.Clipboard.SetText(coordinate);
|
System.Windows.Clipboard.SetText(coordinate);
|
||||||
ShowButtonFeedback(CopyTopButton);
|
ShowButtonFeedback(CopyTopButton);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[坐标窗口] 复制到剪贴板失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -226,7 +232,10 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
System.Windows.Clipboard.SetText(coordinate);
|
System.Windows.Clipboard.SetText(coordinate);
|
||||||
ShowButtonFeedback(CopyBottomButton);
|
ShowButtonFeedback(CopyBottomButton);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Debug($"[坐标窗口] 复制到剪贴板失败: {ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -490,7 +490,7 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,7 +542,7 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ namespace NavisworksTransport.UI.WPF.Views
|
|||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Binding.DoNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,11 +56,7 @@ namespace NavisworksTransport.Utils
|
|||||||
var center1 = GetBoundingBoxCenter(box1);
|
var center1 = GetBoundingBoxCenter(box1);
|
||||||
var center2 = GetBoundingBoxCenter(box2);
|
var center2 = GetBoundingBoxCenter(box2);
|
||||||
|
|
||||||
double dx = center1.X - center2.X;
|
return GeometryHelper.CalculatePointDistance(center1, center2);
|
||||||
double dy = center1.Y - center2.Y;
|
|
||||||
double dz = center1.Z - center2.Z;
|
|
||||||
|
|
||||||
return Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -142,10 +142,10 @@ namespace NavisworksTransport
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">返回类型</typeparam>
|
/// <typeparam name="T">返回类型</typeparam>
|
||||||
/// <param name="operation">要执行的操作</param>
|
/// <param name="operation">要执行的操作</param>
|
||||||
/// <param name="defaultValue">操作失败时的默认返回值</param>
|
|
||||||
/// <param name="operationName">操作名称(用于日志)</param>
|
/// <param name="operationName">操作名称(用于日志)</param>
|
||||||
/// <returns>操作结果</returns>
|
/// <returns>操作结果</returns>
|
||||||
protected T SafeComOperation<T>(Func<T> operation, T defaultValue = default(T), string operationName = "COM操作")
|
/// <exception cref="COMException">COM操作失败时抛出</exception>
|
||||||
|
protected T SafeComOperation<T>(Func<T> operation, string operationName = "COM操作")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -157,17 +157,17 @@ namespace NavisworksTransport
|
|||||||
catch (COMException comEx)
|
catch (COMException comEx)
|
||||||
{
|
{
|
||||||
LogManager.Error($"[COM操作] COM异常 - {operationName}: {comEx.Message} (HRESULT: 0x{comEx.ErrorCode:X8})");
|
LogManager.Error($"[COM操作] COM异常 - {operationName}: {comEx.Message} (HRESULT: 0x{comEx.ErrorCode:X8})");
|
||||||
return defaultValue;
|
throw;
|
||||||
}
|
}
|
||||||
catch (InvalidComObjectException)
|
catch (InvalidComObjectException)
|
||||||
{
|
{
|
||||||
LogManager.Error($"[COM操作] COM对象已无效 - {operationName}");
|
LogManager.Error($"[COM操作] COM对象已无效 - {operationName}");
|
||||||
return defaultValue;
|
throw;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogManager.Error($"[COM操作] 一般异常 - {operationName}: {ex.Message}");
|
LogManager.Error($"[COM操作] 一般异常 - {operationName}: {ex.Message}");
|
||||||
return defaultValue;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,14 +176,14 @@ namespace NavisworksTransport
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="operation">要执行的操作</param>
|
/// <param name="operation">要执行的操作</param>
|
||||||
/// <param name="operationName">操作名称(用于日志)</param>
|
/// <param name="operationName">操作名称(用于日志)</param>
|
||||||
/// <returns>操作是否成功</returns>
|
/// <exception cref="COMException">COM操作失败时抛出</exception>
|
||||||
protected bool SafeComOperation(Action operation, string operationName = "COM操作")
|
protected void SafeComOperation(Action operation, string operationName = "COM操作")
|
||||||
{
|
{
|
||||||
return SafeComOperation(() =>
|
SafeComOperation(() =>
|
||||||
{
|
{
|
||||||
operation();
|
operation();
|
||||||
return true;
|
return true;
|
||||||
}, false, operationName);
|
}, operationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -334,10 +334,7 @@ namespace NavisworksTransport
|
|||||||
if (point1 == null || point2 == null)
|
if (point1 == null || point2 == null)
|
||||||
throw new ArgumentNullException("世界坐标点不能为空");
|
throw new ArgumentNullException("世界坐标点不能为空");
|
||||||
|
|
||||||
double dx = point2.X - point1.X;
|
return GeometryHelper.CalculatePointDistance(point1, point2);
|
||||||
double dy = point2.Y - point1.Y;
|
|
||||||
double dz = point2.Z - point1.Z;
|
|
||||||
return Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -14,13 +14,23 @@ namespace NavisworksTransport
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class GeometryHelper
|
public class GeometryHelper
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认轮廓提取容差(米)
|
||||||
|
/// </summary>
|
||||||
|
private const double DEFAULT_OUTLINE_TOLERANCE_METERS = 0.5;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 1厘米容差(米)- 用于精确几何计算
|
||||||
|
/// </summary>
|
||||||
|
private const double TOLERANCE_1CM_METERS = 0.01;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 提取模型项的顶视图轮廓
|
/// 提取模型项的顶视图轮廓
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="modelItem">模型项</param>
|
/// <param name="modelItem">模型项</param>
|
||||||
/// <param name="tolerance">容差</param>
|
/// <param name="tolerance">容差</param>
|
||||||
/// <returns>轮廓点集合</returns>
|
/// <returns>轮廓点集合</returns>
|
||||||
public static List<Point3D> ExtractTopViewOutline(ModelItem modelItem, double tolerance = 0.5)
|
public static List<Point3D> ExtractTopViewOutline(ModelItem modelItem, double tolerance = DEFAULT_OUTLINE_TOLERANCE_METERS)
|
||||||
{
|
{
|
||||||
var points = new List<Point3D>();
|
var points = new List<Point3D>();
|
||||||
|
|
||||||
@ -594,7 +604,7 @@ namespace NavisworksTransport
|
|||||||
{
|
{
|
||||||
iteration++;
|
iteration++;
|
||||||
var nextEdgeIndex = -1;
|
var nextEdgeIndex = -1;
|
||||||
var tolerance = 0.01; // 1cm容差,稍微放宽
|
var tolerance = TOLERANCE_1CM_METERS; // 1cm容差,稍微放宽
|
||||||
|
|
||||||
for (int i = 0; i < remainingEdges.Count; i++)
|
for (int i = 0; i < remainingEdges.Count; i++)
|
||||||
{
|
{
|
||||||
@ -747,7 +757,7 @@ namespace NavisworksTransport
|
|||||||
|
|
||||||
// 第1步:移除重复点
|
// 第1步:移除重复点
|
||||||
var uniquePoints = new List<Point2D>();
|
var uniquePoints = new List<Point2D>();
|
||||||
const double tolerance = 0.01; // 1cm容差
|
const double tolerance = TOLERANCE_1CM_METERS; // 1cm容差
|
||||||
|
|
||||||
foreach (var point in contour)
|
foreach (var point in contour)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,9 +22,10 @@ namespace NavisworksTransport.Utils
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const double VIEW_BOUNDING_BOX_EXPANSION_FACTOR = 1.2;
|
private const double VIEW_BOUNDING_BOX_EXPANSION_FACTOR = 1.2;
|
||||||
|
|
||||||
/// <summary> 视野扩展范围(米)
|
/// <summary>
|
||||||
|
/// 默认视野扩展范围(米)- 用于调整视角时确保目标完全可见
|
||||||
/// </summary>
|
/// </summary>
|
||||||
const double EXPANSION_METERS = 10.0;
|
private const double DEFAULT_VIEW_EXPANSION_METERS = 10.0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 智能调整视角:调整到路径中心,确保整个路径都在视野内
|
/// 智能调整视角:调整到路径中心,确保整个路径都在视野内
|
||||||
@ -106,7 +107,7 @@ namespace NavisworksTransport.Utils
|
|||||||
|
|
||||||
// 3. 计算扩展边距
|
// 3. 计算扩展边距
|
||||||
double boxWidth = viewBoundingBox.Max.X - viewBoundingBox.Min.X;
|
double boxWidth = viewBoundingBox.Max.X - viewBoundingBox.Min.X;
|
||||||
double expansionFactor = VIEW_BOUNDING_BOX_EXPANSION_FACTOR + (EXPANSION_METERS / baseDimension);
|
double expansionFactor = VIEW_BOUNDING_BOX_EXPANSION_FACTOR + (DEFAULT_VIEW_EXPANSION_METERS / baseDimension);
|
||||||
double expansionMargin = boxWidth * (expansionFactor - 1) / 2;
|
double expansionMargin = boxWidth * (expansionFactor - 1) / 2;
|
||||||
|
|
||||||
// 4. 应用视角(使用通用方法,带 ZoomBox)
|
// 4. 应用视角(使用通用方法,带 ZoomBox)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user