Building Coder(Revit 二次开发) - GetInstanceGeometry() 的开销和无效的引用

来源:互联网 发布:oracle数据库基础 编辑:程序博客网 时间:2024/06/06 12:37
原文链接:GetInstanceGeometry Overhead and Invalid References

通过 GeometryInstance.GetInstanceGeometry() 方法可以获取一个族类型(Family Symbol)的几何数据。来自 Revit API 文档的更准确的说法是:该方法会计算对象的几何特征。注意这里的“计算”真的意味着复杂的计算过程,因此会导致明显的系统开销。

几何数据是针对包含对象的模型所在的坐标系统的。实例对象的上下文(例如:有效的材质)将被应用到族类型。注意该方法的处理中包含对 Revit 数据结构的全面解析。所以如果你的应用对性能敏感,请慎重调用。


在解析对象的几何数据时,Revit 使用和获取该对象本身相同的设置。返回的结果是对象几何数据的一份拷贝,可转换为其它数据格式或者进行分析。但是由于该方法返回的是一份拷贝,所以返回结果中 Revit 元素的引用不能被用于对 Revit 模型的任何修改(例如:创建尺寸)。只有 GetSymbolGeometry() 返回的且没有经过转换(Transform)的几何数据可用于对 Revit 模型的修改。


关于这个问题,《开发者指南》的 Geometry Instance 章节也有明确说明。

问题
我使用 AVF (Analysis Visualization Framework)在指定的面上绘制临时图像。当时使用如下代码应用 AVF 时,一切正常。
  int idx = sfm.AddSpatialFieldPrimitive( face, Transform.Identity );

但是使用如下代码就会导致 Revit 抛出一个异常,提示 reference 必须指向一个在视图中可见的面或者曲线。
 int idx = sfm.AddSpatialFieldPrimitive( face.Reference );

但是我认为这个异常消息不对。我确定这个面是可见的。现在的问题是:我必须使用 AddSpatialFieldPrimitive(Reference ref) 这个重载版本,因为我需要额外指定 SpatialFieldPrimitiveHideMode 参数。
  AddSpatialFieldPrimitive( Reference, SpatialFieldPrimitiveHideMode )

回答
你的问题在于使用了 GeometryInstance.GetInstanceGeometry() 方法的返回结果,然后通过 AVF 访问其中的 Reference。通过上面的说明,你应该认识到这些 Reference 是无效的。你应该改用 GetSymbolGeometry() 方法。其它类似的场景包括:创建尺寸、基于面的族实例创建、以及草图平面创建。

GetInstanceGeometry() 方法的设计初衷是为几何数据的获取提供一个快速方式,然后开发人员可以将这些数据转换为其它格式、或者与一个实体进行布尔操作、或者其它的不需要访问原始元素的几何操作。