EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

萧闫子 发表于 2014-1-15 12:46:00

如何编程判断构件相交?

近日看到一个5d6d的关于Revit API的论坛 既不标识本博文章的链接,也没有说明作者就在其论坛内转载本博的文章,而且发帖人写的是论坛的管理员。 为了更好服务广大Revit API 爱好者,请该版主改正这种行为,在引用本博的帖子里至少补上本博每篇文章链接。这样本博对已有文章的修改和更新读者们有机会过来看看。如果尊重原创,请署上原作者。



应一朋友询问,写了如下的文章。



碰撞检查是大家都非常感兴趣的内容,首先涉及到的就是构件之间的相交。可以通过对象过滤器来实现求出给定对象相交的其它对象。



在Revit2011中,没有直接提供构件相交的过滤器。我们可以变通使用这个过滤器BoundingBoxIntersectsFilter 它实现的功能是给定一个空间立方体,(用OutLine类表示),找出对象的BoundingBox与这个空间立方体相交的对象。这个也有不准确的地方,因为用的是对象的外包立方体,毕竟外包立方体与对象自身的几何体不是等同的。



在Revit 2012里提供了精确的的对象相交的过滤器:ElementIntersectsFilter 。 这个过滤器可以准确找到与制定对象相交的对象。请看下面示例代码:

view plaincopy
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;



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。请看下面代码。

view plaincopy

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

叶雄进

转载请注明出处: http://blog.csdn.net/joexiongjin/article/details/7280419

bin 发表于 2014-2-20 14:11:34

顶起来…………

页: [1]
查看完整版本: 如何编程判断构件相交?