// // (C) Copyright 2003-2017 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using System.Text; using Autodesk.Revit.DB; using Autodesk.Revit; using Element = Autodesk.Revit.DB.Element; namespace KMBIM { /// /// This class is used to detect the obstructions of a Line or a ray. /// class Detector { /// /// Revit Document. /// private Document m_rvtDoc; /// /// Revit 3D view. /// private View3D m_view3d; /// /// Constructor, initialize all the fields. /// /// Revit Document public Detector(Document rvtDoc) { m_rvtDoc = rvtDoc; FilteredElementCollector collector = new FilteredElementCollector(m_rvtDoc); FilteredElementIterator iter = collector.OfClass(typeof(View3D)).GetElementIterator(); iter.Reset(); while (iter.MoveNext()) { m_view3d = iter.Current as View3D; if (null != m_view3d && !m_view3d.IsTemplate) break; } } /// /// Return all the obstructions which intersect with a ray given by an origin and a direction. /// /// Ray's origin /// Ray's direction /// Obstructions intersected with the given ray public List Obstructions(Autodesk.Revit.DB.XYZ origin, Autodesk.Revit.DB.XYZ dir) { List result = new List(); ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3d); referenceIntersector.TargetType = FindReferenceTarget.Face; IList obstructionsOnUnboundLine = referenceIntersector.Find(origin, dir); foreach (ReferenceWithContext gRef in obstructionsOnUnboundLine) { if (!InArray(result, gRef)) { result.Add(gRef); } } result.Sort(CompareReferencesWithContext); return result; } /// /// ��輱�� �����ϴ� ��� ��ֹ��� ��ȯ�Ѵ�. /// /// ��輱 /// Obstructions intersected with the bound line public List Obstructions(Line boundLine) { List result = new List(); ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3d); referenceIntersector.TargetType = FindReferenceTarget.Face; // ������ ������ ���� �������� ������ �����ϰ�, // ReferenceIntersector�� ���ذ� ��ġ�ϴ� ������ ����� ��� ������ ��ȯ�մϴ�. IList obstructionsOnUnboundLine = referenceIntersector.Find(boundLine.GetEndPoint(0), boundLine.Direction); foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine) { Reference gRef = gRefWithContext.GetReference(); // ����Ʈ�� �ٿ�� ���ο� �ִ��� ���θ� �Ǵ��Ѵ�. // ����Ʈ�� ���� ������ �Ÿ��� ���� 0�� ������ ����Ʈ�� �ٿ�� ���ο� �ִ�. if (boundLine.Distance(gRef.GlobalPoint) < 1e-9) { if (!InArray(result, gRefWithContext)) { result.Add(gRefWithContext); } } } result.Sort(CompareReferencesWithContext); return result; } /// /// Judge whether a given Reference is in a Reference list. /// Give two References, if their Proximity and Element Id is equal, /// we say the two reference is equal. /// /// Reference Array /// Reference /// True of false private bool InArray(List arr, ReferenceWithContext entry) { foreach (ReferenceWithContext tmp in arr) { if (Math.Abs(tmp.Proximity - entry.Proximity) < 1e-9 && tmp.GetReference().ElementId == entry.GetReference().ElementId) { return true; } } return false; } /// /// Used to compare two references, just compare their ProximityParameter. /// /// First Reference to compare /// Second Reference to compare /// -1, 0, or 1 public int CompareReferencesWithContext(ReferenceWithContext a, ReferenceWithContext b) { if (a.Proximity > b.Proximity) { return 1; } if (a.Proximity < b.Proximity) { return -1; } return 0; } } }