NavisworksTransport/src/PathPlanning/VoxelCell.cs
2025-10-21 18:48:27 +08:00

161 lines
5.4 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 Autodesk.Navisworks.Api;
using static NavisworksTransport.CategoryAttributeManager;
namespace NavisworksTransport.PathPlanning
{
/// <summary>
/// 体素单元类 - 表示3D网格中的单个体素
/// 用于体素网格路径规划,存储体素的属性和状态信息
/// </summary>
public class VoxelCell
{
/// <summary>
/// 体素类型(对应物流元素分类)
/// </summary>
public LogisticsElementType Type { get; set; }
/// <summary>
/// 是否可通行
/// true: 该体素为自由空间,可以通行
/// false: 该体素为障碍物或不可通行区域
/// </summary>
public bool IsPassable { get; set; }
/// <summary>
/// 到最近障碍物的距离(模型单位)
/// 使用Signed Distance Field (SDF)计算
/// 正值:自由空间,数值表示到最近障碍物的距离
/// 负值:障碍物内部,数值表示到障碍物表面的距离
/// 零值:障碍物表面
/// </summary>
public double Distance { get; set; }
/// <summary>
/// 速度限制(米/秒)
/// 根据体素所在区域的特性设置(如通道、电梯等)
/// 0.0 表示无速度限制(使用默认速度)
/// </summary>
public double SpeedLimit { get; set; }
/// <summary>
/// 源模型元素
/// 如果该体素对应某个BIM模型元素存储其引用
/// 用于追溯体素属性的来源
/// </summary>
public ModelItem SourceItem { get; set; }
/// <summary>
/// 通行成本
/// 用于A*路径规划算法
/// 考虑因素:距离、速度限制、碰撞风险等
/// 值越大表示通行代价越高
/// </summary>
public double Cost { get; set; }
/// <summary>
/// 构造函数 - 创建默认的可通行体素
/// </summary>
public VoxelCell()
{
Type = LogisticsElementType.;
IsPassable = true;
Distance = double.MaxValue; // 初始化为无限远(远离障碍物)
SpeedLimit = 0.0; // 无速度限制
SourceItem = null;
Cost = 1.0; // 默认通行成本
}
/// <summary>
/// 构造函数 - 创建指定属性的体素
/// </summary>
/// <param name="isPassable">是否可通行</param>
/// <param name="type">体素类型</param>
/// <param name="distance">到最近障碍物的距离</param>
public VoxelCell(bool isPassable, LogisticsElementType type = LogisticsElementType., double distance = double.MaxValue)
{
Type = type;
IsPassable = isPassable;
Distance = distance;
SpeedLimit = 0.0;
SourceItem = null;
Cost = isPassable ? 1.0 : double.MaxValue; // 不可通行区域成本为无穷大
}
/// <summary>
/// 克隆体素单元
/// </summary>
/// <returns>体素单元的深拷贝</returns>
public VoxelCell Clone()
{
return new VoxelCell
{
Type = this.Type,
IsPassable = this.IsPassable,
Distance = this.Distance,
SpeedLimit = this.SpeedLimit,
SourceItem = this.SourceItem,
Cost = this.Cost
};
}
/// <summary>
/// 设置为障碍物体素
/// </summary>
/// <param name="sourceItem">源模型元素</param>
public void SetAsObstacle(ModelItem sourceItem = null)
{
IsPassable = false;
Type = LogisticsElementType.;
Distance = 0.0; // 障碍物表面距离为0
Cost = double.MaxValue;
SourceItem = sourceItem;
}
/// <summary>
/// 设置为自由空间体素
/// </summary>
/// <param name="distance">到最近障碍物的距离</param>
public void SetAsFreeSpace(double distance = double.MaxValue)
{
IsPassable = true;
Type = LogisticsElementType.;
Distance = distance;
Cost = 1.0;
}
/// <summary>
/// 根据距离更新通行成本
/// 距离障碍物越近,成本越高(避免贴边行走)
/// </summary>
/// <param name="safetyMargin">安全边距(模型单位)</param>
public void UpdateCostFromDistance(double safetyMargin)
{
if (!IsPassable)
{
Cost = double.MaxValue;
return;
}
if (Distance < safetyMargin)
{
// 在安全边距内,成本线性增加
double ratio = Distance / safetyMargin;
Cost = 1.0 + (1.0 - ratio) * 10.0; // 成本范围1.0 ~ 11.0
}
else
{
Cost = 1.0; // 安全距离外,标准成本
}
}
/// <summary>
/// 返回体素单元的字符串表示
/// </summary>
public override string ToString()
{
string passableStr = IsPassable ? "可通行" : "障碍";
return $"VoxelCell[{passableStr}, Type={Type}, Dist={Distance:F2}, Cost={Cost:F2}]";
}
}
}