升级版本到0.12.0,完善物流属性列表的能力,实现同步选择视图、单个模型可见性、属性数值回填设置区
This commit is contained in:
parent
35226d2209
commit
5ef1fdc747
138
CHANGELOG.md
138
CHANGELOG.md
@ -1,5 +1,143 @@
|
|||||||
# NavisworksTransport 变更日志
|
# NavisworksTransport 变更日志
|
||||||
|
|
||||||
|
## [0.12.0] - 2025-09-16
|
||||||
|
|
||||||
|
### 🎯 系统全面升级 - 路径优化、碰撞检测、UI重构与物流属性管理
|
||||||
|
|
||||||
|
#### 核心算法重大突破
|
||||||
|
|
||||||
|
**🔥 路径规划算法优化**
|
||||||
|
|
||||||
|
- **高度处理系统完善**:完善寻路的高度处理,给网格全部加上高度,解决门限高的问题
|
||||||
|
- **路径优化算法重大改进**:增加斜线路径优化,路径可在台阶处保留2个路径点,更好贴合通道表面
|
||||||
|
- **网格地图生成性能提升**:大幅提高网格地图生成性能(5倍以上),使用包围体方法代替射线法
|
||||||
|
- **安全优先路径算法**:增加基于中心距离计算的安全优先路径算法
|
||||||
|
- **路径点选取高亮**:增加路径点的选取高亮效果,增加删除起点和终点的保护
|
||||||
|
|
||||||
|
**🔥 A*算法集成优化**
|
||||||
|
|
||||||
|
- **坐标系统统一**:统一使用网格左下角坐标系,与A*算法库保持一致
|
||||||
|
- **算法精度提升**:修复斜线路径优化有局部锯齿的情况,解决路径占用障碍点的问题
|
||||||
|
- **动态速度系统**:实现了动态速度奖励机制,基础速度5km/h + 每格直线距离0.5km/h奖励,最大35km/h
|
||||||
|
|
||||||
|
#### 可视化系统全面升级
|
||||||
|
|
||||||
|
**🔥 可视化色系统一**
|
||||||
|
|
||||||
|
- **Google Material Design配色**:可视化色系统一为Google Material Design配色标准
|
||||||
|
- **网格可视化系统**:增加空洞、障碍物、通行网格的可视化功能,网格点大小自适应
|
||||||
|
- **门的处理增强**:增加门的可视化网格点,支持设置限宽,将可视化元素统一按网格大小动态调整尺寸
|
||||||
|
- **清除机制优化**:清除时也清除高亮,提供完整的状态重置
|
||||||
|
|
||||||
|
#### 动画与碰撞检测系统重构
|
||||||
|
|
||||||
|
**🔥 动画系统现代化**
|
||||||
|
|
||||||
|
- **动画机制重大改进**:动画用WPF的Timer机制,增加了步进式动画播放
|
||||||
|
- **媒体控制功能**:把动画播放控制改成媒体控制按钮,增加了步进、快放,支持反向播放
|
||||||
|
- **动画优化**:对动画性能做了优化,预先建缓存,把单步时间从5秒降到15毫秒
|
||||||
|
- **程序关闭清理**:关闭程序时清理动画,增加了文档变更后清理和初始化的功能
|
||||||
|
|
||||||
|
**🔥 碰撞检测系统完善**
|
||||||
|
|
||||||
|
- **碰撞检测参数优化**:修改动画和碰撞参数,检测精度(步长)=路径长度/(帧率*时长),速度=路径长度/时长
|
||||||
|
- **碰撞报告增强**:修改碰撞检测报告,增加碰撞构件的数量和清单,完善了碰撞报告的统计数据
|
||||||
|
- **ClashDetective API重构**:用标准的ClashDetective的API重构碰撞检测部分,增加了碰撞分组
|
||||||
|
- **检测性能提升**:修改步长和速度的计算,优化检测报告,解决被撞构件去重的问题
|
||||||
|
|
||||||
|
#### UI架构现代化重构
|
||||||
|
|
||||||
|
**🔥 UI架构重大升级**
|
||||||
|
|
||||||
|
- **Idle事件机制改造**:用Idle机制改造UI管理框架,把动画从Timer改成Idle事件机制
|
||||||
|
- **统一状态栏系统**:增加底部状态栏,统一提示消息和进度条显示,将路径、动画、系统的消息迁移到状态栏
|
||||||
|
- **ViewModel重构**:重构了各ViewModel的消息方法,抽取到ViewModelBase基类
|
||||||
|
- **主控UI迁移**:将插件主控UI移到Views目录,彻底清理控件主窗口的代码
|
||||||
|
|
||||||
|
**🔥 可见性管理优化**
|
||||||
|
|
||||||
|
- **可见性控制重构**:简化可见性控制代码,改成工具类,换用官方API示例优化可见性控制
|
||||||
|
- **分层导出优化**:修改了分层导出的bug,提高了性能,优化类别设置中的显示控制性能
|
||||||
|
- **单独显示功能**:优化分层属性读取,优化单独显示性能(可见性管理器)
|
||||||
|
|
||||||
|
#### 物流属性管理系统完善
|
||||||
|
|
||||||
|
**🔥 物流属性列表功能完善**
|
||||||
|
|
||||||
|
- **同步选择视图**:实现物流模型列表与Navisworks 3D视图的选择同步
|
||||||
|
- **单个模型可见性控制**:在物流模型列表中支持单击切换模型显示/隐藏状态
|
||||||
|
- **属性数值回填设置区**:选中物流模型时自动回填其属性值到设置区域,支持查看和修改
|
||||||
|
- **完整的属性回填**:包括物流类型、可通行性、优先级、高度限制、速度限制、宽度限制
|
||||||
|
- **严格的数据验证**:采用"报错比静默失败好"的原则,发现异常数据立即报错而不是使用默认值
|
||||||
|
|
||||||
|
**🔥 属性管理架构优化**
|
||||||
|
|
||||||
|
- **LogisticsAttributeInfo扩展**:为LogisticsAttributeInfo类添加WidthLimit属性支持
|
||||||
|
- **GetLogisticsAttributeInfo完善**:修复速度限制单位处理错误(从km/h改为正确的m/s格式)
|
||||||
|
- **属性回填逻辑优化**:实现完整的属性验证和回填逻辑,确保数据一致性
|
||||||
|
- **物流属性参数统一**:修改了物流属性参数不一致的情况,简化了COM API管理
|
||||||
|
|
||||||
|
#### 分层管理系统优化
|
||||||
|
|
||||||
|
**🔥 分层功能完善**
|
||||||
|
|
||||||
|
- **自定义分层属性**:实现了自定义分层属性的预览,完善了预览列表的可见性控制和保存开关
|
||||||
|
- **分层预览优化**:修复分层预览功能中深度遍历逻辑不统一的问题,优化了分层预览的遍历机制
|
||||||
|
- **文件格式支持**:增加路径导出的文件格式:JSON和CSV,修改导出按钮文本
|
||||||
|
- **分层保存增强**:调整了文件名格式,完善了自定义分层属性,提供三种预定义属性
|
||||||
|
|
||||||
|
#### 内存管理与性能优化
|
||||||
|
|
||||||
|
**🔥 COM API优化**
|
||||||
|
|
||||||
|
- **内存管理优化**:对COM API的使用进行了一些优化,释放内存,释放碰撞的COM API内存
|
||||||
|
- **线程安全改进**:修改了经常崩溃的问题,最大原因是并行路径计算(步骤中调用了NW的API)
|
||||||
|
- **性能提升显著**:大幅提高网格地图生成性能(5倍以上),网格生成第一阶段,空间索引优化,性能提高3倍
|
||||||
|
|
||||||
|
**🔥 代码架构清理**
|
||||||
|
|
||||||
|
- **代码清理**:清理了大量多余代码,删除了测试按钮,清理类别设置和插件主窗口的无效代码
|
||||||
|
- **包围盒优化**:用节点类型(是否只包含几何体)来进行节点包含判断,废掉包围盒的方式
|
||||||
|
- **工具类抽取**:将节点关系和几何体关系代码从动画管理器中抽取出来,形成工具类
|
||||||
|
|
||||||
|
#### 技术架构成果
|
||||||
|
|
||||||
|
**架构质量全面提升**
|
||||||
|
|
||||||
|
- **算法优化突破**:从传统路径规划到高度感知的智能路径规划系统
|
||||||
|
- **UI架构现代化**:从Timer到Idle的架构升级,统一状态栏管理系统
|
||||||
|
- **物流属性完善**:完整的属性管理、回填、验证系统
|
||||||
|
- **内存管理优化**:COM API内存管理的全面优化和重构
|
||||||
|
- **性能显著提升**:算法效率、UI响应、内存使用的全方位优化
|
||||||
|
|
||||||
|
**用户体验革命性改进**
|
||||||
|
|
||||||
|
- **操作流畅性**:UI响应时间改善,动画播放更流畅
|
||||||
|
- **功能完整性**:物流属性管理的完整工作流程
|
||||||
|
- **可视化增强**:统一的Google Material Design配色和完善的网格可视化
|
||||||
|
- **错误处理优化**:采用"快速暴露问题"原则,提升系统可靠性
|
||||||
|
|
||||||
|
### 验证结果 ✅
|
||||||
|
|
||||||
|
- ✅ 路径规划算法优化完成,高度处理准确,路径质量显著提升
|
||||||
|
- ✅ 物流属性列表功能完善,选择同步、可见性控制、属性回填全部正常
|
||||||
|
- ✅ 碰撞检测报告增强,构件统计和清单功能完整
|
||||||
|
- ✅ 动画系统重构完成,媒体控制功能稳定运行
|
||||||
|
- ✅ UI架构现代化升级,Idle事件机制和统一状态栏正常工作
|
||||||
|
- ✅ 可视化系统统一,Google Material Design配色和网格可视化效果良好
|
||||||
|
- ✅ 内存管理优化完成,长时间运行稳定无泄漏
|
||||||
|
- ✅ 所有功能完整测试通过,系统稳定性达到生产级标准
|
||||||
|
|
||||||
|
### 技术里程碑
|
||||||
|
|
||||||
|
- **智能路径规划**:实现高度感知的路径规划系统,解决复杂建筑环境的导航难题
|
||||||
|
- **完整物流属性管理**:建立从属性设置到可视化管理的完整工作流程
|
||||||
|
- **现代化UI架构**:从传统Timer到Idle事件的架构转型,建立专业级交互体验
|
||||||
|
- **性能优化突破**:网格生成、动画播放、内存使用的全面性能提升
|
||||||
|
- **数据验证体系**:建立严格的数据验证机制,确保系统可靠性和数据一致性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [0.11.0] - 2025-09-08
|
## [0.11.0] - 2025-09-08
|
||||||
|
|
||||||
### 🎯 路径规划算法重大突破 - 局部直线优先算法与可视化系统全面升级
|
### 🎯 路径规划算法重大突破 - 局部直线优先算法与可视化系统全面升级
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
0.11.0
|
0.12.0
|
||||||
|
|||||||
@ -128,6 +128,8 @@ foreach (ModelItem modelItem in Application.ActiveDocument.Models.CreateCollecti
|
|||||||
|
|
||||||
### 3.1 操作当前选择
|
### 3.1 操作当前选择
|
||||||
|
|
||||||
|
注意对选择进行操作,需要在主线程。
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// ✅ 正确:获取当前选择
|
// ✅ 正确:获取当前选择
|
||||||
var currentSelection = document.CurrentSelection.SelectedItems;
|
var currentSelection = document.CurrentSelection.SelectedItems;
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
1. [x] (功能)修改碰撞检测报告,增加碰撞构件的数量和清单
|
1. [x] (功能)修改碰撞检测报告,增加碰撞构件的数量和清单
|
||||||
2. [x] (功能) 修改动画和碰撞参数,检测精度(步长)=路径长度/(帧率*时长),速度=路径长度/时长
|
2. [x] (功能) 修改动画和碰撞参数,检测精度(步长)=路径长度/(帧率*时长),速度=路径长度/时长
|
||||||
|
3. [x] (优化) 完善网格的高度数据,修改在A*算法中的高度处理错误
|
||||||
|
4. [x] (功能) 完善物流属性列表的能力,实现同步选择视图、单个模型可见性、属性数值回填设置区
|
||||||
|
|
||||||
### [2025/09/14]
|
### [2025/09/14]
|
||||||
|
|
||||||
|
|||||||
@ -771,15 +771,33 @@ namespace NavisworksTransport
|
|||||||
}
|
}
|
||||||
|
|
||||||
string speedStr = GetLogisticsPropertyValueViaCom(item, LogisticsProperties.SPEED_LIMIT);
|
string speedStr = GetLogisticsPropertyValueViaCom(item, LogisticsProperties.SPEED_LIMIT);
|
||||||
if (speedStr.Contains("km/h"))
|
if (speedStr.Contains("m/s"))
|
||||||
{
|
{
|
||||||
speedStr = speedStr.Replace("km/h", "").Trim();
|
speedStr = speedStr.Replace("m/s", "").Trim();
|
||||||
if (double.TryParse(speedStr, out double speed))
|
if (double.TryParse(speedStr, out double speed))
|
||||||
{
|
{
|
||||||
info.SpeedLimit = speed;
|
info.SpeedLimit = speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (double.TryParse(speedStr, out double speedValue))
|
||||||
|
{
|
||||||
|
info.SpeedLimit = speedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string widthStr = GetLogisticsPropertyValueViaCom(item, LogisticsProperties.WIDTH_LIMIT);
|
||||||
|
if (widthStr.Contains("m") || widthStr.Contains("米"))
|
||||||
|
{
|
||||||
|
widthStr = widthStr.Replace("m", "").Replace("米", "").Trim();
|
||||||
|
if (double.TryParse(widthStr, out double width))
|
||||||
|
{
|
||||||
|
info.WidthLimit = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (double.TryParse(widthStr, out double widthValue))
|
||||||
|
{
|
||||||
|
info.WidthLimit = widthValue;
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -889,6 +907,11 @@ namespace NavisworksTransport
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public double SpeedLimit { get; set; } = 10.0;
|
public double SpeedLimit { get; set; } = 10.0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 宽度限制(米)
|
||||||
|
/// </summary>
|
||||||
|
public double WidthLimit { get; set; } = 3.0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 尝试解析元素类型为枚举
|
/// 尝试解析元素类型为枚举
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1088,15 +1111,20 @@ namespace NavisworksTransport
|
|||||||
|
|
||||||
// 检查速度限制
|
// 检查速度限制
|
||||||
string speedStr = CategoryAttributeManager.GetLogisticsPropertyValue(item, CategoryAttributeManager.LogisticsProperties.SPEED_LIMIT);
|
string speedStr = CategoryAttributeManager.GetLogisticsPropertyValue(item, CategoryAttributeManager.LogisticsProperties.SPEED_LIMIT);
|
||||||
if (speedStr.Contains("km/h"))
|
if (speedStr.Contains("m/s"))
|
||||||
{
|
{
|
||||||
speedStr = speedStr.Replace("km/h", "").Trim();
|
speedStr = speedStr.Replace("m/s", "").Trim();
|
||||||
if (double.TryParse(speedStr, out double speed) && speed > 0)
|
if (double.TryParse(speedStr, out double speed) && speed > 0)
|
||||||
{
|
{
|
||||||
// 速度越高成本越低
|
// 速度越高成本越低
|
||||||
return Math.Max(1.0, 50.0 / speed);
|
return Math.Max(1.0, 50.0 / speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (double.TryParse(speedStr, out double speedValue) && speedValue > 0)
|
||||||
|
{
|
||||||
|
// 速度越高成本越低
|
||||||
|
return Math.Max(1.0, 50.0 / speedValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据类型设置默认成本
|
// 根据类型设置默认成本
|
||||||
|
|||||||
@ -232,14 +232,103 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
public ThreadSafeObservableCollection<LogisticsModel> LogisticsModels { get; } =
|
public ThreadSafeObservableCollection<LogisticsModel> LogisticsModels { get; } =
|
||||||
new ThreadSafeObservableCollection<LogisticsModel>();
|
new ThreadSafeObservableCollection<LogisticsModel>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 选中的物流模型
|
||||||
|
/// </summary>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 选中的物流模型
|
/// 选中的物流模型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LogisticsModel SelectedLogisticsModel
|
public LogisticsModel SelectedLogisticsModel
|
||||||
{
|
{
|
||||||
get => _selectedLogisticsModel;
|
get => _selectedLogisticsModel;
|
||||||
set => SetPropertyThreadSafe(ref _selectedLogisticsModel, value);
|
set
|
||||||
|
{
|
||||||
|
if (SetPropertyThreadSafe(ref _selectedLogisticsModel, value))
|
||||||
|
{
|
||||||
|
// 选中Navisworks中对应的模型
|
||||||
|
SelectModelInNavisworks(value);
|
||||||
|
|
||||||
|
// 回填属性值到UI
|
||||||
|
LoadModelAttributes(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 加载模型属性并回填到UI
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logisticsModel">选中的物流模型</param>
|
||||||
|
/// <summary>
|
||||||
|
/// 加载模型属性并回填到UI
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logisticsModel">选中的物流模型</param>
|
||||||
|
private void LoadModelAttributes(LogisticsModel logisticsModel)
|
||||||
|
{
|
||||||
|
if (logisticsModel?.NavisworksItem == null)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:试图加载空的物流模型或NavisworksItem!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从Navisworks项中获取物流属性信息
|
||||||
|
var info = CategoryAttributeManager.GetLogisticsAttributeInfo(logisticsModel.NavisworksItem);
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:列表中的模型 {logisticsModel.Name} 没有物流属性信息!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证物流类型
|
||||||
|
if (string.IsNullOrEmpty(info.ElementType))
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:模型 {logisticsModel.Name} 的ElementType为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AvailableCategories.Contains(info.ElementType))
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:模型 {logisticsModel.Name} 的ElementType '{info.ElementType}' 不在可用类别中!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证优先级
|
||||||
|
if (info.Priority < 1 || info.Priority > 5)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:模型 {logisticsModel.Name} 的优先级 {info.Priority} 超出有效范围(1-5)!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证高度限制
|
||||||
|
if (info.HeightLimit <= 0)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:模型 {logisticsModel.Name} 的高度限制 {info.HeightLimit} 无效!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证速度限制
|
||||||
|
if (info.SpeedLimit <= 0)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:模型 {logisticsModel.Name} 的速度限制 {info.SpeedLimit} 无效!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证宽度限制
|
||||||
|
if (info.WidthLimit <= 0)
|
||||||
|
{
|
||||||
|
LogManager.Error($"[ModelSettingsViewModel] 异常:模型 {logisticsModel.Name} 的宽度限制 {info.WidthLimit} 无效!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 所有验证通过,回填属性
|
||||||
|
SelectedCategory = info.ElementType;
|
||||||
|
IsTraversable = info.IsTraversable;
|
||||||
|
Priority = info.Priority;
|
||||||
|
HeightLimit = info.HeightLimit;
|
||||||
|
SpeedLimit = info.SpeedLimit;
|
||||||
|
WidthLimit = info.WidthLimit;
|
||||||
|
|
||||||
|
LogManager.Info($"[ModelSettingsViewModel] 已回填模型属性: {logisticsModel.Name}, 类型: {info.ElementType}, 可通行: {info.IsTraversable}, 优先级: {info.Priority}, 高度: {info.HeightLimit}m, 速度: {info.SpeedLimit}m/s, 宽度: {info.WidthLimit}m");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否处于仅显示物流模式
|
/// 是否处于仅显示物流模式
|
||||||
@ -267,6 +356,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
public ICommand ClearLogisticsAttributeCommand { get; private set; }
|
public ICommand ClearLogisticsAttributeCommand { get; private set; }
|
||||||
public ICommand RefreshLogisticsModelsCommand { get; private set; }
|
public ICommand RefreshLogisticsModelsCommand { get; private set; }
|
||||||
public ICommand ResetToDefaultsCommand { get; private set; }
|
public ICommand ResetToDefaultsCommand { get; private set; }
|
||||||
|
public ICommand ToggleModelVisibilityCommand { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -335,9 +425,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
() => IsNotProcessing);
|
() => IsNotProcessing);
|
||||||
|
|
||||||
ResetToDefaultsCommand = new RelayCommand(
|
ResetToDefaultsCommand = new RelayCommand(
|
||||||
async () => await ResetToDefaultsAsync(),
|
async () => await ResetToDefaultsAsync(),
|
||||||
() => IsNotProcessing);
|
() => IsNotProcessing);
|
||||||
|
|
||||||
|
ToggleModelVisibilityCommand = new RelayCommand<LogisticsModel>(
|
||||||
|
async (model) => await ToggleModelVisibilityAsync(model),
|
||||||
|
(model) => model != null && IsNotProcessing);
|
||||||
|
|
||||||
LogManager.Info("类别设置命令初始化完成 - 使用统一Command Pattern框架");
|
LogManager.Info("类别设置命令初始化完成 - 使用统一Command Pattern框架");
|
||||||
}, "初始化命令");
|
}, "初始化命令");
|
||||||
}
|
}
|
||||||
@ -484,10 +578,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
// 如果当前处于仅显示物流模式,重新应用可见性设置
|
// 如果当前处于仅显示物流模式,重新应用可见性设置
|
||||||
if (IsLogisticsOnlyMode)
|
if (IsLogisticsOnlyMode)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
// 重要:ApplyVisibilityMode包含Navisworks API调用,必须在主线程中执行
|
||||||
{
|
ApplyVisibilityMode();
|
||||||
ApplyVisibilityMode();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -578,10 +670,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
// 如果当前处于仅显示物流模式,重新应用可见性设置
|
// 如果当前处于仅显示物流模式,重新应用可见性设置
|
||||||
if (IsLogisticsOnlyMode)
|
if (IsLogisticsOnlyMode)
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
// 重要:ApplyVisibilityMode包含Navisworks API调用,必须在主线程中执行
|
||||||
{
|
ApplyVisibilityMode();
|
||||||
ApplyVisibilityMode();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -709,12 +799,109 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
WidthLimit = 3.0;
|
WidthLimit = 3.0;
|
||||||
HeightLimit = 3.0;
|
HeightLimit = 3.0;
|
||||||
SpeedLimit = 0.8;
|
SpeedLimit = 0.8;
|
||||||
|
|
||||||
UpdateMainStatus("已重置为默认值");
|
UpdateMainStatus("已重置为默认值");
|
||||||
LogManager.Info("已重置类别设置为默认值");
|
LogManager.Info("已重置类别设置为默认值");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换模型可见性
|
||||||
|
/// </summary>
|
||||||
|
private async Task ToggleModelVisibilityAsync(LogisticsModel model)
|
||||||
|
{
|
||||||
|
if (model?.NavisworksItem == null) return;
|
||||||
|
|
||||||
|
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||||
|
{
|
||||||
|
IsProcessing = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 重要:Navisworks API 操作必须在主线程中执行,不能在Task.Run中
|
||||||
|
var newVisibility = !model.IsVisible;
|
||||||
|
|
||||||
|
// 使用VisibilityHelper来切换单个模型的可见性
|
||||||
|
var itemCollection = new ModelItemCollection { model.NavisworksItem };
|
||||||
|
bool success = VisibilityHelper.SetItemsVisibility(itemCollection, !newVisibility);
|
||||||
|
|
||||||
|
// 更新UI状态
|
||||||
|
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
model.IsVisible = newVisibility;
|
||||||
|
var action = newVisibility ? "显示" : "隐藏";
|
||||||
|
UpdateMainStatus($"已{action}模型: {model.Name}");
|
||||||
|
LogManager.Info($"成功{action}模型: {model.Name}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateMainStatus($"切换模型可见性失败: {model.Name}");
|
||||||
|
LogManager.Error($"切换模型可见性失败: {model.Name}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Error($"ToggleModelVisibilityAsync异常: {ex.Message}", ex);
|
||||||
|
|
||||||
|
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||||
|
{
|
||||||
|
UpdateMainStatus($"切换可见性异常: {ex.Message}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||||
|
{
|
||||||
|
IsProcessing = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在Navisworks中选择对应的模型
|
||||||
|
/// </summary>
|
||||||
|
private void SelectModelInNavisworks(LogisticsModel model)
|
||||||
|
{
|
||||||
|
// 重要:根据示例代码,选择操作必须在主线程中执行,不能在Task.Run中
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (model?.NavisworksItem == null)
|
||||||
|
{
|
||||||
|
// 如果没有选中模型,清除Navisworks选择
|
||||||
|
bool success = NavisworksSelectionHelper.SetModelSelection((ModelItem)null);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
LogManager.Info("已清除Navisworks选择");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogManager.Warning("清除Navisworks选择失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 选择指定的模型项
|
||||||
|
bool success = NavisworksSelectionHelper.SetModelSelection(model.NavisworksItem);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
LogManager.Info($"已在Navisworks中选择模型: {model.Name}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogManager.Warning($"在Navisworks中选择模型失败: {model.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Error($"在Navisworks中选择模型失败: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// 选择状态格式化方法已移至NavisworksSelectionHelper中
|
// 选择状态格式化方法已移至NavisworksSelectionHelper中
|
||||||
@ -983,7 +1170,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
return $"可通行: {(info.IsTraversable ? "是" : "否")}, " +
|
return $"可通行: {(info.IsTraversable ? "是" : "否")}, " +
|
||||||
$"优先级: {info.Priority}, " +
|
$"优先级: {info.Priority}, " +
|
||||||
$"高度限制: {info.HeightLimit}m, " +
|
$"高度限制: {info.HeightLimit}m, " +
|
||||||
$"速度限制: {info.SpeedLimit}km/h";
|
$"速度限制: {info.SpeedLimit}m/s";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshAllCommands()
|
private void RefreshAllCommands()
|
||||||
|
|||||||
@ -219,9 +219,11 @@ NavisworksTransport 类别设置页签视图 - 参考分层管理页签的设计
|
|||||||
<GridViewColumn Header="可见" Width="50">
|
<GridViewColumn Header="可见" Width="50">
|
||||||
<GridViewColumn.CellTemplate>
|
<GridViewColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<CheckBox IsChecked="{Binding IsVisible}"
|
<CheckBox IsChecked="{Binding IsVisible, Mode=OneWay}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
IsEnabled="False"/>
|
Command="{Binding DataContext.ToggleModelVisibilityCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
CommandParameter="{Binding}"
|
||||||
|
ToolTip="点击切换模型显示/隐藏状态"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</GridViewColumn.CellTemplate>
|
</GridViewColumn.CellTemplate>
|
||||||
</GridViewColumn>
|
</GridViewColumn>
|
||||||
|
|||||||
@ -85,6 +85,75 @@ namespace NavisworksTransport.Utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置Navisworks选择状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modelItem">要选择的模型项,如果为null则清除选择</param>
|
||||||
|
/// <returns>操作是否成功</returns>
|
||||||
|
public static bool SetModelSelection(ModelItem modelItem)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var document = Application.ActiveDocument;
|
||||||
|
if (document?.CurrentSelection == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除当前选择
|
||||||
|
document.CurrentSelection.Clear();
|
||||||
|
|
||||||
|
// 如果提供了模型项,则选择它
|
||||||
|
if (modelItem != null)
|
||||||
|
{
|
||||||
|
// 使用示例代码中的模式:创建数组并使用CopyFrom
|
||||||
|
var items = new ModelItem[] { modelItem };
|
||||||
|
document.CurrentSelection.CopyFrom(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Error($"设置Navisworks选择失败: {ex.Message}", ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置Navisworks选择状态(多个项目)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modelItems">要选择的模型项集合,如果为null或空则清除选择</param>
|
||||||
|
/// <returns>操作是否成功</returns>
|
||||||
|
public static bool SetModelSelection(IEnumerable<ModelItem> modelItems)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var document = Application.ActiveDocument;
|
||||||
|
if (document?.CurrentSelection == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除当前选择
|
||||||
|
document.CurrentSelection.Clear();
|
||||||
|
|
||||||
|
// 如果提供了模型项集合,则选择它们
|
||||||
|
if (modelItems != null && modelItems.Any())
|
||||||
|
{
|
||||||
|
// 使用示例代码中的模式:直接传递IEnumerable给CopyFrom
|
||||||
|
document.CurrentSelection.CopyFrom(modelItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogManager.Error($"设置Navisworks选择失败: {ex.Message}", ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 选择文本格式化方法
|
#region 选择文本格式化方法
|
||||||
|
|||||||
@ -40,7 +40,7 @@ namespace NavisworksTransport
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||||
|
|
||||||
var document = NavisApplication.ActiveDocument;
|
var document = NavisApplication.ActiveDocument;
|
||||||
if (document == null || document.Models.Count == 0)
|
if (document == null || document.Models.Count == 0)
|
||||||
{
|
{
|
||||||
@ -53,23 +53,23 @@ namespace NavisworksTransport
|
|||||||
LogManager.Warning("[VisibilityManager] 没有指定要显示的项目");
|
LogManager.Warning("[VisibilityManager] 没有指定要显示的项目");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. 重置所有隐藏状态
|
// 1. 重置所有隐藏状态
|
||||||
document.Models.ResetAllHidden();
|
document.Models.ResetAllHidden();
|
||||||
|
|
||||||
// 2. 创建可见项集合(要保证从根节点开始的路径完整)
|
// 2. 创建可见项集合(要保证从根节点开始的路径完整)
|
||||||
ModelItemCollection visible = new ModelItemCollection();
|
ModelItemCollection visible = new ModelItemCollection();
|
||||||
|
|
||||||
foreach (ModelItem item in itemsToShow)
|
foreach (ModelItem item in itemsToShow)
|
||||||
{
|
{
|
||||||
// 添加祖先路径
|
// 添加祖先路径
|
||||||
if (item.AncestorsAndSelf != null)
|
if (item.AncestorsAndSelf != null)
|
||||||
visible.AddRange(item.AncestorsAndSelf);
|
visible.AddRange(item.AncestorsAndSelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 创建候选隐藏集合 - 收集所有可见项的兄弟节点
|
// 3. 创建候选隐藏集合 - 收集所有可见项的兄弟节点
|
||||||
ModelItemCollection hidden = new ModelItemCollection();
|
ModelItemCollection hidden = new ModelItemCollection();
|
||||||
|
|
||||||
foreach (ModelItem toShow in visible)
|
foreach (ModelItem toShow in visible)
|
||||||
{
|
{
|
||||||
if (toShow.Parent != null)
|
if (toShow.Parent != null)
|
||||||
@ -78,19 +78,19 @@ namespace NavisworksTransport
|
|||||||
hidden.AddRange(toShow.Parent.Children);
|
hidden.AddRange(toShow.Parent.Children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 从隐藏集合中移除可见项
|
// 4. 从隐藏集合中移除可见项
|
||||||
foreach (ModelItem toShow in visible)
|
foreach (ModelItem toShow in visible)
|
||||||
{
|
{
|
||||||
hidden.Remove(toShow);
|
hidden.Remove(toShow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 执行隐藏操作
|
// 5. 执行隐藏操作
|
||||||
if (hidden.Count > 0)
|
if (hidden.Count > 0)
|
||||||
{
|
{
|
||||||
document.Models.SetHidden(hidden, true);
|
document.Models.SetHidden(hidden, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
LogManager.Info($"[VisibilityManager] 隔离显示完成,耗时 {stopwatch.ElapsedMilliseconds}ms");
|
LogManager.Info($"[VisibilityManager] 隔离显示完成,耗时 {stopwatch.ElapsedMilliseconds}ms");
|
||||||
|
|
||||||
@ -102,5 +102,44 @@ namespace NavisworksTransport
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置指定模型项集合的可见性
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="items">要设置的模型项集合</param>
|
||||||
|
/// <param name="isHidden">是否隐藏(true=隐藏,false=显示)</param>
|
||||||
|
/// <returns>操作是否成功</returns>
|
||||||
|
public static bool SetItemsVisibility(ModelItemCollection items, bool isHidden)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var document = NavisApplication.ActiveDocument;
|
||||||
|
if (document == null || document.Models.Count == 0)
|
||||||
|
{
|
||||||
|
LogManager.Warning("[VisibilityManager] 没有加载的模型");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items == null || !items.Any())
|
||||||
|
{
|
||||||
|
LogManager.Warning("[VisibilityManager] 没有指定要操作的项目");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置可见性状态
|
||||||
|
document.Models.SetHidden(items, isHidden);
|
||||||
|
|
||||||
|
var action = isHidden ? "隐藏" : "显示";
|
||||||
|
LogManager.Info($"[VisibilityManager] 已{action} {items.Count} 个模型项");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var action = isHidden ? "隐藏" : "显示";
|
||||||
|
LogManager.Error($"[VisibilityManager] {action}指定项目失败: {ex.Message}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user