Client/Desktop/KMBIM3.0/KMBIM3.0_23.08.16_수정최종/Cmd/AvoidObstruction/새 폴더/Resolver.cs

1884 lines
76 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//
// (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;
}
}
}