我們在開發的過程中,射線法用的也挺多的,比如:想找到所有的樑;想找到離某一元素最近的元素等。今天簡單的簡介一下射線的用法。
射線的發的核心類: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;
}