本文仅介绍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。
头文件添加了:
- 辅助定义宏:
ODBM_BUILTIN_PARAM_STUFF(OdBmFamilySymbolInternalImpl); - 如有必要,按类型细分的参数函数定义宏:
ODBM_BUILTIN_PARAM_METHOD_DECLARATION(OdInt32); ODBM_BUILTIN_PARAM_METHOD_DECLARATION(double); ODBM_BUILTIN_PARAM_METHOD_DECLARATION(OdString); ODBM_BUILTIN_PARAM_METHOD_DECLARATION(OdBmObjectId); - 如有必要,用于通用参数处理的宏:
ODBM_PARAM_SET_TYPES(ODBM_PARAM_METHODS_DECLARATION, ODBM_VIRTUAL, , ODBM_SEMICOLON); - 获取参数列表的函数:
virtual void getListParams(OdBuiltInParamArray& aParams) const ODRX_OVERRIDE; - 如有必要,过滤函数:
virtual OdBmElementPtr getFilterElement(const OdBm::BuiltInParameter::Enum& parameterId) const ODRX_OVERRIDE;
在 cpp 文件中添加了:
- 使用宏实现参数的通用处理(在我们的例子中,参数首先在 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); - 实现获取参数列表(在我们的例子中,首先通过调用基类形成列表,然后添加 FamilySymbol 特有的参数):
void OdBmFamilySymbolImpl::getListParams(OdBuiltInParamArray& aParams) const { super::getListParams(aParams); //... } - 通过宏实现参数处理函数(以 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; } - 过滤函数的实现(取自 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 — 将参数作为静态值处理。