3931 lines
170 KiB
C#
3931 lines
170 KiB
C#
//
|
||
// (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;
|
||
}
|
||
}
|
||
|
||
}
|