BimRv SDK:使用过滤规则收集元素

为了在 BimRv SDK 中过滤和收集元素,开发人员可以使用 OdBmElementCollector 类来收集符合一组条件的元素。OdBmIterator 类也可以与谓词或过滤规则配合使用。

  • OdBmElementCollector — 收集通过一组条件传递的数据库中的元素。定义在 Database/BmElementCollector.h 中。
    常用方法:
    • OdBmElementCollector& wherePasses(const OdBmFilterRulePtr& pRule) — 将元素过滤器应用于收集器。
    • OdBmElementPtrArray collect() const — 返回通过过滤器的元素集。
    • OdBmElementCollector& ofCategory(OdBm::BuiltInCategory::Enum category) — 将 ElementCategoryFilter 应用于收集器。
    • OdBmElementCollector& ofClass(const OdTfClass* pClass) — 将 ElementClassFilter 应用于收集器。
    • OdBmElementCollector::iterator_type getElementIterator() const — 返回收集到的元素的元素迭代器 (OdBmElementIterator)。
  • OdBmIterator — 一个类模板,定义了类型 T 对象的迭代器。定义在 Common/BmIterator.h 中。迭代器的常用方法:
    • T object() — 返回迭代器指向的对象。
    • bool done() — 如果没有更多对象可迭代,则返回 true。
    • bool next() — 返回数组中的下一个元素。
    • OdBmIterator::pointer_type clone() — 返回迭代器的克隆。
    • OdArray< T > collect() — 返回迭代对象的数组。
    • OdBmIterator::pointer_type filter() — 创建迭代器的克隆,并将过滤条件应用于克隆中的每个对象。
  • OdBmElementIterator — 此迭代器用于迭代数据库中的元素。定义在 Database/Entities/BmElemTable.h 中。
  • OdBmElemTableIterator — OdBmElementIterator 的公共派生类。定义在 Database/Entities/BmElemTable.h 中。

要创建 OdBmElemTableIterator,请使用 OdBmDatabase::newElemTableIterator() 方法。

OdBmElementCollector 和 OdBmIterator 类之间的主要区别在于,OdBmIterator 在设计上是无状态的,并且 collect() 方法会结束迭代器(请参阅下面的示例)。OdBmElementCollector 会保留其数据。

要多次使用迭代器,只需在调用 collect() 或 next() 方法之前克隆它:

OdBmElementIteratorPtr pElementsIt = pDb->newElemTableIterator()->filter(pCategoryRule);
OdBmElementIteratorPtr pElementsItClone = pElementsIt->clone();

下一个示例演示了在数据库中迭代和过滤元素的过程。

示例文件包含七条风管曲线,但其中只有一条在注释中包含“foo”。

要为元素类别构建过滤规则:

OdBmDatabasePtr pDb = app->readFile(L"sample_file.rvt");
// Create filter rule based on OST_DuctCurves category
OdBmFilterCategoryRulePtr pCategoryRule = OdBmFilterCategoryRule::createObject();
pCategoryRule->addCategory(pDb->getObjectId(OdBm::BuiltInCategory::OST_DuctCurves, true));
// Collect elements using category rule
{
  // Create new ElemTable iterator and call filter method to get iterator of Elements that pass the filter rule
  OdBmElementIteratorPtr pElementsIt = pDb->newElemTableIterator()->filter(pCategoryRule);
  // Collect filtered elements into array
  OdBmElementPtrArray elements = pElementsIt->collect();
  // Please notice that the elements1 array will be empty, because iterator is stateless by design
  OdBmElementPtrArray elements1 = pElementsIt->collect();
}

要为元素的注释属性构建字符串规则:

// Create Parameter value provider
OdBmParameterValueProviderPtr pParamEvalProvider = OdBmParameterValueProvider::createObject();
// Set flags and properties
pParamEvalProvider->setElemOrSymbol(1);
pParamEvalProvider->setParameter(OdBmParameterId(pDb->getObjectId(OdBm::BuiltInParameter::ALL_MODEL_INSTANCE_COMMENTS, true)));
// Create string rule with Equal evaluator
OdBmFilterStringRulePtr pStringRule = OdBmFilterStringRule::createObject();
pStringRule->setValueProvider(pParamEvalProvider);
OdBmFilterStringEqualsPtr pEvaluator = OdBmFilterStringEquals::createObject();
pStringRule->setEvaluator(pEvaluator);
pStringRule->setRuleString(L"foo");

要使用类别和字符串规则过滤元素:

OdBmElementIteratorPtr pElementsIt = pDb->newElemTableIterator()->filter(pCategoryRule)->filter(pStringRule);
OdBmElementPtrArray elements = pElementsIt->collect();

要使用 OdBmElementCollector 收集元素:

OdBmDatabasePtr pDb_ = app->readFile(L"rooms.rvt");

// Create a filter rule for anything with ROOM_NAME that isn't "CLOSET"
OdBmParameterValueProviderPtr pParamEvalProvider = OdBmParameterValueProvider::createObject();
pParamEvalProvider->setElemOrSymbol(1);
pParamEvalProvider->setParameter(OdBmParameterId(pDb_->getObjectId(OdBm::BuiltInParameter::ROOM_NAME, true)));
OdBmFilterStringRuleEvaluatorPtr pEvaluator = OdBmFilterStringEquals::createObject();
OdBmFilterStringRulePtr pStringRule = OdBmFilterStringRule::createObject();
pStringRule->setValueProvider(pParamEvalProvider);
pStringRule->setEvaluator(pEvaluator);
pStringRule->setRuleString("CLOSET");
OdBmFilterInverseRulePtr pInverter = OdBmFilterInverseRule::createObject();
pInverter->setInnerRule(pStringRule);

// Get elements without a ROOM_NAME of "CLOSET"
OdBmElementCollector pFilterTest5 = OdBmElementCollector(pDb_).wherePasses(pInverter);
OdBmElementPtrArray arr5 = pFilterTest5.collect();

// Create a rule to filter out all rooms
OdBmFilterCategoryRulePtr pCategoryRule = OdBmFilterCategoryRule::createObject();
pCategoryRule->addCategory(pDb_->getObjectId(OdBm::BuiltInCategory::OST_Rooms, true));

// Get only rooms without a ROOM_NAME of "CLOSET"
OdBmElementCollector pFilterTest6 = pFilterTest5.wherePasses(pCategoryRule);

// Do the same by combining calls of wherePasses()
OdBmElementCollector pFilterTest7 = OdBmElementCollector(pDb_).wherePasses(pInverter).wherePasses(pCategoryRule);

// Get all elements of OdBm::BuiltInCategory::OST_Rooms category
OdBmElementCollector pFilterTest8 = OdBmElementCollector(pDb_).ofCategory(OdBm::BuiltInCategory::OST_Rooms);

// Get all elements of OdBmRoomElem class
OdBmElementCollector pFilterTest9 = OdBmElementCollector(pDb_).ofClass(OdBmRoomElem::desc());

使用 OdBmIterator 和谓词收集元素

您还可以将谓词与迭代器配合使用,例如:

struct c_elemHandle : std::unary_function<OdBmElementPtr, bool> {
  c_elemHandle(OdBm::BuiltInCategory::Enum category) 
    : m_hndl(OdDbHandle(category)) {}
  bool operator()(const OdBmElementPtr& pObj) const {
    return m_hndl == pObj->getCategroryId().getHandle();
  }
private:
  OdDbHandle m_hndl;
};

OdBmElementIteratorPtr pElementsIt = 
pDb->newElemTableIterator()->filter(c_elemHandle(OdBm::BuiltInCategory::OST_Rooms));

有关类和方法(包括用于创建过滤规则的评估器)的更多详细信息,请参阅 BimRv 文档(需要登录)。

今天就开始行动

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

免费试用