IFC SDK 支持标准数据访问接口 (SDAI),它提供了一个低级 API,用于操作使用 EXPRESS 模式定义的数据。本文介绍了如何处理聚合属性,特别是应用程序实例列表。
有关在 IFC SDK 中使用 SDAI 的详细信息,请参阅本文。
具有聚合属性的应用程序实例是指每个属性都由另一个实例的句柄表示。例如,折线对象是定义折线路径的一组点。折线可以按以下方式存储在 .ifc 文件中:
#173= IFCCARTESIANPOINT((-2232.66666666677,-11000.));
#175= IFCCARTESIANPOINT((3767.33333333345,-11000.));
#177= IFCCARTESIANPOINT((3767.33333333345,7000.));
#179= IFCCARTESIANPOINT((-1534.66666666668,7000.));
#181= IFCCARTESIANPOINT((-1534.66666666668,4000.));
#183= IFCCARTESIANPOINT((-2232.66666666677,4000.));
#185= IFCPOLYLINE((#173,#175,#177,#179,#181,#183,#173));
在这里,我们可以看到应用程序实例 (#185) 属性的标准访问。我们使用 sdaiAGGR 类型从属性中提取聚合实例:
SdaiAppInstance applicationInstance = _sdaiGetEntityById(model, 185);
TEST_ASSERT(applicationInstance != NULL);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
SdaiAggr aggregate = NULL;
TEST_ASSERT(sdaiGetAttrBN(applicationInstance,
"points",
sdaiAGGR,
&aggregate) != NULL);
要通过索引获取聚合属性项,请使用 sdaiGetAggrByIndex() 函数。此函数接受四个参数:
- 包含所需属性的聚合实例。
- 要获取的属性的索引值。
- 请求属性的数据类型。
- 指向属性值的原始指针。
该函数返回一个指向存储在第四个输出参数中的属性值的原始指针。
首先,创建一个包含要读取的聚合属性句柄的数组。
const SdaiInteger checkHandleData[] = { 173, 175, 177, 179, 181, 183, 173 };
const SdaiInteger checkHandleDataLength = sizeof(checkHandleData) /
sizeof(checkHandleData[0]);
通过调用 sdaiGetMemberCount() 函数获取聚合属性的数量。此函数返回的值用作迭代属性的循环的边界:
const SdaiInteger indexUpperBound = sdaiGetMemberCount(aggregate);
for (SdaiInteger instanceIndex = 0; instanceIndex < indexUpperBound; ++instanceIndex)
{
SdaiAppInstance instanceFromAggrIndex = NULL;
TEST_ASSERT(sdaiGetAggrByIndex(aggregate,
instanceIndex,
sdaiINSTANCE,
&instanceFromAggrIndex) != NULL);
if (instanceIndex >= checkHandleDataLength){ break; }
TEST_ASSERT(_sdaiGetEntityId(instanceFromAggrIndex) ==
checkHandleData[instanceIndex]);
}
获取聚合属性的另一种方法是使用迭代器对象来顺序访问属性。要获取迭代器,请使用 sdaiCreateIterator() 函数。要与属性集合交互,请使用以下函数:
- sdaiBeginning() 用于移动到属性集合的开头。
- sdaiNext() 用于移动到下一个属性项。
- sdaiGetAggrByIterator() 用于获取属性值。
SdaiIterator aggregateIterator = sdaiCreateIterator(aggregate);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
SdaiInteger iterationCounter = 0;
for (sdaiBeginning(aggregateIterator); sdaiNext(aggregateIterator);)
{
SdaiAppInstance instanceFromIterator = NULL;
TEST_ASSERT(sdaiGetAggrByIterator(aggregateIterator,
sdaiINSTANCE,
&instanceFromIterator) != NULL);
if (iterationCounter >= checkHandleDataLength) { break; }
TEST_ASSERT(_sdaiGetEntityId(instanceFromIterator) ==
checkHandleData[iterationCounter]);
++iterationCounter;
}
为避免内存泄漏,请销毁创建的迭代器:
sdaiDeleteADB(adbToGet);