2020/12/09

3D二次开发中如何定义复杂过滤器

作者 Leon

我们经常需要在代码中根据特定条件来过滤某些对象,就像在3D里面调用一些复杂的过滤器一样,经过过滤的数据源,可以大大增加程序的运行效率。

Dim oFilter As New Filter

首先实例化一个Filter对象,我们可以看到Filter对象的Definition属性中有很多方法,重点介绍下面这几个常用的。

oFilter.Definition.AddHierarchy(HierarchyTypes.XXX, objCol, bIncludeNested)
oFilter.Definition.AddObjectType(Piping\PipingParts\PipeComponents)
oFilter.Definition.AddWhereProperty()
oFilter.Definition.MatchAllProperties = True or False

AddHierarchy是添加System或Assembly或Space或WBS等目录树过滤条件,具体的HierarchyTypes有:System,Assembly,WBS,Analysis,Space,PermissionGroup,Volume_NamedSpace。后面接一个ReadOnly的Business Object的集合,就是目录树节点的集合,注意这里一定要转换成为这种性质的集合。最后一个Boolean类型的意思是是否包含目录树节点的子集。

AddObjectType是设置过滤的对象类型,这个在3D里做过过滤器的应该也很熟悉了,只不过这里的写法需要注意一下了,具体你想过滤什么类型的对象,路径要按照Metadata Browser里面的ClassificationTopNodes的目录填写。

AddWhereProperty是添加属性过滤条件,这个就比较难了。这个方法有多重定义,我们常用的是直接的属性过滤:AddWhereProperty(oPropValue, iOperator),这个就相当于我们在3D中做COM属性过滤时的Direct Property of Object Type,能直接从对象上拿到这个属性就可以这么写。当然你需要先定义一个有具体值的oPropValue。

如果要通过关联关系找到下一层对象上的属性,就用到了AddWhereProperty(oPropValue, iOperator, RelationshipInfo, sRoleName), 这里多了两个参数,做过开发的可能会比较熟悉,我们使用GetRelationhship方法的时候,就需要给一个Relationship的名字和一个Role的名字。这里的RelationshipInfo的定义类似于管道等级或保温等级的获取方法,我们很难去自己定义一个Relationship Information对象,最直接的方法是从某个有这种关联关系的对象身上去获取到。这可能需要我们在3D里建立一些特定类型的对象,专门用来在代码中实例化,然后获取这些关联关系或诸如此类的对象。

Dim oRelationInfo as RelationshipInformation = Nothing
Dim sOD As String = "{XXXXXXXXXXXXXXXXXXXXXX}"
Dim oBMoniker = ActivePlant.PlantModel.GetBOMonikerFromDbIdentifier(sOID)
Dim oBO As BusinessObject = ActivePlant.PlantModel.WrapSP3DBO(oBMoniker)
For Each item in oBO.Relationships
    oRealtionInfo = item.RelationshipInfo
    If oRelationInfo.DisplayName = "XXXXXXXXX" Then
        Exit For
    End If
Next

MatchAllProperties就很好理解了,我们在3D的过滤器中定义属性过滤的时候,有个All和Any,也就是与和或的选择。

最后就是获取这个过滤器的结果了。

Dim rcolBOs As ReadOnlyCollection(of BusinessObject) = oFilter.Apply()
0 0 投票数
文章评分