Close

Relief for ODA Team in Ukraine

Learn more
ODA BimRv SDK
Work with the TB_CDA3DViewTree Module

The TB_CDA3DViewTree module is an implementation of ODA CDA for BimRv SDK. The CDA tree in this module is view-dependent. It represents the filtering of visible elements on the selected view and their grouping by categories, families, and types.

This module implementation allows you to use the following CDA functionality:

  • Access BimRv element parameters through the RxProperties Facet Provider mechanism.
  • Add attributes to object properties. These attributes assist in creating a hierarchy tree based on BimRv database content (attributes such as HierarchyLevel, DisplayAs, and OdaUniqueID).
  • Create dynamic objects with necessary attributes and their properties for the formation of nodes in the hierarchy tree.

Prerequisites

To add Common Data Access API functionality to your custom application based on BimRv SDK:

  1. Include the appropriate header files:
    
    #include "TBDevGuideStdAfx.h"
    #include "DynamicLinker.h"
    #include "RxProperty.h"
    #include "RxValue.h"
    #include "RxMember.h"
    #include "RxAttribute.h"
    #include "RxPropertyVariant.h"
    #include "RxVariant.h"
    #include "RxModelHierarchyTreeBase.h"
    #include "RxModelTreeBaseNode.h"
            
  2. Load the RxProperties and TB_CDAProperties modules:
    
    ::odrxDynamicLinker()->loadModule(L"RxProperties");
    ::odrxDynamicLinker()->loadModule(L"TB_CDA3DViewTree");
            

Retrieve an Element's Properties

To access a BimRv element's properties and iterate through them:

  1. Get an element identifier from the database using its handle:
    
    OdBmCommandContextPtr pDbCmdCtx(pCmdCtx);
    OdBmDatabasePtr m_pDatabase = pDbCmdCtx->database();
    OdSmartPtr<OdBmUserIO> pIO = pDbCmdCtx->userIO();
    OdInt32 handle = -1;
    OdBmObjectPtr pDbObject;
    OdRxMemberIteratorPtr pIter;
    OdRxPropertyPtr pProperty;
    handle = pIO->getInt("Enter handle:", OdEd::kInpDefault, -1);
    if (handle < 0)
    {
      pIO->putString(OD_T("Invalid handle"));
      return;
    }
    OdBmObjectId dbObjectId = m_pDatabase->getObjectId(OdDbHandle(OdUInt64(handle)));
            
  2. If the object's identifier is valid, get the properties iterator (call the OdRxMemberQueryEngine::theEngine()-> newMemberIterator() method):
    
    if (!dbObjectId.isNull())
    {
      pDbObject = dbObjectId.safeOpenObject();
      pIter = OdRxMemberQueryEngine::theEngine()->newMemberIterator(pDbObject.get());
      while (!pIter->done())
      {
        OdString strPropName = pIter->current()->name();
        pIter->next();
      }
      pProperty = OdRxMemberQueryEngine::theEngine()->find(pDbObject.get(), L"Family");
    }
    else
    {
      pIO->putString(OD_T("Invalid handle"));
      return;
    }
            

    To iterate the properties, use the current() method of the iterator instance. To determine that the end of the properties collection is reached, call the done() method. It returns true if the last property was iterated.

    To get the current property name, use the name() method of the current property.

    To move to the next property, call the next() method of the iterator.

To access a property with a specified name, use OdRxMemeberQueryEngine::find(). It returns a smart pointer to an OdRxProperty object. If a property with the specified name is not found, the method returns a NULL smart pointer, therefore after calling the find() method you need to check the returned smart pointer.


if (!pProperty.isNull())
{
  OdRxValue value;
  pProperty->getValue(pDbObject.get(), value);
  OdString strFamilyName = *rxvalue_cast<OdString>(&value);
}
    

To get the RxValue of a property, call the getValue() method. The returned value should be cast to the desired data type by calling the rxvalue_cast operator.

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

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

Retrieve a Specific "DisplayAs" Attribute

Using this variant system, you can get additional information about a property and the "DisplayAs" specific attribute.


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);
}
    

To get the collection of the property attributes, call the attributes() method of the property object. For each attribute, you can determine whether it is a "DisplayAs" specific attribute through the isKindOf() method call.

Create a Hierarchy Database Tree

The CDA API for BimRv provides a collection of types that are used to create a hierarchy database tree. The code fragment below illustrates how to determine whether a property is a collection and how to iterate through the collection elements (values).


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

To determine whether the property is a collection, you can use the isKindOf() method. To get sequential access to the collection values, use the newValueIterator() method of the OdRxCollectionProperty class instance.

To get the whole database element properties cache and structural information in the hierarchy tree, load the RxCommonDataAccessModule module, and create a hierarchy tree object:


::odrxDynamicLinker()->loadModule(RxCommonDataAccessModuleName);
OdRxModelHierarchyTreeBasePtr pTreeBase = OdRxModelHierarchyTreeBase::createObject();
pTreeBase->createDatabaseHierarchyTree(m_pDatabase, true);
    

Navigation through the hierarchy tree is implemented with the getChildren() and getParents() methods of the OdRxModelTreeBaseNode class. These methods can get descendant nodes and ancestor nodes of the tree respectively.


OdRxModelTreeBaseNodePtr pDBNode = pTreeBase->getDatabaseNode();
// getting db children
OdRxModelTreeBaseNodePtrArray pChildren = pDBNode->getChildren();
OdRxModelTreeBaseNodePtr pSomeNode = pChildren.at(0);
OdRxModelTreeBaseNodeRawPtrArray pParents = pSomeNode->getParents();
    

You can also gather additional information about an appropriate node by calling the following methods of the OdRxModelTreeBaseNode class:

  • getNodeName() — Returns the node name.
  • getUniqueSourceID() — Returns the ODAUniqueID object’s property value. This property contains a unique ODA identifier for linking tree nodes to geometry, e.g., for selection purposes.
  • getNodeType() — Gets the node type. The type identifier returned by the method is the node "hierarchy level" in the tree structure:
    • Database
    • Block
    • Model
    • BlockReference
    • Single Entity
  • getProperties() — Retrieves the node's cached properties represented with an array of PropertyInfo structures.

The code fragment below illustrates using these methods:


// node methods example
OdString strNodeName = pSomeNode->getNodeName();
OdUInt64 uId = pSomeNode->getUniqueSourceID();
HierarchyTreeObjectType nodeType = pSomeNode->getNodeType();
OdArray<PropertyInfo> propInfo = pSomeNode->getProperties();
    

The CDA API hierarchy tree system is defined in the following header files:

  • Kernel\Include\RxModelHierarchyTreeBase.h
  • Kernel\Include\RxModelTreeBaseNode.h

BimRv Element Properties Representation

The TB_CDA3DViewTree module supports two kinds of representation for BimRv element parameters:

  • Customer properties
  • Built-in properties

The built-in properties representation template is switched off by default. To turn it on, add the BUILTINPROPENABLE preprocessor definition to your project.

Database Filter View and Node Name Changes

You can choose the node name format. There are two representations: clean and extended. While the clean representation provides only text names for nodes, the extended one adds a quantity of elements in a group for grouping nodes, e.g., "M_Rectangular Column (22)", and adds a decimal DbHandle value, e.g., "M_Rectangular Column : 12x12 [188067]". The module uses the clean representation by default. To change it, use the ClearNames RxProperty as shown in the example below.

// setting extended naming 
OdRxPropertyPtr pClearNames = OdRxMemberQueryEngine::theEngine()->find(pDb, OD_T("ClearNames"));
  
if (pClearNames.isNull())
  return;
  
OdRxValue value = false;
pClearNames->setValue(pDb, value);

You can also use the 3DView to filter elements. By default, the module looks for a view with a name that starts with "3d" and takes its visible elements to build a tree. If there are no such views, the first occurance of a 3D view is taken. If there are no 3D views, a default view is created and will contain all elements.

Database objects have a special View RxProperty to change the active 3DView and a Views RxProperty to get a list of available views. The following code example shows how to change the active view using the ViewsNode property of a database and the Views collection property.

// checking views node property 
OdRxPropertyPtr pViewsNode = OdRxMemberQueryEngine::theEngine()->find(pDb, OD_T("ViewsNode"));
if (pViewsNode.isNull())
  return;
OdRxValue value;
pViewsNode->getValue(pDb, value);
OdRxObjectPtr pObj = *rxvalue_cast(&value);
// getting available 3dViews collection 
OdRxCollectionPropertyPtr pViewsCollection = OdRxMemberQueryEngine::theEngine()->find(pObj, OD_T("Views"));
if (pViewsCollection.isNull())
  return;
OdRxValueIteratorPtr pPrIt = pViewsCollection->newValueIterator(pObj);
  
// taking first view in collection
value = pPrIt->current();
  
// setting active view for filter 
OdRxPropertyPtr pActViewProp = OdRxMemberQueryEngine::theEngine()->find(pDb, OD_T("View"));
if (pActViewProp.isNull())
  return;

pActViewProp->setValue(pDb, value); 

The following image demonstrates using the TB_CDA3DViewTree module in the ODAViewer application (to access the link make sure you are logged into the ODA realm).

The object explorer on the left represents the structure of the database formed with the RxCommonDataAccessModule and TB_CDA3DViewTree modules. The properties panel on the right demonstrates the representation of a single BimRv window element's properties in the built-in and default user templates.

See Also

Common Data Access Wrappers for BimRv

Work with the TB_CDAProperties Module

Work with Elements

Filter Elements

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