目录
前言
最近在用过滤器功能,先按照教程做了筛选墙,再自己做了筛选常规模型的功能,发现有点不一样,问题在于筛选这些Elements的时候没弄清元素是怎么分类的,研究了下Element下”继承关系“的问题,给找到的相关资料做了些笔记分享如下:
感谢:叶雄进老师link、黑夜de骑士link
对象分类
首先要理解Revit中“Category、Family、 FamilySymbol、 FamilyInstance”四者之间的关系与区别。
图源b站up主:黑夜de骑士-面向工程人员的Revit二次开发06_Revit二次开发之过滤器的使用(01:20/58:17)
Revit中直观的关系:
还有个族实例,当然把族类型拖到界面里就变成了族实例了。
当前选中元素的族类型/族实例可以在lookup左上角查看;
特殊的族类型/族实例,如墙,就对应WallType/Wall,选取界面里的一面墙(这里就是选了一个族实例)用lookup查看可以发现:
族类别Category中BuiltInCategory.XXX可以在lookup-Category里查看
在代码里的体现:
collector.OfCategory(BuiltInCategory.OST_Planting).OfClass(typeof(FamilyInstance));
过滤方法
图源b站up主:黑夜de骑士-面向工程人员的Revit二次开发06_Revit二次开发之过滤器的使用(11:00/58:17)
过滤-快速过滤方法:
OfCategory是从大到小找,先找目标Category(如BuiltInCategory.OST_Doors);
OfClass是从小到大找,先找族实例(找FamilyInstance、找Wall);
所以尽量先OfCategory再OfClass(but其实结果都一样,顺序也是可以调换的)。
过滤-通用方法:
将在代码案例里展示。
结合上文给了一些例子,大部分是typeof(Instance),墙是特殊的typeof(wall)。
//筛选窗
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfCategory(BuiltInCategory.OST_Windows).OfClass(typeof(FamilyInstance));
//筛选常规模型
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfCategory(BuiltInCategory.OST_GenericModel).OfClass(typeof(FamilyInstance));
//筛选墙
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfCategory(BuiltInCategory.OST_Walls).OfClass(typeof(Wall));
有时需要筛选族(Family)的时候,只能上OfClass,不能上OfCategory。黑夜de骑士链接:link
下面是叶雄进老师教程里过滤窗&门并收集个数的完整代码 内联代码片
。
这里收集窗时先OfClass再OfCategory了,但效果一模一样的。
收集门时,用的通用方法,相当于把一句话扩写成了三句,详情看注释。
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
namespace Project
{
[Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
public class GetAllWindows : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
{
UIApplication uiApp = commandData.Application;
Autodesk.Revit.ApplicationServices.Application app = uiApp.Application;
Document doc = uiApp.ActiveUIDocument.Document;
//获得所有窗户
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Windows);
//将结果放在lists变量里,再输出有多少个对象
IList<Element> lists = collector.ToElements();
String strMsg = string.Format("There are {0} windows in current model", lists.Count);
MessageBox.Show(strMsg);
//获得所有门(另一种筛选方式)
FilteredElementCollector collector2 = new FilteredElementCollector(doc);
ElementClassFilter ClassFilter = new ElementClassFilter(typeof(FamilyInstance));
ElementCategoryFilter CatFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
//把上两个定义的过滤器当做参数传到逻辑与过滤器里
LogicalAndFilter logicalFilter = new LogicalAndFilter(ClassFilter, CatFilter);
//让collector2通过自定义的LogicalFilter过滤器
collector2.WherePasses(logicalFilter);
//以上两句也可以简写,省略那个逻辑与过滤器
//collector.WherePasses(ClassFilter).WherePasses(CatFilter);
IList<Element> lists2 = collector2.ToElements();
String strMsg2 = string.Format("There are {0} doors in current model", lists2.Count);
MessageBox.Show(strMsg2);
return Result.Succeeded;
}
}
}
这两幅也是来自叶雄进老师link教程里的图,年代久远了,和上面整理的分类略有不同,先存个档。