我们在开发的过程中,射线法用的也挺多的,比如:想找到所有的梁;想找到离某一元素最近的元素等。今天简单的简介一下射线的用法。
射线的发的核心类:ReferenceIntersector
他的内部有2中射线法查找的方法
查找符合条件的所有元素
IList Find(XYZ origin, XYZ direction)
查找符合条件的最近元素
ReferenceWithContext FindNearest(XYZ origin, XYZ direction)
废话不多说了,直接上代码。
- 查找符合条件的所有元素
/// <summary>
/// 射线法查找最近的Element
/// </summary>
/// <param name="doc">Dcument</param>
/// <param name="filter">例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray))</param>
/// <param name="targetRef">目标对象</param>
/// <param name="center">射源</param>
/// <param name="direction">方向</param>
/// <param name="hitElement">被击中的Element</param>
/// <returns>返回该射线</returns>
public static Line xRayFindNearest(this Document doc, ElementFilter filter, FindReferenceTarget targetRef, XYZ center, XYZ direction, ref Element hitElement)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
Func<View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
View3D view3D = collector.OfClass(typeof(View3D)).Cast<View3D>().First<View3D>(isNotTemplate);
ReferenceIntersector refIntersector = new ReferenceIntersector(filter, targetRef, view3D);
ReferenceWithContext rwc = refIntersector.FindNearest(center, direction);
if (null == rwc)
{
return null;
}
Reference reference = rwc.GetReference();
XYZ intersection = reference.GlobalPoint;
hitElement = doc.GetElement(reference);
Line result = null;
if (!center.IsAlmostEqualTo(intersection))
{
result = Line.CreateBound(center, intersection);
}
else
{
hitElement = null;
}
return result;
}
- 查找符合条件的最近元素
/// 射线法查找所有的Element
/// <summary>
/// 射线法查找所有的Element
/// </summary>
/// <param name="doc">Dcument</param>
/// <param name="filter">例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray))</param>
/// <param name="targetRef">目标对象</param>
/// <param name="center">射源</param>
/// <param name="direction">方向</param>
/// <returns>返回该射线</returns>
public static IList<Element> xRayFindAll(this Document doc, ElementFilter filter, FindReferenceTarget targetRef, XYZ center, XYZ direction)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
Func<View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate);
View3D view3D = collector.OfClass(typeof(View3D)).Cast<View3D>().First<View3D>(isNotTemplate);
ReferenceIntersector refIntersector = new ReferenceIntersector(filter, targetRef, view3D);
IList<ReferenceWithContext> refWithContexts = refIntersector.Find(center, direction);
if (null == refWithContexts)
{
return null;
}
IList<Element> resultElements = new List<Element>();
foreach (ReferenceWithContext rwc in refWithContexts)
{
Reference reference = rwc.GetReference();
Element hitElement = doc.GetElement(reference);
if (hitElement != null)
{
resultElements.Add(hitElement);
}
}
return resultElements;
}