// // (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.DB.Electrical; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using KDCS.Utils; using KMBIM.Revit.Tools.Utils; namespace KMBIM { /// /// 이 클래스는 덕트 또는 파이프의 장애물을 나타내는 클래스 /// public class SimpleSection { Document m_rvtDoc; public Line Line { get; set; } public Element ReferenceElement { get; set; } public XYZ MidPoint { get; set; } public SimpleSection(Document doc, Section section) { m_rvtDoc = doc; XYZ sp = section.Start; XYZ ep = section.End; if (section.Refs[0].GetReference().LinkedElementId.IntegerValue != -1) { RevitLinkInstance rli = m_rvtDoc.GetElement(section.Refs[0].GetReference().ElementId) as RevitLinkInstance; if (rli != null) { ReferenceElement = rli.GetLinkDocument().GetElement(section.Refs[0].GetReference().LinkedElementId); } } else { ReferenceElement = m_rvtDoc.GetElement(section.Refs[0].GetReference().ElementId); } this.Line = Line.CreateBound(sp, ep); this.MidPoint = Util.Midpoint(sp, ep); } public List GetIntersectUpperLower(XYZ vRay, View3D view3d) { List lstResut = new List(); ReferenceIntersector referenceIntersector= null; if (ReferenceElement.Document.IsLinked) { List builtInCats = new List(); builtInCats.Add(BuiltInCategory.OST_StructuralFraming); ElementMulticategoryFilter intersectFilter = new ElementMulticategoryFilter(builtInCats); referenceIntersector = new ReferenceIntersector(intersectFilter, FindReferenceTarget.Face, view3d); referenceIntersector.FindReferencesInRevitLinks = true; } else referenceIntersector = new ReferenceIntersector(ReferenceElement.Id, FindReferenceTarget.Face, view3d); // 주어진 요소(eId)이 점과 방향으로 만들어진 광선과 교차하는 지 확인 IList obstructionsOnUnboundLine = referenceIntersector.Find(MidPoint - vRay * 328.0, vRay); foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine) { Reference gRef = gRefWithContext.GetReference(); //var eId = gRef.GetReference().ElementId; // 링크된 모델인 경우 RevitLinkInstance ID //var lId = gRef.GetReference().LinkedElementId; // 링코된 모델에 포함된 요소의 ID XYZ itr = null; if (gRef.LinkedElementId.IntegerValue != -1) { if (gRef.LinkedElementId != ReferenceElement.Id) 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; bool bFound = false; if(lstResut.Find(x => x.DistanceTo(itr) < 0.00328084) == null) lstResut.Add(itr); } return lstResut; } } public class Section { private Document m_rvtDoc; /// /// Pipe centerline's direction. /// private Autodesk.Revit.DB.XYZ m_dir; /// /// Extend factor in negative direction. /// private double m_startFactor; /// /// Extend factor in positive direction. /// private double m_endFactor; /// /// References contained in this obstruction. /// private List m_refs; /// /// Pipes to avoid this obstruction, it is assigned when resolving this obstruction. /// Its count will be three if resolved, the three pipe constructs a "U" shape to round the obstruction. /// private List m_pipes; private List m_ducts; private List m_cabletrays; private List m_conduits; public List m_mergedSections; public KDCSIntersectorElement InterSectorElement { get; set; } public XYZ Start1 { get; set; } public XYZ End1 { get; set; } public bool IsMerged { get; set; } public Plane BasePlane { get; set; } /// /// Private constructor, just be called in static factory method BuildSections. /// /// Pipe's direction private Section(Document doc, Autodesk.Revit.DB.XYZ dir) { m_rvtDoc = doc; m_dir = dir; m_startFactor = 0; m_endFactor = 0; m_refs = new List(); m_ducts = new List(); m_pipes = new List(); m_cabletrays = new List(); m_conduits = new List(); m_mergedSections = new List(); IsMerged = false; } /// /// Pipe centerline's direction. /// public Autodesk.Revit.DB.XYZ CenterLineDirection { get { return m_dir; } } /// /// Pipes to avoid this obstruction, it is assigned when resolving this obstruction. /// Its count will be three if resolved, the three pipe constructs a "U" shape to round the obstruction. /// public List Pipes { get { return m_pipes; } } public List Ducts { get { return m_ducts; } } public List CableTrays { get { return m_cabletrays; } } public List Conduits { get { return m_conduits; } } /// /// Start point of this obstruction. /// public Autodesk.Revit.DB.XYZ Start { get { return m_refs[0].GetReference().GlobalPoint + m_dir * m_startFactor; } } /// /// End point of this obstruction. /// public Autodesk.Revit.DB.XYZ End { get { return m_refs[m_refs.Count - 1].GetReference().GlobalPoint + m_dir * m_endFactor; } } /// /// References contained in this obstruction. /// public List Refs { get { return m_refs; } } /// /// Extend this obstruction's interval in one direction. /// /// index of direction, 0 => start, 1 => end public void Inflate(int index, double value) { if (index == 0) { m_startFactor -= value; } else if(index == 1) { m_endFactor += value; } else { throw new ArgumentOutOfRangeException("Index should be 0 or 1."); } } /// /// 참조 섹션을 만듭니다. 섹션에는 광선이 장애물을 통과하는 여러 지점이 포함됩니다. /// 장애물이 한개인 경우 2개의 점이, 두개인 경우 4개의 점이 포함됩니다. /// /// 참조 /// 회피 요소의 방향 /// 섹션 목록 public static List
BuildSections(Document doc, List allrefs, Autodesk.Revit.DB.XYZ dir) { List buildStack = new List(); List
sections = new List
(); Section current = null; foreach (ReferenceWithContext geoRef in allrefs) { if (buildStack.Count == 0) { current = new Section(doc, dir); sections.Add(current); } current.Refs.Add(geoRef); ReferenceWithContext tmp = Find(buildStack, geoRef); if (tmp != null) { buildStack.Remove(tmp); } else buildStack.Add(geoRef); } return sections; } /// /// Judge whether a Reference is already in the list of Reference, return the founded value. /// /// List of Reference /// Reference to test /// One Reference has the same element's Id with entry private static ReferenceWithContext Find(List arr, ReferenceWithContext entry) { foreach (ReferenceWithContext tmp in arr) { if (tmp.GetReference().ElementId == entry.GetReference().ElementId) { return tmp; } } return null; } } }