在Revit模型中存储数据

使用共享参数或可扩展存储在Revit模型中存储数据。

Revit API提供了两种在Revit模型中存储数据的方法。第一种是使用共享参数。通过Revit API,可以通过编程方式访问通过Revit UI提供的相同共享参数功能。如果共享参数被定义为可见,则用户可以在元素的属性窗口中查看这些参数。可以将共享参数指定给许多(但不是所有)类别的图元。有关详细信息,请参阅共享参数。

另一个选项是可扩展存储,它允许您创建自定义数据结构,然后将该数据的实例分配给模型中的元素。用户在Revit UI中永远看不到这些数据,但其他第三方应用程序可以通过Revit API访问这些数据,具体取决于定义模式时分配给该模式的读/写访问权限。与共享参数不同,可扩展存储不限于某些类别的元素。可扩展存储数据可以指定给从Revit模型中的基类Element派生的任何对象。

本节中的页面

  • 可扩展存储

可扩展存储

创建您自己的类模式数据结构,并将其实例附加到Revit模型中的任何元素。

基于schema的数据与Revit模型一起保存,并允许更高级别的、元数据增强的、面向对象的数据结构。schema数据可以配置为对所有用户可读和/或可写,仅对特定应用程序供应商可读和/或可写,或仅对来自供应商的特定应用程序可读和/或可写。

在Revit中使用Elements存储数据时,必须执行以下步骤:

  1. 创建并命名新schema
  2. 设置schema的读/写访问权限
  3. 为schema定义一个或多个数据字段
  4. 基于schema创建实体
  5. 为实体的字段分配值
  6. 将图元与Revit图元关联

Schema和SchemaBuilder

创建可扩展存储的第一步是定义schema。schema类似于面向对象编程语言中的class。使用SchemaBuilder类构造函数创建新schema。SchemaBuilder是一个用于创建schema的帮助类。一旦使用SchemaBuilder完成schema,就可以使用Schema类访问schema的属性。在该阶段,schema不再是可编辑的。

尽管SchemaBuilder构造函数接受一个用于标识schema的字符串,但schema名称也是必需的。创建schema之后,调用SchemaBuilder.SetSchemaName()为schema分配一个用户友好的标识符。schema名称对于标识错误消息中的schema很有用。

可以独立地设置与schema相关联的实体的读和写访问级别。选项包括Public、Vendor或Application。如果将读或写访问级别设置为Vendor,则必须指定可能访问schema实体的第三方供应商的VendorId。如果将其中一个访问级别设置为应用程序,则必须提供可能访问schema实体的应用程序或外接程序的URL。

注意:schema与文档一起存储,任何Revit API附加模块都可以读取文档中的可用schema以及schema的某些数据。然而,对schema的字段的访问是基于在schema中定义的读访问来限制的,并且与特定元素一起存储的实体中的实际数据是基于在定义schema时在schema中设置的读和写访问级别来限制的。

Fields and FieldBuilder

一旦创建了schema,就可以定义字段。字段类似于类的属性。它包含名称、文档、值类型和单位类型。字段可以是简单类型、数组或映射。允许以下简单数据类型:

Type 类型 Default Value 默认值
int 0
short 0
byte 0
double 0.0
float 0.0
bool false
string Empty string (“”)
GUID Guid.Empty {00000000-0000-0000-0000-000000000000} GUID。
ElementId ElementId.InvalidElementId
Autodesk.Revit.DB.XYZ (0.0,0.0,0.0)
Autodesk.Revit.DB.UV (0.0,0.0)

此外,字段的类型可以是Autodesk. Revit. DB. ExtensibleData. Autonomy。换句话说,它是另一个Schema的实例,也称为SubSchema 或 SubEntity。此类型字段的默认值为Entity,模式为null,guid为Guid.Empty。 使用字符串字段时,请注意Revit对字符串对象的大小限制为16 MB。

可以使用SchemaBuilder.AddSimpleField()方法为字段指定名称和类型来创建简单字段。AddSimpleField()返回一个FieldBuilder,它是一个用于定义Field的帮助类。如果字段的类型被指定为Entity,则使用FieldBuilder.SetSubSchemaString()指定要存储在此字段中的实体的Schema的类型。

使用SchemaBuilder.AddArrayField()方法创建一个字段,该字段包含Schema中的值数组,并具有给定的名称和所包含值的类型。数组字段可以具有与简单字段相同的类型。

使用SchemaBuilder.AddMapField()方法创建一个字段,该字段包含Schema中的有序键值映射,并具有给定的名称、键类型和所包含值的类型。支持的值类型与简单字段相同。支持的键类型仅限于int、short、byte、string、bool、ElementId和String。 一旦使用SchemaBuilder完成Schema,就不能再使用FieldBuilder编辑字段。在该阶段,Schema类提供了按名称获取Field的方法,或者获取Schema中定义的所有Field的列表。

Entity

在为Schema定义了所有字段之后,SchemaBuilder.Finish()将返回完成的Schema。可以使用该Schema创建新Entity。

对于Schema中的每个字段,可以使用Entity.Set()存储值,Entity.Set()接受一个字段和一个值(其类型取决于字段类型)。

一旦为Entity设置了所有适用的字段,就可以使用Element.SetEntity()方法将其分配给元素。

要在以后检索数据,请调用Element.GetEntity(),传入相应的Schema。如果没有基于该Schema的Entity与元素一起保存,则将返回无效Entity。若要检查是否返回了有效的Entity,请调用Entity.IsValid()方法。

可以使用Entity.Get()方法从实体中获取字段值。

若要从Element中删除可扩展存储实体,请调用Element.DeleteEntity(),传入用于创建它的Schema。

要确定与元素一起存储的实体,请使用Element.GetEntitySchemaGuids()方法,该方法返回元素的任何Entity的Schema的GUID。Schemaguid可以与静态方法Schema.schema()一起使用,以检索相应的Schemas。

下面是一个定义可扩展存储模式、创建实体、设置其值、将其分配给元素以及检索数据的示例。

代码区域22-9:可扩展存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Create a data structure, attach it to a wall, populate it with data, and retrieve the data back from the wall
void StoreDataInWall(Wall wall, XYZ dataToStore)
{
Transaction createSchemaAndStoreData = new Transaction(wall.Document, "tCreateAndStore");
createSchemaAndStoreData.Start();
SchemaBuilder schemaBuilder =
new SchemaBuilder(new Guid("720080CB-DA99-40DC-9415-E53F280AA1F0"));
schemaBuilder.SetReadAccessLevel(AccessLevel.Public); // allow anyone to read the object
schemaBuilder.SetWriteAccessLevel(AccessLevel.Vendor); // restrict writing to this vendor only
schemaBuilder.SetVendorId("ADSK"); // required because of restricted write-access
schemaBuilder.SetSchemaName("WireSpliceLocation");
// create a field to store an XYZ
FieldBuilder fieldBuilder =
schemaBuilder.AddSimpleField("WireSpliceLocation", typeof(XYZ));
fieldBuilder.SetUnitType(UnitType.UT_Length);
fieldBuilder.SetDocumentation("A stored location value representing a wiring splice in a wall.");

Schema schema = schemaBuilder.Finish(); // register the Schema object
Entity entity = new Entity(schema); // create an entity (object) for this schema (class)
// get the field from the schema
Field fieldSpliceLocation = schema.GetField("WireSpliceLocation");
// set the value for this entity
entity.Set(fieldSpliceLocation, dataToStore, DisplayUnitType.DUT_METERS);
wall.SetEntity(entity); // store the entity in the element

// get the data back from the wall
Entity retrievedEntity = wall.GetEntity(schema);
XYZ retrievedData =
retrievedEntity.Get(schema.GetField("WireSpliceLocation"),
DisplayUnitType.DUT_METERS);
createSchemaAndStoreData.Commit();
}

优势

自我记录和自定义

通过添加字段、单元、子实体和描述字符串来创建Schema不仅是存储数据的一种方法。对于其他用户来说,它也是一种隐式文档,并且其他人可以通过简单的采用路径在以后创建相同模式的实体。

利用局部性

因为Schema的Entity是以每个元素为基础存储的,所以当应用程序可能只需要当前选定梁的数据时,不需要读取文档中的所有可扩展存储数据(例如,来自所有梁族实例的所有数据)。这允许更具体地针对数据访问代码和更好的数据访问性能的潜力。

注:翻译自Revit API Developers Guide