可扩展存储机制允许将用户数据直接存储在模型元素中。此机制不用于项目或族内部,因此不影响项目或族的参数。有广泛的模型元素集可以存储用户数据。此机制的一个共同特点是使用基于模式的技术。
根据此方法,要在模型元素中存储用户数据,应使用以下对象定义数据:
- 字段 (Field) — 包含数据名称、类型和单位信息,并用作访问实体中相应数据的键。
- 模式 (Schema) — 数据字段对象的集合。
- 实体 (Entity) — 包含与模式对应的数据的对象,可以插入到元素中。
BimRv SDK支持使用以下实现模式、字段构建器和帮助器的类来创建和使用基于模式的数据结构:
- OdBmESSchemaBuilder — 执行模式定义的创建。
- OdBmESFieldBuilder — 在创建新字段时与OdBmESSchemaBuilder一起使用的辅助类。
- OdBmESEntityHelper — 用于访问现有可扩展实体字段值的辅助类。
- OdBmESSchemaHelper — 允许读取现有模式的属性和字段。
- OdBmESFieldHelper — 在读取字段属性和定义时与OdBmESSchemaHelper一起使用的辅助类。
BimRv SDK可扩展帮助器支持以下数据类型:
- bool
- OdInt16
- OdInt32
- double
- float
- OdString
- OdGuid
- OdBmObjectId
- OdGePoint2d
- OdGePoint3d
- OdArray
- OdMap (除double、float、OdGePoint2d和OdGePoint3d外,所有类型都支持作为键)
- OdBmObject (另一个模式的实例)
通过使用属性,可以配置架构以限制所有用户、特定应用程序供应商或来自供应商的特定应用程序的读取和/或写入访问。
下一节将介绍可扩展存储的简单用法。
创建存储描述
要创建新模式,请使用 OdBmESSchemaBuilder 类:
OdBmESSchemaBuilder schemaBuilder(pDb);
schemaBuilder.setSchemaName(L"WireSpliceLocation")
.setSchemaGUID(OdGUID("720080CB-DA99-40DC-9415-E53F280AA1F0"))
.setVendorId(L"BimRv")
.setDocumentation(L"WireSpliceLocation schema")
.setReadAccessLevel(OdBm::ESSchemaAccessLevel::Public)
.setWriteAccessLevel(OdBm::ESSchemaAccessLevel::Public);
应使用 OdBmESFieldBuilder 类在存储中创建字段。此类包含用于设置字段属性的方法,例如:
- setDocumentation() — 字段的描述。
- setSubSchemaGUID() — 描述存储在字段中的子实体的模式的全局唯一标识符 (GUID)。
- setUnitType() — 字段中存储的值所表示的单位类型。
下面是创建两个简单字段(一个数组字段和一个映射字段)的示例:
schemaBuilder.addSimpleField<bool>(L"BooleanField").setDocumentation(L"Boolean value");
schemaBuilder.addSimpleField<OdGePoint3d>(L"XYZField").setUnitType(OdBm::UnitType::UT_Length).setDocumentation(L"XYZ value");
schemaBuilder.addArrayField<OdGUID>(L"GUIDArrayField").setDocumentation(L"GUID array value");
schemaBuilder.addMapField<OdString, OdString>(L"StringMapField").setDocumentation(L"Map value");
字段名称用于访问字段数据以写入和读取值。在模式中定义所有字段后,调用 finish() 方法以完成模式构建器:
OdTfClass* pSchema = schemaBuilder.finish();
要创建模式实例(实体),请调用 OdBmESEntityHelper 类的 createEntity() 方法:
OdBmObjectPtr pESEntity = OdBmESEntityHelper::createEntity(pSchema);
字段属性以及模式属性(例如单位类型、名称和文档)在创建后无法更改。
设置值
要设置实体字段的新值,请使用 OdBmESEntityHelper 类:
OdBmESEntityHelper helper(pESEntity);
helper.set<bool>(L"BooleanField", true);
helper.set<OdGePoint3d>(L"XYZField", OdGePoint3d(20., 21., 22.), OdBm::DisplayUnitType::DUT_METERS);
OdArray<OdGUID>guids;
guids.push_back(OdGUID("60E23C30-169B-4C46-BD2B-DC9FC476FD09"));
guids.push_back(OdGUID("1BAD71AA-137E-4519-8D9B-B0ED1672D1BF"));
helper.set<OdArray<OdGUID>>(L"GUIDArrayField", guids);
OdBmMap<OdString, OdString> stringMap;
stringMap[L"key1"] = L"value1";
stringMap[L"key2"] = L"value2";
helper.set<OdBmMap<OdString, OdString>>(L"StringMapField", stringMap);
显示单位类型参数仅用于 float、double、OdGePoint3d 和 OdGePoint2d 数据类型,并设置字段的单位类型。此方法内部不执行任何转换。
对于 OdBmObjectPtr,在 OdBmESEntityHelper 类实例的 set() 方法调用中使用 clone():
helper.set<OdBmObjectPtr>(L"EntityField", pESEntity->clone());
set<>() 方法的模板参数必须与字段类型完全匹配(字段本身是在创建模式阶段指定的)。
存储数据
应用程序可以将模式实例附加到模型中的任何元素。为避免在共享项目中锁定元素,请使用由 OdBmDataStorage 类表示的特殊元素。
OdBmDataStoragePtr pDataStorageElem = OdBmDataStorage::createObject();
pDataStorageElem->setName(L"DataStorageElem");
ODBM_TRANSACTION_BEGIN(t, pDb)
t.start();
hStorage = pDb->addElement(pDataStorageElem).getHandle();
pDataStorageElem->setESEntity(pESEntity);
t.commit();
ODBM_TRANSACTION_END()
从存储中读取数据
以下代码示例说明了如何从存储助手读取数据:
OdBmObjectPtr pESEntity = pDataStorageElem->getESEntity(OdGUID(L"720080CB-DA99-40DC-9415-E53F280AA1F0"));
OdBmESEntityHelper helper(pESEntity);
bool b = helper.get<bool>(L"BooleanField");
OdGePoint3d xyz = helper.get<OdGePoint3d>(L"XYZField", OdBm::DisplayUnitType::DUT_DECIMETERS);
get<>() 方法中的数据类型可以是第一节中列出的类型之一。作为模式的创建者,您应该知道每个字段的类型。如果不知道,您可以将值作为 OdTfVariant 对象进行处理:
OdTfVariant v;
pESEntity->getProperty(L"BooleanField", v);
您可以在 BimRv/Examples/ExBimDump 中找到将 OdTfVariant 对象转换为字符串的示例,特别是在 BmDumper::dumpVariant 方法实现中。
get<>() 方法中的显示单位类型参数用于将数据转换为所需的单位,例如,先前为字段设置的值的坐标等于 OdGePoint3d(200., 210., 220.):
OdArray<OdGUID>guids = helper.get<OdArray<OdGUID>>(L"GUIDArrayField");
OdBmMap<OdString, OdString> strings = helper.get<OdBmMap<OdString, OdString>>(L"StringMapField");
读取信息例程
要读取记录的信息,请获取模型元素,并确定存储 GUID 和字段名称。要在数据库中获取架构,请使用 OdBmESSchemaHelper 类的静态 listSchemas() 方法:
std::set<OdGUID> schemas = OdBmESSchemaHelper::listSchemas(pDb);
要访问数据库中与架构相关的元素,请使用静态 getElements() 方法:
OdBmObjectIdArray objects = OdBmESSchemaHelper::getElements(guid, pDb);
从字段检索信息的另一种方法是使用 OdBmESFieldHelper:
OdBmESFieldHelper fieldHelper(helper.getField(L"BooleanField"));
字段助手对象提供了访问字段属性的方法:
- getDocumentation() — 返回字段的描述。
- getFieldName() — 返回字段的名称。
- getContainerType() — 返回字段的类型:包含一个值的简单字段或包含多个值的容器。
- getEntryIndex() — 返回字段的索引。
- getSubSchemaGUID() — 返回描述存储在字段中的子实体的全局唯一标识符 (GUID)。
- getUnitType() — 返回字段中存储的值所表示的单位类型。
OdBmESSchemaHelper 类有助于获取有关架构的信息:
OdBmESEntityHelper helper(pESEntity);
OdBmESSchemaHelper schHelper(helper.getSchema());
- getDocumentation() — 返回架构的描述。
- getVendorId() — 返回第三方供应商的字符串标识符,该供应商可以在供应商访问级别下访问架构的实体。
- getSchemaName() — 返回架构的名称。
- getSchemaGUID() — 返回架构的全局唯一标识符 (GUID)。
- getReadAccessLevel() — 检索架构的当前读取访问级别。
- getWriteAccessLevel() — 检索架构的当前写入访问级别。