IFC SDK 支持标准数据访问接口 (SDAI),它提供了一个低级 API,用于操作使用 EXPRESS 模式定义的数据。本文介绍了如何使用简单数据类型的属性。
有关在 IFC SDK 中使用 SDAI 的详细信息,请参阅本文。
访问简单类型属性
SDAI 中有几种简单类型:sdaiINTEGER、sdaiREAL、sdaiNUMBER、sdaiBOOLEAN、sdaiLOGICAL、sdaiSTRING 和 sdaiINSTANCE。
对于此示例,我们将从应用程序实例 #5 中读取其中一个属性:
//#5 = IFCAPPLICATION(#1, '2019', 'Autodesk Revit 2019 (ENU)', 'Revit');
首先,我们使用 sdaiGetEntityById 获取一个应用程序实例。然后,我们调用 sdaiGetAttrBN 从实例中获取属性。sdaiGetAttrBN 有四个参数:
- 实例
- 属性名称
- 查询参数的类型
- 指向一个参数的指针,用于将属性值复制到该参数
如果成功,该函数将返回指向第四个参数的指针,否则返回 null:
SdaiAppInstance applicationInstance = _sdaiGetEntityById(model, 5);
TEST_ASSERT(applicationInstance != NULL);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
接下来我们将尝试三次读取参数。
第一次尝试中,我们成功获取了一个名为“applicationdeveloper”的参数。我们收到了一个句柄为 #1 的应用程序实例。因此,让我们检查收到的数据。使用 _sdaiGetEntityById 从应用程序实例中获取 ID。它应该等于 1:
SdaiAppInstance developer = NULL;
TEST_ASSERT(sdaiGetAttrBN(applicationInstance,
"applicationdeveloper",
sdaiINSTANCE,
&developer) != NULL);
TEST_ASSERT(developer != NULL);
TEST_ASSERT(developer == _sdaiGetEntityById(model, 1));
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
第二次尝试中,我们从名为“version”的属性中获取一个字符串值。它也应该成功读取属性值。将其与“2019”进行比较,以确保我们读取了有效数据:
SdaiString version = NULL;
TEST_ASSERT(sdaiGetAttrBN(applicationInstance, "version", sdaiSTRING, &version) != NULL);
TEST_ASSERT(odStrCmpA(version, "2019") == 0);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
第三次尝试中,我们尝试从名为“version”的属性中获取一个整数值。操作失败,因为我们请求了不兼容的类型 sdaiINTEGER。在这种情况下,sdaiGetAttrBN 返回 NULL。调用 sdaiErrorQuery 获取最后一个错误并重置错误状态。错误代码使用 FIFO 规则在错误查询处收集。每次 sdaiErrorQuery 调用都会从错误队列中移除最后一个错误状态:
SdaiInteger wrongAttrType = -1;
TEST_ASSERT(sdaiGetAttrBN(applicationInstance, "version", sdaiINTEGER, &wrongAttrType) == NULL);
TEST_ASSERT(sdaiErrorQuery() == sdaiVT_NVLD);
另一种简单类型是枚举。SDAI 还支持从应用程序实例中获取枚举值。
例如,假设一个 .ifc 文件在 DATA 部分包含以下条目:
// #43= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
点之间的字符串值是一个枚举值。现在读取其中一个值。首先,我们使用 _sdaiGetEntityById 从模型中获取一个实例:
SdaiAppInstance applicationInstance = _sdaiGetEntityById(model, 43);
TEST_ASSERT(applicationInstance != NULL);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);
然后我们要求应用程序实例返回一个类型化属性。该枚举有其自己的 typedef:
/* enumeration data type: */
typedef char *SdaiEnum;
如我们所见,它的值表示一个字符串值。声明此类型的一个变量,并将指向此值的指针作为第四个参数传递给 sdaiGetAttrBN。如果操作成功,我们将获取此参数并将其与示例文件中的值进行比较:
SdaiEnum enumValue = NULL;
TEST_ASSERT(sdaiGetAttrBN(applicationInstance,
"prefix",
sdaiENUM,
&enumValue) != NULL);
TEST_ASSERT(!odStrCmpA(enumValue, "MILLI"));