如何在Teigha BIM中获取元素参数

本文仅介绍Teigha BIM中用于获取和实现元素参数的一些功能。

可用的内置参数列表位于BmBuiltInParameter.h文件中。用于获取元素参数的Teigha BIM用户界面可在BmElement.h和BmObject.h文件中找到:

  • getListParams 函数 — 获取元素的可用内置参数列表。
  • getParam 函数 — 获取指定参数的值。参数可以有四种类型:整数 (OdInt32)、浮点数 (double)、字符串 (OdString)、对象标识符 (OdBmObjectId)。该参数也可以作为OdTfVariant使用。
  • getFilterElement 函数 — 获取需要从中获取参数以执行过滤的元素。

处理参数的一般原则是:

  • 如有必要,您可以通过getListParams请求可用元素参数列表。
  • 要获取具有应在执行过滤时使用的参数的元素,请通过getFilterElement请求它。
  • 请求参数的元素通过getParam请求其值。
  • 检查函数的返回值:
    • eOk — 请求的参数存在于可用参数列表中,并且参数值已成功接收。
    • eNotImplementedYet — 请求的参数存在于可用参数列表中,但参数值尚未实现。
    • eNotApplicable — 请求的参数存在于可用参数列表中,但参数值缺失 (HasValue = False)。
    • eKeyNotFound — 请求的参数不在可用参数列表中。

使用getFilterElement

在Teigha BIM中,getFilterElement函数用于在OdBmFilterDoubleRule、OdBmFilterElementIdRule、OdBmFilterIntegerRule和OdBmFilterStringRule规则中对可见元素执行过滤。

这些规则是在Autodesk® Revit®中通过“视图”->“过滤器”菜单设置的。

通过这些参数进行过滤,可以不是通过元素本身的参数值,而是通过关联元素的参数值来执行。例如,FamilyInstance元素,其过滤使用的是UNIFORMAT_CODE参数的值,不是来自自身,而是来自关联的MasterSymbolId元素。

OdBmElementPtr OdBmFamilyInstanceImpl::getFilterElement(const OdBm::BuiltInParameter::Enum& parameterId) const {
  switch (parameterId) {
    case OdBm::BuiltInParameter::UNIFORMAT_CODE: {
      if (!getMasterSymbolId().isNull()) {
        return getMasterSymbolId().safeOpenObject();
      }
    } break;
  }

  return super::getFilterElement(parameterId);
}

默认情况下,元素的getFilterElement函数返回元素本身。

OdBmElementPtr OdBmElementImpl::getFilterElement(const OdBm::BuiltInParameter::Enum& parameterId) const {
  return this->getFacade();
}

OdBmElementPtr OdBmElementImpl::getFilterElement(const OdBmObjectId& parameterId) const {
  OdUInt64 value = parameterId.getHandle();
  if (OdBm::BuiltInParameter::contains(value)) {
    return getFilterElement(static_cast<OdBm::BuiltInParameter::Enum>(value));
  }
  return this->getFacade ();
}

工作原理

参数DESIGN_OPTION_ID的实现

DESIGN_OPTION_ID参数是所有元素都存在的参数,因此它被添加到OdBmElementImpl::getListParams函数中的参数列表中。

它在Teigha BIM中的实现是在一个函数中(封装在一个宏中)完成的:

ODBM_BUILTIN_PARAMETERS_COMMON_IMPLEMENTATION(OdBmElementImpl, OdBmObjectId,
                                                    pThis, parameter, value).

然而,在参数值为“-4”的情况下,Revit Lookup会将其替换为“-1”。此替换已在Teigha BIM中实现。

const OdBmObjectId& OdBmElementImpl::getDesignOptionIdAsParam() const {
  const OdBmObjectId& designOptionId = getDesignOptionId();
  return OdBmObjectId::isRegularHandle(designOptionId.getHandle()) ? designOptionId : OdBmObjectId::kNull;
}

以FamilySymbol元素为例获取参数

获取参数的内部实现在 impl 文件中完成,在本例中是 BmFamilySymbolImpl.h 和 BmFamilySymbolImpl.cpp。

头文件添加了:

  1. 辅助定义宏:
    ODBM_BUILTIN_PARAM_STUFF(OdBmFamilySymbolInternalImpl);
    
  2. 如有必要,按类型细分的参数函数定义宏:
    ODBM_BUILTIN_PARAM_METHOD_DECLARATION(OdInt32);
    ODBM_BUILTIN_PARAM_METHOD_DECLARATION(double);
    ODBM_BUILTIN_PARAM_METHOD_DECLARATION(OdString);
    ODBM_BUILTIN_PARAM_METHOD_DECLARATION(OdBmObjectId);
    
  3. 如有必要,用于通用参数处理的宏:
    ODBM_PARAM_SET_TYPES(ODBM_PARAM_METHODS_DECLARATION, ODBM_VIRTUAL, , ODBM_SEMICOLON);
    
  4. 获取参数列表的函数:
    virtual void getListParams(OdBuiltInParamArray& aParams) const ODRX_OVERRIDE;
    
  5. 如有必要,过滤函数:
    virtual OdBmElementPtr getFilterElement(const OdBm::BuiltInParameter::Enum& parameterId) const ODRX_OVERRIDE;
    

在 cpp 文件中添加了:

  1. 使用宏实现参数的通用处理(在我们的例子中,参数首先在 FamilyParams 属性中搜索):
    #define ODBM_PARAM_METHOD_FAMILYSYMBOLIMPL_IMPLEMENTATION(METHOD)            \
      {                                                                          \
        OdResult es =                                                   \
            OdBmFamilyParamsPtr(getParams())->METHOD##Param(parameterId, value); \
        if (es == eOk || es == eNotImplementedYet || es == eNotApplicable) {      \
          return es;                                                             \
        }                                                                        \
        return super::METHOD##Param(parameterId, value);                         \
      }
    
    
    ODBM_PARAM_SET_TYPES(ODBM_PARAM_METHODS_DECLARATION, ,
      OdBmFamilySymbolImpl::,
      ODBM_PARAM_METHOD_FAMILYSYMBOLIMPL_IMPLEMENTATION);
    
  2. 实现获取参数列表(在我们的例子中,首先通过调用基类形成列表,然后添加 FamilySymbol 特有的参数):
    void OdBmFamilySymbolImpl::getListParams(OdBuiltInParamArray& aParams) const {
      super::getListParams(aParams);
      
      //...
    }
    
  3. 通过宏实现参数处理函数(以 OdInt32 类型为例,以通用视图给出):
    ODBM_BUILTIN_PARAMETERS_COMMON_IMPLEMENTATION(OdBmFamilySymbolImpl, OdInt32,
      pThis, parameter, value) {
      switch (parameter) {
        case OdBm::BuiltInParameter::SOME_PARAMETER_1: {
          //...
        } break;
    
        case OdBm::BuiltInParameter::SOME_NOT_IMPLEMENTED_PARAMETER: {
          return eNotImplementedYet;
        } break;
      }
    
      return eKeyNotFound;
    }
    
  4. 过滤函数的实现(取自 FamilyInstance 元素):
    OdBmElementPtr OdBmFamilyInstanceImpl::getFilterElement(const OdBm::BuiltInParameter::Enum& parameterId) const {
      switch (parameterId) {
        case OdBm::BuiltInParameter::UNIFORMAT_CODE: {
          if (!getMasterSymbolId().isNull()) {
            return getMasterSymbolId().safeOpenObject();
          }
        } break;
      }
    
      return super::getFilterElement(parameterId);
    }
    

在实现参数时使用模板方法

在实现参数时,使用了模板方法:

  • forwardParam — 将参数的处理抛给另一个对象。
  • universalAccess — 指示参数的访问函数。
  • onlyStaticValue — 将参数作为静态值处理。

今天就开始行动

免费试用 ODA 软件 60 天。
无风险,无需信用卡。

免费试用