Building Coder(Revit 二次开发)- 使用“实体相交(Solid Intersection)”机制过滤有接触的梁
原文链接:Filter for Touching Beams Using Solid Intersection
几何创建工具创建的临时实体(Solid)可以用于几何特征过滤器。
问题
我想通过编程方式获取全部有接触的梁,不考虑它们之间的连接状态。用户首先选中一根梁,然后程序自动将所有有递归接触的梁(即级联方式接触)选中。
Jeremy
首先让我们讨论这些梁是处于连接状态的情况:你可以使用 Beam.LocationCurve.ElementsAtJoin 属性获取在一根梁的指定端点连接的所有梁。然后再遍历得到的梁的集合,对每根梁继续使用 Beam.LocationCurve.ElementsAtJoin 属性获取级联模式下新的连接梁的集合。你可以在 SDK 例程 TraverseSystem 中找到类似的处理机制,这个例程展示了在管道系统中如何使用 MEP 连接管理器(Connection Manager)来遍历所有处于连接状态的元素。
1. 维护三个梁列表
- 已经处理过的梁(已处理梁表)2. 选中一根梁添加到当前梁表
3. 如果当前梁表非空,则重复如下处理
- 将当前梁添加到已处理梁表public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements ){ UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; CreationApp creapp = app.Create; Document doc = uidoc.Document; Selection sel = uidoc.Selection; Reference r = null; try { r = sel.PickObject( ObjectType.Element, "Please select a beam" ); } catch( RvtOperationCanceledException ) { return Result.Cancelled; } // 初始梁 Element start = doc.GetElement( r ); // 当前梁表(我们需要查找它们的相邻梁) List<ElementId> current = new List<ElementId>(); current.Add( start.Id ); // 已处理梁表 List<ElementId> visited = new List<ElementId>(); // 相邻梁表 List<ElementId> neighbours = new List<ElementId>(); // 递归调用 while( 0 < current.Count ) { // 记录已处理梁表 visited.AddRange( current ); neighbours.Clear(); // 查找当前梁表的相邻梁表(未处理) foreach( ElementId id in current ) { Element e = doc.GetElement( id ); AddConnectedElements( neighbours, e, visited ); } // 当前梁表处理完毕,找到相邻梁表成为下一次操作的当前梁表 // newly found become the next current ones current.Clear(); current.AddRange( neighbours ); } foreach( ElementId id in visited ) { uidoc.Selection.Elements.Add( doc.GetElement( id ) ); } return Result.Succeeded;}注意这个解决方案适用于所有基于曲线的元素。可以用于查找所有接触墙体、管线、管道等等场景。