Using Common Data Access with BimRv SDK (Part 1 of 2)

Ilya Kovaldov

November 28, 2019

ODA Common Data Access (CDA) is a platform-neutral framework for accessing model structure and property information in a common way for all ODA-supported formats. Because СDA is database-neutral, it is based on extensions of the ODA Kernel runtime system RxProperties.

As an example, this two-part series focuses on using CDA with BimRv SDK.

TB_CDAProperties contains the CDA implementation for BimRv SDK. CDA for BimRv is a wrapper around the parameters in the project and is a special representation of the database structure that is close to an IFC version of the tree.

The TB_CDAProperties module does the following:

  • Provides access to BmElements parameters through the RxProperties Facet Provider mechanism.
  • Supplements the lists of object properties with the attributes necessary for the formation of the hierarchy tree of the BimRv database (HierarchyLevel, DisplayAs, OdaUniqueID).
  • Creates dynamic objects for the formation of necessary nodes in the hierarchy tree and fills them with the necessary properties and attributes.
Single Element Examples

Include the necessary headers:

#include "RxValue.h"
#include "RxMember.h"
#include "RxAttribute.h"
#include "RxProperty.h"

Load the necessary modules:

::odrxDynamicLinker()->loadModule(L"RxProperties");
::odrxDynamicLinker()->loadModule(L"TB_CDAProperties");

To list the properties of a given BmElement object, call OdRxMemberQueryEngine::theEngine()->newMemberIterator() to get an iterator for the object. The next example demonstrates how to get an iterator and property names:

OdBmDatabasePtr m_pDatabase;
OdUInt64 handle;
OdBmObjectPtr pDbObject;
OdRxMemberIteratorPtr pIter;

// some code to get necessary BmElement handle
  
OdBmObjectId dbObjectId = m_pDatabase->getObjectId(OdDbHandle(handle));
if (!dbObjectId.isNull())
{
  pDbObject = dbObjectId.safeOpenObject();
  pIter = OdRxMemberQueryEngine::theEngine()->newMemberIterator(pDbObject.get());
  while (!pIter->done())
  {
    OdString strPropName = pIter->current()->name();
    pIter->next();
  }
}

You can also find a known property by its name using the OdRxMemberQueryEngine::find() function. The next example demonstrates how to find the “Family” property of the BmElement and get its value:

OdRxPropertyPtr pProperty = OdRxMemberQueryEngine::theEngine()->find(pDbObject.get(), L"Family");
if (!pProperty.isNull())
{
  OdRxValue value;
  pProperty->getValue(pDbObject.get(), value);
  OdString strFamilyName = *rxvalue_cast<OdString>(&value);
}

OdRxValue is a generic variant type; it can contain any C++ type if the corresponding metaclass was declared. For more information about the variant type system, see the following header files:

  • Kernel\Include\RxValueType.h
  • Kernel\Include\RxValueTypeUtil.h

The next example demonstrates how to get additional information about a property from its attributes and to get the DisplayAs attribute value:

const OdRxAttributeCollection& attributes = pProperty->attributes();
for (int i = 0; i < attributes.count(); i++)
{
  OdRxValue value;
  const OdRxAttribute* pAttribute = attributes.getAt(i);
  if (NULL != pAttribute->isA() && pAttribute->isKindOf(OdRxDisplayAsAttribute::desc()))
    ((OdRxDisplayAsAttribute *)pAttribute)->getDisplayValue(value);
}

There are also collection types for using properties, for example, to provide hierarchy database tree creation. The next example demonstrates how to work with collection properties:

if (pIter->current()->isKindOf(OdRxCollectionProperty::desc()))
{
  OdRxCollectionPropertyPtr pPropertyCollection(pIter->current());
  OdRxValueIteratorPtr pPrIt = pPropertyCollection->newValueIterator(pDbObject);
  while (!pPrIt->done())
  {
    OdRxValue value = pPrIt->current();
    pPrIt->next();
  }
}

The next article in this series will contain additional examples of using CDA with BimRv SDK.