diff --git a/doc/design/2026/NavisworksAPI使用方法.md b/doc/design/2026/NavisworksAPI使用方法.md
index 93441de..8aa50a9 100644
--- a/doc/design/2026/NavisworksAPI使用方法.md
+++ b/doc/design/2026/NavisworksAPI使用方法.md
@@ -3678,3 +3678,430 @@ public static void SaveAndRestoreViewpointExample()
3. **理解每个属性的作用**:不要混淆"视图方向"和"向上向量"
4. **正确的设置顺序很重要**:Position → Rotation → AlignDirection → WorldUpVector
5. **使用 CreateCopy() 而不是 new Viewpoint()**:保留当前视角的其他属性
+
+## 13. 视角控制(Viewpoint)API
+
+基于 Focus 功能实现的真实API用法总结(ViewpointHelper开发经验)。
+
+### 13.1 核心API概念
+
+**关键发现**:`ModelItem.Transform` **不反映** override 后的位置变化,获取实际位置应使用 `BoundingBox().Center`。
+
+#### 视角控制的核心类
+
+| 类/方法 | 用途 | 关键特性 |
+|---------|------|---------|
+| `Viewpoint` | 视角状态对象 | 可修改 Position、Rotation、WorldUpVector |
+| `doc.CurrentViewpoint.Value` | 获取当前视角 | 需要用 `CreateCopy()` 创建副本修改 |
+| `AlignDirection(Vector3D)` | 旋转相机指向方向 | 使用最短路径旋转 |
+| `AlignUp(Vector3D)` | 旋转相机对齐向上向量 | 围绕视线方向旋转 |
+| `ZoomBox(BoundingBox3D)` | 强制适应视图 | **会覆盖**相机距离设置 |
+| `Rotation3D()` | 清除旋转状态 | 用于创建标准视角(俯视图等) |
+
+### 13.2 聚焦到模型对象的两种方法
+
+#### 方法一:距离计算法(精确控制物体占屏比例)
+
+适用于**聚焦到单个对象**,精确控制物体在视图中的占比。
+
+```csharp
+// ✅ 正确:计算相机距离实现目标占比
+public void FocusOnModelItem(ModelItem item, double viewAngleDegrees = 45.0,
+ double targetViewRatio = 0.25)
+{
+ Document doc = Application.ActiveDocument;
+
+ // 1. 获取对象包围盒
+ var boundingBox = item.BoundingBox();
+ Point3D targetCenter = boundingBox.Center;
+ double targetSize = Math.Max(boundingBox.Size.X, boundingBox.Size.Y);
+
+ // 2. 计算相机距离(使用FOV公式)
+ double fovRadians = viewAngleDegrees * Math.PI / 180.0;
+ double cameraDistance = (targetSize / 2.0) / Math.Tan(fovRadians / 2.0) / targetViewRatio;
+
+ // 3. 计算相机位置(使用模型标准视角向量)
+ Vector3D viewDirection = doc.FrontRightTopViewVector; // 标准45度视角
+ Vector3D upVector = doc.FrontRightTopViewUpVector;
+
+ Point3D cameraPosition = new Point3D(
+ targetCenter.X - viewDirection.X * cameraDistance,
+ targetCenter.Y - viewDirection.Y * cameraDistance,
+ targetCenter.Z - viewDirection.Z * cameraDistance
+ );
+
+ // 4. 应用视角
+ ApplyViewpoint(cameraPosition, targetCenter, upVector, useAlignDirection: true);
+}
+
+// 通用视角应用方法
+private static void ApplyViewpoint(Point3D cameraPosition, Point3D targetPoint,
+ Vector3D upVector, bool useAlignDirection)
+{
+ Document doc = Application.ActiveDocument;
+ Viewpoint newViewpoint = doc.CurrentViewpoint.Value.CreateCopy();
+
+ newViewpoint.Position = cameraPosition;
+
+ if (useAlignDirection)
+ {
+ // 使用AlignDirection/AlignUp精确控制方向
+ Vector3D lookDirection = new Vector3D(
+ targetPoint.X - cameraPosition.X,
+ targetPoint.Y - cameraPosition.Y,
+ targetPoint.Z - cameraPosition.Z);
+ lookDirection.Normalize();
+
+ newViewpoint.AlignDirection(lookDirection);
+ newViewpoint.AlignUp(upVector);
+ }
+ else
+ {
+ // 使用Rotation直接设置(适用于标准视角)
+ newViewpoint.Rotation = new Rotation3D();
+ newViewpoint.WorldUpVector = new UnitVector3D(upVector.X, upVector.Y, upVector.Z);
+ }
+
+ doc.CurrentViewpoint.CopyFrom(newViewpoint);
+}
+```
+
+**关键公式**:
+```
+cameraDistance = (targetSize / 2) / tan(FOV / 2) / targetViewRatio
+
+示例:
+- targetSize = 2米, FOV = 45°, ratio = 0.25 (25%占屏)
+- cameraDistance = 1.0 / tan(22.5°) / 0.25 ≈ 9.66 米
+```
+
+#### 方法二:ZoomBox法(确保完整可见)
+
+适用于**显示路径、多个对象或大型物体**,确保完全可见。
+
+```csharp
+// ✅ 正确:使用ZoomBox确保完整可见性
+public void FocusOnBoundingBox(BoundingBox3D bounds, double marginRatio = 0.1)
+{
+ Document doc = Application.ActiveDocument;
+
+ // 1. 计算扩展后的包围盒(添加边距)
+ Vector3D size = bounds.Size;
+ Vector3D margin = new Vector3D(
+ size.X * marginRatio,
+ size.Y * marginRatio,
+ size.Z * marginRatio
+ );
+
+ BoundingBox3D expandedBox = new BoundingBox3D(
+ new Point3D(bounds.Min.X - margin.X, bounds.Min.Y - margin.Y, bounds.Min.Z - margin.Z),
+ new Point3D(bounds.Max.X + margin.X, bounds.Max.Y + margin.Y, bounds.Max.Z + margin.Z)
+ );
+
+ // 2. 设置相机位置(估算)
+ Point3D targetCenter = expandedBox.Center;
+ Vector3D viewDirection = doc.FrontRightTopViewVector;
+ double estimatedDistance = Math.Max(size.X, size.Y) * 2.0;
+
+ Point3D cameraPosition = new Point3D(
+ targetCenter.X - viewDirection.X * estimatedDistance,
+ targetCenter.Y - viewDirection.Y * estimatedDistance,
+ targetCenter.Z - viewDirection.Z * estimatedDistance
+ );
+
+ // 3. 应用视角(设置Rotation和UpVector)
+ ApplyViewpoint(cameraPosition, targetCenter, doc.FrontRightTopViewUpVector,
+ useAlignDirection: false);
+
+ // 4. 关键:使用ZoomBox强制适应视图
+ doc.ActiveView.ZoomBox(expandedBox); // ZoomBox会覆盖相机距离
+}
+```
+
+### 13.3 模型标准视角向量
+
+**重要发现**:Navisworks 提供模型特定的标准视角向量。
+
+```csharp
+// ✅ 获取模型的标准视角方向(45度俯视)
+Vector3D standardViewDirection = doc.FrontRightTopViewVector;
+Vector3D standardUpVector = doc.FrontRightTopViewUpVector;
+
+// 其他可用视角向量:
+// - FrontViewVector / FrontViewUpVector // 正视图
+// - TopViewVector / TopViewUpVector // 俯视图
+// - RightViewVector / RightViewUpVector // 右视图
+// - FrontRightTopViewVector / ... // 45度俯视(最常用)
+```
+
+**使用场景**:
+- **Focus功能**:使用 `FrontRightTopViewVector` 保持与UI一致的标准视角
+- **正视图截图**:使用 `FrontViewVector` 获取正交投影效果
+- **俯视图分析**:使用 `TopViewVector` 进行平面分析
+
+### 13.4 相机距离计算方法对比
+
+| 方法 | 适用场景 | 优点 | 缺点 |
+|------|---------|------|------|
+| FOV公式法 | 单个对象聚焦 | 精确控制占屏比例 | 需要计算目标尺寸 |
+| ZoomBox法 | 路径/多对象显示 | 确保完全可见,自动计算距离 | 覆盖相机位置设置 |
+| 固定距离 | 快速预览 | 简单快速 | 对象大小不一时效果差 |
+
+**FOV计算代码详解**:
+
+```csharp
+// 计算相机距离的完整公式
+private static double CalculateCameraDistance(double targetSize, double fovDegrees,
+ double targetRatio)
+{
+ // 1. 转换FOV为弧度
+ double fovRadians = fovDegrees * Math.PI / 180.0;
+
+ // 2. 计算半角正切值
+ double halfFovTan = Math.Tan(fovRadians / 2.0);
+
+ // 3. 计算目标在FOV中占据一半时的距离
+ // targetSize/2 是目标半宽,halfFovTan 是半角正切
+ double distanceForFullTarget = (targetSize / 2.0) / halfFovTan;
+
+ // 4. 根据目标占屏比例调整距离
+ // ratio=0.5表示目标占视图50%,距离减半
+ double finalDistance = distanceForFullTarget / targetRatio;
+
+ return finalDistance;
+}
+
+// 使用示例:
+// targetSize=3m, FOV=45°, ratio=0.25 → distance ≈ 14.5m
+// 这意味着相机距离目标14.5米时,3米宽的物体将占据视图的25%
+```
+
+### 13.5 常见错误和解决方案
+
+#### 错误1:混用距离计算和ZoomBox
+
+```csharp
+// ❌ 错误:先设置相机距离,再用ZoomBox覆盖
+var viewpoint = doc.CurrentViewpoint.Value.CreateCopy();
+viewpoint.Position = calculatedPosition; // 设置位置
+doc.CurrentViewpoint.CopyFrom(viewpoint);
+doc.ActiveView.ZoomBox(bounds); // ZoomBox会覆盖之前的距离设置!
+
+// ✅ 正确:二选一
+// 方案A:只用距离计算(不调用ZoomBox)
+viewpoint.Position = calculatedPosition;
+doc.CurrentViewpoint.CopyFrom(viewpoint);
+
+// 方案B:用ZoomBox(距离会被自动计算)
+doc.ActiveView.ZoomBox(bounds);
+```
+
+#### 错误2:忽略Rotation3D的影响
+
+```csharp
+// ❌ 错误:不清除旋转直接设置视角
+var viewpoint = doc.CurrentViewpoint.Value.CreateCopy();
+viewpoint.Position = newPosition;
+viewpoint.AlignDirection(newDirection); // 可能受原有旋转影响
+doc.CurrentViewpoint.CopyFrom(viewpoint);
+
+// ✅ 正确:创建新Rotation3D清除旋转状态
+var viewpoint = doc.CurrentViewpoint.Value.CreateCopy();
+viewpoint.Rotation = new Rotation3D(); // 清除旋转
+viewpoint.AlignDirection(newDirection); // 从标准状态开始
+viewpoint.AlignUp(newUpVector);
+doc.CurrentViewpoint.CopyFrom(viewpoint);
+```
+
+#### 错误3:使用错误的向上向量
+
+```csharp
+// ❌ 错误:假设世界Z轴是向上向量
+Vector3D upVector = new Vector3D(0, 0, 1);
+
+// ✅ 正确:使用模型的标准向上向量
+Vector3D upVector = doc.FrontRightTopViewUpVector;
+
+// 或者根据需要计算正确的向上向量
+// 例如:俯视图中,Y轴可能是向上
+Vector3D topViewUp = new Vector3D(0, 1, 0);
+```
+
+### 13.6 实用工具代码
+
+```csharp
+///
+/// 视角控制工具类 - 基于实际项目经验
+///
+public static class ViewpointHelper
+{
+ ///
+ /// 聚焦到单个模型对象(精确控制占屏比例)
+ ///
+ public static void FocusOnModelItem(ModelItem item, double viewAngleDegrees = 45.0,
+ double targetViewRatio = 0.25)
+ {
+ if (item == null) return;
+
+ var bounds = item.BoundingBox();
+ Point3D targetCenter = bounds.Center;
+ double targetSize = Math.Max(bounds.Size.X, bounds.Size.Y);
+
+ // 计算相机距离
+ double cameraDistance = CalculateCameraDistance(
+ targetSize, viewAngleDegrees, targetViewRatio);
+
+ // 使用模型标准视角
+ Document doc = Application.ActiveDocument;
+ Vector3D viewDir = doc.FrontRightTopViewVector;
+ Vector3D upVector = doc.FrontRightTopViewUpVector;
+
+ Point3D cameraPos = new Point3D(
+ targetCenter.X - viewDir.X * cameraDistance,
+ targetCenter.Y - viewDir.Y * cameraDistance,
+ targetCenter.Z - viewDir.Z * cameraDistance
+ );
+
+ ApplyViewpoint(cameraPos, targetCenter, upVector, useAlignDirection: true);
+ }
+
+ ///
+ /// 聚焦到碰撞点(两个对象的中间位置)
+ ///
+ public static void FocusOnCollision(ModelItem item1, ModelItem item2,
+ double viewAngleDegrees = 45.0)
+ {
+ var bounds1 = item1.BoundingBox();
+ var bounds2 = item2.BoundingBox();
+
+ // 计算碰撞中心(两个包围盒最近的点)
+ Point3D collisionCenter = CalculateCollisionCenter(bounds1, bounds2);
+ double maxSize = Math.Max(
+ Math.Max(bounds1.Size.X, bounds1.Size.Y),
+ Math.Max(bounds2.Size.X, bounds2.Size.Y)
+ );
+
+ double cameraDistance = CalculateCameraDistance(
+ maxSize, viewAngleDegrees, 0.35);
+
+ Document doc = Application.ActiveDocument;
+ Vector3D viewDir = doc.FrontRightTopViewVector;
+ Vector3D upVector = doc.FrontRightTopViewUpVector;
+
+ Point3D cameraPos = new Point3D(
+ collisionCenter.X - viewDir.X * cameraDistance,
+ collisionCenter.Y - viewDir.Y * cameraDistance,
+ collisionCenter.Z - viewDir.Z * cameraDistance
+ );
+
+ ApplyViewpoint(cameraPos, collisionCenter, upVector, useAlignDirection: true);
+ }
+
+ ///
+ /// 聚焦到指定点和大小的区域(ZoomBox法)
+ ///
+ public static void FocusOnPosition(Point3D center, double size,
+ double marginRatio = 0.1)
+ {
+ Document doc = Application.ActiveDocument;
+
+ // 创建目标包围盒
+ double halfSize = size / 2.0;
+ double margin = size * marginRatio;
+
+ BoundingBox3D targetBox = new BoundingBox3D(
+ new Point3D(center.X - halfSize - margin, center.Y - halfSize - margin,
+ center.Z - halfSize - margin),
+ new Point3D(center.X + halfSize + margin, center.Y + halfSize + margin,
+ center.Z + halfSize + margin)
+ );
+
+ // 先设置视角方向
+ Vector3D viewDir = doc.FrontRightTopViewVector;
+ Vector3D upVector = doc.FrontRightTopViewUpVector;
+ double distance = size * 2.0;
+
+ Point3D cameraPos = new Point3D(
+ center.X - viewDir.X * distance,
+ center.Y - viewDir.Y * distance,
+ center.Z - viewDir.Z * distance
+ );
+
+ ApplyViewpoint(cameraPos, center, upVector, useAlignDirection: false);
+
+ // 使用ZoomBox确保可见
+ doc.ActiveView.ZoomBox(targetBox);
+ }
+
+ // 私有辅助方法...
+ private static double CalculateCameraDistance(double targetSize, double fovDegrees,
+ double ratio)
+ {
+ double fovRadians = fovDegrees * Math.PI / 180.0;
+ return (targetSize / 2.0) / Math.Tan(fovRadians / 2.0) / ratio;
+ }
+
+ private static void ApplyViewpoint(Point3D cameraPos, Point3D target,
+ Vector3D upVector, bool useAlignDirection)
+ {
+ Document doc = Application.ActiveDocument;
+ Viewpoint vp = doc.CurrentViewpoint.Value.CreateCopy();
+
+ vp.Position = cameraPos;
+
+ if (useAlignDirection)
+ {
+ Vector3D lookDir = new Vector3D(
+ target.X - cameraPos.X,
+ target.Y - cameraPos.Y,
+ target.Z - cameraPos.Z);
+ lookDir.Normalize();
+ vp.AlignDirection(lookDir);
+ vp.AlignUp(upVector);
+ }
+ else
+ {
+ vp.Rotation = new Rotation3D();
+ vp.WorldUpVector = new UnitVector3D(upVector.X, upVector.Y, upVector.Z);
+ }
+
+ doc.CurrentViewpoint.CopyFrom(vp);
+ }
+}
+```
+
+### 13.7 视角控制最佳实践
+
+1. **选择合适的聚焦方法**:
+ - 单个对象精确聚焦 → 距离计算法
+ - 路径或区域显示 → ZoomBox法
+ - 碰撞点查看 → 碰撞中心计算 + 距离法
+
+2. **使用模型标准视角向量**:
+ - 不要硬编码向量值
+ - 使用 `doc.FrontRightTopViewVector` 等API
+
+3. **理解ZoomBox的副作用**:
+ - ZoomBox会覆盖相机距离设置
+ - ZoomBox后不要再调整Position来微调距离
+
+4. **正确处理Rotation3D**:
+ - 创建新视角时,先用 `new Rotation3D()` 清除旋转
+ - 再使用 `AlignDirection` 设置精确方向
+
+5. **保存和恢复视角**:
+ ```csharp
+ // 保存
+ Viewpoint savedView = doc.CurrentViewpoint.Value.CreateCopy();
+
+ // ... 修改视角 ...
+
+ // 恢复
+ doc.CurrentViewpoint.CopyFrom(savedView);
+ ```
+
+---
+
+**文档版本**:2026.2
+**最后更新**:基于 ViewpointHelper 重构经验(聚焦功能实现)
+**适用版本**:Navisworks Manage 2026
diff --git a/src/Utils/ViewpointHelper.cs b/src/Utils/ViewpointHelper.cs
index 97dd9a0..51fb996 100644
--- a/src/Utils/ViewpointHelper.cs
+++ b/src/Utils/ViewpointHelper.cs
@@ -104,31 +104,14 @@ namespace NavisworksTransport.Utils
double cameraDistanceMeters = UnitsConverter.ConvertToMeters(cameraDistance);
LogManager.Info($"相机设置: 位置=({cameraPosition.X:F2}, {cameraPosition.Y:F2}, {cameraPosition.Z:F2}), 焦点=({focusCenter.X:F2}, {focusCenter.Y:F2}, {focusCenter.Z:F2}), 相机距离={cameraDistanceMeters:F2}米");
- // 3. 创建当前视角的副本(关键:使用 CreateCopy 而不是 new Viewpoint())
- Viewpoint newViewpoint = doc.CurrentViewpoint.Value.CreateCopy();
-
- // 设置标准俯视图的相机配置
- // 相机位置:在目标正上方
- newViewpoint.Position = cameraPosition;
-
- // 直接设置 Rotation 为无旋转(单位四元数),实现标准的俯视图
- // 这样可以彻底清除任何旋转,使视图与世界坐标轴对齐
- newViewpoint.Rotation = new Rotation3D();
-
- // 设置向上向量:Y 轴向上(标准俯视图的向上方向)
- newViewpoint.WorldUpVector = new UnitVector3D(0, 1, 0);
-
- // 4. 扩展路径包围盒,避免边缘贴得太近
+ // 3. 计算扩展边距
double boxWidth = viewBoundingBox.Max.X - viewBoundingBox.Min.X;
double expansionFactor = VIEW_BOUNDING_BOX_EXPANSION_FACTOR + (EXPANSION_METERS / baseDimension);
double expansionMargin = boxWidth * (expansionFactor - 1) / 2;
- BoundingBox3D expandedViewBoundingBox = BoundingBoxGeometryUtils.ExpandBoundingBox(viewBoundingBox, expansionMargin);
- // 5. 使用 ZoomBox 调整视野范围(使用扩展后的视野包围盒,确保整个路径都在视野内)
- newViewpoint.ZoomBox(expandedViewBoundingBox);
-
- // 6. 应用视角到文档
- doc.CurrentViewpoint.CopyFrom(newViewpoint);
+ // 4. 应用视角(使用通用方法,带 ZoomBox)
+ Vector3D upVector = new Vector3D(0, 1, 0); // Y轴向上
+ ApplyViewpointWithZoomBox(cameraPosition, focusCenter, upVector, viewBoundingBox, expansionMargin);
LogManager.Info($"视角已调整完成: 俯视图(已摆正), 基准尺寸={baseDimension:F2}米, 相机距离={cameraDistanceMeters:F2}米, FOV=自动, 包围盒扩展系数={VIEW_BOUNDING_BOX_EXPANSION_FACTOR:F1}, 扩展边距={expansionMargin:F2}米");
}
@@ -277,6 +260,88 @@ namespace NavisworksTransport.Utils
System.Threading.Thread.Sleep(VIEW_UPDATE_DELAY_MS);
}
+ #region 通用视角设置方法
+
+ ///
+ /// 应用视角设置(核心通用方法)
+ ///
+ /// 相机位置
+ /// 目标点(相机看向的位置)
+ /// 相机上方向
+ /// 是否使用 AlignDirection/AlignUp(true)还是直接设置 Rotation(false)
+ private static void ApplyViewpoint(Point3D cameraPosition, Point3D targetPoint, Vector3D upVector, bool useAlignDirection = true)
+ {
+ Document doc = Application.ActiveDocument;
+ if (doc == null || doc.IsClear)
+ {
+ throw new InvalidOperationException("没有活动的文档");
+ }
+
+ Viewpoint newViewpoint = doc.CurrentViewpoint.Value.CreateCopy();
+ newViewpoint.Position = cameraPosition;
+
+ if (useAlignDirection)
+ {
+ // 方法1:使用 AlignDirection + AlignUp(推荐用于聚焦对象)
+ Vector3D lookDirection = new Vector3D(
+ targetPoint.X - cameraPosition.X,
+ targetPoint.Y - cameraPosition.Y,
+ targetPoint.Z - cameraPosition.Z
+ );
+ lookDirection.Normalize();
+ newViewpoint.AlignDirection(lookDirection);
+ newViewpoint.AlignUp(upVector);
+ }
+ else
+ {
+ // 方法2:直接设置 Rotation 和 WorldUpVector(用于标准俯视图等)
+ newViewpoint.Rotation = new Rotation3D();
+ newViewpoint.WorldUpVector = new UnitVector3D(upVector.X, upVector.Y, upVector.Z);
+ }
+
+ doc.CurrentViewpoint.CopyFrom(newViewpoint);
+ }
+
+ ///
+ /// 应用视角并缩放视野(使用 ZoomBox)
+ ///
+ /// 相机位置
+ /// 目标点
+ /// 相机上方向
+ /// 视野包围盒(用于 ZoomBox)
+ /// 包围盒扩展边距
+ private static void ApplyViewpointWithZoomBox(Point3D cameraPosition, Point3D targetPoint, Vector3D upVector, BoundingBox3D viewBoundingBox, double expansionMargin = 0)
+ {
+ Document doc = Application.ActiveDocument;
+ if (doc == null || doc.IsClear)
+ {
+ throw new InvalidOperationException("没有活动的文档");
+ }
+
+ Viewpoint newViewpoint = doc.CurrentViewpoint.Value.CreateCopy();
+ newViewpoint.Position = cameraPosition;
+
+ // 使用 AlignDirection + AlignUp
+ Vector3D lookDirection = new Vector3D(
+ targetPoint.X - cameraPosition.X,
+ targetPoint.Y - cameraPosition.Y,
+ targetPoint.Z - cameraPosition.Z
+ );
+ lookDirection.Normalize();
+ newViewpoint.AlignDirection(lookDirection);
+ newViewpoint.AlignUp(upVector);
+
+ // 使用 ZoomBox 调整视野
+ BoundingBox3D expandedBox = expansionMargin > 0
+ ? BoundingBoxGeometryUtils.ExpandBoundingBox(viewBoundingBox, expansionMargin)
+ : viewBoundingBox;
+ newViewpoint.ZoomBox(expandedBox);
+
+ doc.CurrentViewpoint.CopyFrom(newViewpoint);
+ }
+
+ #endregion
+
#region 模型元素聚焦方法
///
@@ -326,31 +391,9 @@ namespace NavisworksTransport.Utils
// 3. 计算相机位置(使用模型标准视角方向)
Point3D cameraPosition = CalculateCameraPosition(center, maxDimension, viewAngleDegrees, targetViewRatio);
- // 4. 创建视角并设置相机
- Viewpoint newViewpoint = doc.CurrentViewpoint.Value.CreateCopy();
- newViewpoint.Position = cameraPosition;
-
- // 获取模型的标准视角向量
- Vector3D viewDirection = doc.FrontRightTopViewVector;
- viewDirection.Normalize();
-
- // 使用 AlignDirection 设置相机朝向(看向目标方向)
- // 方向是从相机指向目标
- Vector3D lookDirection = new Vector3D(
- center.X - cameraPosition.X,
- center.Y - cameraPosition.Y,
- center.Z - cameraPosition.Z
- );
- lookDirection.Normalize();
- newViewpoint.AlignDirection(lookDirection);
-
- // 使用 AlignUp 设置相机的上方向(基于模型的标准上方向)
+ // 4. 应用视角(使用通用方法)
Vector3D upVector = doc.FrontRightTopViewUpVector;
- upVector.Normalize();
- newViewpoint.AlignUp(upVector);
-
- // 5. 应用视角(不使用 ZoomBox,让相机距离决定视野比例)
- doc.CurrentViewpoint.CopyFrom(newViewpoint);
+ ApplyViewpoint(cameraPosition, center, upVector, useAlignDirection: true);
LogManager.Info($"视角已调整: 标准前右上视角, 目标占据视图{targetViewRatio:P0}");
}
@@ -446,30 +489,9 @@ namespace NavisworksTransport.Utils
// 计算相机位置(使用模型标准视角方向)
Point3D cameraPosition = CalculateCameraPosition(center, targetSize, viewAngleDegrees, 0.25);
- // 创建视角并设置相机
- Viewpoint newViewpoint = doc.CurrentViewpoint.Value.CreateCopy();
- newViewpoint.Position = cameraPosition;
-
- // 获取模型的标准视角向量
- Vector3D viewDirection = doc.FrontRightTopViewVector;
- viewDirection.Normalize();
-
- // 使用 AlignDirection 设置相机朝向
- Vector3D lookDirection = new Vector3D(
- center.X - cameraPosition.X,
- center.Y - cameraPosition.Y,
- center.Z - cameraPosition.Z
- );
- lookDirection.Normalize();
- newViewpoint.AlignDirection(lookDirection);
-
- // 使用 AlignUp 设置相机的上方向
+ // 应用视角(使用通用方法)
Vector3D upVector = doc.FrontRightTopViewUpVector;
- upVector.Normalize();
- newViewpoint.AlignUp(upVector);
-
- // 应用视角(不使用 ZoomBox,让相机距离决定视野比例)
- doc.CurrentViewpoint.CopyFrom(newViewpoint);
+ ApplyViewpoint(cameraPosition, center, upVector, useAlignDirection: true);
}
catch (Exception ex)
{