在revit二次开发中,过滤指定类型元素的需求是很常见的,比如说获取标高、轴网、三维视图、FamilySymbol等等,于是乎:
/// <summary>
/// 元素过滤服务
/// </summary>
public static class FilterElementService
{
#region 通用过滤器
/// <summary>
/// 过滤元素
/// </summary>
/// <typeparam name="T">元素类型</typeparam>
/// <param name="document"></param>
/// <param name="category">元素类别</param>
/// <param name="view">执行过滤的视图</param>
/// <returns></returns>
public static IEnumerable<T> FilterElement<T>(
this Document document,
BuiltInCategory category = BuiltInCategory.INVALID,
View view = null) where T : Element
{
System.Diagnostics.Debug.Assert(document != null);
ElementFilter filter = new ElementClassFilter(typeof(T));
if (category != BuiltInCategory.INVALID)
{
var catefilter = new ElementCategoryFilter(category);
filter = new LogicalAndFilter(filter, catefilter);
}
FilteredElementCollector collector =
view == null ?
new FilteredElementCollector(document) :
new FilteredElementCollector(document, view.Id);
return collector.WherePasses(filter).ToElements().Cast<T>();
}
/// <summary>
/// 过滤元素
/// </summary>
/// <param name="document"></param>
/// <param name="categoryList">元素类别</param>
/// <param name="view"></param>
/// <returns></returns>
public static IEnumerable<Element> FilterElement(
this Document document,
List<BuiltInCategory> categoryList,
View view = null)
{
System.Diagnostics.Debug.Assert(document != null);
System.Diagnostics.Debug.Assert(categoryList != null && categoryList.Count > 0);
var cateFilter = ToElementFilter(categoryList);
FilteredElementCollector collector =
view == null ?
new FilteredElementCollector(document) :
new FilteredElementCollector(document, view.Id);
return collector.WherePasses(cateFilter).ToElements();
}
#endregion
#region 常用元素过滤器
/// <summary>
/// 获取所有标高集合
/// </summary>
/// <param name="document"></param>
/// <param name="descending">根据标高降序排列</param>
/// <returns></returns>
public static IEnumerable<Level> GetLevel(this Document document, bool descending = false)
{
var levels = document.FilterElement<Level>(BuiltInCategory.OST_Levels);
return descending ? levels.OrderByDescending(o => o.Elevation) : levels.OrderBy(o => o.Elevation);
}
/// <summary>
/// 获取轴网集合
/// </summary>
/// <param name="document"></param>
/// <param name="view"></param>
/// <returns></returns>
public static IEnumerable<Grid> GetGrid(this Document document, View view = null)
{
return document.FilterElement<Grid>(BuiltInCategory.OST_Grids, view);
}
/// <summary>
/// 获取 所有视图
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
public static IEnumerable<View> GetViews(this Document document)
{
return document.FilterElement<View>().Where(o => o.CanBePrinted);
}
/// <summary>
/// 获取 三维视图
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
public static IEnumerable<View3D> GetView3d(this Document document)
{
return document.FilterElement<View3D>().Where(o => o.CanBePrinted);
}
/// <summary>
/// 获取默认的三维视图
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
public static View3D GetDefaultView3d(this Document document)
{
var all3dViews = GetView3d(document);
var find = all3dViews.FirstOrDefault(o =>
o.Name == "{三维}" ||
string.Equals(o.Name, "{3D}", StringComparison.CurrentCultureIgnoreCase));
if (find == null)
find = all3dViews.FirstOrDefault();
if (find == null) throw new Exception("找不到默认三维视图.");
return find;
}
#endregion
/// <summary>
/// 获取选择集中元素
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
public static IEnumerable<Element> GetSelection(this Autodesk.Revit.UI.UIDocument uiDocument)
{
System.Diagnostics.Debug.Assert(uiDocument != null);
var document = uiDocument.Document;
return uiDocument.Selection.GetElementIds().Select(o => document.GetElement(o));
}
/// <summary>
/// 获取选择集中元素
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
public static IEnumerable<T> GetSelection<T>(this Autodesk.Revit.UI.UIDocument uiDocument) where T : Element
{
System.Diagnostics.Debug.Assert(uiDocument != null);
return GetSelection(uiDocument).Where(o => o is T).Cast<T>();
}
#region UTILS
static ElementFilter ToElementFilter(List<BuiltInCategory> categoryList)
{
ElementFilter elmFilter = null;
int iCount = categoryList.Count;
if (iCount > 0)
elmFilter = new ElementCategoryFilter(categoryList[0]);
for (int i = 1; i < iCount; i++)
{
var catefilter = new ElementCategoryFilter(categoryList[i]);
elmFilter = new LogicalOrFilter(elmFilter, catefilter);
}
return elmFilter;
}
#endregion
}
这个类,我本人是用的非常频繁的,它至少覆盖我大部分获取元素的需求情况,
如果您有更好的方法获取建议,请留言告诉我,谢谢,分享创造价值。