[返回博客](/cn/blog) # 如何在Teigha BIM中获取元素参数

Artur Vakhramov 三月 30, 2018 [\#rvt](/cn/blog/tag/rvt) [\#rfa](/cn/blog/tag/rfa) [\#Example](/cn/blog/tag/example)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

本文仅介绍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®中通过“视图”-&gt;“过滤器”菜单设置的。

通过这些参数进行过滤，可以不是通过元素本身的参数值，而是通过关联元素的参数值来执行。例如，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 天。  
无风险，无需信用卡。**

[免费试用](https://www.opendesign.com/cn/free-trial)
