using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
namespace ShrlAlgoToolkit.Revit.Assists;
public static class ElementCollectorExtensions
{
///
/// 多类别的元素集合
///
///
///
///
public static FilteredElementCollector OfCategories(this FilteredElementCollector collector, params BuiltInCategory[] categories) =>
collector.WherePasses(new ElementMulticategoryFilter(categories));
/////
///// 基于视图的类别收集器
/////
///// 收集的视图
///// 元素的类别
///// 过滤元素收集器
//public static FilteredElementCollector OfCategory(this View view, BuiltInCategory builtInCategory) =>
// view.OfCollector().OfCategory(builtInCategory);
///
/// 类型的元素集合
///
///
///
///
public static FilteredElementCollector OfClass(this Document doc)
where T : Element => doc.OfCollector().OfClass(typeof(T));
///
/// 基于视图的类型收集器
///
/// 元素的类
/// 收集的视图
/// 过滤元素收集器
public static FilteredElementCollector OfClass(this View view)
where T : Element => view.OfCollector().OfClass(typeof(T));
///
/// 多类型的元素集合
///
///
/// 指定类型
///
public static FilteredElementCollector OfClasses(this Document doc, params Type[] types) =>
doc.OfCollector().WherePasses(new ElementMulticlassFilter(types));
///
/// 基于视图的多类别收集器
///
/// 收集的视图
/// 多个类别
/// 过滤元素收集器
public static FilteredElementCollector OfClasses(this View view, params Type[] types) =>
view.OfCollector().WherePasses(new ElementMulticlassFilter(types));
///
/// 视图元素收集器(临时隐藏也算不可见)
///
/// 收集的视图
///
public static FilteredElementCollector OfCollector(this View view) =>
view == null
? throw new ArgumentNullException(nameof(view), "收集视图为空")
: FilteredElementCollector.IsViewValidForElementIteration(view.Document, view.Id)
? new FilteredElementCollector(view.Document, view.Id)
: throw new ArgumentException($"视图{view.Id}不可应用收集器");
///
/// 文档的元素收集器
///
///
/// 过滤元素收集器
public static FilteredElementCollector OfCollector(this Document document) => document == null ? throw new ArgumentNullException(nameof(document), "文档为空") : new(document);
///
/// 基于视图的实例收集器
///
/// 收集的视图
/// 元素的类别
/// 过滤元素收集器
public static FilteredElementCollector OfElementType(this FilteredElementCollector collector) =>
collector.WhereElementIsElementType();
///
/// 基于过滤器元素集合
///
///
///
///
public static FilteredElementCollector OfFilter(this FilteredElementCollector collector, ElementFilter filter) =>
collector.WherePasses(filter);
///
/// 多个过滤器的收集器
///
/// 收集器
///
///
public static FilteredElementCollector OfFilters(
this FilteredElementCollector collector,
List filters,
bool logicalAnd = false
)
{
ElementLogicalFilter filter = logicalAnd ? new LogicalAndFilter(filters) : new LogicalOrFilter(filters);
collector.WherePasses(filter);
return collector;
}
///
/// 基于视图的实例收集器
///
/// 收集器
/// 过滤元素收集器
public static FilteredElementCollector OfInstances(this FilteredElementCollector collector) =>
collector.WhereElementIsNotElementType();
public static FilteredElementCollector OfModelCollector(this Document doc)
{
if (doc == null)
{
throw new ArgumentNullException(nameof(doc), "文档为空");
}
var li = doc.OfCollector()
.WhereElementIsNotElementType()
.Where(
e => e is TopographySurface ||
e is DirectShape ||
(e.CanHaveTypeAssigned()
&& e.IsValidObject
&& e.HasPhases()
&& e.get_BoundingBox(null) != null
&& e.Category is { Parent: null, CategoryType: CategoryType.Model }
&& e is not Panel
&& e is not Mullion
&& e is not RevitLinkInstance)).Select(e => e.Id).ToList();
if (li.Count == 0)
{
return null;
}
return new FilteredElementCollector(doc, li).WhereElementIsNotElementType();
}
///
/// 过滤项目文件最顶层的模型元素
///
/// 元素集合
public static IEnumerable OfParentModelElements(this Document doc) =>
doc.OfCollector()
.WhereElementIsNotElementType()
.Where(
e => e is TopographySurface ||
e is DirectShape ||
(e.CanHaveTypeAssigned()
&& e.IsValidObject
&& e.HasPhases()
&& e.get_BoundingBox(null) != null
&& e.Category is { CategoryType: CategoryType.Model, AllowsBoundParameters: true }
&& (e is HostObject || e.Category.Parent == null)
&& e is not Panel
&& e is not Mullion
&& e is not RevitLinkInstance)
);
///
/// 过滤项目文件的所有模型元素
///
/// 元素集合
public static IEnumerable OfAllModelElements(this Document doc) =>
doc.OfCollector()
.WhereElementIsNotElementType()
.Where(
e => e is TopographySurface ||
e is DirectShape ||
(e.CanHaveTypeAssigned()
&& e.IsValidObject
&& e.HasPhases()
&& e.ViewSpecific == false
&& e.Category is { CategoryType: CategoryType.Model, AllowsBoundParameters: true }
&& e.get_BoundingBox(null) != null
&& e is not RevitLinkInstance)
);
}