原文链接:
Extensible Storage
我们之前讨论过 Revit 2012 API 中一些主要的特性,其中不少是开发者期望的功能。这里我想谈谈另外一个热点功能,实际上 Revit 2012 API 做得比我们期望的还要好。
提问:
我如何用 Revit API 将定制的业务数据存储到 Revit 文件中?
回答:
使用共享参数是一种选择。这个方案有些复杂,包括正确地建立共享参数文本文件。你可以选择是否将共享参数共享参数设置为用户可见。整个过程可以参考SDK例程FireRating和我其它几篇博文:
可扩展存储
现在 Revit API 允许开发者定制一个像类一样的样式(Schema)结构,并且可以将该结构的实例附着到Revit模型中的任意元素。这个功能可以完全替代不可见的共享参数。基于样式的数据保存在 Revit 模型中,并且允许高层的、元数据增强的和面向对象的数据结构。样式数据可以被设置为对不同的用户可读或者可写。目前Revit API支持的用户类别有“所有用户”、“指定应用程序供应商”和“一个供应商提供的指定应用程序”。
和可扩展存储相关的类都被定义在命名空间 Autodesk.Revit.DB.ExtensibleStorage 中:
目前 Revit API 支持的数据类型有:
上面提到的 VendorId 和 add-in manifest 文件中新增的 VendorId ( new required VendorId tag in the add-in manifest) 是同一个值。ADSK 是 Autodesk 使用的 VendorId,第三方开发者应该使用自己的 Autodesk 注册开发者 Symbol RDS ( Autodesk Registered Developer Symbol RDS)。
我们之前讨论过 Revit 2012 API 中一些主要的特性,其中不少是开发者期望的功能。这里我想谈谈另外一个热点功能,实际上 Revit 2012 API 做得比我们期望的还要好。
提问:
我如何用 Revit API 将定制的业务数据存储到 Revit 文件中?
回答:
使用共享参数是一种选择。这个方案有些复杂,包括正确地建立共享参数文本文件。你可以选择是否将共享参数共享参数设置为用户可见。整个过程可以参考SDK例程FireRating和我其它几篇博文:
- Creating and using a shared parameter on various elements.
- Storing structured data in a Revit shared parameter.
- Storing project data.
可扩展存储
现在 Revit API 允许开发者定制一个像类一样的样式(Schema)结构,并且可以将该结构的实例附着到Revit模型中的任意元素。这个功能可以完全替代不可见的共享参数。基于样式的数据保存在 Revit 模型中,并且允许高层的、元数据增强的和面向对象的数据结构。样式数据可以被设置为对不同的用户可读或者可写。目前Revit API支持的用户类别有“所有用户”、“指定应用程序供应商”和“一个供应商提供的指定应用程序”。
和可扩展存储相关的类都被定义在命名空间 Autodesk.Revit.DB.ExtensibleStorage 中:
- Schema – 包含一个唯一的样式编号,读写权限和一个数据字段集合。
- Entity – 包含Schema数据的对象,可被插入 Revit 元素。
- Field – 包含数据名称、类型和单位信息。是访问 Entity 中数据的键
- SchemaBuilder – 用于创建样式定义。
- FieldBuilder – 帮助类。配合SchemaBuilder使用来创建一个新字段。
目前 Revit API 支持的数据类型有:
- int
- short
- double
- float
- bool
- string
- Guid
- ElementId
- Autodesk.Revit.DB.UV
- Autodesk.Revit.DB.XYZ
- Array (as a System.Collections.Generic.IList<T>)
- Map (as a System.Collections.Generic.IDictionary<TKey, TValue> – TKey 不能为 double, float, XYZ, and UV 类型)
- Autodesk.Revit.DB.ExtensibleStorage.Entity (Schema 实例,也称为 SubSchema)
/// <summary>
/// 创建一个数据结构,将其附着到一面墙。为数据结构填充数据,并从墙体取回这些数据
/// </summary>
public 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" ) );
// allow anyone to read the object
schemaBuilder.SetReadAccessLevel( AccessLevel.Public );
// restrict writing to this vendor only
schemaBuilder.SetWriteAccessLevel( AccessLevel.Vendor );
// required because of restricted write-access
schemaBuilder.SetVendorId( "ADSK" );
// 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." );
schemaBuilder.SetSchemaName( "WireSpliceLocation" );
Schema schema = schemaBuilder.Finish(); // register the Schema object
// create an entity (object) for this schema (class)
Entity entity = new Entity( schema );
// get the field from the schema
Field fieldSpliceLocation = schema.GetField( "WireSpliceLocation" );
entity.Set<XYZ>( fieldSpliceLocation, dataToStore, DisplayUnitType.DUT_METERS ); // set the value for this entity
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<XYZ>( schema.GetField( "WireSpliceLocation" ), DisplayUnitType.DUT_METERS );
createSchemaAndStoreData.Commit();
}
Revit 2012 SDK 包含了一个更加完整的例程:ExtensibleStorageManager。
上面提到的 VendorId 和 add-in manifest 文件中新增的 VendorId ( new required VendorId tag in the add-in manifest) 是同一个值。ADSK 是 Autodesk 使用的 VendorId,第三方开发者应该使用自己的 Autodesk 注册开发者 Symbol RDS ( Autodesk Registered Developer Symbol RDS)。