如何编程判断构件相交?
近日看到一个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
顶起来…………
页:
[1]