// // (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; using KMBIM.Revit.Tools.Utils; using KDCS.Utils; 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; } } public View3D GetView3d() { return m_view3d; } /// /// Return all the obstructions which intersect with a bound line. /// /// Bound line /// Obstructions intersected with the bound line public List Obstructions(Line lineSeg, KDCSIntersectorElement kdcs_itse) { ElementId eId = kdcs_itse.Id; List result = new List(); ReferenceIntersector referenceIntersector = null; // ¿¬°áµÈ Revit ¸ðµ¨ÀÎ °æ¿ì ºö(°Å´õ) °£¼· È®ÀÎ if (kdcs_itse.GetLinkDocument() != null) { List builtInCats = new List(); builtInCats.Add(BuiltInCategory.OST_StructuralFraming); ElementMulticategoryFilter intersectFilter = new ElementMulticategoryFilter(builtInCats); referenceIntersector = new ReferenceIntersector(intersectFilter, FindReferenceTarget.Face, m_view3d); referenceIntersector.FindReferencesInRevitLinks = true; // ÁÖ¾îÁø ¿ä¼Ò(eId)ÀÌ Á¡°ú ¹æÇâÀ¸·Î ¸¸µé¾îÁø ±¤¼±°ú ±³Â÷ÇÏ´Â Áö È®ÀÎ Line vline = Line.CreateBound(lineSeg.GetEndPoint(0) - lineSeg.Direction * 0.32, lineSeg.GetEndPoint(0) + lineSeg.Direction * 0.32); } else { referenceIntersector = new ReferenceIntersector(eId, FindReferenceTarget.Face, m_view3d); } List pts = new List(); // ÁÖ¾îÁø ¿ä¼Ò(eId)ÀÌ Á¡°ú ¹æÇâÀ¸·Î ¸¸µé¾îÁø ±¤¼±°ú ±³Â÷ÇÏ´Â Áö È®ÀÎ IList obstructionsOnUnboundLine = referenceIntersector.Find(lineSeg.GetEndPoint(0), lineSeg.Direction); foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine) { Reference gRef = gRefWithContext.GetReference(); XYZ itr = null; if (kdcs_itse.GetRevitLinkInstance() != null) { if (gRef.LinkedElementId != eId) continue; RevitLinkInstance rli = m_rvtDoc.GetElement(gRef.ElementId) as RevitLinkInstance; if (rli != null) { itr = rli.GetTransform().OfPoint(gRef.GlobalPoint); } else itr = gRef.GlobalPoint; } else { itr = gRef.GlobalPoint; } if (lineSeg.Distance(itr) < 1e-9) { if (!InArray(result, gRefWithContext)) { pts.Add(itr); result.Add(gRefWithContext); } } } if (pts.Count >= 2) { //Util.CreateModelLine(m_rvtDoc, pts[0], pts[1]); } 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; } } }