IFC SDK supports two different ways to access data:
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:
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:
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;
}
}
Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.
|