Client/Desktop/KMBIM3.0/23.10.18/Cmd/AvoidObstruction/Resolver.cs

3931 lines
170 KiB
C#
Raw Blame History

//
// (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
}
/// <summary>
/// Custom filter for selection.
/// </summary>
public class AvoidObstructionSelectionFilter : ISelectionFilter
{
private RevitLinkInstance _RevitLinkInstance;
private List<Type> m_listsElementType = null; // 특정 유형만 선택할 수 있도록 한다.
public AvoidObstructionSelectionFilter(List<Type> lstElementType)
{
m_listsElementType = new List<Type>();
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<Type> m_listsElementType = null;
public FamilyInstanceSelectionFilter(List<Type> lstElementType)
{
m_listsElementType = new List<Type>();
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;
}
}
/// <summary>
/// This class implement the algorithm to detect the obstruction and resolve it.
/// </summary>
public class Resolver
{
/// <summary>
/// Revit Document.
/// </summary>
private Document m_rvtDoc;
public double UpDownAngle { get; set; } // 오르내림 각도
public double UpDownFreeSpaceHeight { get; set; } // 오르내림 여유공간
EnumAvoidObstructionType m_AvoidObstructionType;
EnumAvoidObstructionCheckPoint m_enumAOChectPoint;
/// <summary>
/// Detector to detect the obstructions.
/// </summary>
private Detector m_detector;
PipingSystemType m_pipingSystemType;
MechanicalSystemType m_ductSystemType;
private List<KDCSIntersectorElement> m_lstObstruction = null;
private List<KDCSIntersectorElement> m_lstAvoidance = null;
//private List<SimpleSection> m_sections = null;
public XYZ m_ptMidSectionOn { get; set; }
/// <summary>
/// Constructor, initialize all the fields of this class.
/// </summary>
/// <param name="data">Revit ExternalCommandData from external command entrance</param>
public Resolver(Document doc)
{
m_rvtDoc = doc;
m_detector = new Detector(doc);
//m_sections = new List<SimpleSection>();
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<KDCSIntersectorElement> lstObstruction, ref List<KDCSIntersectorElement> lstAvoidance)
{
m_lstObstruction = lstObstruction;
m_lstAvoidance = lstAvoidance;
}
public void GetElement(ref List<KDCSIntersectorElement> lstObstruction, ref List<KDCSIntersectorElement> lstAvoidance)
{
lstObstruction = m_lstObstruction;
lstAvoidance = m_lstAvoidance;
}
public void SetAvoidObstructionType(EnumAvoidObstructionType obstructionType)
{
m_AvoidObstructionType = obstructionType;
}
/// <summary>
/// Calculate the uniform perpendicular directions with inputting direction "dir".
/// </summary>
/// <param name="dir">Direction to calculate</param>
/// <param name="count">How many perpendicular directions will be calculated</param>
/// <returns>The calculated perpendicular directions with dir</returns>
private List<Autodesk.Revit.DB.XYZ> PerpendicularDirs(Autodesk.Revit.DB.XYZ dir, int count)
{
List<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
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;
}
/// <summary>
/// 주어진 회피요소 파이프가 충돌요소를 회피합니다.
/// </summary>
/// <param name="bendPipe">회피 요소(벤딩)</param>
/// <param name="obstruction">충돌 요소(장애물)</param>
public void Bend(Pipe bendElement, XYZ hitPoint, ref List<KDCSIntersectorElement> 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<ReferenceWithContext> obstructionRefArr = new List<ReferenceWithContext>();
foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction)
{
m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None;
// 상단
List<ReferenceWithContext> 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<Section> 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<Section> lstSectionTmp = new List<Section>();
//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<Element> lstElement2BeDeleted = new List<Element>();
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<Element> lstElement2BeDeleted = new List<Element>();
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);
}
/// <summary>
/// Use Autodesk.Revit.DB.ElementId to get the corresponding element
/// </summary>
/// <param name="id">the element id value</param>
/// <returns>the corresponding element</returns>
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;
}
/// <summary>
/// 동일 선상에 연속적으로 놓인 2개의 덕트를 서로 연결하여 하나의 덕트 세그먼트로 만들어 준다.
/// </summary>
/// <param name="cThis">기준 덕트 커넥터</param>
/// <param name="cOther">연결될 덕트 커넥터</param>
/// <param name="lstElement2BeDeleted">삭제될 덕트 요소</param>
private void JoinDuctSegment(Connector cThis, ref Connector cOther, ref List<Element> 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<Element> 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;
}
}
/// <summary>
/// 동일 선상에 연속적으로 놓인 2개의 케이블트레이를 서로 연결하여 하나의 덕트 세그먼트로 만들어 준다.
/// </summary>
/// <param name="cThis">기준 덕트 커넥터</param>
/// <param name="cOther">연결될 덕트 커넥터</param>
/// <param name="lstElement2BeDeleted">삭제될 덕트 요소</param>
private void JoinCableTraySegment(Connector cThis, ref Connector cOther, ref List<Element> 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<Element> 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;
}
/// <summary>
/// 주어진 회피요소 덕트가 충돌요소를 회피합니다.
/// </summary>
/// <param name="bendDuct">회피 요소(벤딩)</param>
/// <param name="obstruction">충돌 요소(장애물)</param>
public void Bend(Duct bendElement, XYZ hitPoint, ref List<KDCSIntersectorElement> 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<ReferenceWithContext> obstructionRefArr = new List<ReferenceWithContext>();
foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction)
{
m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None;
// 상단
List<ReferenceWithContext> 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<Section> 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<Section> lstSectionTmp = new List<Section>();
//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<Element> lstElement2BeDeleted = new List<Element>();
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<Element> lstElement2BeDeleted = new List<Element>();
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);
}
/// <summary>
/// 주어진 회피요소 케이블트레이가 충돌요소를 회피합니다.
/// </summary>
/// <param name="bendElement">회피 요소(벤딩)</param>
/// <param name="lstObstruction">충돌요소(장애물)</param>
public void Bend(CableTray bendElement, XYZ hitPoint, ref List<KDCSIntersectorElement> 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<ReferenceWithContext> obstructionRefArr = new List<ReferenceWithContext>();
foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction)
{
m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None;
// 상단
List<ReferenceWithContext> 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<Section> 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<Element> lstElement2BeDeleted = new List<Element>();
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<Element> lstElement2BeDeleted = new List<Element>();
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);
}
/// <summary>
/// 二쇱뼱吏??뚰뵾?붿냼 ?꾩꽑愿<EABD91> 異⑸룎?붿냼瑜??뚰뵾?⑸땲??
/// </summary>
/// <param name="bendElement"></param>
/// <param name="lstObstruction"></param>
public void Bend(Conduit bendElement, XYZ hitPoint, ref List<KDCSIntersectorElement> 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<ReferenceWithContext> obstructionRefArr = new List<ReferenceWithContext>();
foreach (KDCSIntersectorElement intersectorObstrion in lstObstruction)
{
m_enumAOChectPoint = EnumAvoidObstructionCheckPoint.None;
// ?곷떒
List<ReferenceWithContext> 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<Section> 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<Section> lstSectionTmp = new List<Section>();
//lstSectionTmp.AddRange(sections);
bool bAllMerge = false;
if (m_AvoidObstructionType != EnumAvoidObstructionType.AvoidUpDn && m_AvoidObstructionType != EnumAvoidObstructionType.AvoidDnUp) bAllMerge = true;
Plane base_section_plane = null;
// ?뱀뀡??李몄“媛<E2809C> 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;
// ?꾩옱 ?뱀뀡??蹂묓빀?섏? ?딆븯怨??ㅼ쓬 ?뱀뀡怨쇱쓽 嫄곕━媛<E29481> ?덈Т 吏㏃쓣 寃쎌슦 蹂묓빀?쒕떎.
// ?꾩꽑愿<EABD91>?<3F> 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;
}
// 異⑸룎 ?뱀뀡遺<EB80A1> 踰ㅻ뵫 ?묒뾽
foreach (Section cur_section in sections)
{
Resolve(bendElement, cur_section);
}
// 踰ㅻ뱶?<3F> 踰ㅻ뱶瑜??댁씠以<EC94A0>??
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; }
}
}
// ?꾩꽑愿<EABD91> ?쒖옉履쎄낵 ?앹そ ?곌껐
// 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));
// ?꾩꽑愿<EABD91> ?쒖옉履?泥섎━
//------------------------------------------------------------------------------------------------
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<Element> lstElement2BeDeleted = new List<Element>();
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<Element> lstElement2BeDeleted = new List<Element>();
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);
}
/// <summary>
/// Filter the inputting References, just allow Pipe, Duct and Beam References.
/// </summary>
/// <param name="pipe">Pipe</param>
/// <param name="refs">References to filter</param>
private void Filter(Pipe pipe, List<ReferenceWithContext> 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<ReferenceWithContext> 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);
}
}
}
/// <summary>
/// ?μ븷臾쇨낵 援먯감?섏뿬 留뚮뱾?댁쭊 ?뱀뀡 以묒떖?먯꽌 ???섎줈 愿<>?듯븯???좉낵 留뚮굹??援먯감????以?理쒖긽/理쒗븯 ?먯쓣 援ы븳??
/// </summary>
/// <param name="pln">湲곗? ?뱀뀡 ?됰㈃</param>
/// <param name="sections"></param>
/// <param name="vUp"></param>
/// <param name="ptUpper"></param>
/// <param name="ptLower"></param>
private void GetIntersectVerticalUpperLower(Plane pln, ref List<SimpleSection> 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);
}
}
}
/// <summary>
/// ?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 ?뺥듃 以묒떖?좉낵 ?됲뻾???좎쓣 李얜뒗??
/// </summary>
/// <param name="duct">?뺥듃</param>
/// <param name="section">?뱀뀡</param>
/// <returns>?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 ?뺥듃 以묒떖?좉낵 ?됲뻾????/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<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
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;
}
/// <summary>
/// ?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 ?뚯씠??以묒떖?좉낵 ?됲뻾???좎쓣 李얜뒗??
/// </summary>
/// <param name="pipe">?뚯씠??/param>
/// <param name="section">?뱀뀡</param>
/// <returns>?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 ?뚯씠??以묒떖?좉낵 ?됲뻾????/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<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
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<Section> 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;
}
/// <summary>
/// ?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 耳<>?대툝?몃젅??以묒떖?좉낵 ?됲뻾???좎쓣 李얜뒗??
/// </summary>
/// <param name="duct">耳<>?대툝?몃젅??/param>
/// <param name="section">?뱀뀡</param>
/// <returns>?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 耳<>?대툝?몃젅??以묒떖?좉낵 ?됲뻾????/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<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
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<Section> 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;
}
/// <summary>
/// ?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 ?꾩꽑愿<EABD91> 以묒떖?좉낵 ?됲뻾???좎쓣 李얜뒗??
/// </summary>
/// <param name="conduit">?꾩꽑愿<EABD91></param>
/// <param name="section">?뱀뀡</param>
/// <returns>?μ븷臾쇱쓣 ?쇳븷 ???덈뒗 ?뚯씠??以묒떖?좉낵 ?됲뻾????/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<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
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;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="refs">References</param>
/// <returns>Reference array</returns>
private ReferenceWithContext[] GetClosestSectionsToOrigin(List<ReferenceWithContext> 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<Element> 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;
}
/// <summary>
/// ?μ븷臾쇱쓣 ?뚰뵾?섍린 ?꾪븳 寃쎈줈瑜?李얜뒗??
/// </summary>
/// <param name="duct">?뚰뵾?붿냼(?뺥듃)</param>
/// <param name="section">?뺥듃??吏꾨줈瑜?諛⑺빐?섎뒗 Section</param>
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);
}
}
/// <summary>
/// 장애물을 회피하기 위한 경로를 찾는다.
/// </summary>
/// <param name="pipe">회피요소(파이프)</param>
/// <param name="section">파이프의 진로를 방해하는 Section</param>
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);
}
}
/// <summary>
/// 장애물을 회피하기 위한 경로를 찾는다.
/// </summary>
/// <param name="duct">회피요소(케이블트레이)</param>
/// <param name="section">케이블트레이의 진로를 방해하는 Section</param>
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 설정
}
}
}
}
/// <summary>
/// 장애물을 회피하기 위한 경로를 찾는다.
/// </summary>
/// <param name="duct">회피요소(덕트)</param>
/// <param name="section">덕트의 진로를 방해하는 Section</param>
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);
}
}
/// <summary>
/// Copy parameters from source pipe to target pipe.
/// </summary>
/// <param name="source">Coping source</param>
/// <param name="target">Coping target</param>
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);
}
/// <summary>
/// Find out a connector from pipe with a specified point.
/// </summary>
/// <param name="pipe">Pipe to find the connector</param>
/// <param name="conXYZ">Specified point</param>
/// <returns>Connector whose origin is conXYZ</returns>
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;
}
/// <summary>
/// Find out the connector which the pipe's specified connector connected to.
/// The pipe's specified connector is given by point conxyz.
/// </summary>
/// <param name="pipe">Pipe to find the connector</param>
/// <param name="conXYZ">Specified point</param>
/// <returns>Connector whose origin is conXYZ</returns>
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;
}
}
}