Close

Relief for ODA Team in Ukraine

Learn more
ODA IFC SDK
Data Access Mechanisms

Overview of Data Access Mechanisms

IFC SDK supports two different ways to access data:

  • Early binding access assumes that data types are described precisely and values of these types are accessed using built-in function-accessors. For each data unit, an individual non-virtual function-accessor is implemented.
  • Late binding access to data is implemented through virtual functions that have interfaces described in the base classes of the IFC SDK class hierarchy.

    IFC SDK uses string names of data types and variables to indicate data objects for manipulation. Each type of data manipulation is implemented with a special interface (excluding wrappers that allow work in a case-insensitive mode).

    For data type conversion operations, the interface of the OdRxValue class is used. When a data object is passed from a custom application to the IFC SDK, first it is converted into an OdRxValue object. Data from the IFC SDK is passed to a custom application as an OdRxValue and the application uses appropriate wrappers to convert data to the desired data type.

Interfaces for both mechanisms are implemented in the SDAI and IfcCore modules.

Late binding access in IFC SDK is based on the late binding mechanism of the C++ language. Each class that can share its data using the late binding mechanism must contain an implementation of the following algorithm:

        Requested data object's name is compared to data identifiers contained in the class.
        If the name was found 
          Required manipulation is performed by calling an appropriate method of the class. 
        
        If the name was not found
          Request is forwarded up in the class hierarchy. 
          
        If the request was not resolved within the class hierarchy
          An error value is returned.
    

OdRxValue provides the conversion into a number of different data types through one unified interface:

  • Simple types: boolean, integer, real, etc.
  • Enumeration
  • Selection and aggregation types
  • Pointers to datatypes mentioned above

The OdRxValue class can determine whether a data object has a specified data type. This is implemented through a set of methods that return true if the data object has an appropriate data type or false otherwise. For example, to find out whether a data value belongs to the aggregate data type, use the isAggregate() method.

There are specific details for working with wrapped values:

  • For aggregation data types, the wrapper must contain a pointer to an aggregate value.
  • Selection types are wrapped as pointers to a value by the IFC SDK, but when passing to the IFC SDK, they must be provided as values.
  • Enumeration types and simple types are wrapped by value.

Usage Examples

The code fragment below demonstrates creating an IfcRectangularPyramid object and working with its attributes using early binding and late binding mechanisms.

Early binding approach:

      
IfcRectangularPyramidPtr pPyramid = IfcRectangularPyramid::createObject();
IfcPositiveLengthMeasure length = 10.0;
IfcPositiveLengthMeasure attributeValue = 0.0;

pPyramid->setXLength(length);
pPyramid->setYLength(length);
pPyramid->setHeight(length);

attributeValue = pPyramid->getHeight();
      
    

In the code above, an object of the IfcRectangularPyramid class is created and then its properties are set using specific methods of this class (setXLength(), setYLength(), setHeight()). To retrieve the current attribute value, an appropriate get-method is called (in this case, the getHeight() method is used).

The late binding mechanism is implemented through the putAttrCaseInsensitive() and getAttrCaseInsensitive() methods of the IfcRectangularPyramid class:

      
OdIfcModelPtr pModel = …; //here the IFC model instance should be created

…

OdIfcEntityPtr pEntity = pModel->createEntityInstance("IfcRectangularPyramid");
IfcPositiveLengthMeasure length = 10.0;
IfcPositiveLengthMeasure attributeValue = 0.0;

pEntity->putAttrCaseInsensitive("XLength", length);
pEntity->putAttr("ylength", length); //All attributes are compared in lower case
pEntity->putAttrCaseInsensitive("Height", length);

OdRxValue odRxAttributeValue = pEntity->getAttrCaseInsensitive("Height");
odRxAttributeValue >> attributeValue;
      
    

After setting pyramid attributes, you can read them into an instance of the OdRxValue class and convert it to an appropriate data object (the IfcPositiveLengthMeasure object) through a call of the >> operator.

In the next code fragment, the IfcActor class functionality is used.

      
IfcActorPtr pActor = IfcActor::createObject();
IfcActorSelect select;
IfcOrganizationPtr pOrganization = …;

select.setIfcOrganization(pOrganization);
pActor->setTheActor(select);

IfcActorSelect attributeValue = pActor->getTheActor();

OdDAIObjectIds objectIds;
pActor->getInvIsActingUpon(objectIds);
      
    

Selection types are passed to IFC SDK by value but returned from it as pointers to a value. Aggregation types are wrapped as pointers to a value.

      
OdIfcEntityPtr pActor = pModel->createEntityInstance("IfcActor");
OdIfcEntityPtr pOrganization = pModel->createEntityInstance("IfcOrganization");
OdDAIObjectId idOrganization = pModel->appendEntityInstance(pOrganization);
OdDAIObjectId attributeValue;

pActor->putAttrCaseInsensitive("TheActor", idOrganization);

OdRxValue odRxAttributeValue = pActor->getAttrCaseInsensitive("TheActor");
if(!odRxAttributeValue.typePath().iCompare("IfcOrganization"))
  odRxAttributeValue >> attributeValue;


Set < OdDAIObjectId >* pSet = NULL;
odRxAttributeValue = pActor->getAttrCaseInsensitive("IsActingUpon");
      
    

The typePath() method retrieves a string that contains the meaning of the variable value.

To work with aggregate values it is convenient to use the base type with an iterator; the following code fragment illustrates it:

      
OdIfcEntityPtr pActor = …;
AggrBase* pAggrBase = NULL;
if (odRxAttributeValue >> pAggrBase)
{
  for (IteratorPtr it = pAggrBase->createIterator(); it->next();)
  {
    OdDAIObjectId objectId;
    it->getCurrentMember() >> objectId;
  }
}
      
    

See Also

Standard Data Access Interface in IFC SDK

Get Started with IFC SDK

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.