清理多余的动画检测实时计算代码
This commit is contained in:
parent
f8320066c1
commit
12616629b0
@ -10,7 +10,7 @@
|
||||
4. [ ] (功能)动画检测时,过滤门和其他可通行构件
|
||||
5. [ ] (BUG)只有手动路径时,导出路径按钮没激活
|
||||
6. [ ] (BUG)重复打开模型,有时程序崩溃,需要先关闭物流插件窗口
|
||||
7. [ ] (优化)生成动画时,显示要检测的构件数量,当数量大于阈值时,给于警示,并预估处理时间。
|
||||
7. [ ] (优化)提高碰撞检测在处理大型模型时的性能
|
||||
|
||||
### [2025/12/05]
|
||||
|
||||
|
||||
@ -266,8 +266,13 @@ namespace NavisworksTransport.Core.Animation
|
||||
// 预计算动画帧和碰撞
|
||||
PrecomputeAnimationFrames();
|
||||
|
||||
// 关键修复:将车辆立即移动到路径起点
|
||||
// 这样动画就从路径起点开始,而不是从车辆当前位置开始
|
||||
// 验证预计算结果
|
||||
if (_animationFrames == null || _animationFrames.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("动画帧预计算失败,无法创建动画");
|
||||
}
|
||||
|
||||
// 将车辆移动到路径起点
|
||||
MoveVehicleToPathStart();
|
||||
|
||||
// 记录文档单位信息
|
||||
@ -595,8 +600,8 @@ namespace NavisworksTransport.Core.Animation
|
||||
LogManager.Info("TimeLiner 不可用,使用基础动画功能");
|
||||
}
|
||||
|
||||
// 设置动态碰撞检测(简化版本)
|
||||
SetupDynamicClashDetection();
|
||||
// 设置碰撞检测转发(用于高亮显示和UI更新)
|
||||
SetupCollisionReportForwarding();
|
||||
|
||||
// 初始化动画状态
|
||||
_animationStartTime = DateTime.Now;
|
||||
@ -1240,20 +1245,20 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置动态碰撞检测(实时模式,集成 Clash Detective)
|
||||
/// 设置碰撞报告转发(用于高亮显示和UI更新)
|
||||
/// </summary>
|
||||
private void SetupDynamicClashDetection()
|
||||
private void SetupCollisionReportForwarding()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 订阅碰撞检测事件
|
||||
ClashDetectiveIntegration.Instance.CollisionDetected += OnClashDetectiveCollisionDetected;
|
||||
|
||||
LogManager.Info("动态碰撞检测设置完成(实时模式)");
|
||||
LogManager.Info("碰撞报告转发设置完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"设置动态碰撞检测失败: {ex.Message}");
|
||||
LogManager.Error($"设置碰撞报告转发失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1283,18 +1288,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
CollisionDetected?.Invoke(this, e);
|
||||
}
|
||||
|
||||
// 已删除:CheckAndHighlightCollisions - 使用Clash Detective集成代替
|
||||
|
||||
/// <summary>
|
||||
/// 检查两个包围盒是否相交
|
||||
/// </summary>
|
||||
private bool BoundingBoxesIntersect(BoundingBox3D box1, BoundingBox3D box2)
|
||||
{
|
||||
return !(box1.Max.X < box2.Min.X || box2.Max.X < box1.Min.X ||
|
||||
box1.Max.Y < box2.Min.Y || box2.Max.Y < box1.Min.Y ||
|
||||
box1.Max.Z < box2.Min.Z || box2.Max.Z < box1.Min.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置动画持续时间
|
||||
/// </summary>
|
||||
@ -1690,115 +1683,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 快速测试TimeLiner API的可用性
|
||||
/// </summary>
|
||||
public bool TestTimeLinerAPI()
|
||||
{
|
||||
try
|
||||
{
|
||||
var doc = NavisApplication.ActiveDocument;
|
||||
|
||||
// 尝试访问TimeLiner
|
||||
var timeliner = doc.Timeliner;
|
||||
if (timeliner != null)
|
||||
{
|
||||
LogManager.Info("TimeLiner API基本可用");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info("TimeLiner API不可用");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Info($"TimeLiner API测试失败: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简化的动画设置方法,支持直接传入部件和路径
|
||||
/// </summary>
|
||||
/// <param name="component">部件模型</param>
|
||||
/// <param name="pathPoints">路径点列表</param>
|
||||
/// <param name="durationSeconds">动画持续时间(秒)</param>
|
||||
public bool SetupSimpleAnimation(ModelItem component, List<Point3D> pathPoints, double durationSeconds = 10.0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (component == null)
|
||||
{
|
||||
LogManager.Error("部件模型不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pathPoints == null || pathPoints.Count < 2)
|
||||
{
|
||||
LogManager.Error("路径点数量必须至少为2个");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 使用现有的SetupAnimation方法
|
||||
SetupAnimation(component, pathPoints, durationSeconds);
|
||||
|
||||
LogManager.Info($"简化动画设置成功:部件={component.DisplayName}, 路径点数={pathPoints.Count}, 时长={durationSeconds}秒");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"简化动画设置失败: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前选中的部件模型(简化版本)
|
||||
/// </summary>
|
||||
/// <returns>选中的部件模型,如果没有选中或选中多个则返回null</returns>
|
||||
public static ModelItem GetSelectedComponent()
|
||||
{
|
||||
try
|
||||
{
|
||||
var doc = NavisApplication.ActiveDocument;
|
||||
var selectedItems = doc.CurrentSelection.SelectedItems;
|
||||
|
||||
if (selectedItems.Count == 1)
|
||||
{
|
||||
var item = selectedItems.First;
|
||||
if (item.HasGeometry)
|
||||
{
|
||||
LogManager.Info($"已获取选中部件: {item.DisplayName}");
|
||||
return item;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning("选中的项目没有几何体,可能不适合用于动画");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (selectedItems.Count == 0)
|
||||
{
|
||||
LogManager.Info("没有选中任何项目");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info($"选中了{selectedItems.Count}个项目,请只选择一个部件");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"获取选中部件失败: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置动画帧率
|
||||
/// </summary>
|
||||
|
||||
@ -529,7 +529,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 从配置读取动画持续时间
|
||||
AnimationDuration = config.Animation.DurationSeconds;
|
||||
|
||||
// 设置初始状态 - 修改: 默认状态应该是未激活,等待有效动画
|
||||
// 设置初始状态 - 默认状态未激活,等待有效动画
|
||||
CanPauseAnimation = false;
|
||||
CanStopAnimation = false;
|
||||
|
||||
@ -540,9 +540,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 从配置读取碰撞检测参数
|
||||
DetectionGap = config.Animation.DetectionGapMeters;
|
||||
AnimationFrameRate = config.Animation.FrameRate;
|
||||
// 注意:CollisionDetectionAccuracy(步长)和MovementSpeed(速度)现在是计算属性,不需要设置初始值
|
||||
|
||||
// 修改: 使用新的按钮状态更新方法来设置正确的初始状态
|
||||
// 设置动画按钮的初始状态
|
||||
UpdateAnimationButtonStates();
|
||||
|
||||
LogManager.Info($"动画设置初始化完成 - 帧率:{SelectedFrameRate}fps, 持续时间:{AnimationDuration}秒, 检测间隙:{DetectionGap}米");
|
||||
@ -553,7 +552,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private void InitializeCommands()
|
||||
{
|
||||
// 原有命令
|
||||
StartAnimationCommand = new RelayCommand(async () => await ExecuteStartAnimationAsync(), () => CanStartAnimation);
|
||||
PauseAnimationCommand = new RelayCommand(async () => await ExecutePauseAnimationAsync(), () => CanPauseAnimation);
|
||||
StopAnimationCommand = new RelayCommand(async () => await ExecuteStopAnimationAsync(), () => CanStopAnimation);
|
||||
@ -561,8 +559,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
SelectAnimatedObjectCommand = new RelayCommand(ExecuteSelectAnimatedObject);
|
||||
ClearAnimatedObjectCommand = new RelayCommand(ExecuteClearAnimatedObject, () => HasSelectedAnimatedObject);
|
||||
GenerateAnimationCommand = new RelayCommand(ExecuteGenerateAnimation, () => CanGenerateAnimation);
|
||||
|
||||
// 媒体控制命令
|
||||
PlayForwardCommand = new RelayCommand(ExecutePlayForward, CanExecuteMediaCommands);
|
||||
PlayReverseCommand = new RelayCommand(ExecutePlayReverse, CanExecuteMediaCommands);
|
||||
StepForwardCommand = new RelayCommand(ExecuteStepForward, CanExecuteMediaCommands);
|
||||
@ -970,7 +966,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
OnPropertyChanged(nameof(MovementSpeed));
|
||||
OnPropertyChanged(nameof(PathLength));
|
||||
|
||||
// 使用新的统一按钮状态更新方法
|
||||
// 按钮状态更新
|
||||
UpdateAnimationButtonStates();
|
||||
|
||||
// 更新碰撞状态
|
||||
@ -992,11 +988,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
/// <summary>
|
||||
/// 处理动画进度变化事件
|
||||
/// 直接使用Dispatcher更新UI,避免UIStateManager的超时机制导致UI积压
|
||||
/// 使用Dispatcher更新UI
|
||||
/// </summary>
|
||||
private void OnAnimationProgressChanged(object sender, double progressPercent)
|
||||
{
|
||||
// 直接使用Dispatcher.BeginInvoke进行UI更新,避免UIStateManager的5秒超时导致积压
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
// 更新时间轴相关属性
|
||||
@ -1008,11 +1003,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
/// <summary>
|
||||
/// 处理动画状态变化事件
|
||||
/// 直接使用Dispatcher更新UI,避免UIStateManager的超时机制导致UI积压
|
||||
/// </summary>
|
||||
private void OnAnimationStateChanged(object sender, NavisworksTransport.Core.Animation.AnimationState state)
|
||||
{
|
||||
// 直接使用Dispatcher.BeginInvoke进行UI更新,避免UIStateManager的5秒超时导致积压
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
switch (state)
|
||||
@ -1346,8 +1339,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateMainStatus("动画对象分析失败,将使用实时计算");
|
||||
LogManager.Warning("[缓存预计算] 预计算失败,碰撞检测将使用实时计算模式");
|
||||
UpdateMainStatus("动画对象分析失败,无法生成动画");
|
||||
LogManager.Error("[缓存预计算] 预计算失败: 无法构建碰撞排除列表");
|
||||
}
|
||||
}));
|
||||
}
|
||||
@ -1404,15 +1397,19 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
if (!success)
|
||||
{
|
||||
LogManager.Warning("[动画生成] 动画对象分析失败,将使用实时计算模式");
|
||||
var msg = "[动画生成] 动画对象分析失败,无法继续生成动画";
|
||||
LogManager.Error(msg);
|
||||
UpdateMainStatus("生成失败:对象分析错误");
|
||||
return; // 关键修改:直接返回,不再回退到实时模式
|
||||
}
|
||||
}
|
||||
catch (Exception cacheEx)
|
||||
{
|
||||
LogManager.Warning($"[动画生成] 缓存构建失败: {cacheEx.Message},将使用实时计算模式");
|
||||
LogManager.Error($"[动画生成] 缓存构建失败: {cacheEx.Message}");
|
||||
UpdateMainStatus($"生成失败:{cacheEx.Message}");
|
||||
return; // 关键修改:处理异常并返回
|
||||
}
|
||||
|
||||
// 原有的动画生成逻辑
|
||||
UpdateMainStatus("正在生成路径动画...", -1, true);
|
||||
|
||||
// 设置动画参数到PathAnimationManager
|
||||
@ -1424,13 +1421,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 将PathRouteViewModel的点转换为Point3D列表
|
||||
var pathPoints = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
|
||||
|
||||
// 添加调试日志
|
||||
LogManager.Info($"[ExecuteGenerateAnimation] 准备创建动画: 路径名称='{CurrentPathRoute.Name}', ID='{CurrentPathRoute.Id}', 动画对象='{SelectedAnimatedObject.DisplayName}'");
|
||||
|
||||
// 使用PathAnimationManager创建物体动画(真正的物体移动动画,会设置状态为Ready)
|
||||
// 使用PathAnimationManager创建物体动画
|
||||
_pathAnimationManager.CreateAnimation(SelectedAnimatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name, CurrentPathRoute.Id);
|
||||
|
||||
// 更新状态 - 使用新的按钮状态更新方法
|
||||
// 更新状态
|
||||
UpdateAnimationButtonStates();
|
||||
UpdateMainStatus("动画生成成功");
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ namespace NavisworksTransport.UI.WPF
|
||||
|
||||
// 分层管理视图
|
||||
private LayerManagementView _layerManagementView;
|
||||
|
||||
|
||||
// 类别设置视图
|
||||
private ModelSettingsView _modelSettingsView;
|
||||
|
||||
@ -37,7 +37,7 @@ namespace NavisworksTransport.UI.WPF
|
||||
ViewModel = new LogisticsControlViewModel();
|
||||
SystemManagementViewModel = new SystemManagementViewModel(ViewModel); // 传递主ViewModel引用
|
||||
DataContext = ViewModel;
|
||||
|
||||
|
||||
// 为SystemManagementView设置独立的DataContext
|
||||
SystemManagementView.DataContext = SystemManagementViewModel;
|
||||
|
||||
@ -59,13 +59,13 @@ namespace NavisworksTransport.UI.WPF
|
||||
|
||||
// 创建分层管理视图,传入主ViewModel以启用统一状态栏
|
||||
_layerManagementView = new LayerManagementView(ViewModel);
|
||||
|
||||
|
||||
// 将分层管理视图添加到主界面
|
||||
LayerManagementContent.Content = _layerManagementView;
|
||||
|
||||
// 创建类别设置视图,传入主ViewModel引用以启用统一状态栏
|
||||
_modelSettingsView = new ModelSettingsView(ViewModel);
|
||||
|
||||
|
||||
// 将类别设置视图添加到主界面
|
||||
ModelSettingsContent.Content = _modelSettingsView;
|
||||
|
||||
@ -75,7 +75,7 @@ namespace NavisworksTransport.UI.WPF
|
||||
|
||||
// 初始化PathEditingView
|
||||
InitializePathEditingView();
|
||||
|
||||
|
||||
// 初始化SystemManagementView
|
||||
InitializeSystemManagementView();
|
||||
|
||||
@ -210,7 +210,7 @@ namespace NavisworksTransport.UI.WPF
|
||||
LogManager.Error($"初始化PathEditingView失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化SystemManagementView
|
||||
/// </summary>
|
||||
@ -336,13 +336,13 @@ namespace NavisworksTransport.UI.WPF
|
||||
|
||||
// 清理PathEditingView
|
||||
PathEditingView?.Cleanup();
|
||||
|
||||
|
||||
// 🔧 修复:清理ModelSettingsView(会调用ViewModel的Dispose)
|
||||
_modelSettingsView?.Cleanup();
|
||||
|
||||
|
||||
// 🔧 修复:清理LayerManagementView(会调用ViewModel的Dispose)
|
||||
_layerManagementView?.Cleanup();
|
||||
|
||||
|
||||
// 清理SystemManagementViewModel
|
||||
SystemManagementViewModel?.Cleanup();
|
||||
|
||||
@ -429,14 +429,13 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
// 优先从PathEditingView获取选中的路径
|
||||
PathRouteViewModel selectedPath = null;
|
||||
|
||||
|
||||
if (PathEditingView?.ViewModel?.SelectedPathRoute != null)
|
||||
{
|
||||
selectedPath = PathEditingView.ViewModel.SelectedPathRoute;
|
||||
LogManager.Info($"从PathEditingView同步路径: {selectedPath.Name}");
|
||||
}
|
||||
// 主ViewModel不再包含SelectedPathRoute,仅从PathEditingView获取路径
|
||||
|
||||
|
||||
if (selectedPath != null)
|
||||
{
|
||||
AnimationControlView.ViewModel.SetCurrentPath(selectedPath);
|
||||
@ -466,7 +465,7 @@ namespace NavisworksTransport.UI.WPF
|
||||
{
|
||||
await _layerManagementView.ViewModel.UpdateCurrentSelectionAsync();
|
||||
}
|
||||
|
||||
|
||||
// 同时更新类别设置视图的ViewModel
|
||||
if (_modelSettingsView?.DataContext is ModelSettingsViewModel modelSettingsViewModel)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user