前言
这个例子介绍了如何使用过滤器以及墙体的位置线来及进行相交检测,包括:
- 找到和墙相交的柱子
- 找到出入口的障碍物
- 找到墙各个端点接近的墙
- 验证墙和其它墙的交接情况
内容
找到和墙相交的柱子
关键点在于 ElementIntersectsElementFilter
可以用于过滤和对应Element
几何相交的其它Element
,核心逻辑:
// 找到文件所有的建筑柱和结构柱
FilteredElementCollector collector = new FilteredElementCollector(m_doc);
List<BuiltInCategory> columnCategories = new List<BuiltInCategory>();
columnCategories.Add(BuiltInCategory.OST_Columns);
columnCategories.Add(BuiltInCategory.OST_StructuralColumns);
collector.WherePasses(new ElementMulticategoryFilter(columnCategories));
// 用 ElementIntersectsElementFilter 进行过滤
ElementIntersectsElementFilter testElementIntersectsElementFilter =
new ElementIntersectsElementFilter(wall);
collector.WherePasses(testElementIntersectsElementFilter);
找到出入口的障碍物
核心逻辑:
- 得到所有的出入口
- 用出入口 Element 的几何来做过滤
得到所有的出入口:
FilteredElementCollector collector = new FilteredElementCollector(m_doc);
ElementClassFilter filterFamilyInstance = new ElementClassFilter(typeof(FamilyInstance));
ElementCategoryFilter filterDoorCategory = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
LogicalAndFilter filterDoorInstance = new LogicalAndFilter(filterDoorCategory, filterFamilyInstance);
return collector.WherePasses(filterDoorInstance).ToElements();
用出入口 Element 的几何来做过滤:
// 得到出入口构件的几何实体
IEnumerator<GeometryObject> Objects = egressElement.get_Geometry(new Autodesk.Revit.DB.Options()).GetEnumerator();
Objects.MoveNext();
GeometryInstance gi = Objects.Current as GeometryInstance;
IEnumerator<GeometryObject> Objects1 = gi.GetInstanceGeometry().GetEnumerator();
while (Objects1.MoveNext()){
// 得到当前出入口的几何实体
GeometryObject egressGObj = Objects1.Current;
if (egressGObj is Solid){
Solid egressVolume = egressGObj as Solid;
// 过滤掉ElementType,保留其它Element
FilteredElementCollector blockingcollector = new FilteredElementCollector(m_doc);
blockingcollector.WhereElementIsNotElementType();
// 用过滤器判断是否和几何实体相交
ElementIntersectsSolidFilter testElementIntersectsSolidFilter =
new ElementIntersectsSolidFilter(egressVolume);
blockingcollector.WherePasses(testElementIntersectsSolidFilter);
IEnumerable<Element> blockingElement = blockingcollector;
// Exclude the door itself
List<ElementId> exclusions = new List<ElementId>();
exclusions.Add(egressElement.Id);
blockingcollector.Excluding(exclusions);
count++;
}
}
效果:
找到墙各个端点接近的墙
核心逻辑:
- 找到墙中心线
- 用墙中心线端点生成圆柱
- 判断其它墙是否和圆柱相交
核心代码,用墙中心线端点生成圆柱来进行过滤:
// 用墙中心线端点生成圆柱
List<CurveLoop> curveloops = new List<CurveLoop>();
CurveLoop circle = new CurveLoop();
circle.Append(Arc.Create(point, radius
, 0, Math.PI,
XYZ.BasisX, XYZ.BasisY));
circle.Append(Arc.Create(point, radius
, Math.PI, 2 * Math.PI,
XYZ.BasisX, XYZ.BasisY));
curveloops.Add(circle);
Solid wallEndCylinder =
GeometryCreationUtilities.CreateExtrusionGeometry(curveloops, XYZ.BasisZ, height);
// 遍历所有的墙,进行几何相交判断
FilteredElementCollector collector = new FilteredElementCollector(m_doc);
collector.OfCategory(BuiltInCategory.OST_Walls);
ElementIntersectsSolidFilter testElementIntersectsSolidFilter =
new ElementIntersectsSolidFilter(wallEndCylinder);
collector.WherePasses(testElementIntersectsSolidFilter);
效果:
验证墙和其它墙的交接情况
核心逻辑,获取墙中心线,断开连接,判断是否连接,然后重新连接。
核心 API:
namespace Autodesk.Revit.DB
{
public static class WallUtils
{
// 允许墙在相应端点与其它墙相交
public static void AllowWallJoinAtEnd(Wall wall, int end);
// 禁止墙在相应端点与其它墙相交
public static void DisallowWallJoinAtEnd(Wall wall, int end);
// 判断墙在相应端点是否与其它墙相交
public static bool IsWallJoinAllowedAtEnd(Wall wall, int end);
}
}
如何获取墙的中心线:
LocationCurve locationCurve = wall.Location as LocationCurve;
如何从中心线获取与其它墙的相交信息:
ElementArray array = locationCurve.get_ElementsAtJoin(end);