1884 lines
76 KiB
C#
1884 lines
76 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;
|
||
|
||
namespace KMBIM
|
||
{
|
||
|
||
enum EnumAvoidObstructionType
|
||
{
|
||
None = 0,
|
||
AvoidUpDn,
|
||
Avoid_Up,
|
||
Avoid_Dn,
|
||
AvoidDnUp,
|
||
AvoidUp_,
|
||
AvoidDn_
|
||
}
|
||
|
||
/// <summary>
|
||
/// Custom filter for selection.
|
||
/// </summary>
|
||
public class AvoidObstructionSelectionFilter : ISelectionFilter
|
||
{
|
||
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)
|
||
{
|
||
foreach (Type t1 in m_listsElementType)
|
||
{
|
||
if (elem.GetType() == t1) return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public bool AllowReference(Reference refer, XYZ point)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// This class implement the algorithm to detect the obstruction and resolve it.
|
||
/// </summary>
|
||
class Resolver
|
||
{
|
||
/// <summary>
|
||
/// Revit Document.
|
||
/// </summary>
|
||
private UIDocument m_rvtUIDoc;
|
||
private Document m_rvtDoc;
|
||
|
||
/// <summary>
|
||
/// Revit Application.
|
||
/// </summary>
|
||
private Autodesk.Revit.ApplicationServices.Application m_rvtApp;
|
||
|
||
EnumAvoidObstructionType m_AvoidObstructionType;
|
||
|
||
/// <summary>
|
||
/// Detector to detect the obstructions.
|
||
/// </summary>
|
||
private Detector m_detector;
|
||
|
||
PipingSystemType m_pipingSystemType;
|
||
MechanicalSystemType m_ductSystemType;
|
||
|
||
/// <summary>
|
||
/// Constructor, initialize all the fields of this class.
|
||
/// </summary>
|
||
/// <param name="data">Revit ExternalCommandData from external command entrance</param>
|
||
public Resolver(ExternalCommandData data)
|
||
{
|
||
m_rvtUIDoc = data.Application.ActiveUIDocument;
|
||
m_rvtDoc = data.Application.ActiveUIDocument.Document;
|
||
m_rvtApp = data.Application.Application;
|
||
m_detector = new Detector(m_rvtDoc);
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Detect and resolve the obstructions of all Pipes.
|
||
/// </summary>
|
||
/// <param name="lstObstruction">충돌요소</param>
|
||
/// <param name="lstAvoidance">회피요소</param>
|
||
public void Resolve(ref List<Element> lstObstruction, ref List<Element> lstAvoidance)
|
||
{
|
||
foreach (Element e1 in lstAvoidance)
|
||
{
|
||
foreach (Element e2 in lstObstruction)
|
||
{
|
||
Type et1 = e1.GetType(); // 회피요소 유형
|
||
using (Transaction tr = new Transaction(m_rvtDoc, "External Tool - Resolver"))
|
||
{
|
||
tr.Start();
|
||
try
|
||
{
|
||
if (et1 == typeof(Duct))
|
||
{
|
||
Run(e1 as Duct, e2);
|
||
|
||
}
|
||
else if (et1 == typeof(Pipe))
|
||
{
|
||
Run(e1 as Pipe, e2);
|
||
}
|
||
else if (et1 == typeof(CableTray))
|
||
{
|
||
|
||
}
|
||
else if (et1 == typeof(Conduit))
|
||
{
|
||
|
||
}
|
||
tr.Commit();
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
string str_msg = ex.Message;
|
||
tr.RollBack();
|
||
}
|
||
}
|
||
}//for-each
|
||
}//for-each
|
||
}
|
||
|
||
|
||
|
||
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;
|
||
}
|
||
|
||
|
||
private void Bend(Pipe pipe, Pipe obstruction)
|
||
{
|
||
var parameter = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
|
||
var levelId = parameter.AsElementId();
|
||
var systemTypeId = m_pipingSystemType.Id;
|
||
// Get the centerline of pipe.
|
||
Line pipeLine = (pipe.Location as LocationCurve).Curve as Line;
|
||
double pipRad = pipe.Diameter * 0.5;
|
||
// Calculate the intersection references with pipe's centerline.
|
||
Autodesk.Revit.DB.XYZ startPt = pipeLine.GetEndPoint(0);
|
||
Autodesk.Revit.DB.XYZ endPt = pipeLine.GetEndPoint(1);
|
||
|
||
Autodesk.Revit.DB.XYZ axisZ = (endPt - startPt).Normalize();
|
||
double pipeLength = startPt.DistanceTo(endPt);
|
||
|
||
XYZ axisX = new XYZ();
|
||
XYZ axisY = new XYZ();
|
||
|
||
|
||
Util.AxesXY(axisZ, ref axisX, ref axisY);
|
||
|
||
|
||
XYZ orgR = startPt + axisX * pipRad;
|
||
XYZ orgL = startPt - axisX * pipRad;
|
||
XYZ orgT = startPt + axisY * pipRad;
|
||
XYZ orgB = startPt - axisY * pipRad;
|
||
|
||
// <20>浹 Ȯ<>μ<EFBFBD>
|
||
Line checkLeftLine = Line.CreateBound(orgL, orgL + axisZ * pipeLength);
|
||
Line checkRightLine = Line.CreateBound(orgR, orgR + axisZ * pipeLength);
|
||
Line checkTopLine = Line.CreateBound(orgT, orgT + axisZ * pipeLength);
|
||
Line checkBottomLine = Line.CreateBound(orgB, orgB + axisZ * pipeLength);
|
||
|
||
|
||
|
||
// <20><>Ʈ<EFBFBD><C6AE> <20>߽ɼ<DFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>)<29><> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
List<ReferenceWithContext> obstructionTopRefArr = m_detector.Obstructions(checkTopLine);
|
||
List<ReferenceWithContext> obstructionBottomRefArr = m_detector.Obstructions(checkBottomLine);
|
||
List<ReferenceWithContext> obstructionLeftRefArr = m_detector.Obstructions(checkLeftLine);
|
||
List<ReferenceWithContext> obstructionRightRefArr = m_detector.Obstructions(checkRightLine);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>) <20><> <20><>Ʈ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
// duct: <20><> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>ܽ<EFBFBD>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
Filter(pipe, obstructionTopRefArr);
|
||
Filter(pipe, obstructionBottomRefArr);
|
||
Filter(pipe, obstructionLeftRefArr);
|
||
Filter(pipe, obstructionRightRefArr);
|
||
|
||
List<ReferenceWithContext> obstructionRefArr = null;
|
||
// <20><>-><3E><>-><3E><>-><3E><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (obstructionTopRefArr.Count > 0) obstructionRefArr = obstructionTopRefArr; // <20><>
|
||
if (obstructionBottomRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionBottomRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionBottomRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
|
||
if (obstructionRefArr == null)
|
||
{
|
||
if (obstructionLeftRefArr.Count > 0) obstructionRefArr = obstructionLeftRefArr; // <20><>
|
||
if (obstructionRightRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionRightRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionRightRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||
if (obstructionRefArr == null) return;
|
||
if (obstructionRefArr.Count == 0) return;
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ۼ<EFBFBD><DBBC>Ѵ<EFBFBD>.
|
||
obstructionRefArr.Sort(m_detector.CompareReferencesWithContext);
|
||
List<Section> sections = Section.BuildSections(obstructionRefArr, pipeLine.Direction);
|
||
|
||
List<Section> lstSectionTmp = new List<Section>();
|
||
lstSectionTmp.AddRange(sections);
|
||
// <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>-><3E><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Section<6F><6E> <20><EFBFBD><DFBB><EFBFBD> <20><><EFBFBD> <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (sections.Count > 1)
|
||
{
|
||
while (lstSectionTmp.Count > 0)
|
||
{
|
||
Section section1 = lstSectionTmp[0];
|
||
lstSectionTmp.RemoveAt(0);
|
||
var intResult1 = pipeLine.Project(KDCS.Utils.Util.Midpoint(section1.Start, section1.End));
|
||
foreach (Section section2 in lstSectionTmp)
|
||
{
|
||
var intResult2 = pipeLine.Project(KDCS.Utils.Util.Midpoint(section2.Start, section2.End));
|
||
if (intResult2 != null)
|
||
{
|
||
if (intResult1.XYZPoint.DistanceTo(intResult2.XYZPoint) < pipRad)
|
||
{
|
||
sections.Remove(section2);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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;
|
||
if (detal.GetLength() < pipe.Diameter * 3)
|
||
{
|
||
sections[i].Refs.AddRange(sections[i + 1].Refs);
|
||
sections.RemoveAt(i + 1);
|
||
}
|
||
}
|
||
|
||
// Resolve the obstructions one by one.
|
||
foreach (Section sec in sections)
|
||
{
|
||
Resolve(pipe, sec);
|
||
}
|
||
|
||
// Connect the neighbor sections with pipe and elbow fittings.
|
||
//
|
||
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 pipe between two neighbor section.
|
||
Pipe tmpPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, start, end);
|
||
|
||
// Copy pipe's parameters values to tmpPipe.
|
||
CopyParameters(pipe, tmpPipe);
|
||
|
||
// Create elbow fitting to connect previous section with tmpPipe.
|
||
Connector conn1 = FindConnector(sections[i - 1].Pipes[2], start);
|
||
Connector conn2 = FindConnector(tmpPipe, start);
|
||
FamilyInstance f1 = null;
|
||
|
||
try{
|
||
f1 = 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);
|
||
FamilyInstance f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4);
|
||
}
|
||
|
||
// Find two connectors which pipe's two ends connector connected to.
|
||
Connector startConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(0));
|
||
Connector endConn = FindConnectedTo(pipe, pipeLine.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, pipe.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, pipe.PipeType.Id, levelId, sections[0].Start1, pipeLine.GetEndPoint(0));
|
||
}
|
||
|
||
// Copy parameters from pipe to startPipe.
|
||
CopyParameters(pipe, startPipe);
|
||
|
||
// Connect the startPipe and first section with elbow fitting.
|
||
Connector connStart1 = FindConnector(startPipe, sections[0].Start1);
|
||
Connector connStart2 = FindConnector(sections[0].Pipes[0], sections[0].Start1);
|
||
FamilyInstance f3 = null;
|
||
try{
|
||
f3 = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2);
|
||
}
|
||
catch (Exception ex) { string strmsg = ex.Message; }
|
||
|
||
Pipe endPipe = null;
|
||
int count = sections.Count;
|
||
if (null != endConn)
|
||
{
|
||
// Create a pipe between pipe's end connector and pipe's end section.
|
||
endPipe = Pipe.Create(m_rvtDoc, pipe.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, pipe.PipeType.Id, levelId, sections[count - 1].End1, pipeLine.GetEndPoint(1));
|
||
}
|
||
|
||
// Copy parameters from pipe to endPipe.
|
||
CopyParameters(pipe, endPipe);
|
||
|
||
// Connect the endPipe and last section with elbow fitting.
|
||
Connector connEnd1 = FindConnector(endPipe, sections[count - 1].End1);
|
||
Connector connEnd2 = FindConnector(sections[count - 1].Pipes[2], sections[count - 1].End1);
|
||
FamilyInstance f4 = null;
|
||
try{
|
||
f4 = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2);
|
||
}
|
||
catch (Exception ex) { string strmsg = ex.Message; }
|
||
|
||
// Delete the pipe after resolved.
|
||
m_rvtDoc.Delete(pipe.Id);
|
||
}
|
||
|
||
|
||
private void Bend(Pipe pipe, Duct obstruction)
|
||
{
|
||
var parameter = pipe.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
|
||
var levelId = parameter.AsElementId();
|
||
var systemTypeId = m_pipingSystemType.Id;
|
||
// Get the centerline of pipe.
|
||
Line pipeLine = (pipe.Location as LocationCurve).Curve as Line;
|
||
double pipRad = pipe.Diameter * 0.5;
|
||
// Calculate the intersection references with pipe's centerline.
|
||
Autodesk.Revit.DB.XYZ startPt = pipeLine.GetEndPoint(0);
|
||
Autodesk.Revit.DB.XYZ endPt = pipeLine.GetEndPoint(1);
|
||
|
||
Autodesk.Revit.DB.XYZ axisZ = (endPt - startPt).Normalize();
|
||
double pipeLength = startPt.DistanceTo(endPt);
|
||
|
||
XYZ axisX = new XYZ();
|
||
XYZ axisY = new XYZ();
|
||
|
||
|
||
KDCS.Utils.Util.AxesXY(axisZ, ref axisX, ref axisY);
|
||
|
||
|
||
XYZ orgR = startPt + axisX * pipRad;
|
||
XYZ orgL = startPt - axisX * pipRad;
|
||
XYZ orgT = startPt + axisY * pipRad;
|
||
XYZ orgB = startPt - axisY * pipRad;
|
||
|
||
// <20>浹 Ȯ<>μ<EFBFBD>
|
||
Line checkLeftLine = Line.CreateBound(orgL, orgL + axisZ * pipeLength);
|
||
Line checkRightLine = Line.CreateBound(orgR, orgR + axisZ * pipeLength);
|
||
Line checkTopLine = Line.CreateBound(orgT, orgT + axisZ * pipeLength);
|
||
Line checkBottomLine = Line.CreateBound(orgB, orgB + axisZ * pipeLength);
|
||
|
||
|
||
|
||
// <20><>Ʈ<EFBFBD><C6AE> <20>߽ɼ<DFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>)<29><> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
List<ReferenceWithContext> obstructionTopRefArr = m_detector.Obstructions(checkTopLine);
|
||
List<ReferenceWithContext> obstructionBottomRefArr = m_detector.Obstructions(checkBottomLine);
|
||
List<ReferenceWithContext> obstructionLeftRefArr = m_detector.Obstructions(checkLeftLine);
|
||
List<ReferenceWithContext> obstructionRightRefArr = m_detector.Obstructions(checkRightLine);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>) <20><> <20><>Ʈ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
// duct: <20><> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>ܽ<EFBFBD>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
Filter(pipe, obstructionTopRefArr);
|
||
Filter(pipe, obstructionBottomRefArr);
|
||
Filter(pipe, obstructionLeftRefArr);
|
||
Filter(pipe, obstructionRightRefArr);
|
||
|
||
List<ReferenceWithContext> obstructionRefArr = null;
|
||
// <20><>-><3E><>-><3E><>-><3E><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (obstructionTopRefArr.Count > 0) obstructionRefArr = obstructionTopRefArr; // <20><>
|
||
if (obstructionBottomRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionBottomRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionBottomRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
|
||
if (obstructionRefArr == null)
|
||
{
|
||
if (obstructionLeftRefArr.Count > 0) obstructionRefArr = obstructionLeftRefArr; // <20><>
|
||
if (obstructionRightRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionRightRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionRightRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||
if (obstructionRefArr == null) return;
|
||
if (obstructionRefArr.Count == 0) return;
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ۼ<EFBFBD><DBBC>Ѵ<EFBFBD>.
|
||
obstructionRefArr.Sort(m_detector.CompareReferencesWithContext);
|
||
List<Section> sections = Section.BuildSections(obstructionRefArr, pipeLine.Direction);
|
||
|
||
List<Section> lstSectionTmp = new List<Section>();
|
||
lstSectionTmp.AddRange(sections);
|
||
// <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>-><3E><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Section<6F><6E> <20><EFBFBD><DFBB><EFBFBD> <20><><EFBFBD> <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (sections.Count > 1)
|
||
{
|
||
while (lstSectionTmp.Count > 0)
|
||
{
|
||
Section section1 = lstSectionTmp[0];
|
||
lstSectionTmp.RemoveAt(0);
|
||
var intResult1 = pipeLine.Project(KDCS.Utils.Util.Midpoint(section1.Start, section1.End));
|
||
foreach (Section section2 in lstSectionTmp)
|
||
{
|
||
var intResult2 = pipeLine.Project(KDCS.Utils.Util.Midpoint(section2.Start, section2.End));
|
||
if (intResult2 != null)
|
||
{
|
||
if (intResult1.XYZPoint.DistanceTo(intResult2.XYZPoint) < pipRad)
|
||
{
|
||
sections.Remove(section2);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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;
|
||
if (detal.GetLength() < pipe.Diameter * 3)
|
||
{
|
||
sections[i].Refs.AddRange(sections[i + 1].Refs);
|
||
sections.RemoveAt(i + 1);
|
||
}
|
||
}
|
||
|
||
// Resolve the obstructions one by one.
|
||
foreach (Section sec in sections)
|
||
{
|
||
Resolve(pipe, sec);
|
||
}
|
||
|
||
// Connect the neighbor sections with pipe and elbow fittings.
|
||
//
|
||
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 pipe between two neighbor section.
|
||
Pipe tmpPipe = Pipe.Create(m_rvtDoc, systemTypeId, pipe.PipeType.Id, levelId, start, end);
|
||
|
||
// Copy pipe's parameters values to tmpPipe.
|
||
CopyParameters(pipe, tmpPipe);
|
||
|
||
// Create elbow fitting to connect previous section with tmpPipe.
|
||
Connector conn1 = FindConnector(sections[i - 1].Pipes[2], start);
|
||
Connector conn2 = FindConnector(tmpPipe, start);
|
||
FamilyInstance f1 = null;
|
||
|
||
try
|
||
{
|
||
f1 = 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);
|
||
FamilyInstance f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4);
|
||
}
|
||
|
||
// Find two connectors which pipe's two ends connector connected to.
|
||
Connector startConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(0));
|
||
Connector endConn = FindConnectedTo(pipe, pipeLine.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, pipe.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, pipe.PipeType.Id, levelId, sections[0].Start1, pipeLine.GetEndPoint(0));
|
||
}
|
||
|
||
// Copy parameters from pipe to startPipe.
|
||
CopyParameters(pipe, startPipe);
|
||
|
||
// Connect the startPipe and first section with elbow fitting.
|
||
Connector connStart1 = FindConnector(startPipe, sections[0].Start1);
|
||
Connector connStart2 = FindConnector(sections[0].Pipes[0], sections[0].Start1);
|
||
FamilyInstance f3 = null;
|
||
try
|
||
{
|
||
f3 = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2);
|
||
}
|
||
catch (Exception ex) { string strmsg = ex.Message; }
|
||
|
||
Pipe endPipe = null;
|
||
int count = sections.Count;
|
||
if (null != endConn)
|
||
{
|
||
// Create a pipe between pipe's end connector and pipe's end section.
|
||
endPipe = Pipe.Create(m_rvtDoc, pipe.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, pipe.PipeType.Id, levelId, sections[count - 1].End1, pipeLine.GetEndPoint(1));
|
||
}
|
||
|
||
// Copy parameters from pipe to endPipe.
|
||
CopyParameters(pipe, endPipe);
|
||
|
||
// Connect the endPipe and last section with elbow fitting.
|
||
Connector connEnd1 = FindConnector(endPipe, sections[count - 1].End1);
|
||
Connector connEnd2 = FindConnector(sections[count - 1].Pipes[2], sections[count - 1].End1);
|
||
FamilyInstance f4 = null;
|
||
try
|
||
{
|
||
f4 = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2);
|
||
}
|
||
catch (Exception ex) { string strmsg = ex.Message; }
|
||
|
||
// Delete the pipe after resolved.
|
||
m_rvtDoc.Delete(pipe.Id);
|
||
}
|
||
/// <summary>
|
||
/// Detect the obstructions of pipe and resolve them.
|
||
/// </summary>
|
||
/// <param name="pipe">Pipe to resolve</param>
|
||
private void Run(Pipe pipe, Element obstruction)
|
||
{
|
||
if(obstruction.GetType() == typeof(Pipe)){
|
||
Bend(pipe, obstruction as Pipe);
|
||
}else if(obstruction.GetType() == typeof(Duct)){
|
||
Bend(pipe, obstruction as Duct);
|
||
}
|
||
|
||
}
|
||
|
||
private double GetDuctWidth(Duct duct)
|
||
{
|
||
double width = 0d;
|
||
ConnectorProfileType shape = KDCS.Utils.Util.GetShape(duct);
|
||
if (shape == ConnectorProfileType.Round)
|
||
{
|
||
width = duct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsDouble();
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
width = duct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble();
|
||
|
||
}
|
||
return width;
|
||
}
|
||
private double GetDuctHeight(Duct duct)
|
||
{
|
||
double height = 0d;
|
||
ConnectorProfileType shape = KDCS.Utils.Util.GetShape(duct);
|
||
if (shape == ConnectorProfileType.Round)
|
||
{
|
||
height = duct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsDouble();
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
height = duct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).AsDouble();
|
||
|
||
}
|
||
return height;
|
||
}
|
||
|
||
|
||
/// <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;
|
||
}
|
||
|
||
|
||
private void Bend(Duct duct, Duct obstruction)
|
||
{
|
||
// duct.LookupParameter(string name)
|
||
var paramLevel = duct.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
|
||
var levelId = paramLevel.AsElementId();
|
||
var systemTypeId = m_ductSystemType.Id;
|
||
// <20><>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
var halfWidth = GetDuctWidth(duct) * 0.5;
|
||
var halfHeight = GetDuctHeight(duct) * 0.5;
|
||
|
||
// <20><>Ʈ <20>߽ɼ<DFBD><C9BC><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
|
||
Line ductLine = (duct.Location as LocationCurve).Curve as Line;
|
||
|
||
|
||
Autodesk.Revit.DB.XYZ startPt = ductLine.GetEndPoint(0);
|
||
Autodesk.Revit.DB.XYZ endPt = ductLine.GetEndPoint(1);
|
||
|
||
Autodesk.Revit.DB.XYZ axisZ = (endPt - startPt).Normalize();
|
||
double ductLength = startPt.DistanceTo(endPt);
|
||
|
||
XYZ axisX = new XYZ();
|
||
XYZ axisY = new XYZ();
|
||
|
||
|
||
KDCS.Utils.Util.AxesXY(axisZ, ref axisX, ref axisY);
|
||
|
||
|
||
XYZ orgR = startPt + axisX * halfWidth;
|
||
XYZ orgL = startPt - axisX * halfWidth;
|
||
XYZ orgT = startPt + axisY * halfHeight;
|
||
XYZ orgB = startPt - axisY * halfHeight;
|
||
|
||
// <20>浹 Ȯ<>μ<EFBFBD>
|
||
Line checkLeftLine = Line.CreateBound(orgL, orgL + axisZ * ductLength);
|
||
Line checkRightLine = Line.CreateBound(orgR, orgR + axisZ * ductLength);
|
||
Line checkTopLine = Line.CreateBound(orgT, orgT + axisZ * ductLength);
|
||
Line checkBottomLine = Line.CreateBound(orgB, orgB + axisZ * ductLength);
|
||
|
||
|
||
|
||
// <20><>Ʈ<EFBFBD><C6AE> <20>߽ɼ<DFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>)<29><> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
List<ReferenceWithContext> obstructionTopRefArr = m_detector.Obstructions(checkTopLine);
|
||
List<ReferenceWithContext> obstructionBottomRefArr = m_detector.Obstructions(checkBottomLine);
|
||
List<ReferenceWithContext> obstructionLeftRefArr = m_detector.Obstructions(checkLeftLine);
|
||
List<ReferenceWithContext> obstructionRightRefArr = m_detector.Obstructions(checkRightLine);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>) <20><> <20><>Ʈ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
// duct: <20><> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>ܽ<EFBFBD>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
Filter(duct, obstructionTopRefArr);
|
||
Filter(duct, obstructionBottomRefArr);
|
||
Filter(duct, obstructionLeftRefArr);
|
||
Filter(duct, obstructionRightRefArr);
|
||
|
||
List<ReferenceWithContext> obstructionRefArr = null;
|
||
// <20><>-><3E><>-><3E><>-><3E><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (obstructionTopRefArr.Count > 0) obstructionRefArr = obstructionTopRefArr; // <20><>
|
||
if (obstructionBottomRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionBottomRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionBottomRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
|
||
if (obstructionRefArr == null)
|
||
{
|
||
if (obstructionLeftRefArr.Count > 0) obstructionRefArr = obstructionLeftRefArr; // <20><>
|
||
if (obstructionRightRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionRightRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionRightRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||
if (obstructionRefArr == null) return;
|
||
if (obstructionRefArr.Count == 0) return;
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ۼ<EFBFBD><DBBC>Ѵ<EFBFBD>.
|
||
obstructionRefArr.Sort(m_detector.CompareReferencesWithContext);
|
||
List<Section> sections = Section.BuildSections(obstructionRefArr, ductLine.Direction);
|
||
|
||
List<Section> lstSectionTmp = new List<Section>();
|
||
lstSectionTmp.AddRange(sections);
|
||
// <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>-><3E><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Section<6F><6E> <20><EFBFBD><DFBB><EFBFBD> <20><><EFBFBD> <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (sections.Count > 1)
|
||
{
|
||
while (lstSectionTmp.Count > 0)
|
||
{
|
||
Section section1 = lstSectionTmp[0];
|
||
lstSectionTmp.RemoveAt(0);
|
||
var intResult1 = ductLine.Project(KDCS.Utils.Util.Midpoint(section1.Start, section1.End));
|
||
foreach (Section section2 in lstSectionTmp)
|
||
{
|
||
var intResult2 = ductLine.Project(KDCS.Utils.Util.Midpoint(section2.Start, section2.End));
|
||
if (intResult2 != null)
|
||
{
|
||
if (intResult1.XYZPoint.DistanceTo(intResult2.XYZPoint) < halfHeight)
|
||
{
|
||
sections.Remove(section2);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>ʹ<EFBFBD> ª<><C2AA> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
double width = GetDuctWidth(duct);
|
||
for (int i = sections.Count - 2; i >= 0; i--)
|
||
{
|
||
Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start;
|
||
if (detal.GetLength() < width * 3)
|
||
{
|
||
sections[i].Refs.AddRange(sections[i + 1].Refs);
|
||
sections.RemoveAt(i + 1);
|
||
}
|
||
}
|
||
|
||
// <20><>ֹ<EFBFBD><D6B9><EFBFBD> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20>ذ<EFBFBD>.
|
||
foreach (Section sec in sections)
|
||
{
|
||
Resolve(duct, sec);
|
||
}
|
||
|
||
|
||
|
||
|
||
// <20><>Ʈ <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
|
||
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, duct.DuctType.Id, levelId, start, end);
|
||
|
||
// Copy pipe's parameters values to tmpPipe.
|
||
CopyParameters(duct, 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(duct, ductLine.GetEndPoint(0));
|
||
Connector endConn = FindConnectedTo(duct, ductLine.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, duct.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, duct.DuctType.Id, levelId, sections[0].Start1, ductLine.GetEndPoint(0));
|
||
}
|
||
|
||
// Copy parameters from pipe to startPipe.
|
||
CopyParameters(duct, startDuct);
|
||
|
||
// starDuct<63><74> ù <20><>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
Connector connStart1 = FindConnector(startDuct, sections[0].Start1);
|
||
Connector connStart2 = FindConnector(sections[0].Ducts[0], sections[0].Start1);
|
||
FamilyInstance fii = null;
|
||
if (connStart1 != null && connStart2 != null)
|
||
{
|
||
try
|
||
{
|
||
fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2);
|
||
}
|
||
catch (Exception ex) { string strmsg = ex.Message; }
|
||
}
|
||
|
||
Duct endDuct = null;
|
||
int count = sections.Count;
|
||
if (null != endConn)
|
||
{
|
||
// Create a pipe between pipe's end connector and pipe's end section.
|
||
endDuct = Duct.Create(m_rvtDoc, duct.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, duct.DuctType.Id, levelId, sections[count - 1].End1, ductLine.GetEndPoint(1));
|
||
}
|
||
|
||
// Copy parameters from pipe to endPipe.
|
||
CopyParameters(duct, endDuct);
|
||
|
||
// endDuct<63><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
Connector connEnd1 = FindConnector(endDuct, sections[count - 1].End1);
|
||
Connector 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; }
|
||
}
|
||
|
||
|
||
|
||
|
||
// <20>浹 ȸ<><C8B8> <20><> <20><>Ʈ <20><><EFBFBD><EFBFBD>
|
||
m_rvtDoc.Delete(duct.Id);
|
||
}
|
||
|
||
private void Bend(Duct duct, Pipe obstruction)
|
||
{
|
||
// duct.LookupParameter(string name)
|
||
var paramLevel = duct.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
|
||
var levelId = paramLevel.AsElementId();
|
||
var systemTypeId = m_ductSystemType.Id;
|
||
// <20><>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
var halfWidth = GetDuctWidth(duct) * 0.5;
|
||
var halfHeight = GetDuctHeight(duct) * 0.5;
|
||
|
||
// <20><>Ʈ <20>߽ɼ<DFBD><C9BC><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
|
||
Line ductLine = (duct.Location as LocationCurve).Curve as Line;
|
||
|
||
|
||
Autodesk.Revit.DB.XYZ startPt = ductLine.GetEndPoint(0);
|
||
Autodesk.Revit.DB.XYZ endPt = ductLine.GetEndPoint(1);
|
||
|
||
Autodesk.Revit.DB.XYZ axisZ = (endPt - startPt).Normalize();
|
||
double ductLength = startPt.DistanceTo(endPt);
|
||
|
||
XYZ axisX = new XYZ();
|
||
XYZ axisY = new XYZ();
|
||
|
||
|
||
KDCS.Utils.Util.AxesXY(axisZ, ref axisX, ref axisY);
|
||
|
||
|
||
XYZ orgR = startPt + axisX * halfWidth;
|
||
XYZ orgL = startPt - axisX * halfWidth;
|
||
XYZ orgT = startPt + axisY * halfHeight;
|
||
XYZ orgB = startPt - axisY * halfHeight;
|
||
|
||
// <20>浹 Ȯ<>μ<EFBFBD>
|
||
Line checkLeftLine = Line.CreateBound(orgL, orgL + axisZ * ductLength);
|
||
Line checkRightLine = Line.CreateBound(orgR, orgR + axisZ * ductLength);
|
||
Line checkTopLine = Line.CreateBound(orgT, orgT + axisZ * ductLength);
|
||
Line checkBottomLine = Line.CreateBound(orgB, orgB + axisZ * ductLength);
|
||
|
||
|
||
|
||
// <20><>Ʈ<EFBFBD><C6AE> <20>߽ɼ<DFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>)<29><> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
List<ReferenceWithContext> obstructionTopRefArr = m_detector.Obstructions(checkTopLine);
|
||
List<ReferenceWithContext> obstructionBottomRefArr = m_detector.Obstructions(checkBottomLine);
|
||
List<ReferenceWithContext> obstructionLeftRefArr = m_detector.Obstructions(checkLeftLine);
|
||
List<ReferenceWithContext> obstructionRightRefArr = m_detector.Obstructions(checkRightLine);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>浹<EFBFBD><E6B5B9>) <20><> <20><>Ʈ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
// duct: <20><> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>ܽ<EFBFBD>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
Filter(duct, obstructionTopRefArr);
|
||
Filter(duct, obstructionBottomRefArr);
|
||
Filter(duct, obstructionLeftRefArr);
|
||
Filter(duct, obstructionRightRefArr);
|
||
|
||
List<ReferenceWithContext> obstructionRefArr = null;
|
||
// <20><>-><3E><>-><3E><>-><3E><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (obstructionTopRefArr.Count > 0) obstructionRefArr = obstructionTopRefArr; // <20><>
|
||
if (obstructionBottomRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionBottomRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionBottomRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
|
||
if (obstructionRefArr == null)
|
||
{
|
||
if (obstructionLeftRefArr.Count > 0) obstructionRefArr = obstructionLeftRefArr; // <20><>
|
||
if (obstructionRightRefArr.Count > 0)
|
||
{
|
||
if (obstructionRefArr == null) obstructionRefArr = obstructionRightRefArr; // <20><>
|
||
else obstructionRefArr.AddRange(obstructionRightRefArr); // <20><>,<2C><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||
if (obstructionRefArr == null) return;
|
||
if (obstructionRefArr.Count == 0) return;
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ۼ<EFBFBD><DBBC>Ѵ<EFBFBD>.
|
||
obstructionRefArr.Sort(m_detector.CompareReferencesWithContext);
|
||
List<Section> sections = Section.BuildSections(obstructionRefArr, ductLine.Direction);
|
||
|
||
List<Section> lstSectionTmp = new List<Section>();
|
||
lstSectionTmp.AddRange(sections);
|
||
// <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>-><3E><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Section<6F><6E> <20><EFBFBD><DFBB><EFBFBD> <20><><EFBFBD> <20>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (sections.Count > 1)
|
||
{
|
||
while (lstSectionTmp.Count > 0)
|
||
{
|
||
Section section1 = lstSectionTmp[0];
|
||
lstSectionTmp.RemoveAt(0);
|
||
var intResult1 = ductLine.Project(KDCS.Utils.Util.Midpoint(section1.Start, section1.End));
|
||
foreach (Section section2 in lstSectionTmp)
|
||
{
|
||
var intResult2 = ductLine.Project(KDCS.Utils.Util.Midpoint(section2.Start, section2.End));
|
||
if (intResult2 != null)
|
||
{
|
||
if (intResult1.XYZPoint.DistanceTo(intResult2.XYZPoint) < halfHeight)
|
||
{
|
||
sections.Remove(section2);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>ʹ<EFBFBD> ª<><C2AA> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
double width = GetDuctWidth(duct);
|
||
for (int i = sections.Count - 2; i >= 0; i--)
|
||
{
|
||
Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start;
|
||
if (detal.GetLength() < width * 3)
|
||
{
|
||
sections[i].Refs.AddRange(sections[i + 1].Refs);
|
||
sections.RemoveAt(i + 1);
|
||
}
|
||
}
|
||
|
||
// <20><>ֹ<EFBFBD><D6B9><EFBFBD> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20>ذ<EFBFBD>.
|
||
foreach (Section sec in sections)
|
||
{
|
||
Resolve(duct, sec);
|
||
}
|
||
|
||
|
||
|
||
|
||
// <20><>Ʈ <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
|
||
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, duct.DuctType.Id, levelId, start, end);
|
||
|
||
// Copy pipe's parameters values to tmpPipe.
|
||
CopyParameters(duct, 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(duct, ductLine.GetEndPoint(0));
|
||
Connector endConn = FindConnectedTo(duct, ductLine.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, duct.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, duct.DuctType.Id, levelId, sections[0].Start1, ductLine.GetEndPoint(0));
|
||
}
|
||
|
||
// Copy parameters from pipe to startPipe.
|
||
CopyParameters(duct, startDuct);
|
||
|
||
// starDuct<63><74> ù <20><>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
Connector connStart1 = FindConnector(startDuct, sections[0].Start1);
|
||
Connector connStart2 = FindConnector(sections[0].Ducts[0], sections[0].Start1);
|
||
FamilyInstance fii = null;
|
||
if (connStart1 != null && connStart2 != null)
|
||
{
|
||
try
|
||
{
|
||
fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2);
|
||
}
|
||
catch (Exception ex) { string strmsg = ex.Message; }
|
||
}
|
||
|
||
Duct endDuct = null;
|
||
int count = sections.Count;
|
||
if (null != endConn)
|
||
{
|
||
// Create a pipe between pipe's end connector and pipe's end section.
|
||
endDuct = Duct.Create(m_rvtDoc, duct.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, duct.DuctType.Id, levelId, sections[count - 1].End1, ductLine.GetEndPoint(1));
|
||
}
|
||
|
||
// Copy parameters from pipe to endPipe.
|
||
CopyParameters(duct, endDuct);
|
||
|
||
// endDuct<63><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
Connector connEnd1 = FindConnector(endDuct, sections[count - 1].End1);
|
||
Connector 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; }
|
||
}
|
||
|
||
|
||
|
||
|
||
// <20>浹 ȸ<><C8B8> <20><> <20><>Ʈ <20><><EFBFBD><EFBFBD>
|
||
m_rvtDoc.Delete(duct.Id);
|
||
}
|
||
/// <summary>
|
||
/// 주어진 덕트가 충돌요소를 회피유형과 여유공간 높이에 따라 회피하도록 한다.
|
||
/// </summary>
|
||
/// <param name="duct">회피요소</param>
|
||
/// <param name="eObstruction">충돌요소</param>
|
||
private void Run(Duct duct, Element eObstruction)
|
||
{
|
||
if (eObstruction.GetType() == typeof(Duct))
|
||
{
|
||
Bend(duct, eObstruction as Duct);
|
||
}else if (eObstruction.GetType() == typeof(Pipe))
|
||
{
|
||
Bend(duct, eObstruction as Pipe);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <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);
|
||
|
||
// <20>־<EFBFBD><D6BE><EFBFBD> <20><>Ʈ <20>ڽ<EFBFBD><DABD><EFBFBD> <20>ƴ<EFBFBD> <20><>Ʈ,<2C><> <20><> <20>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if (curElem.Id == duct.Id ||
|
||
(!(curElem is Duct) && curElem.Category.Id.IntegerValue != (int)BuiltInCategory.OST_StructuralFraming))
|
||
{
|
||
refs.RemoveAt(i);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// This method will find out a route to avoid the obstruction.
|
||
/// </summary>
|
||
/// <param name="pipe">Pipe to resolve</param>
|
||
/// <param name="section">Pipe's one obstruction</param>
|
||
/// <returns>A route which can avoid the obstruction</returns>
|
||
private Line FindRoute(Pipe pipe, Section section)
|
||
{
|
||
// Perpendicular direction minimal length.
|
||
double minLength = pipe.Diameter * 2;
|
||
|
||
// Parallel direction jump step.
|
||
double jumpStep = pipe.Diameter;
|
||
|
||
// Calculate the directions in which to find the solution.
|
||
List<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
|
||
Autodesk.Revit.DB.XYZ crossDir = null;
|
||
foreach (ReferenceWithContext gref in section.Refs)
|
||
{
|
||
Element elem = m_rvtDoc.GetElement(gref.GetReference());
|
||
Line locationLine = (elem.Location as LocationCurve).Curve as Line;
|
||
Autodesk.Revit.DB.XYZ refDir = locationLine.GetEndPoint(1) - locationLine.GetEndPoint(0);
|
||
refDir = refDir.Normalize();
|
||
if (refDir.IsAlmostEqualTo(section.CenterLineDirection) || refDir.IsAlmostEqualTo(-section.CenterLineDirection))
|
||
{
|
||
continue;
|
||
}
|
||
crossDir = refDir.CrossProduct(section.CenterLineDirection);
|
||
dirs.Add(crossDir.Normalize());
|
||
break;
|
||
}
|
||
|
||
// When all the obstruction are parallel with the centerline of the pipe,
|
||
// We can't calculate the direction from the vector.Cross method.
|
||
if (dirs.Count == 0)
|
||
{
|
||
// Calculate perpendicular directions with dir in four directions.
|
||
List<Autodesk.Revit.DB.XYZ> perDirs = PerpendicularDirs(section.CenterLineDirection, 4);
|
||
dirs.Add(perDirs[0]);
|
||
dirs.Add(perDirs[1]);
|
||
}
|
||
|
||
Line foundLine = null;
|
||
while (null == foundLine)
|
||
{
|
||
// Extend the section interval by jumpStep.
|
||
section.Inflate(0, jumpStep);
|
||
section.Inflate(1, jumpStep);
|
||
|
||
// Find solution in the given directions.
|
||
for (int i = 0; null == foundLine && i < dirs.Count; i++)
|
||
{
|
||
// Calculate the intersections.
|
||
List<ReferenceWithContext> obs1 = m_detector.Obstructions(section.Start, dirs[i]);
|
||
List<ReferenceWithContext> obs2 = m_detector.Obstructions(section.End, dirs[i]);
|
||
|
||
// Filter out the intersection result.
|
||
Filter(pipe, obs1);
|
||
Filter(pipe, obs2);
|
||
|
||
// Find out the minimal intersections in two opposite direction.
|
||
ReferenceWithContext[] mins1 = GetClosestSectionsToOrigin(obs1);
|
||
ReferenceWithContext[] mins2 = GetClosestSectionsToOrigin(obs2);
|
||
|
||
// Find solution in the given direction and its opposite direction.
|
||
for (int j = 0; null == foundLine && j < 2; j++)
|
||
{
|
||
if (mins1[j] != null && Math.Abs(mins1[j].Proximity) < minLength ||
|
||
mins2[j] != null && Math.Abs(mins2[j].Proximity) < minLength)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
// Calculate the maximal height that the parallel line can be reached.
|
||
double maxHeight = 0;
|
||
if (mins1[j] != null && mins2[j] != null)
|
||
{
|
||
maxHeight = Math.Min(Math.Abs(mins1[j].Proximity), Math.Abs(mins2[j].Proximity));
|
||
}
|
||
else if (mins1[j] != null)
|
||
{
|
||
maxHeight = Math.Abs(mins1[j].Proximity);
|
||
}
|
||
else if (mins2[j] != null)
|
||
{
|
||
maxHeight = Math.Abs(mins2[j].Proximity);
|
||
}
|
||
|
||
|
||
if (maxHeight < jumpStep * 3) maxHeight = jumpStep * 3;
|
||
Autodesk.Revit.DB.XYZ dir = (j == 1) ? dirs[i] : -dirs[i];
|
||
|
||
// Calculate the parallel line which can avoid obstructions.
|
||
foundLine = FindParallelLine(pipe, section, dir, maxHeight);
|
||
}
|
||
}
|
||
}
|
||
return foundLine;
|
||
}
|
||
|
||
/// <summary>
|
||
/// This method will find out a route to avoid the obstruction.
|
||
/// </summary>
|
||
/// <param name="pipe">Pipe to resolve</param>
|
||
/// <param name="section">Pipe's one obstruction</param>
|
||
/// <returns><3E><>ֹ<EFBFBD><D6B9><EFBFBD> <20><><EFBFBD>Ҽ<EFBFBD> <20>ִ<EFBFBD> <20><>Ʈ <20>߽ɼ<DFBD><C9BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>θ<EFBFBD> ã<>´<EFBFBD>.</returns>
|
||
private Line FindRoute(Duct duct, Section section)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ּ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
double minLength = GetDuctWidth(duct);
|
||
|
||
// Parallel direction jump step.
|
||
double jumpStep = GetDuctHeight(duct);
|
||
|
||
// <20><><EFBFBD>ع<EFBFBD><D8B9><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
List<Autodesk.Revit.DB.XYZ> dirs = new List<Autodesk.Revit.DB.XYZ>();
|
||
XYZ ptMidSection = KDCS.Utils.Util.Midpoint(section.Start, section.End); // <20><><EFBFBD><EFBFBD> <20>߽<EFBFBD><DFBD><EFBFBD>
|
||
|
||
Line locationLineSelf = (duct.Location as LocationCurve).Curve as Line;
|
||
Autodesk.Revit.DB.XYZ selfDir = locationLineSelf.GetEndPoint(1) - locationLineSelf.GetEndPoint(0);
|
||
Line ublineSelf = Line.CreateUnbound(locationLineSelf.GetEndPoint(0), selfDir);
|
||
|
||
|
||
//Autodesk.Revit.DB.XYZ crossDir = null;
|
||
foreach (ReferenceWithContext gref in section.Refs)
|
||
{
|
||
Element elem = m_rvtDoc.GetElement(gref.GetReference());
|
||
Line locationObstructionLine = (elem.Location as LocationCurve).Curve as Line;
|
||
Autodesk.Revit.DB.XYZ refObstructionDir = locationObstructionLine.GetEndPoint(1) - locationObstructionLine.GetEndPoint(0);
|
||
refObstructionDir.Normalize();
|
||
if (refObstructionDir.IsAlmostEqualTo(section.CenterLineDirection) || refObstructionDir.IsAlmostEqualTo(-section.CenterLineDirection))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
//crossDir = refDir.CrossProduct(section.CenterLineDirection);
|
||
Line ubObstructionLineOther = Line.CreateUnbound(locationObstructionLine.GetEndPoint(0), refObstructionDir);
|
||
var ptOnDuct = ubObstructionLineOther.Project(ptMidSection);
|
||
if (ptOnDuct != null)
|
||
{
|
||
// <20><>ֹ<EFBFBD> <20>߽ɿ<DFBD><C9BF><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߽<EFBFBD><DFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
XYZ v1 = (ptOnDuct.XYZPoint - ptMidSection).Normalize();
|
||
if (v1.GetLength() > 0)
|
||
{
|
||
dirs.Add(v1);
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// <20><><EFBFBD> <20><>ֹ<EFBFBD><D6B9><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20>߽ɼ<DFBD><C9BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> vector.Cross <20>Լ<EFBFBD><D4BC><EFBFBD> <20>̿<EFBFBD><CCBF>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
|
||
if (dirs.Count == 0)
|
||
{
|
||
// Calculate perpendicular directions with dir in four directions.
|
||
List<Autodesk.Revit.DB.XYZ> perDirs = PerpendicularDirs(section.CenterLineDirection, 4);
|
||
dirs.Add(perDirs[0]);
|
||
dirs.Add(perDirs[1]);
|
||
}
|
||
|
||
Line foundLine = null;
|
||
while (null == foundLine)
|
||
{
|
||
// jumpStep <20><>ŭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>.
|
||
section.Inflate(0, jumpStep);
|
||
section.Inflate(1, jumpStep);
|
||
|
||
// <20>־<EFBFBD><D6BE><EFBFBD> <20><><EFBFBD><EFBFBD><E2BFA1> <20>ذ<EFBFBD>å<EFBFBD><C3A5> ã<>´<EFBFBD>.
|
||
for (int i = 0; null == foundLine && i < dirs.Count; i++)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
|
||
List<ReferenceWithContext> obs1 = m_detector.Obstructions(section.Start, dirs[i]);
|
||
List<ReferenceWithContext> obs2 = m_detector.Obstructions(section.End, dirs[i]);
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڱ<EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD> <20>Ǵ<EFBFBD> <20><>Ʈ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20>ƴ<EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
Filter(duct, obs1);
|
||
Filter(duct, obs2);
|
||
|
||
|
||
// <20>ΰ<EFBFBD><CEB0><EFBFBD> <20>ݴ<EFBFBD> <20><><EFBFBD><EFBFBD><E2BFA1> <20>ּ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<>´<EFBFBD>.
|
||
ReferenceWithContext[] mins1 = GetClosestSectionsToOrigin(obs1);
|
||
ReferenceWithContext[] mins2 = GetClosestSectionsToOrigin(obs2);
|
||
|
||
// <20>־<EFBFBD><D6BE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20>ݴ<EFBFBD> <20><><EFBFBD><EFBFBD><E2BFA1> <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD> ã<>´<EFBFBD>.
|
||
for (int j = 0; null == foundLine && j < 2; j++)
|
||
{
|
||
if (mins1[j] != null && Math.Abs(mins1[j].Proximity) < minLength ||
|
||
mins2[j] != null && Math.Abs(mins2[j].Proximity) < minLength)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
// <20><><EFBFBD>༱<EFBFBD><E0BCB1> <20><><EFBFBD><EFBFBD> <20><> <20><> <20>ִ<EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
double maxHeight = 0d;
|
||
if (mins1[j] != null && mins2[j] != null)
|
||
{
|
||
maxHeight = Math.Max(Math.Abs(mins1[j].Proximity), Math.Abs(mins2[j].Proximity));
|
||
}
|
||
else if (mins1[j] != null)
|
||
{
|
||
maxHeight = Math.Abs(mins1[j].Proximity);
|
||
}
|
||
else if (mins2[j] != null)
|
||
{
|
||
maxHeight = Math.Abs(mins2[j].Proximity);
|
||
}
|
||
|
||
|
||
if (maxHeight < jumpStep*3) maxHeight = jumpStep*3;
|
||
|
||
Autodesk.Revit.DB.XYZ dir = (j == 1) ? dirs[i] : -dirs[i];
|
||
|
||
// <20><>ֹ<EFBFBD><D6B9><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> <20><><EFBFBD>༱ <20><><EFBFBD>
|
||
foundLine = FindParallelLine(duct, section, dir, maxHeight);
|
||
}
|
||
}
|
||
}
|
||
return foundLine;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Find a line Parallel to pipe's centerline to avoid the obstruction.
|
||
/// </summary>
|
||
/// <param name="pipe">Pipe who has obstructions</param>
|
||
/// <param name="section">Pipe's one obstruction</param>
|
||
/// <param name="dir">Offset Direction of the parallel line</param>
|
||
/// <param name="maxLength">Maximum offset distance</param>
|
||
/// <returns>Parallel line which can avoid the obstruction</returns>
|
||
private Line FindParallelLine(Pipe pipe, Section section, Autodesk.Revit.DB.XYZ dir, double maxLength)
|
||
{
|
||
double step = pipe.Diameter;
|
||
double height = 2 * pipe.Diameter;
|
||
while (height <= maxLength)
|
||
{
|
||
Autodesk.Revit.DB.XYZ detal = dir * height;
|
||
Line line = Line.CreateBound(section.Start + detal, section.End + detal);
|
||
List<ReferenceWithContext> refs = m_detector.Obstructions(line);
|
||
Filter(pipe, refs);
|
||
|
||
if (refs.Count == 0)
|
||
{
|
||
return line;
|
||
}
|
||
height += step;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
|
||
private Line FindParallelLine(Duct duct, Section section, Autodesk.Revit.DB.XYZ dir, double maxLength)
|
||
{
|
||
double step = duct.Width;
|
||
double height = 2 * duct.Height;
|
||
while (height <= maxLength)
|
||
{
|
||
Autodesk.Revit.DB.XYZ detal = dir * height;
|
||
Line line = Line.CreateBound(section.Start + detal, section.End + detal);
|
||
List<ReferenceWithContext> refs = m_detector.Obstructions(line);
|
||
Filter(duct, refs);
|
||
|
||
if (refs.Count == 0)
|
||
{
|
||
return line;
|
||
}
|
||
height += step;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/// <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>
|
||
/// Resolve one obstruction of Pipe.
|
||
/// </summary>
|
||
/// <param name="pipe">Pipe to resolve</param>
|
||
/// <param name="section">One pipe's obstruction</param>
|
||
private void Resolve(Pipe pipe, Section section)
|
||
{
|
||
|
||
// Find out a parallel line of pipe centerline, which can avoid the obstruction.
|
||
Line offset = FindRoute(pipe, section);
|
||
XYZ dir = offset.Direction;
|
||
|
||
// <20>־<EFBFBD><D6BE><EFBFBD> <20><><EFBFBD>ǿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
||
Line pipeLine = (pipe.Location as LocationCurve).Curve as Line;
|
||
XYZ sectionStart = pipeLine.Project(section.Start).XYZPoint;
|
||
XYZ sectionEnd = pipeLine.Project(section.End).XYZPoint;
|
||
Line sectionLine = Line.CreateBound(sectionStart, sectionEnd);
|
||
|
||
|
||
double x_offset = 0;
|
||
XYZ ptStart = sectionLine.GetEndPoint(0);
|
||
XYZ ptEnd = sectionLine.GetEndPoint(1);
|
||
if (x_offset > 0)
|
||
{
|
||
ptStart = ptStart - dir * x_offset;
|
||
ptEnd = ptEnd + dir * x_offset;
|
||
}
|
||
section.Start1 = ptStart;
|
||
section.End1 = ptEnd;
|
||
// Construct two side lines, which can avoid the obstruction too.
|
||
Line side1 = Line.CreateBound(sectionLine.GetEndPoint(0), offset.GetEndPoint(0));
|
||
Line side2 = Line.CreateBound(offset.GetEndPoint(1), sectionLine.GetEndPoint(1));
|
||
|
||
//
|
||
// 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;
|
||
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);
|
||
|
||
// 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>
|
||
/// <20><>Ʈ<EFBFBD><C6AE> <20><>ֹ<EFBFBD><D6B9>κ<EFBFBD><CEBA><EFBFBD> ȸ<><C8B8><EFBFBD>Ѵ<EFBFBD>.
|
||
/// </summary>
|
||
/// <param name="pipe">ȸ<><C8B8><EFBFBD><EFBFBD> <20><>Ʈ</param>
|
||
/// <param name="section"><3E><>Ʈ <20>ϳ<EFBFBD><CFB3><EFBFBD> <20><>ֹ<EFBFBD></param>
|
||
private void Resolve(Duct duct, Section section)
|
||
{
|
||
// <20><>ֹ<EFBFBD><D6B9><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> <20><>Ʈ <20>߽ɼ<DFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>༱<EFBFBD><E0BCB1> <20><><EFBFBD>Ѵ<EFBFBD>.
|
||
Line offset = FindRoute(duct, section);
|
||
|
||
var ductHeight = GetDuctHeight(duct);
|
||
var section_len = section.Start.DistanceTo(section.End);
|
||
if (section_len < ductHeight*2.5)
|
||
{
|
||
section.Inflate(0, ductHeight * 1.5);
|
||
section.Inflate(1, ductHeight * 1.5);
|
||
}
|
||
|
||
// <20>־<EFBFBD><D6BE><EFBFBD> <20><><EFBFBD>ǿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
||
Line ductLine = (duct.Location as LocationCurve).Curve as Line;
|
||
XYZ sectionStart = ductLine.Project(section.Start).XYZPoint;
|
||
XYZ sectionEnd = ductLine.Project(section.End).XYZPoint;
|
||
Line sectionLine = Line.CreateBound(sectionStart, sectionEnd);
|
||
XYZ dir = (offset.GetEndPoint(1) - offset.GetEndPoint(0)).Normalize();
|
||
|
||
XYZ xa = new XYZ();
|
||
XYZ ya = new XYZ();
|
||
KDCS.Utils.Util.AxesXY(dir, ref xa, ref ya);
|
||
|
||
Plane geometryPlane = Plane.CreateByNormalAndOrigin(ya, offset.GetEndPoint(0));
|
||
SketchPlane plane = SketchPlane.Create(m_rvtDoc, geometryPlane);
|
||
|
||
if (plane != null)
|
||
{
|
||
m_rvtDoc.Create.NewModelCurve(Line.CreateBound(offset.Origin, offset.Origin + offset.Direction * 20), plane);
|
||
}
|
||
|
||
|
||
|
||
|
||
double x_offset = sectionLine.GetEndPoint(0).DistanceTo(offset.GetEndPoint(0));
|
||
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 = m_ductSystemType.Id;
|
||
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);
|
||
|
||
// 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>
|
||
/// 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);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
/// <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;
|
||
}
|
||
|
||
|
||
|
||
/// <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;
|
||
}
|
||
}
|
||
}
|