近日看到一个5d6d的关于Revit API的论坛 既不标识本博文章的链接,也没有说明作者就在其论坛内转载本博的文章,而且发帖人写的是论坛的管理员。 为了更好服务广大Revit API 爱好者,请该版主改正这种行为,在引用本博的帖子里至少补上本博每篇文章链接。这样本博对已有文章的修改和更新读者们有机会过来看看。如果尊重原创,请署上原作者。
应一朋友询问,写了如下的文章。
碰撞检查是大家都非常感兴趣的内容,首先涉及到的就是构件之间的相交。可以通过对象过滤器来实现求出给定对象相交的其它对象。
在Revit2011中,没有直接提供构件相交的过滤器。我们可以变通使用这个过滤器BoundingBoxIntersectsFilter 它实现的功能是给定一个空间立方体,(用OutLine类表示),找出对象的BoundingBox与这个空间立方体相交的对象。这个也有不准确的地方,因为用的是对象的外包立方体,毕竟外包立方体与对象自身的几何体不是等同的。
在Revit 2012里提供了精确的的对象相交的过滤器:ElementIntersectsFilter 。 这个过滤器可以准确找到与制定对象相交的对象。请看下面示例代码:
using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.UI.Selection; [TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class FindIntersectWallsByElement : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; Transaction trans = new Transaction(doc, "ExComm"); trans.Start(); //pick the column Selection sel = app.ActiveUIDocument.Selection; Reference ref1 = sel.PickObject(ObjectType.Element, "Please pick a column"); Element column = doc.GetElement(ref1); FilteredElementCollector collector = new FilteredElementCollector(doc); ElementIntersectsElementFilter elementFilter = new ElementIntersectsElementFilter(column, false); collector.WherePasses(elementFilter); List<ElementId> excludes = new List<ElementId>(); excludes.Add(column.Id); collector.Excluding(excludes); sel.Elements.Clear(); //Add these interseting element to the selection foreach (Element elem in collector) { sel.Elements.Add(elem); } trans.Commit(); return Result.Succeeded; } }
在Revit 2012里也可以给定一个空间立方体,找出与这个空间立方体相交的对象。使用过滤器ElementIntersectsSolidFilter。请看下面代码。
[TransactionAttribute(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class FindIntersectWallsByGeometry : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string messages, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; Transaction trans = new Transaction(doc, "ExComm2"); trans.Start(); //pick a point to draw solid Selection sel = app.ActiveUIDocument.Selection; XYZ pt = sel.PickPoint("Please pick a point to get the close walls"); //XYZ pttemp1 = sel.PickPoint(Autodesk.Revit.UI.Selection.ObjectSnapTypes.None, "Pick leader end..."); //XYZ pttemp2 = sel.PickPoint(Autodesk.Revit.UI.Selection.ObjectSnapTypes.None, "Pick leader elbow..."); // double dBoxLength = 3; XYZ pt1 = new XYZ(pt.X - dBoxLength / 2, pt.Y - dBoxLength / 2, pt.Z); XYZ pt2 = new XYZ(pt.X + dBoxLength / 2, pt.Y - dBoxLength / 2, pt.Z); XYZ pt3 = new XYZ(pt.X + dBoxLength / 2, pt.Y + dBoxLength / 2, pt.Z); XYZ pt4 = new XYZ(pt.X - dBoxLength / 2, pt.Y + dBoxLength / 2, pt.Z); Line lineBottom = app.Application.Create.NewLineBound(pt1, pt2); Line lineRight = app.Application.Create.NewLineBound(pt2, pt3); Line lineTop = app.Application.Create.NewLineBound(pt3, pt4); Line lineLeft = app.Application.Create.NewLineBound(pt4, pt1); CurveLoop profile = new CurveLoop(); profile.Append(lineBottom); profile.Append(lineRight); profile.Append(lineTop); profile.Append(lineLeft); List<CurveLoop> loops = new List<CurveLoop>(); loops.Add(profile); XYZ vector = new XYZ(0, 0, 1); Solid solid = GeometryCreationUtilities.CreateExtrusionGeometry(loops, vector, 10); FilteredElementCollector collector = new FilteredElementCollector(doc); ElementIntersectsSolidFilter solidFilter = new ElementIntersectsSolidFilter(solid); collector.WherePasses(solidFilter); sel.Elements.Clear(); //Add these interseting element to the selection foreach (Element elem in collector) { sel.Elements.Add(elem); } trans.Commit(); return Result.Succeeded; } }
请看我的一个过滤器专题讲座提到的如何使用上面的方法 http://blog.csdn.net/joexiongjin/article/details/6792174
叶雄进 2012.2.21
转载请注明出处: http://blog.csdn.net/joexiongjin/article/details/7280419