125 lines
5.4 KiB
C#
125 lines
5.4 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|
||
}
|