IFC SDK and SDAI: Work with Select Attributes

Egor Vorobyov

November 12, 2020

IFC SDK supports the Standard Data Access Interface (SDAI) which provides a low-level API for manipulating data defined with the EXPRESS Schema. This article describes how to work with select attributes.

For details about generally working with SDAI in IFC SDK, see this article.

Select attributes can contain values of different types. To provide storage of different types of values with different lengths in bytes, the attribute data block (ADB) is used.

For this example, it is assumed that there is an instance similar to the following in an .ifc file (with an attribute select value):

// #49 = IFCMEASUREWITHUNIT(IFCRATIOMEASURE(0.0174532925199433), #47);

It has a select attribute named “valuecomponent”. Read an application instance using sdaiGetEntityById:

SdaiAppInstance applicationInstance = _sdaiGetEntityById(model, 49);
TEST_ASSERT(applicationInstance != NULL);
TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);

To read the select attribute from an application instance, we use a standard function sdaiGetAttrBN. But there is one difference: we should pass to the fourth parameter an ADB value that is already created. To do it, use a function sdaiCreateEmptyADB:

SdaiADB adbToGet = sdaiCreateEmptyADB();
  TEST_ASSERT(adbToGet != NULL);
 				&adbToGet) != NULL);

When you successfully get it, you can extract a value contained at the ADB. As you can see from the fragment of the .ifc file above, the attribute data block stores a real value (IFCRATIOMEASURE(0.0174532925199433)), therefore you have to get the attribute value as a real data type value:

SdaiReal  adbRealValue = .0;
  sdaiGetADBValue(adbToGet, sdaiREAL, &adbRealValue);
  TEST_ASSERT(OdEqual(0.0174532925199433, adbRealValue));

According to the code fragment, the sdaiGetADBValue() function should be called to get a value from an attribute data block. This function accepts three parameters:

  • A handle of the attribute data block.
  • An attribute data type.
  • A placeholder to store the value of the requested data type.

The sdaiGetADBValue() function returns a raw pointer to the attribute value if it is successfully retrieved or the NULL value in the other case so you can check the result of the ADB operation.

Another data type that can be stored in an attribute data block is a path. This data is represented as an array of strings. We can get the path of an ADB using sdaiGetADBTypePath. This function has two parameters: an ADB instance and a pointer to SdaiInteger. If the operation is successful, the function returns a pointer to SdaiString as a pointer to an array of paths, and to the second parameter it puts the size of the returned array; if the operation fails, the function returns NULL.

SdaiInteger collectionSize = 0;
SdaiString* pathCollection = sdaiGetADBTypePath(adbToGet, &collectionSize);

  TEST_ASSERT(collectionSize > 0);
  for (SdaiInteger pathIndex = 0; pathIndex < collectionSize; ++pathIndex)
    TEST_ASSERT(pathCollection[pathIndex] && odStrLenA(pathCollection[pathIndex]) > 0);

When finished working with an ADB instance, call sdaiDeleteADB if the instance was created using sdaiCreateEmptyADB:

TEST_ASSERT(sdaiErrorQuery() == sdaiNO_ERR);