NavisworksTransport/src/Utils/CollisionSceneHelper.cs

125 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 System;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Core;
using NavisworksTransport.Core.Animation;
namespace NavisworksTransport.Utils
{
/// <summary>
/// 碰撞场景辅助类
/// 提供碰撞场景还原和截图的通用功能
/// </summary>
public static class CollisionSceneHelper
{
/// <summary>
/// 将动画物体移动到碰撞位置并聚焦到碰撞场景
/// </summary>
/// <param name="collision">碰撞结果</param>
/// <param name="animatedObject">动画物体(运动物体)</param>
/// <param name="waitForViewUpdate">是否等待视图更新</param>
public static void MoveToCollisionAndFocus(CollisionResult collision, ModelItem animatedObject, bool waitForViewUpdate = true)
{
if (collision == null) return;
try
{
// 获取被撞对象Item2是运动物体碰撞的静态对象
var hitObject = collision.Item2 ?? collision.Item1;
if (hitObject != null)
{
// 清除之前的高亮
ModelHighlightHelper.ClearAllHighlights();
// 高亮被撞对象(使用碰撞检测结果专用红色)
ModelHighlightHelper.HighlightItems(ModelHighlightHelper.ClashDetectiveResultsCategory, new[] { hitObject });
// 聚焦到被撞对象
ViewpointHelper.FocusOnModelItem(hitObject, viewAngleDegrees: 60.0, targetViewRatio: 0.25);
LogManager.Info(string.Format("聚焦到被撞对象: {0}", hitObject.DisplayName));
}
// 移动动画物体到碰撞位置
if (animatedObject != null && collision.Item1 == animatedObject && collision.HasPositionInfo && collision.Item1Position != null)
{
// 计算目标底面位置Item1Position存储的是包围盒中心需要转换为底面
var bounds = animatedObject.BoundingBox();
double halfHeight = (bounds.Max.Z - bounds.Min.Z) / 2.0;
var targetGroundPosition = new Point3D(
collision.Item1Position.X,
collision.Item1Position.Y,
collision.Item1Position.Z - halfHeight
);
// 使用工具方法从CAD原始状态移动到目标位置
ModelItemTransformHelper.MoveItemToPositionAndYaw(animatedObject, targetGroundPosition, collision.Item1YawRadians);
LogManager.Info(string.Format("运动物体已移动到碰撞位置: ({0:F2}, {1:F2}, {2:F2}), 朝向: {3:F2}°",
targetGroundPosition.X, targetGroundPosition.Y, targetGroundPosition.Z,
collision.Item1YawRadians * 180 / Math.PI));
}
// 等待视图更新
if (waitForViewUpdate)
{
ViewpointHelper.WaitForViewUpdate();
}
}
catch (Exception ex)
{
LogManager.Error(string.Format("移动并聚焦到碰撞位置失败: {0}", ex.Message), ex);
}
}
/// <summary>
/// 保存动画物体当前状态
/// </summary>
/// <param name="animatedObject">动画物体</param>
/// <returns>状态快照</returns>
public static ModelItemTransformHelper.ObjectStateSnapshot SaveAnimatedObjectState(ModelItem animatedObject)
{
if (animatedObject == null) return null;
try
{
// 从PathAnimationManager获取当前实际朝向
var pam = PathAnimationManager.GetInstance();
var currentYaw = pam.CurrentYaw;
var state = ModelItemTransformHelper.SaveObjectState(animatedObject, currentYaw);
LogManager.Info(string.Format("已保存动画物体状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°",
animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z,
currentYaw * 180 / Math.PI));
return state;
}
catch (Exception ex)
{
LogManager.Error(string.Format("保存动画物体状态失败: {0}", ex.Message), ex);
return null;
}
}
/// <summary>
/// 恢复动画物体到保存的状态
/// </summary>
/// <param name="animatedObject">动画物体</param>
/// <param name="state">状态快照</param>
public static void RestoreAnimatedObjectState(ModelItem animatedObject, ModelItemTransformHelper.ObjectStateSnapshot state)
{
if (animatedObject == null || state == null) return;
try
{
ModelItemTransformHelper.RestoreObjectState(animatedObject, state);
LogManager.Info(string.Format("动画物体已恢复到原始状态: {0}", animatedObject.DisplayName));
}
catch (Exception ex)
{
LogManager.Error(string.Format("恢复动画物体状态失败: {0}", ex.Message), ex);
}
}
}
}