// // (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.UI; using Autodesk.Revit; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.DB.Mechanical; using System.Diagnostics; using Element = Autodesk.Revit.DB.Element; using System.Collections; using System.Windows.Forms; using Autodesk.Revit.DB.Electrical; using Autodesk.Revit.UI.Selection; using KDCS.Utils; using KMBIM.Revit.Tools.Utils; namespace KMBIM { public enum EnumAvoidObstructionType { None = 0, AvoidUpDn, Avoid_Up, Avoid_Dn, AvoidDnUp, AvoidUp_, AvoidDn_ } public enum EnumAvoidObstructionCheckPoint { None = 0, AO_ChectPointTop, AO_ChectPointBottom, AO_ChectPointLeft, AO_ChectPointRight, AO_ChectPointCenter, AO_ChectPointOther // ֹ ߽ɼ ȸ Ȯ } public enum EnumPipeConnectType { None = 0, Connect, Prev, Next } /// /// Custom filter for selection. /// public class AvoidObstructionSelectionFilter : ISelectionFilter { private RevitLinkInstance _RevitLinkInstance; private List m_listsElementType = null; // Ư ֵ Ѵ. public AvoidObstructionSelectionFilter(List lstElementType) { m_listsElementType = new List(); foreach (Type t1 in lstElementType) { m_listsElementType.Add(t1); } } public bool AllowElement(Element elem) { Type etype = elem.GetType(); foreach (Type t1 in m_listsElementType) { if (etype == t1) { if (etype == typeof(FamilyInstance)) // йи νϽ { Category cat = elem.Category; if (cat != null) { if (cat.Id.IntegerValue.Equals((int)BuiltInCategory.OST_StructuralFraming)) return true; else return false; } } else if (etype == typeof(RevitLinkInstance)) { _RevitLinkInstance = elem as RevitLinkInstance; return true; }else return true; } } return false; } public bool AllowReference(Reference refer, XYZ point) { if (_RevitLinkInstance != null) { Element e = _RevitLinkInstance.GetLinkDocument().GetElement(refer.LinkedElementId); // Accept the selection if the element exists and is of the correct type var t = e.GetType(); if (t.Equals(typeof(FamilyInstance))) { Category cat = e.Category; if (cat != null) { if (cat.Id.IntegerValue.Equals((int)BuiltInCategory.OST_StructuralFraming)) return true; else return false; } return false; } else return false; } return true; } } public class FamilyInstanceSelectionFilter : ISelectionFilter { private RevitLinkInstance _RevitLinkInstance; private List m_listsElementType = null; public FamilyInstanceSelectionFilter(List lstElementType) { m_listsElementType = new List(); foreach (Type t1 in lstElementType) { m_listsElementType.Add(t1); } } public bool AllowElement(Element elem) { Type etype = elem.GetType(); foreach (Type t1 in m_listsElementType) { if (etype == t1) { if (etype == typeof(FamilyInstance)) // ????스?스 { Category cat = elem.Category; if (cat != null) { if (cat.Id.IntegerValue.Equals((int)BuiltInCategory.OST_GenericModel)) return true; else return false; } } else if (etype == typeof(RevitLinkInstance)) { _RevitLinkInstance = elem as RevitLinkInstance; return true; } else return true; } } return false; } public bool AllowReference(Reference refer, XYZ point) { if (_RevitLinkInstance != null) { Element e = _RevitLinkInstance.GetLinkDocument().GetElement(refer.LinkedElementId); // Accept the selection if the element exists and is of the correct type var t = e.GetType(); if (t.Equals(typeof(FamilyInstance))) { Category cat = e.Category; if (cat != null) { if (cat.Id.IntegerValue.Equals((int)BuiltInCategory.OST_GenericModel)) return true; else return false; } return false; } else return false; } return true; } } /// /// This class implement the algorithm to detect the obstruction and resolve it. /// public class Resolver { /// /// Revit Document. /// private Document m_rvtDoc; public double UpDownAngle { get; set; } // public double UpDownFreeSpaceHeight { get; set; } // EnumAvoidObstructionType m_AvoidObstructionType; EnumAvoidObstructionCheckPoint m_enumAOChectPoint; /// /// Detector to detect the obstructions. /// private Detector m_detector; PipingSystemType m_pipingSystemType; MechanicalSystemType m_ductSystemType; private List m_lstObstruction = null; private List m_lstAvoidance = null; //private List m_sections = null; public XYZ m_ptMidSectionOn { get; set; } /// /// Constructor, initialize all the fields of this class. /// /// Revit ExternalCommandData from external command entrance public Resolver(Document doc) { m_rvtDoc = doc; m_detector = new Detector(doc); //m_sections = new List(); FilteredElementCollector collector = new FilteredElementCollector(m_rvtDoc); var pipingSystemTypes = collector.OfClass(typeof(PipingSystemType)).ToElements(); foreach (PipingSystemType pipingSystemType in pipingSystemTypes) { if (pipingSystemType.SystemClassification == MEPSystemClassification.SupplyHydronic || pipingSystemType.SystemClassification == MEPSystemClassification.ReturnHydronic) { m_pipingSystemType = pipingSystemType; break; } } FilteredElementCollector collectorDuct = new FilteredElementCollector(m_rvtDoc); var ductSystemTypes = collectorDuct.OfClass(typeof(MechanicalSystemType)).ToElements(); foreach (MechanicalSystemType ductSystemType in ductSystemTypes) { if (ductSystemType.SystemClassification == MEPSystemClassification.SupplyAir || ductSystemType.SystemClassification == MEPSystemClassification.ReturnAir) { m_ductSystemType = ductSystemType; break; } } } public void SetElement(ref List lstObstruction, ref List lstAvoidance) { m_lstObstruction = lstObstruction; m_lstAvoidance = lstAvoidance; } public void GetElement(ref List lstObstruction, ref List lstAvoidance) { lstObstruction = m_lstObstruction; lstAvoidance = m_lstAvoidance; } public void SetAvoidObstructionType(EnumAvoidObstructionType obstructionType) { m_AvoidObstructionType = obstructionType; } /// /// Calculate the uniform perpendicular directions with inputting direction "dir". /// /// Direction to calculate /// How many perpendicular directions will be calculated /// The calculated perpendicular directions with dir private List PerpendicularDirs(Autodesk.Revit.DB.XYZ dir, int count) { List dirs = new List(); Plane plane = Plane.CreateByNormalAndOrigin(dir, Autodesk.Revit.DB.XYZ.Zero); Arc arc = Arc.Create(plane, 1.0, 0, 6.2831); double delta = 1.0 / (double)count; for (int i = 1; i <= count; i++) { Autodesk.Revit.DB.XYZ pt = arc.Evaluate(delta * i, true); dirs.Add(pt); } return dirs; } /// /// ־ ȸǿ 浹Ҹ ȸմϴ. /// /// ȸ () /// 浹 (ֹ) public void Bend(Pipe bendElement, XYZ hitPoint, ref List lstObstruction) { // duct.LookupParameter(string name) var paramLevel = bendElement.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = paramLevel.AsElementId(); //var systemTypeId = m_pipingSystemType.Id; var systemTypeId = bendElement.MEPSystem.GetTypeId(); // Ȯ KDCSIntersectorElement intersectorElement = new KDCSIntersectorElement(bendElement); // ֹ 浹 Ȯ List obstructionRefArr = new List(); foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction) { m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None; // List obstructionReference = m_detector.Obstructions(intersectorElement.LineTop, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointTop; } else { // ߽ obstructionReference = m_detector.Obstructions(intersectorElement.Line, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointCenter; } else { // ϴ obstructionReference = m_detector.Obstructions(intersectorElement.LineBottom, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointBottom; } else { // obstructionReference = m_detector.Obstructions(intersectorElement.LineLeft, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } else { // obstructionReference = m_detector.Obstructions(intersectorElement.LineRight, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } } } } } } if (obstructionRefArr.Count == 0) return; obstructionRefArr.Sort(m_detector.CompareReferencesWithContext); // ۼ List
sections = Section.BuildSections(m_rvtDoc, obstructionRefArr, intersectorElement.Line.Direction); if (sections.Count < 1) return; Section section1 = sections[0]; Line line_ub1 = intersectorElement.Line; XYZ ptOnHit = line_ub1.Project(hitPoint).XYZPoint; XYZ mp_section = Util.Midpoint(section1.Start, section1.End); mp_section = line_ub1.Project(mp_section).XYZPoint; XYZ v1 = (mp_section - ptOnHit).Normalize(); XYZ v2 = intersectorElement.Line.Direction; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up){ if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidUp_; }else if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn){ if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidDn_; } //List
lstSectionTmp = new List
(); //lstSectionTmp.AddRange(sections); bool bAllMerge = false; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUpDn && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDnUp) bAllMerge = true; Plane base_section_plane = null; // ǿ 2 ̻ if (sections.Count > 1) { if (bAllMerge == true) { XYZ s_sp = null; XYZ s_ep = null; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { // s_sp = sections[0].Start; s_ep = sections[0].End; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { // s_sp = sections[sections.Count - 1].Start; s_ep = sections[sections.Count - 1].End; } if (s_sp != null && s_ep != null) { base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(s_sp, s_ep)); } } for (int i = sections.Count - 2; i >= 0; i--) { Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start; SetInterSectorElement(sections[i]); SetInterSectorElement(sections[i+1]); sections[i].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i + 1].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i + 1].Start, sections[i + 1].End)); double dstOffset1 = 0d; double dstOffset2 = 0d; base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i])); FindRoute(bendElement, sections[i], base_section_plane, ref dstOffset1); sections[i + 1].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i + 1])); FindRoute(bendElement, sections[i + 1], base_section_plane, ref dstOffset2); base_section_plane = null; // ǰ ǰ Ÿ ʹ ª Ѵ. double radUpdownAng = Util.DTR(UpDownAngle); // double r1 = Math.Max(dstOffset1, dstOffset2) / Math.Sin(radUpdownAng); double x_offset = r1 * Math.Cos(radUpdownAng); if (detal.GetLength() < (x_offset * 2d + bendElement.Diameter*4.0) || bAllMerge) { if (sections[i].IsMerged == false) { sections[i].IsMerged = true; // յ ǿ ߰ sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i + 1])); sections[i].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); } sections[i].Refs.AddRange(sections[i + 1].Refs); sections.RemoveAt(i + 1); } } } else { if (sections.Count > 0) { base_section_plane = null; sections[0].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[0])); sections[0].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[0].Start, sections[0].End)); SetInterSectorElement(sections[0]); //sections[0].InterSectorElement = new KDCSIntersectorElement(m_rvtDoc.GetElement(sections[0].Refs[0].GetReference().ElementId)); } else return; } // 浹 Ǻ ۾ foreach (Section cur_section in sections) { Resolve(bendElement, cur_section); } // 带 ش. for (int i = 1; i < sections.Count; i++) { // Get the end point from the previous section. Autodesk.Revit.DB.XYZ start = sections[i - 1].End1; // Get the start point from the current section. Autodesk.Revit.DB.XYZ end = sections[i].Start1; // Create a duct between two neighbor section. Pipe tmpPipe = Pipe.Create(m_rvtDoc, systemTypeId, bendElement.PipeType.Id, levelId, start, end); // Copy pipe's parameters values to tmpPipe. CopyParameters(bendElement, tmpPipe); // Create elbow fitting to connect previous section with tmpPipe. Connector conn1 = FindConnector(sections[i - 1].Pipes[2], start); Connector conn2 = FindConnector(tmpPipe, start); if (conn1 != null && conn2 != null) { FamilyInstance fi = null; try { fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); } catch (Exception ex) { string strmsg = ex.Message; } } // Create elbow fitting to connect current section with tmpPipe. Connector conn3 = FindConnector(sections[i].Pipes[0], end); Connector conn4 = FindConnector(tmpPipe, end); if (conn3 != null && conn4 != null) { FamilyInstance f2 = null; try { f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } catch (Exception ex) { string strmsg = ex.Message; } } } // ʰ // Find two connectors which pipe's two ends connector connected to. Connector startConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(0)); Connector endConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(1)); // ó //------------------------------------------------------------------------------------------------ Pipe startPipe = null; if (null != startConn) { // Create a pipe between pipe's start connector and pipe's start section. startPipe = Pipe.Create(m_rvtDoc, bendElement.PipeType.Id, levelId, startConn, sections[0].Start1); } else { // Create a pipe between pipe's start point and pipe's start section. startPipe = Pipe.Create(m_rvtDoc, systemTypeId, bendElement.PipeType.Id, levelId, sections[0].Start1, intersectorElement.Line.GetEndPoint(0)); } // Copy parameters from pipe to startPipe. CopyParameters(bendElement, startPipe); // ߰ Connector connStart1 = FindConnector(startPipe, sections[0].Start1); Connector connStart2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDn_ && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUp_) { connStart2 = FindConnector(sections[0].Pipes[0], sections[0].Start1); } int count = sections.Count; FamilyInstance fii = null; if (connStart1 != null && connStart2 != null) { try { fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2); } catch (Exception ex) { string strmsg = ex.Message; } } else if (connStart2 == null && startPipe != null) { // startPipe?pipes[1]??이?맞추? ?결?다. var line1 = (sections[count - 1].Pipes[1].Location as LocationCurve).Curve as Line; var line2 = (startPipe.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(0) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(0) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, startPipe.Id, translation); List lstElement2BeDeleted = new List(); connStart1 = FindConnector(sections[count - 1].Pipes[1], line1.GetEndPoint(0)); connStart2 = FindConnector(startPipe, line1.GetEndPoint(0)); if (connStart1 != null && connStart2 != null) { JoinPipeSegment(connStart1, ref connStart2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } // ?이???쪽 처리 //------------------------------------------------------------------------------------------------ Pipe endPipe = null; if (null != endConn) { // Create a pipe between pipe's end connector and pipe's end section. endPipe = Pipe.Create(m_rvtDoc, bendElement.PipeType.Id, levelId, endConn, sections[count - 1].End1); } else { // Create a pipe between pipe's end point and pipe's end section. endPipe = Pipe.Create(m_rvtDoc, systemTypeId, bendElement.PipeType.Id, levelId, sections[count - 1].End1, intersectorElement.Line.GetEndPoint(1)); } // Copy parameters from pipe to endPipe. CopyParameters(bendElement, endPipe); // ?쪽 ?보 추? Connector connEnd1 = FindConnector(endPipe, sections[count - 1].End1); Connector connEnd2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Dn && m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Up) { connEnd2 = FindConnector(sections[count - 1].Pipes[2], sections[count - 1].End1); } FamilyInstance fiii = null; if (connEnd1 != null && connEnd2 != null) { try { fiii = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2); } catch (Exception ex) { string strmsg = ex.Message; } } else if (connEnd2 == null && endPipe != null) { // endDuct?ducts[1]??이?맞추? ?결?다. var line1 = (sections[count - 1].Pipes[1].Location as LocationCurve).Curve as Line; var line2 = (endPipe.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(1) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(1) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, endPipe.Id, translation); List lstElement2BeDeleted = new List(); connEnd1 = FindConnector(sections[count - 1].Pipes[1], line1.GetEndPoint(1)); connEnd2 = FindConnector(endPipe, line1.GetEndPoint(1)); if (connEnd1 != null && connEnd2 != null) { JoinPipeSegment(connEnd1, ref connEnd2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } m_rvtDoc.Delete(bendElement.Id); } /// /// Use Autodesk.Revit.DB.ElementId to get the corresponding element /// /// the element id value /// the corresponding element Autodesk.Revit.DB.Element GetElementById(int id) { // Create a Autodesk.Revit.DB.ElementId data Autodesk.Revit.DB.ElementId elementId = new Autodesk.Revit.DB.ElementId(id); // Get the corresponding element return m_rvtDoc.GetElement(elementId); } SketchPlane GetSketchPlaneById(int id) { // First get the sketch plane by the giving element id. SketchPlane workPlane = GetElementById(id) as SketchPlane; if (null == workPlane) { throw new Exception("Don't have the work plane you select."); } return workPlane; } /// /// 2 Ʈ Ͽ ϳ Ʈ ׸Ʈ ش. /// /// Ʈ Ŀ /// Ʈ Ŀ /// Ʈ private void JoinDuctSegment(Connector cThis, ref Connector cOther, ref List lstElement2BeDeleted) { Duct dct1 = cThis.Owner as Duct; Duct dct2 = cOther.Owner as Duct; XYZ p1, p2, p3, p4; bool bOk = false; // Ʈ  쿡 Ʈ ׸Ʈ ϳ . if (cThis.Shape == cOther.Shape) { if (cThis.Shape == ConnectorProfileType.Round) { if (dct1.Diameter == dct2.Diameter) bOk = true; } else if (cThis.Shape == ConnectorProfileType.Rectangular || cThis.Shape == ConnectorProfileType.Oval) { if (dct1.Width == dct2.Width && dct1.Height == dct2.Height) bOk = true; } } if (bOk == true) { LocationCurve lineLoc1 = dct1.Location as LocationCurve; Line c1 = lineLoc1.Curve as Line; p1 = c1.GetEndPoint(0); p2 = c1.GetEndPoint(1); Line c2 = (dct2.Location as LocationCurve).Curve as Line; p3 = c2.GetEndPoint(0); p4 = c2.GetEndPoint(1); XYZ mp1 = Util.Midpoint(p1, p2); XYZ mp2 = Util.Midpoint(p3, p4); Line check_line = Line.CreateBound(mp1, mp2); bool bFlowDir = check_line.Direction.IsAlmostEqualTo(c1.Direction); XYZ dct1_sp = new XYZ(); XYZ dct1_ep = new XYZ(); if (bFlowDir) { dct1_sp = Util.makeXYZ(check_line.Distance(p2) < 1e-9 ? p1 : p2); dct1_ep = Util.makeXYZ(check_line.Distance(p3) < 1e-9 ? p4 : p3); } else { dct1_sp = Util.makeXYZ(check_line.Distance(p4) < 1e-9 ? p3 : p4); dct1_ep = Util.makeXYZ(check_line.Distance(p1) < 1e-9 ? p2 : p1); } if (bFlowDir) // dct1->dct2 { Connector con_dct2ep = FindConnectedTo(dct2, dct1_ep); lineLoc1.Curve = Line.CreateBound(dct1_sp, dct1_ep); Connector con_dct1ep = FindConnector(dct1, dct1_ep); if (con_dct2ep != null && con_dct1ep != null) { if (con_dct2ep.IsConnected) { con_dct1ep.ConnectTo(con_dct2ep); } } } else // dct2->dct1 { Connector con_dct2sp = FindConnectedTo(dct2, dct1_sp); lineLoc1.Curve = Line.CreateBound(dct1_sp, dct1_ep); Connector con_dct1sp = FindConnector(dct1, dct1_sp); if (con_dct2sp != null && con_dct1sp != null) { if (con_dct2sp.IsConnected) { con_dct1sp.ConnectTo(con_dct2sp); } } } //PlumbingUtils.BreakCurve( //MechanicalUtils.BreakCurve( Util.ShortenCurve(dct2); lstElement2BeDeleted.Add(cOther.Owner); cOther = null; } else if (dct1 != null && dct2 == null) { LocationCurve lineLoc1 = dct1.Location as LocationCurve; Line c1 = lineLoc1.Curve as Line; p1 = c1.GetEndPoint(0); p2 = c1.GetEndPoint(1); if (cOther.Origin.DistanceTo(p1) < cOther.Origin.DistanceTo(p2)) lineLoc1.Curve = Line.CreateBound(cOther.Origin, p2); else lineLoc1.Curve = Line.CreateBound(p1, cOther.Origin); } } public void JoinPipeSegment(Connector cThis, ref Connector cOther, ref List lstElement2BeDeleted) { Pipe pip1 = cThis.Owner as Pipe; Pipe pip2 = cOther.Owner as Pipe; XYZ p1, p2, p3, p4; if (cThis.Radius == cOther.Radius) { LocationCurve lineLoc1 = pip1.Location as LocationCurve; Line c1 = lineLoc1.Curve as Line; p1 = c1.GetEndPoint(0); p2 = c1.GetEndPoint(1); Line c2 = (pip2.Location as LocationCurve).Curve as Line; p3 = c2.GetEndPoint(0); p4 = c2.GetEndPoint(1); XYZ mp1 = Util.Midpoint(p1, p2); XYZ mp2 = Util.Midpoint(p3, p4); Line check_line = Line.CreateBound(mp1, mp2); bool bFlowDir = check_line.Direction.IsAlmostEqualTo(c1.Direction); XYZ pip1_sp = new XYZ(); XYZ pip1_ep = new XYZ(); if (bFlowDir) { pip1_sp = Util.makeXYZ(check_line.Distance(p2) < 1e-9 ? p1 : p2); pip1_ep = Util.makeXYZ(check_line.Distance(p3) < 1e-9 ? p4 : p3); } else { pip1_sp = Util.makeXYZ(check_line.Distance(p4) < 1e-9 ? p3 : p4); pip1_ep = Util.makeXYZ(check_line.Distance(p1) < 1e-9 ? p2 : p1); } if (bFlowDir) // pip1->pip2 { Connector con_dct2ep = FindConnectedTo(pip2, pip1_ep); lineLoc1.Curve = Line.CreateBound(pip1_sp, pip1_ep); Connector con_dct1ep = FindConnector(pip1, pip1_ep); if (con_dct2ep != null && con_dct1ep != null) { if (con_dct2ep.IsConnected) { con_dct1ep.ConnectTo(con_dct2ep); } } } else // pip2->dct1 { Connector con_dct2sp = FindConnectedTo(pip2, pip1_sp); lineLoc1.Curve = Line.CreateBound(pip1_sp, pip1_ep); Connector con_dct1sp = FindConnector(pip1, pip1_sp); if (con_dct2sp != null && con_dct1sp != null) { if (con_dct2sp.IsConnected) { con_dct1sp.ConnectTo(con_dct2sp); } } } //PlumbingUtils.BreakCurve( //MechanicalUtils.BreakCurve( Util.ShortenCurve(pip2); lstElement2BeDeleted.Add(cOther.Owner); cOther = null; } } /// /// 2 ̺Ʈ̸ Ͽ ϳ Ʈ ׸Ʈ ش. /// /// Ʈ Ŀ /// Ʈ Ŀ /// Ʈ private void JoinCableTraySegment(Connector cThis, ref Connector cOther, ref List lstElement2BeDeleted) { CableTray dct1 = cThis.Owner as CableTray; CableTray dct2 = cOther.Owner as CableTray; XYZ p1, p2, p3, p4; bool bOk = false; // Ʈ  쿡 Ʈ ׸Ʈ ϳ . if (cThis.Shape == cOther.Shape) { if (cThis.Shape == ConnectorProfileType.Round) { if (dct1.Diameter == dct2.Diameter) bOk = true; } else if (cThis.Shape == ConnectorProfileType.Rectangular || cThis.Shape == ConnectorProfileType.Oval) { if (dct1.Width == dct2.Width && dct1.Height == dct2.Height) bOk = true; } } if (bOk == true) { LocationCurve lineLoc1 = dct1.Location as LocationCurve; Line c1 = lineLoc1.Curve as Line; p1 = c1.GetEndPoint(0); p2 = c1.GetEndPoint(1); Line c2 = (dct2.Location as LocationCurve).Curve as Line; p3 = c2.GetEndPoint(0); p4 = c2.GetEndPoint(1); XYZ mp1 = Util.Midpoint(p1, p2); XYZ mp2 = Util.Midpoint(p3, p4); Line check_line = Line.CreateBound(mp1, mp2); bool bFlowDir = check_line.Direction.IsAlmostEqualTo(c1.Direction); XYZ dct1_sp = new XYZ(); XYZ dct1_ep = new XYZ(); if (bFlowDir) { dct1_sp = Util.makeXYZ(check_line.Distance(p2) < 1e-9 ? p1 : p2); dct1_ep = Util.makeXYZ(check_line.Distance(p3) < 1e-9 ? p4 : p3); } else { dct1_sp = Util.makeXYZ(check_line.Distance(p4) < 1e-9 ? p3 : p4); dct1_ep = Util.makeXYZ(check_line.Distance(p1) < 1e-9 ? p2 : p1); } if (bFlowDir) // dct1->dct2 { Connector con_dct2ep = FindConnectedTo(dct2, dct1_ep); lineLoc1.Curve = Line.CreateBound(dct1_sp, dct1_ep); Connector con_dct1ep = FindConnector(dct1, dct1_ep); if (con_dct2ep != null && con_dct1ep != null) { if (con_dct2ep.IsConnected) { con_dct1ep.ConnectTo(con_dct2ep); } } } else // dct2->dct1 { Connector con_dct2sp = FindConnectedTo(dct2, dct1_sp); lineLoc1.Curve = Line.CreateBound(dct1_sp, dct1_ep); Connector con_dct1sp = FindConnector(dct1, dct1_sp); if (con_dct2sp != null && con_dct1sp != null) { if (con_dct2sp.IsConnected) { con_dct1sp.ConnectTo(con_dct2sp); } } } //PlumbingUtils.BreakCurve( //MechanicalUtils.BreakCurve( Util.ShortenCurve(dct2); lstElement2BeDeleted.Add(cOther.Owner); cOther = null; } else if (dct1 != null && dct2 == null) { LocationCurve lineLoc1 = dct1.Location as LocationCurve; Line c1 = lineLoc1.Curve as Line; p1 = c1.GetEndPoint(0); p2 = c1.GetEndPoint(1); if (cOther.Origin.DistanceTo(p1) < cOther.Origin.DistanceTo(p2)) lineLoc1.Curve = Line.CreateBound(cOther.Origin, p2); else lineLoc1.Curve = Line.CreateBound(p1, cOther.Origin); } } private void JoinConduitSegment(Connector cThis, ref Connector cOther, ref List lstElement2BeDeleted) { Conduit conduit1 = cThis.Owner as Conduit; Conduit conduit2 = cOther.Owner as Conduit; XYZ p1, p2, p3, p4; if (cThis.Radius == cOther.Radius) { LocationCurve lineLoc1 = conduit1.Location as LocationCurve; Line c1 = lineLoc1.Curve as Line; p1 = c1.GetEndPoint(0); p2 = c1.GetEndPoint(1); Line c2 = (conduit2.Location as LocationCurve).Curve as Line; p3 = c2.GetEndPoint(0); p4 = c2.GetEndPoint(1); XYZ mp1 = Util.Midpoint(p1, p2); XYZ mp2 = Util.Midpoint(p3, p4); Line check_line = Line.CreateBound(mp1, mp2); bool bFlowDir = check_line.Direction.IsAlmostEqualTo(c1.Direction); XYZ conduit1_sp = new XYZ(); XYZ conduit1_ep = new XYZ(); if (bFlowDir) { conduit1_sp = Util.makeXYZ(check_line.Distance(p2) < 1e-9 ? p1 : p2); conduit1_ep = Util.makeXYZ(check_line.Distance(p3) < 1e-9 ? p4 : p3); } else { conduit1_sp = Util.makeXYZ(check_line.Distance(p4) < 1e-9 ? p3 : p4); conduit1_ep = Util.makeXYZ(check_line.Distance(p1) < 1e-9 ? p2 : p1); } if (bFlowDir) // conduit1->conduit2 { Connector con_dct2ep = FindConnectedTo(conduit2, conduit1_ep); lineLoc1.Curve = Line.CreateBound(conduit1_sp, conduit1_ep); Connector con_dct1ep = FindConnector(conduit1, conduit1_ep); if (con_dct2ep != null && con_dct1ep != null) { if (con_dct2ep.IsConnected) { con_dct1ep.ConnectTo(con_dct2ep); } } } else // conduit2->dct1 { Connector con_dct2sp = FindConnectedTo(conduit2, conduit1_sp); lineLoc1.Curve = Line.CreateBound(conduit1_sp, conduit1_ep); Connector con_dct1sp = FindConnector(conduit1, conduit1_sp); if (con_dct2sp != null && con_dct1sp != null) { if (con_dct2sp.IsConnected) { con_dct1sp.ConnectTo(con_dct2sp); } } } //PlumbingUtils.BreakCurve( //MechanicalUtils.BreakCurve( Util.ShortenCurve(conduit2); lstElement2BeDeleted.Add(cOther.Owner); cOther = null; } } private void SetInterSectorElement(Section section) { var linkedElementId = section.Refs[0].GetReference().LinkedElementId; var elementId = section.Refs[0].GetReference().ElementId; Element elm = null; if (linkedElementId.IntegerValue != -1) { Element elLink = m_rvtDoc.GetElement(elementId); var revitLinkedInstance = elLink as RevitLinkInstance; Document doc = revitLinkedInstance.GetLinkDocument(); elm = doc.GetElement(linkedElementId); section.InterSectorElement = new KDCSIntersectorElement(elm, null, doc); section.InterSectorElement.SetRevitLinkInstance(revitLinkedInstance); } else { elm = m_rvtDoc.GetElement(elementId); section.InterSectorElement = new KDCSIntersectorElement(elm); } } private Element GetElement(Section section) { var linkedElementId = section.Refs[0].GetReference().LinkedElementId; var elementId = section.Refs[0].GetReference().ElementId; Element elm = null; if (linkedElementId.IntegerValue != -1) { var revitLinkedInstance = m_rvtDoc.GetElement(elementId) as RevitLinkInstance; Document doc = revitLinkedInstance.GetLinkDocument(); elm = doc.GetElement(linkedElementId); } else { elm = m_rvtDoc.GetElement(elementId); } return elm; } /// /// ־ ȸǿ Ʈ 浹Ҹ ȸմϴ. /// /// ȸ () /// 浹 (ֹ) public void Bend(Duct bendElement, XYZ hitPoint, ref List lstObstruction) { // duct.LookupParameter(string name) var paramLevel = bendElement.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = paramLevel.AsElementId(); //var systemTypeId = m_ductSystemType.Id; var systemTypeId = bendElement.MEPSystem.GetTypeId(); // Ȯ KDCSIntersectorElement intersectorElement = new KDCSIntersectorElement(bendElement); // ֹ 浹 Ȯ List obstructionRefArr = new List(); foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction) { m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None; // List obstructionReference = m_detector.Obstructions(intersectorElement.LineTop, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointTop; } else { // ߽ obstructionReference = m_detector.Obstructions(intersectorElement.Line, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointCenter; } else { // ϴ obstructionReference = m_detector.Obstructions(intersectorElement.LineBottom, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointBottom; } else { // obstructionReference = m_detector.Obstructions(intersectorElement.LineLeft, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } else { // obstructionReference = m_detector.Obstructions(intersectorElement.LineRight, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } } } } } } if (obstructionRefArr.Count == 0) return; obstructionRefArr.Sort(m_detector.CompareReferencesWithContext); // ۼ List
sections = Section.BuildSections(m_rvtDoc, obstructionRefArr, intersectorElement.Line.Direction); if (sections.Count < 1) return; Section section1 = sections[0]; Line line_ub1 = intersectorElement.Line; XYZ ptOnHit = line_ub1.Project(hitPoint).XYZPoint; XYZ mp_section = Util.Midpoint(section1.Start, section1.End); mp_section = line_ub1.Project(mp_section).XYZPoint; XYZ v1 = (mp_section - ptOnHit).Normalize(); XYZ v2 = intersectorElement.Line.Direction; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up) { if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidUp_; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidDn_; } //List
lstSectionTmp = new List
(); //lstSectionTmp.AddRange(sections); bool bAllMerge = false; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUpDn && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDnUp) bAllMerge = true; Plane base_section_plane = null; // ǿ 2 ̻ if (sections.Count > 1) { if (bAllMerge == true) { XYZ s_sp = null; XYZ s_ep = null; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { // s_sp = sections[0].Start; s_ep = sections[0].End; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { // s_sp = sections[sections.Count - 1].Start; s_ep = sections[sections.Count - 1].End; } if (s_sp != null && s_ep != null) { base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(s_sp, s_ep)); } } // Merge the neighbor sections if the distance of them is too close. for (int i = sections.Count - 2; i >= 0; i--) { Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start; SetInterSectorElement(sections[i]); SetInterSectorElement(sections[i+1]); sections[i].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i + 1].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i + 1].Start, sections[i + 1].End)); double dstOffset1 = 0d; double dstOffset2 = 0d; base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i])); FindRoute(bendElement, sections[i], base_section_plane, ref dstOffset1); sections[i + 1].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i+1])); FindRoute(bendElement, sections[i + 1], base_section_plane, ref dstOffset2); base_section_plane = null; if (detal.GetLength() < (Math.Max(dstOffset1, dstOffset2) * 2d + bendElement.Height * 3d) || bAllMerge) { if (sections[i].IsMerged == false) { sections[i].IsMerged = true; // յ ǿ ߰ sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i+1])); sections[i].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); } sections[i].Refs.AddRange(sections[i + 1].Refs); sections.RemoveAt(i + 1); } } } else { if (sections.Count > 0) { base_section_plane = null; sections[0].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[0])); sections[0].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[0].Start, sections[0].End)); SetInterSectorElement(sections[0]); } else return; } // 浹 Ǻ ۾ foreach (Section cur_section in sections) { Resolve(bendElement, cur_section); } // 带 ش. for (int i = 1; i < sections.Count; i++) { // Get the end point from the previous section. Autodesk.Revit.DB.XYZ start = sections[i - 1].End1; // Get the start point from the current section. Autodesk.Revit.DB.XYZ end = sections[i].Start1; // Create a duct between two neighbor section. Duct tmpDuct = Duct.Create(m_rvtDoc, systemTypeId, bendElement.DuctType.Id, levelId, start, end); // Copy pipe's parameters values to tmpPipe. CopyParameters(bendElement, tmpDuct); // Create elbow fitting to connect previous section with tmpPipe. Connector conn1 = FindConnector(sections[i - 1].Ducts[2], start); Connector conn2 = FindConnector(tmpDuct, start); if (conn1 != null && conn2 != null) { FamilyInstance fi = null; try { fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); } catch (Exception ex) { string strmsg = ex.Message; } } // Create elbow fitting to connect current section with tmpPipe. Connector conn3 = FindConnector(sections[i].Ducts[0], end); Connector conn4 = FindConnector(tmpDuct, end); if (conn3 != null && conn4 != null) { FamilyInstance f2 = null; try { f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } catch (Exception ex) { string strmsg = ex.Message; } } } // Ʈ ʰ // Find two connectors which pipe's two ends connector connected to. Connector startConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(0)); Connector endConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(1)); // Ʈ ó //------------------------------------------------------------------------------------------------ Duct startDuct = null; if (null != startConn) { // Create a pipe between pipe's start connector and pipe's start section. startDuct = Duct.Create(m_rvtDoc, bendElement.DuctType.Id, levelId, startConn, sections[0].Start1); } else { // Create a pipe between pipe's start point and pipe's start section. startDuct = Duct.Create(m_rvtDoc, systemTypeId, bendElement.DuctType.Id, levelId, sections[0].Start1, intersectorElement.Line.GetEndPoint(0)); } // Copy parameters from pipe to startPipe. CopyParameters(bendElement, startDuct); // ߰ Connector connStart1 = FindConnector(startDuct, sections[0].Start1); Connector connStart2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDn_ && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUp_) { connStart2 = FindConnector(sections[0].Ducts[0], sections[0].Start1); } int count = sections.Count; FamilyInstance fii = null; if (connStart1 != null && connStart2 != null) { try { fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2); } catch (Exception ex) { string strmsg = ex.Message; } } else if (connStart2 == null && startDuct != null) { // startDuct ducts[1] ̸ ߰, Ѵ. var line1 = (sections[count - 1].Ducts[1].Location as LocationCurve).Curve as Line; var line2 = (startDuct.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(0) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(0) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, startDuct.Id, translation); List lstElement2BeDeleted = new List(); connStart1 = FindConnector(sections[count - 1].Ducts[1], line1.GetEndPoint(0)); connStart2 = FindConnector(startDuct, line1.GetEndPoint(0)); if (connStart1 != null && connStart2 != null) { JoinDuctSegment(connStart1, ref connStart2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } // Ʈ ó //------------------------------------------------------------------------------------------------ Duct endDuct = null; if (null != endConn) { // Create a pipe between pipe's end connector and pipe's end section. endDuct = Duct.Create(m_rvtDoc, bendElement.DuctType.Id, levelId, endConn, sections[count - 1].End1); } else { // Create a pipe between pipe's end point and pipe's end section. endDuct = Duct.Create(m_rvtDoc, systemTypeId, bendElement.DuctType.Id, levelId, sections[count - 1].End1, intersectorElement.Line.GetEndPoint(1)); } // Copy parameters from pipe to endPipe. CopyParameters(bendElement, endDuct); // ߰ Connector connEnd1 = FindConnector(endDuct, sections[count - 1].End1); Connector connEnd2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Dn && m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Up) { connEnd2 = FindConnector(sections[count - 1].Ducts[2], sections[count - 1].End1); } FamilyInstance fiii = null; if (connEnd1 != null && connEnd2 != null) { try { fiii = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2); } catch (Exception ex) { string strmsg = ex.Message; } } else if (connEnd2 == null && endDuct != null) { // endDuct ducts[1] ̸ ߰, Ѵ. var line1 = (sections[count - 1].Ducts[1].Location as LocationCurve).Curve as Line; var line2 = (endDuct.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(1) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(1) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, endDuct.Id, translation); List lstElement2BeDeleted = new List(); connEnd1 = FindConnector(sections[count - 1].Ducts[1], line1.GetEndPoint(1)); connEnd2 = FindConnector(endDuct, line1.GetEndPoint(1)); if (connEnd1 != null && connEnd2 != null) { JoinDuctSegment(connEnd1, ref connEnd2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } m_rvtDoc.Delete(bendElement.Id); } /// /// ־ ȸǿ ̺Ʈ̰ 浹Ҹ ȸմϴ. /// /// ȸ () /// 浹(ֹ) public void Bend(CableTray bendElement, XYZ hitPoint, ref List lstObstruction) { // duct.LookupParameter(string name) var paramLevel = bendElement.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = paramLevel.AsElementId(); // ֹ 浹 Ȯ KDCSIntersectorElement intersectorElement = new KDCSIntersectorElement(bendElement); // ?애?충돌 ?인 List obstructionRefArr = new List(); foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction) { m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None; // List obstructionReference = m_detector.Obstructions(intersectorElement.LineTop, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointTop; } else { // ߽ obstructionReference = m_detector.Obstructions(intersectorElement.Line, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointCenter; } else { // ϴ obstructionReference = m_detector.Obstructions(intersectorElement.LineBottom, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointBottom; } else { // obstructionReference = m_detector.Obstructions(intersectorElement.LineLeft, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } else { // obstructionReference = m_detector.Obstructions(intersectorElement.LineRight, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } } } } } } if (obstructionRefArr.Count == 0) return; obstructionRefArr.Sort(m_detector.CompareReferencesWithContext); // ۼ List
sections = Section.BuildSections(m_rvtDoc, obstructionRefArr, intersectorElement.Line.Direction); if (sections.Count < 1) return; Section section1 = sections[0]; Line line_ub1 = intersectorElement.Line; XYZ ptOnHit = line_ub1.Project(hitPoint).XYZPoint; XYZ mp_section = Util.Midpoint(section1.Start, section1.End); mp_section = line_ub1.Project(mp_section).XYZPoint; XYZ v1 = (mp_section - ptOnHit).Normalize(); XYZ v2 = intersectorElement.Line.Direction; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up) { if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidUp_; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidDn_; } bool bAllMerge = false; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUpDn && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDnUp) bAllMerge = true; Plane base_section_plane = null; // ǿ 2 ̻ if (sections.Count > 1) { if (bAllMerge == true) { XYZ s_sp = null; XYZ s_ep = null; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { // s_sp = sections[0].Start; s_ep = sections[0].End; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { // s_sp = sections[sections.Count - 1].Start; s_ep = sections[sections.Count - 1].End; } if (s_sp != null && s_ep != null) { base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(s_sp, s_ep)); } } // Merge the neighbor sections if the distance of them is too close. for (int i = sections.Count - 2; i >= 0; i--) { Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start; SetInterSectorElement(sections[i]); SetInterSectorElement(sections[i + 1]); sections[i].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i + 1].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i + 1].Start, sections[i + 1].End)); double dstOffset1 = 0d; double dstOffset2 = 0d; base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i])); FindRoute(bendElement, sections[i], base_section_plane, ref dstOffset1); sections[i + 1].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i + 1])); FindRoute(bendElement, sections[i + 1], base_section_plane, ref dstOffset2); base_section_plane = null; // ǰ Ÿ(1500mm(4.92125984ft)) ʹ ª if (detal.GetLength() < 4.92125984 || bAllMerge) { if (sections[i].IsMerged == false) { sections[i].IsMerged = true; // յ ǿ ߰ sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i + 1])); sections[i].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); } sections[i].Refs.AddRange(sections[i + 1].Refs); sections.RemoveAt(i + 1); } } } else { if (sections.Count > 0) { base_section_plane = null; sections[0].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[0])); sections[0].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[0].Start, sections[0].End)); SetInterSectorElement(sections[0]); // sections[0].InterSectorElement = new KDCSIntersectorElement(m_rvtDoc.GetElement(sections[0].Refs[0].GetReference().ElementId)); } else return; } // 浹 Ǻ ۾ foreach (Section cur_section in sections) { Resolve(bendElement, cur_section); } double bendRadius = 0.32808399; // 100mm // 带 ش. ElementId idCableTrayType = bendElement.GetTypeId(); // Util.FindCableTrayTypeId(m_rvtDoc, "Default"); for (int i = 1; i < sections.Count; i++) { // Get the end point from the previous section. Autodesk.Revit.DB.XYZ start = sections[i - 1].End1; // Get the start point from the current section. Autodesk.Revit.DB.XYZ end = sections[i].Start1; // Create a cabletray between two neighbor section. CableTray tmpCableTray = CableTray.Create(m_rvtDoc, idCableTrayType, start, end, levelId); // Copy pipe's parameters values to tmpPipe. CopyParameters(bendElement, tmpCableTray); // Create elbow fitting to connect previous section with tmpPipe. Connector conn1 = FindConnector(sections[i - 1].CableTrays[2], start); Connector conn2 = FindConnector(tmpCableTray, start); if (conn1 != null && conn2 != null) { try { var fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); //"failed to insert elbow": if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } } catch (Exception ex) { string strmsg = ex.Message; } } // Create elbow fitting to connect current section with tmpPipe. Connector conn3 = FindConnector(sections[i].CableTrays[0], end); Connector conn4 = FindConnector(tmpCableTray, end); if (conn3 != null && conn4 != null) { try { var fi = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); //"failed to insert elbow": if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } } catch (Exception ex) { string strmsg = ex.Message; } } } // Ʈ ʰ // Find two connectors which pipe's two ends connector connected to. Connector startConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(0)); Connector endConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(1)); // ̺Ʈ ó //------------------------------------------------------------------------------------------------ CableTray startCableTray = null; if (null != startConn) { // Create a pipe between pipe's start connector and pipe's start section. startCableTray = CableTray.Create(m_rvtDoc, idCableTrayType, startConn.Origin, sections[0].Start1, levelId); } else { // Create a pipe between pipe's start point and pipe's start section. startCableTray = CableTray.Create(m_rvtDoc, idCableTrayType, sections[0].Start1, intersectorElement.Line.GetEndPoint(0), levelId); } // Copy parameters from pipe to startPipe. CopyParameters(bendElement, startCableTray); // ߰ Connector connStart1 = FindConnector(startCableTray, sections[0].Start1); Connector connStart2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDn_ && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUp_) { connStart2 = FindConnector(sections[0].CableTrays[0], sections[0].Start1); } int count = sections.Count; if (connStart1 != null && connStart2 != null) { try { var fi = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2); if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } } catch (Exception ex) { string strmsg = ex.Message; } } else if (connStart2 == null && startCableTray != null) { // startCableTray CableTrays[1] ̸ ߰, Ѵ. var line1 = (sections[count - 1].CableTrays[1].Location as LocationCurve).Curve as Line; var line2 = (startCableTray.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(0) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(0) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, startCableTray.Id, translation); List lstElement2BeDeleted = new List(); connStart1 = FindConnector(sections[count - 1].CableTrays[1], line1.GetEndPoint(0)); connStart2 = FindConnector(startCableTray, line1.GetEndPoint(0)); if (connStart1 != null && connStart2 != null) { JoinCableTraySegment(connStart1, ref connStart2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } // Ʈ ó //------------------------------------------------------------------------------------------------ CableTray endCableTray = null; if (null != endConn) { // Create a pipe between pipe's end connector and pipe's end section. endCableTray = CableTray.Create(m_rvtDoc, idCableTrayType, endConn.Origin, sections[count - 1].End1, levelId); } else { // Create a pipe between pipe's end point and pipe's end section. endCableTray = CableTray.Create(m_rvtDoc, idCableTrayType, sections[count - 1].End1, intersectorElement.Line.GetEndPoint(1), levelId); } // Copy parameters from pipe to endPipe. CopyParameters(bendElement, endCableTray); // ߰ Connector connEnd1 = FindConnector(endCableTray, sections[count - 1].End1); Connector connEnd2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Dn && m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Up) { connEnd2 = FindConnector(sections[count - 1].CableTrays[2], sections[count - 1].End1); } if (connEnd1 != null && connEnd2 != null) { try { var fi = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2); if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } } catch (Exception ex) { string strmsg = ex.Message; } } else if (connEnd2 == null && endCableTray != null) { // endCableTray CableTrays[1] ̸ ߰, Ѵ. var line1 = (sections[count - 1].CableTrays[1].Location as LocationCurve).Curve as Line; var line2 = (endCableTray.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(1) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(1) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, endCableTray.Id, translation); List lstElement2BeDeleted = new List(); connEnd1 = FindConnector(sections[count - 1].CableTrays[1], line1.GetEndPoint(1)); connEnd2 = FindConnector(endCableTray, line1.GetEndPoint(1)); if (connEnd1 != null && connEnd2 != null) { JoinCableTraySegment(connEnd1, ref connEnd2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } m_rvtDoc.Delete(bendElement.Id); } /// /// 주어??피?소 ?선관 충돌?소??피?니?? /// /// /// public void Bend(Conduit bendElement, XYZ hitPoint, ref List lstObstruction) { // duct.LookupParameter(string name) var paramLevel = bendElement.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = paramLevel.AsElementId(); var conduitTypeId = bendElement.GetTypeId(); // 교차 ?인 ?소 KDCSIntersectorElement intersectorElement = new KDCSIntersectorElement(bendElement); // ?애?충돌 ?인 List obstructionRefArr = new List(); foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction) { m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None; // ?단 List obstructionReference = m_detector.Obstructions(intersectorElement.LineTop, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointTop; } else { // 중심 obstructionReference = m_detector.Obstructions(intersectorElement.Line, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointCenter; } else { // ?단 obstructionReference = m_detector.Obstructions(intersectorElement.LineBottom, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointBottom; } else { // ?쪽 obstructionReference = m_detector.Obstructions(intersectorElement.LineLeft, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } else { // ?른? obstructionReference = m_detector.Obstructions(intersectorElement.LineRight, intersectorObstrion); if (obstructionReference.Count > 0) { foreach (var rwc in obstructionReference) { if (obstructionRefArr.Contains(rwc) == false) obstructionRefArr.Add(rwc); } m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.AO_ChectPointLeft; } } } } } } if (obstructionRefArr.Count == 0) return; obstructionRefArr.Sort(m_detector.CompareReferencesWithContext); // ?션 ?성 List
sections = Section.BuildSections(m_rvtDoc, obstructionRefArr, intersectorElement.Line.Direction); if (sections.Count < 1) return; Section section1 = sections[0]; Line line_ub1 = intersectorElement.Line; XYZ ptOnHit = line_ub1.Project(hitPoint).XYZPoint; XYZ mp_section = Util.Midpoint(section1.Start, section1.End); mp_section = line_ub1.Project(mp_section).XYZPoint; XYZ v1 = (mp_section - ptOnHit).Normalize(); XYZ v2 = intersectorElement.Line.Direction; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up) { if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidUp_; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { if (v1.IsAlmostEqualTo(v2) == false) m_AvoidObstructionType = EnumAvoidObstructionType.AvoidDn_; } //List
lstSectionTmp = new List
(); //lstSectionTmp.AddRange(sections); bool bAllMerge = false; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUpDn && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDnUp) bAllMerge = true; Plane base_section_plane = null; // ?션??참조가 2??상??경우 if (sections.Count > 1) { if (bAllMerge == true) { XYZ s_sp = null; XYZ s_ep = null; if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { // ?작 ?션 s_sp = sections[0].Start; s_ep = sections[0].End; } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { // ???션 s_sp = sections[sections.Count - 1].Start; s_ep = sections[sections.Count - 1].End; } if (s_sp != null && s_ep != null) { base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(s_sp, s_ep)); } } //double radUpdownAng = Util.DTR(UpDownAngle); // ?르?림 각도 //double r1 = dstOffset / Math.Sin(radUpdownAng); //double x_offset = r1 * Math.Cos(radUpdownAng); for (int i = sections.Count - 2; i >= 0; i--) { Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start; SetInterSectorElement(sections[i]); SetInterSectorElement(sections[i + 1]); sections[i].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i + 1].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i + 1].Start, sections[i + 1].End)); double dstOffset1 = 0d; double dstOffset2 = 0d; base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i])); FindRoute(bendElement, sections[i], base_section_plane, ref dstOffset1); sections[i + 1].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i + 1])); FindRoute(bendElement, sections[i + 1], base_section_plane, ref dstOffset2); base_section_plane = null; // ?재 ?션??병합?? ?았??음 ?션과의 거리가 ?무 짧을 경우 병합?다. // ?선관? 3m ?내??정 ?정 if (detal.GetLength() < 9.84252 || bAllMerge) { if (sections[i].IsMerged == false) { sections[i].IsMerged = true; // 병합???션???재 ?션??추? sections[i].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[i + 1])); sections[i].BasePlane = base_section_plane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[i].Start, sections[i].End)); } sections[i].Refs.AddRange(sections[i + 1].Refs); sections.RemoveAt(i + 1); } } } else { if (sections.Count > 0) { base_section_plane = null; sections[0].m_mergedSections.Add(new SimpleSection(m_rvtDoc, sections[0])); sections[0].BasePlane = Plane.CreateByNormalAndOrigin(intersectorElement.EndConnector.CoordinateSystem.BasisY, Util.Midpoint(sections[0].Start, sections[0].End)); SetInterSectorElement(sections[0]); //sections[0].InterSectorElement = new KDCSIntersectorElement(m_rvtDoc.GetElement(sections[0].Refs[0].GetReference().ElementId)); } else return; } // 충돌 ?션부 벤딩 ?업 foreach (Section cur_section in sections) { Resolve(bendElement, cur_section); } // 벤드? 벤드??이준?? for (int i = 1; i < sections.Count; i++) { // Get the end point from the previous section. Autodesk.Revit.DB.XYZ start = sections[i - 1].End1; // Get the start point from the current section. Autodesk.Revit.DB.XYZ end = sections[i].Start1; // Create a duct between two neighbor section. // static Conduit Create(Document document, ElementId conduitType, XYZ startPoint, XYZ endPoint, ElementId levelId); Conduit tmpPipe = Conduit.Create(m_rvtDoc, bendElement.GetTypeId(), start, end, levelId); // Copy pipe's parameters values to tmpPipe. CopyParameters(bendElement, tmpPipe); // Create elbow fitting to connect previous section with tmpPipe. Connector conn1 = FindConnector(sections[i - 1].Conduits[2], start); Connector conn2 = FindConnector(tmpPipe, start); if (conn1 != null && conn2 != null) { FamilyInstance fi = null; try { fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); } catch (Exception ex) { string strmsg = ex.Message; } } // Create elbow fitting to connect current section with tmpPipe. Connector conn3 = FindConnector(sections[i].Conduits[0], end); Connector conn4 = FindConnector(tmpPipe, end); if (conn3 != null && conn4 != null) { FamilyInstance f2 = null; try { f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } catch (Exception ex) { string strmsg = ex.Message; } } } // ?선관 ?작쪽과 ?쪽 ?결 // Find two connectors which pipe's two ends connector connected to. Connector startConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(0)); Connector endConn = FindConnectedTo(bendElement, intersectorElement.Line.GetEndPoint(1)); // ?선관 ?작?처리 //------------------------------------------------------------------------------------------------ Conduit startPipe = null; if (null != startConn) { // Create a pipe between pipe's start connector and pipe's start section. startPipe = Conduit.Create(m_rvtDoc, conduitTypeId, startConn.Origin, sections[0].Start1, levelId); } else { // Create a pipe between pipe's start point and pipe's start section. startPipe = Conduit.Create(m_rvtDoc, conduitTypeId, sections[0].Start1, intersectorElement.Line.GetEndPoint(0), levelId); } // Copy parameters from pipe to startPipe. CopyParameters(bendElement, startPipe); // ?작??보 추? Connector connStart1 = FindConnector(startPipe, sections[0].Start1); Connector connStart2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDn_ && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUp_) { connStart2 = FindConnector(sections[0].Conduits[0], sections[0].Start1); } int count = sections.Count; FamilyInstance fii = null; if (connStart1 != null && connStart2 != null) { try { fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2); } catch (Exception ex) { string strmsg = ex.Message; } } else if (connStart2 == null && startPipe != null) { // startPipe?pipes[1]??이?맞추? ?결?다. var line1 = (sections[count - 1].Conduits[1].Location as LocationCurve).Curve as Line; var line2 = (startPipe.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(0).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(0) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(0) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, startPipe.Id, translation); List lstElement2BeDeleted = new List(); connStart1 = FindConnector(sections[count - 1].Conduits[1], line1.GetEndPoint(0)); connStart2 = FindConnector(startPipe, line1.GetEndPoint(0)); if (connStart1 != null && connStart2 != null) { JoinConduitSegment(connStart1, ref connStart2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } // ?이???쪽 처리 //------------------------------------------------------------------------------------------------ Conduit endPipe = null; if (null != endConn) { // Create a pipe between pipe's end connector and pipe's end section. endPipe = Conduit.Create(m_rvtDoc, bendElement.GetTypeId(), endConn.Origin, sections[count - 1].End1, levelId); } else { // Create a pipe between pipe's end point and pipe's end section. endPipe = Conduit.Create(m_rvtDoc, bendElement.GetTypeId(), sections[count - 1].End1, intersectorElement.Line.GetEndPoint(1), levelId); } // Copy parameters from pipe to endPipe. CopyParameters(bendElement, endPipe); // ?쪽 ?보 추? Connector connEnd1 = FindConnector(endPipe, sections[count - 1].End1); Connector connEnd2 = null; if (m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Dn && m_AvoidObstructionType != EnumAvoidObstructionType.Avoid_Up) { connEnd2 = FindConnector(sections[count - 1].Conduits[2], sections[count - 1].End1); } FamilyInstance fiii = null; if (connEnd1 != null && connEnd2 != null) { try { fiii = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2); } catch (Exception ex) { string strmsg = ex.Message; } } else if (connEnd2 == null && endPipe != null) { // endDuct?ducts[1]??이?맞추? ?결?다. var line1 = (sections[count - 1].Conduits[1].Location as LocationCurve).Curve as Line; var line2 = (endPipe.Location as LocationCurve).Curve as Line; XYZ translation = null; if (line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(0)) < line1.GetEndPoint(1).DistanceTo(line2.GetEndPoint(1))) { translation = line1.GetEndPoint(1) - line2.GetEndPoint(0); } else { translation = line1.GetEndPoint(1) - line2.GetEndPoint(1); } ElementTransformUtils.MoveElement(m_rvtDoc, endPipe.Id, translation); List lstElement2BeDeleted = new List(); connEnd1 = FindConnector(sections[count - 1].Conduits[1], line1.GetEndPoint(1)); connEnd2 = FindConnector(endPipe, line1.GetEndPoint(1)); if (connEnd1 != null && connEnd2 != null) { JoinConduitSegment(connEnd1, ref connEnd2, ref lstElement2BeDeleted); foreach (var el in lstElement2BeDeleted) { m_rvtDoc.Delete(el.Id); } } } m_rvtDoc.Delete(bendElement.Id); } /// /// Filter the inputting References, just allow Pipe, Duct and Beam References. /// /// Pipe /// References to filter private void Filter(Pipe pipe, List refs) { for (int i = refs.Count - 1; i >= 0; i--) { Reference cur = refs[i].GetReference(); Element curElem = m_rvtDoc.GetElement(cur); if (curElem.Id == pipe.Id || (!(curElem is Pipe) && !(curElem is Duct) && curElem.Category.Id.IntegerValue != (int)BuiltInCategory.OST_StructuralFraming)) { refs.RemoveAt(i); } } } private void Filter(Duct duct, List refs) { for (int i = refs.Count - 1; i >= 0; i--) { Reference cur = refs[i].GetReference(); Element curElem = m_rvtDoc.GetElement(cur); // ?음 조건??만족?? ?으??거 if (curElem.Id == duct.Id || (!(curElem is Duct) && curElem.Category.Id.IntegerValue != (int)BuiltInCategory.OST_StructuralFraming)) { refs.RemoveAt(i); } } } /// /// ?애물과 교차?여 만들?진 ?션 중심?서 ???로 관?하???과 만나??교차?????최상/최하 ?을 구한?? /// /// 기? ?션 ?면 /// /// /// /// private void GetIntersectVerticalUpperLower(Plane pln, ref List sections, XYZ vUp, ref XYZ ptUpper, ref XYZ ptLower) { double upperMax = double.MinValue; double lowerMax = double.MinValue; ptUpper = new XYZ(0, 0, double.MinValue); ptLower = new XYZ(0, 0, double.MaxValue); bool bIsTop = false; bool bIsBottom = false; // ?션?을 ?직?로 관?하???들 ?가???쪽 ?과 ?래 ??을 각각 구한?? foreach (SimpleSection cur_section in sections) { var pts = cur_section.GetIntersectUpperLower(vUp, m_detector.GetView3d()); if (pts.Count >= 2) { //Util.CreateModelLine(m_rvtDoc, pts[0], pts[1]); foreach (XYZ pt in pts) { XYZ ptOnSectionPlane = Util.Project(pln, pt); double dst = ptOnSectionPlane.DistanceTo(pt); if ((pt - ptOnSectionPlane).Normalize().IsAlmostEqualTo(vUp) == true) { if (dst > upperMax) { ptUpper = new XYZ(pt.X, pt.Y, pt.Z); upperMax = dst; bIsTop = true; } } else { if (dst > lowerMax) { ptLower = new XYZ(pt.X, pt.Y, pt.Z); lowerMax = dst; bIsBottom = true; } } } } else { // 케?블 ?레?처???래쪽에?면이 존재?거???는 경우 처리 var pt = cur_section.MidPoint; KDCSIntersectorElement ie = new KDCSIntersectorElement(cur_section.ReferenceElement); XYZ ptOnCLine = ie.Line.Project(pt).XYZPoint; ptUpper = new XYZ(pt.X, pt.Y, ptOnCLine.Z + ie.Height * 0.5); ptLower = new XYZ(pt.X, pt.Y, ptOnCLine.Z - ie.Height * 0.5); } } if(sections.Count>0){ var pt = sections[0].MidPoint; KDCSIntersectorElement ie = new KDCSIntersectorElement(sections[0].ReferenceElement); XYZ ptOnCLine = ie.Line.Project(pt).XYZPoint; if (bIsTop == false) { ptUpper = new XYZ(pt.X, pt.Y, ptOnCLine.Z + ie.Height * 0.5); } if (bIsBottom == false) { ptLower = new XYZ(pt.X, pt.Y, ptOnCLine.Z - ie.Height * 0.5); } } } /// /// ?애물을 ?할 ???는 ?트 중심?과 ?행???을 찾는?? /// /// ?트 /// ?션 /// ?애물을 ?할 ???는 ?트 중심?과 ?행????/returns> private Line FindRoute(Duct duct, Section section, Plane base_section_plane, ref double dstOffset) { KDCSIntersectorElement ieDuct = new KDCSIntersectorElement(duct); XYZ vUp = ieDuct.EndConnector.CoordinateSystem.BasisY.Z > 0 ? ieDuct.EndConnector.CoordinateSystem.BasisY : -ieDuct.EndConnector.CoordinateSystem.BasisY; //double jumpStep = ieDuct.Height; //Util.CreateModelLine(this.m_rvtDoc, section.Start, section.End); List dirs = new List(); XYZ ptMidSection = Util.Midpoint(section.Start, section.End); // ?션 중심?? XYZ ptUpper = new XYZ(0, 0, double.MinValue); XYZ ptLower = new XYZ(0, 0, double.MaxValue); if (base_section_plane != null) { ptMidSection = base_section_plane.Origin; GetIntersectVerticalUpperLower(base_section_plane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } else { ptMidSection = section.m_mergedSections[0].MidPoint; Document linkDoc = section.InterSectorElement.GetLinkDocument(); Element elm = section.m_mergedSections[0].ReferenceElement; KDCSIntersectorElement curveElm = new KDCSIntersectorElement(elm, null, linkDoc); //Util.CreateModelLine(m_rvtDoc, curveElm.StartPoint, curveElm.EndPoint); GetIntersectVerticalUpperLower(section.BasePlane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } XYZ ptOnObstruction = section.InterSectorElement.Line.Project(ptMidSection).XYZPoint; double dstMidSection2OnObstruction = 0; // ?애??션 중심?서 ?피 방향?로 지?는 광선?교차?는 교차?을 구한?? Line sectionVLine = Line.CreateBound(ptOnObstruction - vUp * section.InterSectorElement.Height, ptOnObstruction + vUp * section.InterSectorElement.Height); XYZ ptMidSectionOn = sectionVLine.Project(ptMidSection).XYZPoint; m_ptMidSectionOn = section.InterSectorElement.Line.Project(ptMidSectionOn).XYZPoint; // ?이??중심?을 지?는 ?면 Plane planeDuct = Plane.CreateByNormalAndOrigin(vUp, ieDuct.StartPoint); XYZ ptOnDuct = Util.Project(planeDuct, ptMidSectionOn); XYZ vAvoid = (ptOnDuct - ptMidSectionOn).Normalize(); // ?트 ?피 방향 m_AvoidObstructionType // 간섭?소 중심?을 지?는 ?면 Plane planeObstruction = Plane.CreateByNormalAndOrigin(vUp, section.InterSectorElement.StartPoint); XYZ ptOnObstructionCenter = Util.Project(planeObstruction, ptMidSectionOn); //double dInflate = section.InterSectorElement.Width < iePipe.Height ? iePipe.Height * 3d : iePipe.Height * 0.3; double dInflate = ieDuct.Height * 0.3; section.Inflate(0, dInflate); section.Inflate(1, dInflate); double moveHeight = ieDuct.Height * 3d; // 0.5 + mins1[0].Proximity; switch (m_AvoidObstructionType) { case EnumAvoidObstructionType.Avoid_Up: case EnumAvoidObstructionType.AvoidUpDn: case EnumAvoidObstructionType.AvoidUp_: vAvoid = vUp; if (base_section_plane != null) { moveHeight = ieDuct.Height / 2 + Util.Project(base_section_plane, ptUpper).DistanceTo(ptUpper); } else { moveHeight = ieDuct.Height / 2 + Util.Project(section.BasePlane, ptUpper).DistanceTo(ptUpper); } break; case EnumAvoidObstructionType.Avoid_Dn: case EnumAvoidObstructionType.AvoidDnUp: case EnumAvoidObstructionType.AvoidDn_: vAvoid = -vUp; if (base_section_plane != null) { ptMidSectionOn = Util.Project(base_section_plane, ptLower); moveHeight = ieDuct.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); } else { ptMidSectionOn = Util.Project(section.BasePlane, ptLower); moveHeight = ieDuct.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); //+p2.DistanceTo(ptMidSectionOn); } break; } moveHeight += Geo.MmToFoot(UpDownFreeSpaceHeight); // + ?유공간?이 // ?르?림 ?기 + ?유공간 ?이 Line foundLine = FindParallelLine(section, vAvoid, moveHeight); XYZ spFoundLine = foundLine.GetEndPoint(0); dstOffset = Util.Project(planeDuct, spFoundLine).DistanceTo(spFoundLine); return foundLine; } /// /// ?애물을 ?할 ???는 ?이??중심?과 ?행???을 찾는?? /// /// ?이??/param> /// ?션 /// ?애물을 ?할 ???는 ?이??중심?과 ?행????/returns> private Line FindRoute(Pipe pipe, Section section, Plane base_section_plane, ref double dstOffset) { KDCSIntersectorElement iePipe = new KDCSIntersectorElement(pipe); XYZ vUp = iePipe.EndConnector.CoordinateSystem.BasisY.Z > 0 ? iePipe.EndConnector.CoordinateSystem.BasisY : -iePipe.EndConnector.CoordinateSystem.BasisY; //double minLength = iePipe.Width * 2; //double jumpStep = iePipe.Height; List dirs = new List(); XYZ ptMidSection = Util.Midpoint(section.Start, section.End); // ?션 중심?? XYZ ptUpper = new XYZ(0, 0, double.MinValue); XYZ ptLower = new XYZ(0, 0, double.MaxValue); if (base_section_plane != null) { ptMidSection = base_section_plane.Origin; GetIntersectVerticalUpperLower(base_section_plane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } else { ptMidSection = section.m_mergedSections[0].MidPoint; KDCSIntersectorElement curveElm = new KDCSIntersectorElement(GetElement(section)); //Util.CreateModelLine(m_rvtDoc, curveElm.StartPoint, curveElm.EndPoint); GetIntersectVerticalUpperLower(section.BasePlane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } XYZ ptOnObstruction = section.InterSectorElement.Line.Project(ptMidSection).XYZPoint; double dstMidSection2OnObstruction = 0; // ?애??션 중심?서 ?피 방향?로 지?는 광선?교차?는 교차?을 구한?? Line sectionVLine = Line.CreateBound(ptOnObstruction - vUp * 328.0, ptOnObstruction + vUp * 328.0); XYZ ptMidSectionOn = sectionVLine.Project(ptMidSection).XYZPoint; m_ptMidSectionOn = section.InterSectorElement.Line.Project(ptMidSectionOn).XYZPoint; /* var obsRef = m_detector.Obstructions(sectionVLine, section.InterSectorElement.Id); XYZ p1 = new XYZ(); XYZ p2 = new XYZ(); if (obsRef.Count > 0) { List
sectionsUp = Section.BuildSections(obsRef, vUp); p1 = sectionsUp[0].Start; p2 = sectionsUp[0].End; if ((p1 - p2).Z < 0) { p1 = obsRef[1].GetReference().GlobalPoint; p2 = obsRef[0].GetReference().GlobalPoint; } //Util.CreateModelLine(this.m_rvtDoc, p1, p2); dstMidSection2OnObstruction = p1.DistanceTo(ptMidSectionOn); } else return null; */ // ?이??중심?을 지?는 ?면 Plane planePipe = Plane.CreateByNormalAndOrigin(vUp, iePipe.StartPoint); XYZ ptOnDuct = Util.Project(planePipe, ptMidSectionOn); XYZ vAvoid = (ptOnDuct - ptMidSectionOn).Normalize(); // ?트 ?피 방향 m_AvoidObstructionType // 간섭?소 중심?을 지?는 ?면 Plane planeObstruction = Plane.CreateByNormalAndOrigin(vUp, section.InterSectorElement.StartPoint); XYZ ptOnObstructionCenter = Util.Project(planeObstruction, ptMidSectionOn); //double dInflate = section.InterSectorElement.Width < iePipe.Height ? iePipe.Height * 3d : iePipe.Height * 0.3; double dInflate = iePipe.Height * 0.3; section.Inflate(0, dInflate); section.Inflate(1, dInflate); double moveHeight = iePipe.Height * 3d; // 0.5 + mins1[0].Proximity; switch (m_AvoidObstructionType) { case EnumAvoidObstructionType.Avoid_Up: case EnumAvoidObstructionType.AvoidUpDn: case EnumAvoidObstructionType.AvoidUp_: vAvoid = vUp; if (base_section_plane != null) { moveHeight = iePipe.Height / 2 + Util.Project(base_section_plane, ptUpper).DistanceTo(ptUpper); } else { moveHeight = iePipe.Height / 2 + Util.Project(section.BasePlane, ptUpper).DistanceTo(ptUpper); } break; case EnumAvoidObstructionType.Avoid_Dn: case EnumAvoidObstructionType.AvoidDnUp: case EnumAvoidObstructionType.AvoidDn_: vAvoid = -vUp; if (base_section_plane != null) { ptMidSectionOn = Util.Project(base_section_plane, ptLower); moveHeight = iePipe.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); } else { ptMidSectionOn = Util.Project(section.BasePlane, ptLower); moveHeight = iePipe.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); //+p2.DistanceTo(ptMidSectionOn); } break; } moveHeight += Geo.MmToFoot(UpDownFreeSpaceHeight); // + ?유공간?이 // ?르?림 ?기 + ?유공간 ?이 Line foundLine = FindParallelLine(section, vAvoid, moveHeight); XYZ spFoundLine = foundLine.GetEndPoint(0); dstOffset = Util.Project(planePipe, spFoundLine).DistanceTo(spFoundLine); return foundLine; } /// /// ?애물을 ?할 ???는 케?블?레??중심?과 ?행???을 찾는?? /// /// 케?블?레??/param> /// ?션 /// ?애물을 ?할 ???는 케?블?레??중심?과 ?행????/returns> private Line FindRoute(CableTray cabletray, Section section, Plane base_section_plane, ref double dstOffset) { KDCSIntersectorElement ieCableTray = new KDCSIntersectorElement(cabletray); XYZ vUp = ieCableTray.EndConnector.CoordinateSystem.BasisY.Z > 0 ? ieCableTray.EndConnector.CoordinateSystem.BasisY : -ieCableTray.EndConnector.CoordinateSystem.BasisY; List dirs = new List(); XYZ ptMidSection = Util.Midpoint(section.Start, section.End); // ?션 중심?? XYZ ptUpper = new XYZ(0, 0, double.MinValue); XYZ ptLower = new XYZ(0, 0, double.MaxValue); if (base_section_plane != null) { ptMidSection = base_section_plane.Origin; GetIntersectVerticalUpperLower(base_section_plane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } else { ptMidSection = section.BasePlane.Origin; GetIntersectVerticalUpperLower(section.BasePlane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } XYZ ptOnObstruction = section.InterSectorElement.Line.Project(ptMidSection).XYZPoint; double dstMidSection2OnObstruction = 0; // ?애??션 중심?서 ?피 방향?로 지?는 광선?교차?는 교차?을 구한?? Line sectionVLine = Line.CreateBound(ptOnObstruction - vUp * section.InterSectorElement.Height, ptOnObstruction + vUp * section.InterSectorElement.Height); XYZ ptMidSectionOn = sectionVLine.Project(ptMidSection).XYZPoint; m_ptMidSectionOn = section.InterSectorElement.Line.Project(ptMidSectionOn).XYZPoint; /* var obsRef = m_detector.Obstructions(sectionVLine, section.InterSectorElement); XYZ p1 = new XYZ(); XYZ p2 = new XYZ(); if (obsRef.Count > 0) { List
sectionsUp = Section.BuildSections(m_rvtDoc, obsRef, vUp); p1 = sectionsUp[0].Start; p2 = sectionsUp[0].End; if ((p1 - p2).Z < 0) { p1 = obsRef[1].GetReference().GlobalPoint; p2 = obsRef[0].GetReference().GlobalPoint; } //Util.CreateModelLine(this.m_rvtDoc, p1, p2); dstMidSection2OnObstruction = p1.DistanceTo(ptMidSectionOn); } else return null; */ // 케?블?레??중심?을 지?는 ?면 Plane planeCableTray = Plane.CreateByNormalAndOrigin(vUp, ieCableTray.StartPoint); XYZ ptOnCableTray = Util.Project(planeCableTray, ptMidSectionOn); XYZ vAvoid = (ptOnCableTray - ptMidSectionOn).Normalize(); // 케?블?레???피 방향 m_AvoidObstructionType double dInflate = ieCableTray.Height * 0.3 + 0.246063; // 75mm(0.246063ft): ?보 ?레??기본 길이 section.Inflate(0, dInflate); section.Inflate(1, dInflate); double moveHeight = ieCableTray.Height * 3d; // 0.5 + mins1[0].Proximity; switch (m_AvoidObstructionType) { case EnumAvoidObstructionType.Avoid_Up: case EnumAvoidObstructionType.AvoidUpDn: case EnumAvoidObstructionType.AvoidUp_: vAvoid = vUp; if (base_section_plane != null) { moveHeight = ieCableTray.Height / 2 + Util.Project(base_section_plane, ptUpper).DistanceTo(ptUpper); } else { //moveHeight = ieCableTray.Height / 2 + p1.DistanceTo(ptMidSectionOn); moveHeight = ieCableTray.Height / 2 + Util.Project(section.BasePlane, ptUpper).DistanceTo(ptUpper); } break; case EnumAvoidObstructionType.Avoid_Dn: case EnumAvoidObstructionType.AvoidDnUp: case EnumAvoidObstructionType.AvoidDn_: vAvoid = -vUp; if (base_section_plane != null) { ptMidSectionOn = Util.Project(base_section_plane, ptLower); moveHeight = ieCableTray.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); } else { ptMidSection = Util.Project(section.BasePlane, ptLower); moveHeight = ieCableTray.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); //+p2.DistanceTo(ptMidSectionOn); } break; } moveHeight += Geo.MmToFoot(UpDownFreeSpaceHeight); // + ?유공간?이 // ?르?림 ?기 + ?유공간 ?이 Line foundLine = FindParallelLine(section, vAvoid, moveHeight); XYZ spFoundLine = foundLine.GetEndPoint(0); dstOffset = Util.Project(planeCableTray, spFoundLine).DistanceTo(spFoundLine); return foundLine; } /// /// ?애물을 ?할 ???는 ?선관 중심?과 ?행???을 찾는?? /// /// ?선관 /// ?션 /// ?애물을 ?할 ???는 ?이??중심?과 ?행????/returns> private Line FindRoute(Conduit conduit, Section section, Plane base_section_plane, ref double dstOffset) { KDCSIntersectorElement iePipe = new KDCSIntersectorElement(conduit); XYZ vUp = iePipe.EndConnector.CoordinateSystem.BasisY.Z > 0 ? iePipe.EndConnector.CoordinateSystem.BasisY : -iePipe.EndConnector.CoordinateSystem.BasisY; //double minLength = iePipe.Width * 2; //double jumpStep = iePipe.Height; List dirs = new List(); XYZ ptMidSection = Util.Midpoint(section.Start, section.End); // ?션 중심?? XYZ ptUpper = new XYZ(0, 0, double.MinValue); XYZ ptLower = new XYZ(0, 0, double.MaxValue); if (base_section_plane != null) { ptMidSection = base_section_plane.Origin; GetIntersectVerticalUpperLower(base_section_plane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } else { ptMidSection = section.m_mergedSections[0].MidPoint; KDCSIntersectorElement curveElm = new KDCSIntersectorElement(GetElement(section)); //Util.CreateModelLine(m_rvtDoc, curveElm.StartPoint, curveElm.EndPoint); GetIntersectVerticalUpperLower(section.BasePlane, ref section.m_mergedSections, vUp, ref ptUpper, ref ptLower); } XYZ ptOnObstruction = section.InterSectorElement.Line.Project(ptMidSection).XYZPoint; // ?애??션 중심?서 ?피 방향?로 지?는 광선?교차?는 교차?을 구한?? Line sectionVLine = Line.CreateBound(ptOnObstruction - vUp * 328.0, ptOnObstruction + vUp * 328.0); XYZ ptMidSectionOn = sectionVLine.Project(ptMidSection).XYZPoint; m_ptMidSectionOn = section.InterSectorElement.Line.Project(ptMidSectionOn).XYZPoint; // ?이??중심?을 지?는 ?면 Plane planePipe = Plane.CreateByNormalAndOrigin(vUp, iePipe.StartPoint); XYZ ptOnDuct = Util.Project(planePipe, ptMidSectionOn); XYZ vAvoid = (ptOnDuct - ptMidSectionOn).Normalize(); // ?트 ?피 방향 m_AvoidObstructionType // 간섭?소 중심?을 지?는 ?면 Plane planeObstruction = Plane.CreateByNormalAndOrigin(vUp, section.InterSectorElement.StartPoint); XYZ ptOnObstructionCenter = Util.Project(planeObstruction, ptMidSectionOn); //double dInflate = section.InterSectorElement.Width < iePipe.Height ? iePipe.Height * 3d : iePipe.Height * 0.3; double dInflate = section.Start.DistanceTo(section.End) < 1.8 ? 1.8 : iePipe.Height * 0.3; section.Inflate(0, dInflate); section.Inflate(1, dInflate); double moveHeight = iePipe.Height * 3d; // 0.5 + mins1[0].Proximity; switch (m_AvoidObstructionType) { case EnumAvoidObstructionType.Avoid_Up: case EnumAvoidObstructionType.AvoidUpDn: case EnumAvoidObstructionType.AvoidUp_: vAvoid = vUp; if (base_section_plane != null) { moveHeight = iePipe.Height / 2 + Util.Project(base_section_plane, ptUpper).DistanceTo(ptUpper); } else { moveHeight = iePipe.Height / 2 + Util.Project(section.BasePlane, ptUpper).DistanceTo(ptUpper); } break; case EnumAvoidObstructionType.Avoid_Dn: case EnumAvoidObstructionType.AvoidDnUp: case EnumAvoidObstructionType.AvoidDn_: vAvoid = -vUp; if (base_section_plane != null) { ptMidSectionOn = Util.Project(base_section_plane, ptLower); moveHeight = iePipe.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); } else { ptMidSectionOn = Util.Project(section.BasePlane, ptLower); moveHeight = iePipe.Height / 2 + ptLower.DistanceTo(ptMidSectionOn); //+p2.DistanceTo(ptMidSectionOn); } break; } moveHeight += Geo.MmToFoot(UpDownFreeSpaceHeight); // + ?유공간?이 // ?르?림 ?기 + ?유공간 ?이 Line foundLine = FindParallelLine(section, vAvoid, moveHeight); XYZ spFoundLine = foundLine.GetEndPoint(0); dstOffset = Util.Project(planePipe, spFoundLine).DistanceTo(spFoundLine); return foundLine; } private Line FindParallelLine(Section section, Autodesk.Revit.DB.XYZ dir, double height) { Autodesk.Revit.DB.XYZ detal = dir * height; Line line = Line.CreateBound(section.Start + detal, section.End + detal); return line; } /// /// Find out two References, whose ProximityParameter is negative or positive, /// And Get the minimal value from all positive reference, and get the maximal value /// from the negative reference. if there are no such reference, using null instead. /// /// References /// Reference array private ReferenceWithContext[] GetClosestSectionsToOrigin(List refs) { ReferenceWithContext[] mins = new ReferenceWithContext[2]; if (refs.Count == 0) { return mins; } if (refs[0].Proximity > 0) { mins[1] = refs[0]; return mins; } for (int i = 0; i < refs.Count - 1; i++) { if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0) { mins[0] = refs[i]; mins[1] = refs[i + 1]; return mins; } } mins[0] = refs[refs.Count - 1]; return mins; } public void MepSystem() { Document doc = m_rvtDoc; FilteredElementCollector systemCollector = new FilteredElementCollector(doc).OfClass(typeof(MEPSystem)); IEnumerable desirableSystems = systemCollector.ToElements(); foreach (Element elm in desirableSystems) { MEPSystem system = elm as MEPSystem; if (system != null) { if (system.GetType() == typeof(Autodesk.Revit.DB.Plumbing.PipingSystem)) { Autodesk.Revit.DB.Plumbing.PipeSystemType type = (system as Autodesk.Revit.DB.Plumbing.PipingSystem).SystemType; } string name = system.Name; } } } public Pipe CreateNewPipe(Document document, ElementId systemTypeId, ElementId levelId) { Pipe pipe = null; PipeType pipeType = null; // find a pipe type var pipeTypes = new FilteredElementCollector(document).OfClass(typeof(PipeType)).ToElements(); if (pipeTypes.Count > 0) { pipeType = pipeTypes[pipeTypes.Count - 1] as PipeType; } if (pipeType == null) return null; // create pipe between 2 points XYZ p1 = new XYZ(0, 0, 0); XYZ p2 = new XYZ(10, 0, 0); pipe = Pipe.Create(document, systemTypeId, pipeType.Id, levelId, p1, p2); return pipe; } /// /// ?애물을 ?피?기 ?한 경로?찾는?? /// /// ?피?소(?트) /// ?트??진로?방해?는 Section private void Resolve(Duct duct, Section section) { KDCSIntersectorElement ieDuct = new KDCSIntersectorElement(duct); var ductHeight = ieDuct.Height; var section_len = section.Start.DistanceTo(section.End); if (section_len < ductHeight * 2.5) { section.Inflate(0, ductHeight); section.Inflate(1, ductHeight); } // ?애물을 ?할 ???는 ?트 중심?과 ?행???을 찾는?? double dstOffset = 0d; // ?피?소 중심?서 ?르?림???기(?이) Line offset = null; if (section.IsMerged) { offset = FindRoute(duct, section, section.BasePlane, ref dstOffset); XYZ v1 = (offset.GetEndPoint(0) - section.Start); double hgt = v1.GetLength(); v1 = v1.Normalize(); XYZ p1 = Util.Project(section.BasePlane, section.Start); XYZ p2 = Util.Project(section.BasePlane, section.End); offset = Line.CreateBound(p1 + v1 * hgt, p2 + v1 * hgt); } else offset = FindRoute(duct, section, null, ref dstOffset); // 벤딩 Line ductLine = ieDuct.Line; XYZ sectionStart = ductLine.Project(offset.GetEndPoint(0)).XYZPoint; XYZ sectionEnd = ductLine.Project(offset.GetEndPoint(1)).XYZPoint; Line sectionLine = Line.CreateBound(sectionStart, sectionEnd); XYZ dir = offset.Direction; //Util.CreateModelLine(m_rvtDoc, offset.GetEndPoint(0), offset.GetEndPoint(1)); double radUpdownAng = Util.DTR(UpDownAngle); // ?르?림 각도 double r1 = dstOffset / Math.Sin(radUpdownAng); double x_offset = r1 * Math.Cos(radUpdownAng); XYZ ptStart = sectionLine.GetEndPoint(0) - dir * x_offset; XYZ ptEnd = sectionLine.GetEndPoint(1) + dir * x_offset; section.Start1 = ptStart; section.End1 = ptEnd; // Construct two side lines, which can avoid the obstruction too. Line side1 = Line.CreateBound(ptStart, offset.GetEndPoint(0)); Line side2 = Line.CreateBound(offset.GetEndPoint(1), ptEnd); // // Create an "U" shape, which connected with three pipes and two elbows, to round the obstruction. // DuctType ductType = duct.DuctType; Autodesk.Revit.DB.XYZ start = side1.GetEndPoint(0); Autodesk.Revit.DB.XYZ startOffset = offset.GetEndPoint(0); Autodesk.Revit.DB.XYZ endOffset = offset.GetEndPoint(1); Autodesk.Revit.DB.XYZ end = side2.GetEndPoint(1); var parameter = duct.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = parameter.AsElementId(); // Create three side pipes of "U" shape. var systemTypeId = duct.MEPSystem.GetTypeId(); // m_ductSystemType.Id duct.MEPSystem.GetTypeId() by gslee 2023-05-03 if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { side2 = null; Duct duct1 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, start, startOffset); Duct duct2 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, startOffset, endOffset); // Copy parameters from pipe to other three created pipes. CopyParameters(duct, duct1); CopyParameters(duct, duct2); // Add the created three pipes to current section. section.Ducts.Add(duct1); section.Ducts.Add(duct2); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(duct1, startOffset); Connector conn2 = FindConnector(duct2, startOffset); m_rvtDoc.Create.NewElbowFitting(conn1, conn2); section.End1 = sectionLine.GetEndPoint(1); // Create the second elbow to connect another two neighbor pipes of "U" shape. //Connector conn3 = FindConnector(duct2, endOffset); } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { side1 = null; Duct duct2 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, startOffset, endOffset); Duct duct3 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, endOffset, end); // Copy parameters from pipe to other three created pipes. CopyParameters(duct, duct2); CopyParameters(duct, duct3); // Add the created three pipes to current section. section.Ducts.Add(null); section.Ducts.Add(duct2); section.Ducts.Add(duct3); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(duct2, endOffset); Connector conn4 = FindConnector(duct3, endOffset); m_rvtDoc.Create.NewElbowFitting(conn3, conn4); section.Start1 = sectionLine.GetEndPoint(0); } else { Duct duct1 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, start, startOffset); Duct duct2 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, startOffset, endOffset); Duct duct3 = Duct.Create(m_rvtDoc, systemTypeId, ductType.Id, levelId, endOffset, end); // Copy parameters from pipe to other three created pipes. CopyParameters(duct, duct1); CopyParameters(duct, duct2); CopyParameters(duct, duct3); // Add the created three pipes to current section. section.Ducts.Add(duct1); section.Ducts.Add(duct2); section.Ducts.Add(duct3); /* Util.CreateModelLine(m_rvtDoc, section.Start, section.End, new Color(0,255,0)); Util.CreateModelLine(m_rvtDoc, start, startOffset); Util.CreateModelLine(m_rvtDoc, startOffset, endOffset); Util.CreateModelLine(m_rvtDoc, endOffset, end);*/ // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(duct1, startOffset); Connector conn2 = FindConnector(duct2, startOffset); m_rvtDoc.Create.NewElbowFitting(conn1, conn2); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(duct2, endOffset); Connector conn4 = FindConnector(duct3, endOffset); m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } } /// /// ֹ ȸϱ θ ã´. /// /// ȸǿ() /// θ ϴ Section private void Resolve(Pipe pipe, Section section) { //Util.CreateModelLine(m_rvtDoc, section.Start, section.End); KDCSIntersectorElement iePipe = new KDCSIntersectorElement(pipe); var pipeHeight = iePipe.Height; var section_len = section.Start.DistanceTo(section.End); if (section_len < pipeHeight * 2.5) { section.Inflate(0, pipeHeight); section.Inflate(1, pipeHeight); } // ֹ ִ ߽ɼ ã´. double dstOffset = 0d; // ȸǿ ߽ɿ ũ() Line offset = null; if (section.IsMerged) { offset = FindRoute(pipe, section, section.BasePlane, ref dstOffset); XYZ v1 = (offset.GetEndPoint(0) - section.Start); double hgt = v1.GetLength(); v1 = v1.Normalize(); XYZ p1 = Util.Project(section.BasePlane, section.Start); XYZ p2 = Util.Project(section.BasePlane, section.End); offset = Line.CreateBound(p1 + v1 * hgt, p2 + v1 * hgt); } else offset = FindRoute(pipe, section, null, ref dstOffset); XYZ offset_start = offset.GetEndPoint(0) - offset.Direction * Unit.MMToFeet(UpDownFreeSpaceHeight); XYZ offset_end = offset.GetEndPoint(1) + offset.Direction * Unit.MMToFeet(UpDownFreeSpaceHeight); offset = Line.CreateBound(offset_start, offset_end); // Line pipeLine = iePipe.Line; XYZ sectionStart = pipeLine.Project(offset.GetEndPoint(0)).XYZPoint; XYZ sectionEnd = pipeLine.Project(offset.GetEndPoint(1)).XYZPoint; Line sectionLine = Line.CreateBound(sectionStart, sectionEnd); XYZ dir = offset.Direction; //sectionStart = sectionStart - sectionLine.Direction * Unit.MMToFeet(UpDownFreeSpaceHeight); //sectionEnd = sectionEnd + sectionLine.Direction * Unit.MMToFeet(UpDownFreeSpaceHeight); sectionLine = Line.CreateBound(sectionStart, sectionEnd); //Util.CreateModelLine(m_rvtDoc, offset.GetEndPoint(0), offset.GetEndPoint(1)); double radUpdownAng = Util.DTR(UpDownAngle); // double r1 = dstOffset / Math.Sin(radUpdownAng); double x_offset = r1 * Math.Cos(radUpdownAng); XYZ ptStart = sectionLine.GetEndPoint(0) - dir * x_offset; XYZ ptEnd = sectionLine.GetEndPoint(1) + dir * x_offset; section.Start1 = ptStart; section.End1 = ptEnd; // Construct two side lines, which can avoid the obstruction too. Line side1 = Line.CreateBound(ptStart, offset.GetEndPoint(0)); Line side2 = Line.CreateBound(offset.GetEndPoint(1), ptEnd); // // Create an "U" shape, which connected with three pipes and two elbows, to round the obstruction. // PipeType pipeType = pipe.PipeType; Autodesk.Revit.DB.XYZ start = side1.GetEndPoint(0); Autodesk.Revit.DB.XYZ startOffset = offset.GetEndPoint(0); Autodesk.Revit.DB.XYZ endOffset = offset.GetEndPoint(1); Autodesk.Revit.DB.XYZ end = side2.GetEndPoint(1); var parameter = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = parameter.AsElementId(); // Create three side pipes of "U" shape. //var systemTypeId = m_pipingSystemType.Id; var systemTypeId = pipe.MEPSystem.GetTypeId(); if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { side2 = null; Pipe pipe1 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, start, startOffset); Pipe pipe2 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, startOffset, endOffset); // Copy parameters from pipe to other three created pipes. CopyParameters(pipe, pipe1); CopyParameters(pipe, pipe2); // Add the created three pipes to current section. section.Pipes.Add(pipe1); section.Pipes.Add(pipe2); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(pipe1, startOffset); Connector conn2 = FindConnector(pipe2, startOffset); m_rvtDoc.Create.NewElbowFitting(conn1, conn2); section.End1 = sectionLine.GetEndPoint(1); // Create the second elbow to connect another two neighbor pipes of "U" shape. //Connector conn3 = FindConnector(duct2, endOffset); } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { side1 = null; Pipe pipe2 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, startOffset, endOffset); Pipe pipe3 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, endOffset, end); // Copy parameters from pipe to other three created pipes. CopyParameters(pipe, pipe2); CopyParameters(pipe, pipe3); // Add the created three pipes to current section. section.Pipes.Add(null); section.Pipes.Add(pipe2); section.Pipes.Add(pipe3); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(pipe2, endOffset); Connector conn4 = FindConnector(pipe3, endOffset); m_rvtDoc.Create.NewElbowFitting(conn3, conn4); section.Start1 = sectionLine.GetEndPoint(0); } else { Pipe pipe1 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, start, startOffset); Pipe pipe2 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, startOffset, endOffset); Pipe pipe3 = Pipe.Create(m_rvtDoc, systemTypeId, pipeType.Id, levelId, endOffset, end); //Util.CreateModelLine(m_rvtDoc, start, startOffset); //Util.CreateModelLine(m_rvtDoc, startOffset, endOffset); //Util.CreateModelLine(m_rvtDoc, endOffset, end); // Copy parameters from pipe to other three created pipes. CopyParameters(pipe, pipe1); CopyParameters(pipe, pipe2); CopyParameters(pipe, pipe3); // Add the created three pipes to current section. section.Pipes.Add(pipe1); section.Pipes.Add(pipe2); section.Pipes.Add(pipe3); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(pipe1, startOffset); Connector conn2 = FindConnector(pipe2, startOffset); m_rvtDoc.Create.NewElbowFitting(conn1, conn2); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(pipe2, endOffset); Connector conn4 = FindConnector(pipe3, endOffset); m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } } /// /// ֹ ȸϱ θ ã´. /// /// ȸǿ(̺Ʈ) /// ̺Ʈ θ ϴ Section private void Resolve(CableTray cableTray, Section section) { KDCSIntersectorElement ieCableTray = new KDCSIntersectorElement(cableTray); var ductHeight = ieCableTray.Height; var section_len = section.Start.DistanceTo(section.End); if (section_len < ductHeight * 2.5) { section.Inflate(0, ductHeight); section.Inflate(1, ductHeight); } // ֹ ִ Ʈ ߽ɼ ã´. double dstOffset = 0d; // ȸǿ ߽ɿ ũ() Line offset = null; if (section.IsMerged) { offset = FindRoute(cableTray, section, section.BasePlane, ref dstOffset); XYZ v1 = (offset.GetEndPoint(0) - section.Start); double hgt = v1.GetLength(); v1 = v1.Normalize(); XYZ p1 = Util.Project(section.BasePlane, section.Start); XYZ p2 = Util.Project(section.BasePlane, section.End); offset = Line.CreateBound(p1 + v1 * hgt, p2 + v1 * hgt); } else offset = FindRoute(cableTray, section, null, ref dstOffset); // Line ductLine = ieCableTray.Line; XYZ sectionStart = ductLine.Project(offset.GetEndPoint(0)).XYZPoint; XYZ sectionEnd = ductLine.Project(offset.GetEndPoint(1)).XYZPoint; Line sectionLine = Line.CreateBound(sectionStart, sectionEnd); XYZ dir = offset.Direction; //Util.CreateModelLine(m_rvtDoc, offset.GetEndPoint(0), offset.GetEndPoint(1)); double radUpdownAng = Util.DTR(UpDownAngle); // double r1 = dstOffset / Math.Sin(radUpdownAng); double x_offset = r1 * Math.Cos(radUpdownAng); XYZ ptStart = sectionLine.GetEndPoint(0) - dir * x_offset; XYZ ptEnd = sectionLine.GetEndPoint(1) + dir * x_offset; section.Start1 = ptStart; section.End1 = ptEnd; // Construct two side lines, which can avoid the obstruction too. Line side1 = Line.CreateBound(ptStart, offset.GetEndPoint(0)); Line side2 = Line.CreateBound(offset.GetEndPoint(1), ptEnd); // // Create an "U" shape, which connected with three pipes and two elbows, to round the obstruction. // ElementId idCableTrayType = cableTray.GetTypeId();// Util.FindCableTrayTypeId(m_rvtDoc, "Default"); Autodesk.Revit.DB.XYZ start = side1.GetEndPoint(0); Autodesk.Revit.DB.XYZ startOffset = offset.GetEndPoint(0); Autodesk.Revit.DB.XYZ endOffset = offset.GetEndPoint(1); Autodesk.Revit.DB.XYZ end = side2.GetEndPoint(1); var parameter = cableTray.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = parameter.AsElementId(); double bendRadius = 0.32808399; // 100mm // Create three side pipes of "U" shape. if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { side2 = null; CableTray cableTray1 = CableTray.Create(m_rvtDoc, idCableTrayType, start, startOffset, levelId); CableTray cableTray2 = CableTray.Create(m_rvtDoc, idCableTrayType, startOffset, endOffset, levelId); // Copy parameters from pipe to other three created pipes. CopyParameters(cableTray, cableTray1); CopyParameters(cableTray, cableTray2); // Add the created three pipes to current section. section.CableTrays.Add(cableTray1); section.CableTrays.Add(cableTray2); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(cableTray1, startOffset); Connector conn2 = FindConnector(cableTray2, startOffset); FamilyInstance fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } section.End1 = sectionLine.GetEndPoint(1); // Create the second elbow to connect another two neighbor pipes of "U" shape. //Connector conn3 = FindConnector(duct2, endOffset); } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { side1 = null; CableTray cableTray2 = CableTray.Create(m_rvtDoc, idCableTrayType, startOffset, endOffset, levelId); CableTray cableTray3 = CableTray.Create(m_rvtDoc, idCableTrayType, endOffset, end, levelId); // Copy parameters from pipe to other three created pipes. CopyParameters(cableTray, cableTray2); CopyParameters(cableTray, cableTray3); // Add the created three pipes to current section. section.CableTrays.Add(null); section.CableTrays.Add(cableTray2); section.CableTrays.Add(cableTray3); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(cableTray2, endOffset); Connector conn4 = FindConnector(cableTray3, endOffset); var fi = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } section.Start1 = sectionLine.GetEndPoint(0); } else { CableTray cableTray1 = CableTray.Create(m_rvtDoc, idCableTrayType, start, startOffset, levelId); CableTray cableTray2 = CableTray.Create(m_rvtDoc, idCableTrayType, startOffset, endOffset, levelId); CableTray cableTray3 = CableTray.Create(m_rvtDoc, idCableTrayType, endOffset, end, levelId); // Copy parameters from pipe to other three created pipes. CopyParameters(cableTray, cableTray1); CopyParameters(cableTray, cableTray2); CopyParameters(cableTray, cableTray3); // Add the created three pipes to current section. section.CableTrays.Add(cableTray1); section.CableTrays.Add(cableTray2); section.CableTrays.Add(cableTray3); //Util.CreateModelLine(m_rvtDoc, section.Start, section.End, new Color(0, 255, 0)); //Util.CreateModelLine(m_rvtDoc, start, startOffset); // Util.CreateModelLine(m_rvtDoc, startOffset, endOffset); //Util.CreateModelLine(m_rvtDoc, endOffset, end); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(cableTray1, startOffset); Connector conn2 = FindConnector(cableTray2, startOffset); if (conn1 != null && conn2 != null) { conn1.ConnectTo(conn2); var fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); //"failed to insert elbow": if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); //fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } } // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(cableTray2, endOffset); Connector conn4 = FindConnector(cableTray3, endOffset); if (conn3 != null && conn4 != null) { conn3.ConnectTo(conn4); var fi = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); //"failed to insert elbow": if (fi != null) { //fi.get_Parameter(BuiltInParameter.RBS_CABLETRAY_BENDRADIUS).Set(bendRadius); // fi.LookupParameter("Ʈ ").Set(0.082021); // 25mm } } } } /// /// ֹ ȸϱ θ ã´. /// /// ȸǿ(Ʈ) /// Ʈ θ ϴ Section private void Resolve(Conduit conduit, Section section) { KDCSIntersectorElement iePipe = new KDCSIntersectorElement(conduit); var pipeHeight = iePipe.Height; var section_len = section.Start.DistanceTo(section.End); if (section_len < pipeHeight * 2.5) { section.Inflate(0, pipeHeight); section.Inflate(1, pipeHeight); } var conduitTypeId = conduit.GetTypeId(); // ֹ ִ Ʈ ߽ɼ ã´. double dstOffset = 0d; // ȸǿ ߽ɿ ũ() Line offset = null; if (section.IsMerged) { offset = FindRoute(conduit, section, section.BasePlane, ref dstOffset); XYZ v1 = (offset.GetEndPoint(0) - section.Start); double hgt = v1.GetLength(); v1 = v1.Normalize(); XYZ p1 = Util.Project(section.BasePlane, section.Start); XYZ p2 = Util.Project(section.BasePlane, section.End); offset = Line.CreateBound(p1 + v1 * hgt, p2 + v1 * hgt); } else offset = FindRoute(conduit, section, null, ref dstOffset); // Line pipeLine = iePipe.Line; XYZ sectionStart = pipeLine.Project(offset.GetEndPoint(0)).XYZPoint; XYZ sectionEnd = pipeLine.Project(offset.GetEndPoint(1)).XYZPoint; Line sectionLine = Line.CreateBound(sectionStart, sectionEnd); XYZ dir = offset.Direction; //Util.CreateModelLine(m_rvtDoc, offset.GetEndPoint(0), offset.GetEndPoint(1)); double radUpdownAng = Util.DTR(UpDownAngle); // double r1 = dstOffset / Math.Sin(radUpdownAng); double x_offset = r1 * Math.Cos(radUpdownAng); XYZ ptStart = sectionLine.GetEndPoint(0) - dir * x_offset; XYZ ptEnd = sectionLine.GetEndPoint(1) + dir * x_offset; section.Start1 = ptStart; section.End1 = ptEnd; // Construct two side lines, which can avoid the obstruction too. Line side1 = Line.CreateBound(ptStart, offset.GetEndPoint(0)); Line side2 = Line.CreateBound(offset.GetEndPoint(1), ptEnd); // // Create an "U" shape, which connected with three pipes and two elbows, to round the obstruction. // Autodesk.Revit.DB.XYZ start = side1.GetEndPoint(0); Autodesk.Revit.DB.XYZ startOffset = offset.GetEndPoint(0); Autodesk.Revit.DB.XYZ endOffset = offset.GetEndPoint(1); Autodesk.Revit.DB.XYZ end = side2.GetEndPoint(1); var parameter = conduit.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = parameter.AsElementId(); // Create three side pipes of "U" shape. if (m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Up || m_AvoidObstructionType == EnumAvoidObstructionType.Avoid_Dn) { side2 = null; Conduit conduit1 = Conduit.Create(m_rvtDoc, conduitTypeId, start, startOffset, levelId); Conduit conduit2 = Conduit.Create(m_rvtDoc, conduitTypeId, startOffset, endOffset, levelId); // Copy parameters from pipe to other three created pipes. CopyParameters(conduit, conduit1); CopyParameters(conduit, conduit2); // Add the created three pipes to current section. section.Conduits.Add(conduit1); section.Conduits.Add(conduit2); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(conduit1, startOffset); Connector conn2 = FindConnector(conduit2, startOffset); m_rvtDoc.Create.NewElbowFitting(conn1, conn2); section.End1 = sectionLine.GetEndPoint(1); // Create the second elbow to connect another two neighbor pipes of "U" shape. //Connector conn3 = FindConnector(duct2, endOffset); } else if (m_AvoidObstructionType == EnumAvoidObstructionType.AvoidUp_ || m_AvoidObstructionType == EnumAvoidObstructionType.AvoidDn_) { side1 = null; Conduit conduit2 = Conduit.Create(m_rvtDoc, conduitTypeId, startOffset, endOffset, levelId); Conduit conduit3 = Conduit.Create(m_rvtDoc, conduitTypeId, endOffset, end, levelId); // Copy parameters from pipe to other three created pipes. CopyParameters(conduit, conduit2); CopyParameters(conduit, conduit3); // Add the created three pipes to current section. section.Conduits.Add(null); section.Conduits.Add(conduit2); section.Conduits.Add(conduit3); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(conduit2, endOffset); Connector conn4 = FindConnector(conduit3, endOffset); m_rvtDoc.Create.NewElbowFitting(conn3, conn4); section.Start1 = sectionLine.GetEndPoint(0); } else { /* Util.CreateModelLine(m_rvtDoc, section.Start, section.End, new Color(0,255,0)); Util.CreateModelLine(m_rvtDoc, start, startOffset); Util.CreateModelLine(m_rvtDoc, startOffset, endOffset); Util.CreateModelLine(m_rvtDoc, endOffset, end); */ Conduit conduit1 = Conduit.Create(m_rvtDoc, conduitTypeId, start, startOffset, levelId); Conduit conduit2 = Conduit.Create(m_rvtDoc, conduitTypeId, startOffset, endOffset, levelId); Conduit conduit3 = Conduit.Create(m_rvtDoc, conduitTypeId, endOffset, end, levelId); // Copy parameters from pipe to other three created pipes. CopyParameters(conduit, conduit1); CopyParameters(conduit, conduit2); CopyParameters(conduit, conduit3); // Add the created three pipes to current section. section.Conduits.Add(conduit1); section.Conduits.Add(conduit2); section.Conduits.Add(conduit3); // Create the first elbow to connect two neighbor pipes of "U" shape. Connector conn1 = FindConnector(conduit1, startOffset); Connector conn2 = FindConnector(conduit2, startOffset); m_rvtDoc.Create.NewElbowFitting(conn1, conn2); // Create the second elbow to connect another two neighbor pipes of "U" shape. Connector conn3 = FindConnector(conduit2, endOffset); Connector conn4 = FindConnector(conduit3, endOffset); m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } } /// /// Copy parameters from source pipe to target pipe. /// /// Coping source /// Coping target private void CopyParameters(Pipe source, Pipe target) { double diameter = source.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(diameter); } private void CopyParameters(Duct source, Duct target) { ConnectorProfileType shape = KDCS.Utils.Util.GetShape(source); if (shape == ConnectorProfileType.Round) { double diameter = source.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).Set(diameter); } else if (shape == ConnectorProfileType.Rectangular) { double width = source.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(width); double height = source.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(height); } else if (shape == ConnectorProfileType.Oval) { double width = source.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(width); double height = source.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(height); } } private void CopyParameters(CableTray source, CableTray target) { double width = source.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM).Set(width); double height = source.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).AsDouble(); target.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM).Set(height); } private void CopyParameters(Conduit source, Conduit target) { target.get_Parameter(BuiltInParameter.RBS_CONDUIT_DIAMETER_PARAM).Set(source.Diameter); double od = source.get_Parameter(BuiltInParameter.RBS_CONDUIT_OUTER_DIAM_PARAM).AsDouble(); Parameter odTP = target.get_Parameter(BuiltInParameter.RBS_CONDUIT_OUTER_DIAM_PARAM); if (odTP.IsReadOnly == false) odTP.Set(od); double id = source.get_Parameter(BuiltInParameter.RBS_CONDUIT_INNER_DIAM_PARAM).AsDouble(); Parameter idTP = target.get_Parameter(BuiltInParameter.RBS_CONDUIT_INNER_DIAM_PARAM); if(idTP.IsReadOnly == false) idTP.Set(id); } /// /// Find out a connector from pipe with a specified point. /// /// Pipe to find the connector /// Specified point /// Connector whose origin is conXYZ private Connector FindConnector(Pipe pipe, Autodesk.Revit.DB.XYZ conXYZ) { ConnectorSet conns = pipe.ConnectorManager.Connectors; foreach (Connector conn in conns) { if (conn.Origin.IsAlmostEqualTo(conXYZ)) { return conn; } } return null; } private Connector FindConnector(Duct duct, Autodesk.Revit.DB.XYZ conXYZ) { ConnectorSet conns = duct.ConnectorManager.Connectors; foreach (Connector conn in conns) { if (conn.Origin.IsAlmostEqualTo(conXYZ)) { return conn; } } return null; } private Connector FindConnector(CableTray cabletray, Autodesk.Revit.DB.XYZ conXYZ) { ConnectorSet conns = cabletray.ConnectorManager.Connectors; foreach (Connector conn in conns) { if (conn.Origin.IsAlmostEqualTo(conXYZ)) { return conn; } } return null; } private Connector FindConnector(Conduit conduit, Autodesk.Revit.DB.XYZ conXYZ) { ConnectorSet conns = conduit.ConnectorManager.Connectors; foreach (Connector conn in conns) { if (conn.Origin.IsAlmostEqualTo(conXYZ)) { return conn; } } return null; } /// /// Find out the connector which the pipe's specified connector connected to. /// The pipe's specified connector is given by point conxyz. /// /// Pipe to find the connector /// Specified point /// Connector whose origin is conXYZ private Connector FindConnectedTo(Pipe pipe, Autodesk.Revit.DB.XYZ conXYZ) { Connector connItself = FindConnector(pipe, conXYZ); ConnectorSet connSet = connItself.AllRefs; foreach (Connector conn in connSet) { if (conn.Owner.Id.IntegerValue != pipe.Id.IntegerValue && conn.ConnectorType == ConnectorType.End) { return conn; } } return null; } private Connector FindConnectedTo(Duct duct, Autodesk.Revit.DB.XYZ conXYZ) { Connector connItself = FindConnector(duct, conXYZ); ConnectorSet connSet = connItself.AllRefs; foreach (Connector conn in connSet) { if (conn.Owner.Id.IntegerValue != duct.Id.IntegerValue && conn.ConnectorType == ConnectorType.End) { return conn; } } return null; } private Connector FindConnectedTo(CableTray cabletray, Autodesk.Revit.DB.XYZ conXYZ) { Connector connItself = FindConnector(cabletray, conXYZ); ConnectorSet connSet = connItself.AllRefs; foreach (Connector conn in connSet) { if (conn.Owner.Id.IntegerValue != cabletray.Id.IntegerValue && conn.ConnectorType == ConnectorType.End) { return conn; } } return null; } private Connector FindConnectedTo(Conduit conduit, Autodesk.Revit.DB.XYZ conXYZ) { Connector connItself = FindConnector(conduit, conXYZ); ConnectorSet connSet = connItself.AllRefs; foreach (Connector conn in connSet) { if (conn.Owner.Id.IntegerValue != conduit.Id.IntegerValue && conn.ConnectorType == ConnectorType.End) { return conn; } } return null; } } }