NavisworksTransport/doc/working/2026-04-06-navisworks-transform-api-official-reference.md
2026-04-09 23:09:56 +08:00

28 KiB
Raw Blame History

Navisworks 变换 API 官方原始定义整理

更新时间2026-04-06

本文只整理当前讨论中直接用到的 Navisworks .NET API 官方原始定义与语法。

原则:

  • 正文尽量保留官方原始内容
  • 不混入项目内部“局部坐标系”“参考姿态”等二次解释
  • 如果官方示例目录中未找到对应 API 的直接示例,就如实记录“未找到直接示例”
  • 只在最后增加一段简短归纳

1. DocumentModels.OverridePermanentTransform(...)

官方文档:

官方标题:

DocumentModels.OverridePermanentTransform Method

官方定义:

Apply an incremental transform to a selection.

官方 C# 语法:

public void OverridePermanentTransform(
    IEnumerable<ModelItem> items,
    Transform3D transform,
    bool updateModelTransform
)

官方 Remarks

If the selection contains any files, and the updateModelTransform
parameter is true, then instead of applying a transform to the
fragments, the File Units and Transform will be updated.

官方示例情况:

在官方 NET examples 目录中,未找到该方法的直接示例代码。

2. DocumentModels.ResetPermanentTransform(...)

官方文档:

官方标题:

DocumentModels.ResetPermanentTransform Method

官方定义:

Reset incremental transforms for all model items contained in the selection.

官方 C# 语法:

public void ResetPermanentTransform(
    IEnumerable<ModelItem> items
)

官方示例情况:

在官方 NET examples 目录中,未找到该方法的直接示例代码。

3. ModelGeometry.ActiveTransform

官方文档:

官方标题:

ModelGeometry.ActiveTransform Property

官方定义:

Returns the currently active transform of the geometry.

官方 C# 语法:

public Transform3D ActiveTransform { get; }

官方示例情况:

在官方 NET examples 目录中,未找到该属性的直接示例代码。

4. Transform3D

官方文档:

官方标题:

Transform3D Class

官方定义:

A generic transformation in 3D space.

官方 Remarks

Considered an immutable value type.

官方 C# 类型语法:

public class Transform3D : NativeHandle

官方成员页中可见的相关构造/工厂:

  • Transform3D(Rotation3D)
  • Transform3D(Matrix3, Vector3D)
  • Transform3D(Rotation3D, Vector3D)
  • CreateIdentity()
  • CreateTranslation(Vector3D)

来源:

官方示例情况:

在官方 NET examples 目录中,未找到该类型的直接示例代码。

5. Transform3D(Rotation3D)

官方文档:

官方定义:

Make a transform from a rotation (3D homogenous).

官方 C# 语法:

public Transform3D(
    Rotation3D rotation
)

6. Transform3D(Rotation3D, Vector3D)

官方文档:

官方定义:

Make a transform from a rotation and a translation.

官方 C# 语法:

public Transform3D(
    Rotation3D rotation,
    Vector3D translation
)

7. Transform3D.CreateIdentity()

官方文档:

官方定义:

Create an identity transform.

官方 C# 语法:

public static Transform3D CreateIdentity()

8. Transform3D.CreateTranslation(Vector3D)

官方文档:

官方定义:

Set matrix to be 3D homogenous translation matrix.

官方 C# 语法:

public static Transform3D CreateTranslation(
    Vector3D translation
)

9. Rotation3D(UnitVector3D, Double)

官方文档:

官方定义:

Create a rotation as a rotation about an axis by an angle.

官方 C# 语法:

public Rotation3D(
    UnitVector3D axis,
    double angle
)

官方示例情况:

在官方 NET examples 目录中,未找到该构造函数的直接示例代码。

10. Transform3D.Inverse()

官方文档:

官方定义:

Return inverse transformation.

官方 C# 语法:

public Transform3D Inverse()

11. Transform3D.Multiply(Transform3D, Transform3D)

官方文档:

官方定义:

Multiply two transformations in the order supplied.

官方 C# 语法:

public static Transform3D Multiply(
    Transform3D left,
    Transform3D right
)

12. 当前已用实验钉死的最小用法

本节不是官方原文,而是基于上面这些官方 API 和本仓库 ReadTransformTestCommand 的实验结果整理出的最小结论。

12.1 宿主世界轴直接转 90° 的 API 参数

90° 在 API 中应写成弧度:

Math.PI / 2.0

宿主世界轴应直接使用世界单位轴:

var hostX = new UnitVector3D(1, 0, 0);
var hostY = new UnitVector3D(0, 1, 0);
var hostZ = new UnitVector3D(0, 0, 1);

对应的旋转对象写法:

var rx90 = new Rotation3D(hostX, Math.PI / 2.0);
var ry90 = new Rotation3D(hostY, Math.PI / 2.0);
var rz90 = new Rotation3D(hostZ, Math.PI / 2.0);

如果要直接喂给 OverridePermanentTransform(...)

var transform = new Transform3D(ry90);
doc.Models.OverridePermanentTransform(items, transform, false);

12.2 从当前姿态到目标姿态的纯旋转增量

当前实验已经验证:

deltaRotation = currentInverse * target

在 API 上应写成:

var currentTransform = new Transform3D(currentRotation);
var targetTransform = new Transform3D(targetRotation);
var deltaTransform = Transform3D.Multiply(
    currentTransform.Inverse(),
    targetTransform);

已验证:

  • currentInverse * target
  • target * currentInverse 不对

12.3 纯旋转增量的默认旋转中心

当前实验已验证:

  • OverridePermanentTransform(..., rotationOnly, false) 的纯旋转增量默认绕宿主原点 (0,0,0) 生效

因此:

  • 不能把纯旋转理解成“围绕当前业务跟踪点原地自转”
  • Ground + 真实物体,旋转后必须再单独做位置重对齐

9. Transform3D.Factor(Vector3D worldCenter)

官方文档:

官方标题:

Transform3D.Factor Method (Vector3D)

官方定义:

Treat as homogenous 3D matrix and factor into scale orientation, scale, rotation and translation components.

官方 C# 语法:

public Transform3DComponents Factor(
    Vector3D worldCenter
)

目前从官方原文可确认:

  • 该重载显式接收 worldCenter
  • 说明 Transform3D 的分解结果与指定的世界中心有关

当前实验用途:

  • 用它比较“同一个旋转增量”在
    • worldCenter = (0,0,0)
    • worldCenter = 基线BoundingBox.Center
  • 两种情况下分解出来的 Translation
  • 以验证 Navisworks 增量旋转是否表现得像“绕宿主原点旋转”

9. Transform3DComponents

官方文档:

官方标题:

Transform3DComponents Class

官方定义:

Affine transform represented as individual components that combine to form complete transform. Immutable.

官方 Remarks

Affine transform represented as individual components that combine to form complete transform. Immutable. M = c' * so' * s * so * r * c * t * p, where so is scale orientation, s is scale, c is center, r is rotation and t is translation.

官方 C# 类型语法:

public class Transform3DComponents : NativeHandle

官方示例情况:

在官方 NET examples 目录中,未找到该类型的直接示例代码。

10. Transform3DComponents.Translation

官方文档:

官方定义:

The translation component of the transform.

官方 C# 语法:

public Vector3D Translation { get; set; }

11. Transform3DComponents.Rotation

官方文档:

官方定义:

The rotation component of the transform.

官方 C# 语法:

public Rotation3D Rotation { get; set; }

12. Transform3DComponents.Scale

官方文档:

官方定义:

The scale component of the transform.

官方 C# 语法:

public Vector3D Scale { get; set; }

13. Transform3DComponents.Combine()

官方文档:

官方定义:

Combine components together into a composite transform.

官方 C# 语法:

public Transform3D Combine()

14. Transform3D.Multiply(Transform3D, Transform3D)

官方文档:

官方定义:

Multiply two transforms in the order that the arguments are given, and return the result.

官方 C# 语法:

public static Transform3D Multiply(
    Transform3D leftTransform,
    Transform3D rightTransform
)

15. Transform3D.Factor()

官方文档:

官方定义:

Treat as homogenous 3D matrix and factor into scale orientation, scale, rotation and translation components.

官方 C# 语法:

public Transform3DComponents Factor()

16. Transform3D.Inverse()

官方文档:

官方定义:

Return inverse of matrix. Matrix must be non-singular (non-zero determinant).

官方 C# 语法:

public Transform3D Inverse()

官方异常说明:

ObjectDisposedException
Object has been Disposed

17. Transform3D.TranslateRight(Vector3D, Transform3D)

官方文档:

官方定义:

Translate a transform by a vector.

官方 C# 语法:

public static Transform3D TranslateRight(
    Vector3D translation,
    Transform3D transform
)

18. Rotation3D

官方文档:

官方 C# 类型语法:

public class Rotation3D : NativeHandle

19. Rotation3D(UnitVector3D, Double)

官方文档:

官方定义:

Creates rotation about given axis by angle in radians

官方 C# 语法:

public Rotation3D(
    UnitVector3D axis,
    double angle
)

20. Rotation3D.CreateFromEulerAngles(Double, Double, Double)

官方文档:

官方定义:

Creates a Euler angle rotation.
Parameters are in radians.
Rotation is created by combination of rotations about X, Y and Z axes.

官方 C# 语法:

public static Rotation3D CreateFromEulerAngles(
    double x,
    double y,
    double z
)

21. Rotation3D.ToAxisAndAngle()

官方文档:

官方定义:

Calculates an axis and angle representation of this rotation.

官方 C# 语法:

public AxisAndAngleResult ToAxisAndAngle()

22. Rotation3D.ToEulerAngles()

官方文档:

官方定义:

Calculates the Euler angles for this rotation.

官方 C# 语法:

public EulerAngleResult ToEulerAngles()

23. 由官方 API 原始定义直接能表达的增量求法

这一节不引入项目术语,只把前面几条官方定义并列摆出:

currentTransform = 当前生效的几何变换ModelGeometry.ActiveTransform
targetTransform = 目标完整 Transform3D
currentInverse = currentTransform.Inverse()
incrementalTransform = Transform3D.Multiply(targetTransform, currentInverse)
OverridePermanentTransform(..., incrementalTransform, ...)

这一段的依据完全来自前文官方定义:

  • ActiveTransform = Returns the currently active transform of the geometry.
  • Inverse() = Return inverse of matrix.
  • Multiply(left, right) = Multiply two transforms in the order that the arguments are given.
  • OverridePermanentTransform(...) = Apply an incremental transform to a selection.

这里只说明“这些 API 可以这样直接串起来表达完整当前变换 -> 目标变换 -> 增量变换”,不额外添加项目侧解释。


24. 官方示例检索结果

检索范围:

C:\Users\Tellme\apps\NavisworksTransport\doc\navisworks_api\NET\examples\

检索关键词:

OverridePermanentTransform
ResetPermanentTransform
ActiveTransform
Transform3DComponents
CreateTranslation
new Transform3D(

检索结论:

当前官方 NET examples 目录中,未找到这些 API 的直接示例代码。

因此本文中的“示例”部分不补写项目侧示例,只保留官方文档中的原始定义与语法。


25. 2026-04-06 Transform API 实验结论

以下结论来自仓库内实验按钮:

实验对象:

Chair Lounge Couch Double

实验日志位置:

C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\debug.log

25.1 纯旋转增量的真实行为

实验结果表明:

  • 对真实物体调用
    • OverridePermanentTransform(..., rotationOnly, false)
  • 其视觉效果等价于:
    • 绕宿主原点 (0,0,0) 旋转

已验证的旋转:

  • X + 90°
  • Y + 90°
  • Z + 90°

实验日志中,这三项都满足:

按原点旋转预期Center == 实际Center
误差 = (0, 0, 0)

因此当前可以视为已证实:

  • .NET API 下的纯旋转增量默认不是“围绕对象当前中心自转”
  • 而是“围绕宿主原点旋转”

25.2 Factor(worldCenter) 的语义价值

实验结果表明:

  • 对同一个纯旋转增量:
    • Factor(Vector3D.Zero) 得到的 Translation = (0,0,0)
    • Factor(基线Center) 会得到非零 Translation

这说明:

  • Transform3D 的分解结果确实依赖 worldCenter
  • Factor(worldCenter) 可以用于分析“同一变换相对于不同世界中心的平移语义”

但它只是:

  • 分解分析 API

不是:

  • “设置旋转中心”的构造 API

25.3 “绕指定中心旋转”的三种 API 组合实验

我们验证了三种做法,目标都是尝试复现 UI 中“指定变换中心后旋转”的效果。

做法 A直接把 T(center) * R * T(-center) 当作增量

结果:

  • 不成立
  • 对基线中心的误差为:
(427.280, -492.199, 0.000)

做法 B完整目标左乘

做法:

target = centerRotation * current
incremental = target * current.Inverse()

结果:

  • 与做法 A 等价
  • 同样不成立

做法 C完整目标右乘

做法:

target = current * centerRotation
incremental = target * current.Inverse()

结果:

  • 也不成立
  • 误差更大:
(693.643, 0.000, -689.804)

25.4 当前可以正式采用的结论

基于本轮实验,当前可以采用以下工程结论:

  1. OverridePermanentTransform(..., false) 的纯旋转增量,默认绕宿主原点旋转。
  2. 当前 .NET API 暴露的这套:
    • Transform3D.CreateTranslation
    • Rotation3D
    • Transform3D.Multiply
    • OverridePermanentTransform 不能直接复现 UI 的“指定变换中心旋转”语义。
  3. 因此对 Ground 这类业务链,不能把问题继续建模成“通过 API 复刻 UI 中心旋转”。
  4. Ground 更可靠的策略应是:
    • 接受旋转默认绕宿主原点
    • 再基于业务跟踪点语义做位置重对齐

25.5 当前未证实的事项

以下事项目前仍未在原始 API 文档中找到明确说明:

  1. UI 中“变换中心”是否有对应的 .NET API 可直接读写。
  2. UI 的“变换中心旋转”是否走的是另一套未公开的内部机制。
  3. 是否存在未被当前文档索引捕获的 COM API / UI API 可直接设置该中心。

26. 归纳

基于以上官方原始定义,可以先得到一个非常克制的结论:

  1. OverridePermanentTransform(...) 的官方语义就是“应用增量变换”。
  2. ResetPermanentTransform(...) 的官方语义就是“重置这层增量变换”。
  3. ModelGeometry.ActiveTransform 表示“当前生效的几何变换”。
  4. Transform3D / Transform3DComponents 官方暴露的核心概念是:
    • 平移
    • 旋转
    • 缩放
  5. Transform3D.Multiply(...) 官方明确说明“按参数给定顺序相乘”。
  6. Transform3D.Inverse() 官方明确是“返回矩阵逆”。
  7. Rotation3D(UnitVector3D, Double) 官方明确是“绕给定轴、按弧度创建旋转”。
  8. Rotation3D.CreateFromEulerAngles(...) 官方明确是“按 X/Y/Z 轴组合欧拉旋转,参数单位为弧度”。
  9. 这些官方定义里并没有把“局部业务坐标系解释”当成变换 API 的主语。

因此,从官方原始定义可以直接得到一个非常具体的增量表达方式:

  • 当前变换:ModelGeometry.ActiveTransform
  • 目标变换:调用方构造的 targetTransform
  • 增量变换:Transform3D.Multiply(targetTransform, currentTransform.Inverse())
  • 应用:OverridePermanentTransform(...)

因此,后续如果要重构真实物体变换工具,更合理的方向是:

  • 先把工具方法收成“宿主坐标系下的平移 / 旋转 / 缩放”
  • 再在需要时把它们组合成完整 Transform3D
  • 再用 currentTransform.Inverse()Transform3D.Multiply(...) 求增量
  • 最后把这个增量变换交给 OverridePermanentTransform(...)

而不是在变换工具层继续传播 reference axis / local axis / hostUpLocalAxis 之类的概念。


27. 2026-04-06 当天追加结论

基于当天对真实物体、Ground 起点、逐帧、实验按钮的连续实验,可以再补充一条更直接的工程结论:

  1. 对 Navisworks 当前这套增量 API真正稳定的做法只有最简单的增量法
    • 直接构造宿主坐标系下的旋转增量
    • 直接构造宿主坐标系下的平移增量
    • 按业务需要分步应用
  2. 对真实物体来说,旋转和平移不需要再引入“物体局部映射”来解释 API 行为。
  3. 也就是说,变换主语应始终是:
    • 宿主坐标系下绕哪根轴旋转
    • 宿主坐标系下平移多少
  4. 如果继续把问题建模成:
    • 先解释物体局部轴
    • 再把宿主旋转翻译成局部旋转
    • 再去重建完整目标姿态 这条链在真实物体上非常容易把问题复杂化,而且会引入额外歧义。
  5. 因此,后续 Ground 真实物体变换链的工程方向应当是:
    • 只保留宿主坐标系增量变换
    • 旋转和平移分开处理
    • 不再在变换工具层传播“局部坐标系 / 局部轴映射”概念

一句话总结:

  • 只有最简单的宿主坐标系增量法,才能尽量无副作用地做真实物体变换。
  • 旋转和平移不需要物体局部映射,局部坐标的概念可以从这条变换链里彻底移除。

28. 2026-04-09 Ground 真实物体增量链追加结论

以下结论来自 2026-04-09 对 Ground + 真实物体 的连续回归:

  • 起点落位
  • X / Y / Z 角度调整
  • 逐帧动画
  • 通行空间尺寸

以及同一对象在 Navisworks 中的实际可视结果与日志对照。

28.1 Ground 角度调整的正确主语

Ground + 真实物体,角度调整的正确主语仍然只有:

  • 宿主世界 X
  • 宿主世界 Y
  • 宿主世界 Z

也就是说:

  • XDegrees 就是绕宿主 X 轴的增量
  • YDegrees 就是绕宿主 Y 轴的增量
  • ZDegrees 就是绕宿主 Z 轴的增量

不需要再额外解释:

  • 物体当前局部轴
  • 参考姿态
  • 基姿态
  • fragment 代表姿态
  • 局部轴业务映射

28.2 角度调整必须按“单轴增量”逐次应用

本轮实验已经验证:

  • Ground 的角度调整不能先重建“完整目标姿态”
  • 也不能把多个轴的旋转先合成为一份“总姿态”再去应用

更稳定的工程做法是:

  1. 对当前物体直接叠加一个宿主轴旋转增量
  2. 一次只处理一个轴
  3. up 轴修正做完后,再处理路径方向对应的 yaw
  4. 最后再做平移补偿 / tracked point 对齐

一句话:

  • Ground 真实物体的角度调整应实现为“直接对物体叠加宿主轴增量”,而不是“先解释姿态,再重建目标姿态”。

28.3 不要从当前显示姿态反解新的平面角

本轮实际问题证明:

  • X / Zup 轴修正,如果先应用一次宿主轴增量
  • 再从修正后的当前显示姿态里重新反解 currentYaw
  • 很容易把非平面旋转的结果错误混入后续平面转向链

Ground 这条链,更稳定的做法是:

  • up 轴修正只负责自身的单轴增量旋转
  • 路径 yaw 仍然只作为“平面转向”处理
  • 不再把前一步的三维旋转结果重新解释成新的 yaw 起点

28.4 Ground 通行空间的正确数学模型

Ground + 真实物体 的通行空间,当前验证通过的最简单数学模型是:

  1. 先确定一组固定的宿主语义尺寸:
    • forward
    • side
    • up
  2. 再只根据宿主轴角度修正,计算旋转后的:
    • forwardExtent
    • sideExtent
    • upExtent
  3. 不再把这组三个尺寸二次投影到 pathForward

原因是:

  • 渲染器本身已经会把:
    • along
    • across
    • normal 摆到路径上
  • 如果在尺寸链里再按路径方向投影一次,就会把路径方向重复计算

因此对 Ground 通行空间,更合理的输入应当是:

  • 角度修正后的宿主语义尺寸

而不是:

  • 再投影到路径方向后的尺寸

28.5 当前已补齐的最小数学测试集合

本轮已经在:

补齐 Ground / YUp 下的宿主轴尺寸测试,包括:

  • X / Y / Z
  • 45 / 90 / 135 / 180 / 270

这些测试锁住的不是业务解释,而是最基础的数学结论:

  • 一个长方体在宿主语义尺寸下
  • 经宿主轴旋转后
  • forward / side / up 三个尺寸应如何变化

28.6 当前可以正式采用的 Ground 工程约束

Ground + 真实物体,当前可以正式采用以下工程约束:

  1. 起点、角度调整、逐帧动画都优先走宿主坐标系增量链。
  2. X / Y / Z 角度调整一次只处理一个宿主轴,不重建总姿态。
  3. yaw 只处理平面路径转向,不再承担三维姿态解释职责。
  4. 通行空间只消费“角度调整后的宿主语义尺寸”,不再重复按路径方向投影。
  5. 这条链不再传播:
    • 基姿态
    • 参考姿态
    • 局部轴映射
    • fragment 代表姿态 这些概念作为变换主语。

一句话总结:

  • Ground 真实物体这条链,已经证明“宿主轴单轴增量 + 平面 yaw + 平移补偿”是目前最稳定、最可控的实现方式。