Client/Desktop/KMBIM3.0/KMBIM3.0_소스/Cmd/PipeConnection/ResolverForPipeConnect.cs

975 lines
32 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using KMBIM.Utils;
using KMBIM.Revit.Tools.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using KDCS.Utils;
namespace KMBIM.Revit.Tools.Cmd.PipeConnection
{
public class ResolverForPipeConnect
{
public enum EnumResolverMode
{
Undef,
RefBaseModelLine,
Prev,
Next,
Run,
Close
}
private UIApplication m_rvtUIApp;
private UIDocument m_rvtUIDoc;
private Document m_rvtDoc;
private Autodesk.Revit.ApplicationServices.Application m_rvtApp;
public Autodesk.Revit.UI.UIDocument uidoc { get; set; }
private int m_inx;
private bool m_bFlexible;
private bool m_bRefFloorBaseLine;
Dictionary<string, List<XYZ>> m_Routes = new Dictionary<string, List<XYZ>>();
List<Pipe> lstCurve = new List<Pipe>();
EnumResolverMode m_ResolverMode;
ElementId systemTypeId = null;
Element m_baseElementOrigin = null;
Element m_baseElement = null;
Element m_targetElement = null;
Connector m_baseConnectorOrigin = null;
Connector m_baseConnector = null;
Connector m_targetConnector = null;
Pipe basePipe = null;
Pipe targetPipe = null;
PipeType pipeType = null;
FlexPipeType flexPipeType = null;
private double m_pipeDiameter;
//private int m_LineStyle = (int)BuiltInCategory.OST_HiddenLines;
private int m_LineStyle = (int)BuiltInCategory.OST_Lines;
public ResolverForPipeConnect(UIApplication uiapp)
{
m_rvtUIApp = uiapp;
m_rvtApp = uiapp.Application;
m_rvtUIDoc = uiapp.ActiveUIDocument;
m_rvtDoc = m_rvtUIDoc.Document;
m_inx = 0;
m_bFlexible = false;
m_bRefFloorBaseLine = false;
}
public void SetRefFloorBaseLine(bool bRefFloorBaseLine)
{
m_bRefFloorBaseLine = bRefFloorBaseLine;
}
public void SetResolverMode(EnumResolverMode mode)
{
m_ResolverMode = mode;
}
public void SetRoute(ref Dictionary<string, List<XYZ>> route)
{
this.m_Routes = route;
m_inx = 0;
}
public void SetPipeDiameter(double dia)
{
m_pipeDiameter = dia;
}
public void SetBaseElementOrigin(Element elm, Connector con)
{
this.m_baseElementOrigin = elm;
this.m_baseConnectorOrigin = con;
Pipe pipe1 = elm as Pipe;
if (pipe1 != null)
{
this.pipeType = pipe1.PipeType;
if (systemTypeId == null)
{
systemTypeId = pipe1.MEPSystem.GetTypeId();
}
}else if(con != null){
if (con.MEPSystem != null)
{
systemTypeId = con.MEPSystem.GetTypeId();
}
}
}
public void SetElement(Element e1, Element e2)
{
this.m_baseElement = e1;
this.m_targetElement = e2;
if (pipeType == null)
{
Pipe pipe1 = e1 as Pipe;
if (pipe1 != null)
{
this.pipeType = pipe1.PipeType;
}
else
{
Pipe pipe2 = e2 as Pipe;
if (pipe2 != null)
{
this.pipeType = pipe2.PipeType;
}
}
}
}
public void SetConnector(Connector c1, Connector c2)
{
this.m_baseConnector = c1;
this.m_targetConnector = c2;
}
public void GetRoute(ref Dictionary<string, List<XYZ>> route)
{
route = this.m_Routes;
}
public int GetIndex()
{
return this.m_Routes.Keys.Count > 0 ? m_inx % this.m_Routes.Keys.Count : m_inx;
}
public void MoveNext()
{
if (m_inx >= (m_Routes.Keys.Count - 1)) m_inx = 0;
else m_inx += 1;
}
public void MovePrevious()
{
if (m_inx > 0)
{
m_inx -= 1;
}
}
public void SetSystemType(ElementId systemtypeid)
{
this.systemTypeId = systemtypeid;
}
public ElementId GetSystemType()
{
return this.systemTypeId;
}
private void DrawRoute()
{
if (this.m_Routes == null) return;
if (this.m_Routes.Count < 1) return;
var levelId = m_baseElement.LevelId;
Pipe pipeBase = m_baseElement as Pipe;
if (pipeBase != null)
{
levelId = pipeBase.ReferenceLevel.Id;
}
if (this.pipeType == null)
{
var pipeTypes = new FilteredElementCollector(m_rvtDoc).OfClass(typeof(PipeType)).ToElements();
if (pipeTypes.Count > 0)
{
pipeType = pipeTypes[pipeTypes.Count - 1] as PipeType;
}
}
var lst = this.m_Routes[(m_inx + 1).ToString()];
if (lst == null) return;
using (Transaction tr = new Transaction(m_rvtDoc, "Create3DModelLine"))
{
tr.Start();
// Line is slightly off axis and may cause inaccuracies.
// (선이 축을 약간 벗어났습니다.부정확새질 수 있습니다.)
// => This is not an error, it is a warning. You can pass warnings but can't pass errors.
FailureHandlingOptions failureHandlingOptions = tr.GetFailureHandlingOptions();
failureHandlingOptions.SetFailuresPreprocessor(new KdcsFailureHandler());
tr.SetFailureHandlingOptions(failureHandlingOptions);
for (int i = 0; i < lst.Count - 1; i++)
{
XYZ p1 = lst[i];
XYZ p2 = lst[i + 1];
var crv = Pipe.CreatePlaceholder(m_rvtDoc, systemTypeId, pipeType.Id, levelId, p1, p2);
if (crv != null) lstCurve.Add(crv);
}
if (lstCurve.Count > 2)
{
for (int i = 0; i < lstCurve.Count - 1; i++)
{
Pipe pipe1 = lstCurve.ElementAt(i);
Pipe pipe2 = lstCurve.ElementAt(i+1);
Connector sc1, ec1, sc2, ec2;
sc1=ec1=sc2=ec2=null;
Util.GetStartEndConnector(pipe1, ref sc1, ref ec1);
Util.GetStartEndConnector(pipe2, ref sc2, ref ec2);
ec1.ConnectTo(sc2);
}
}
tr.Commit();
}
}
public void DeleteCurves()
{
if (lstCurve.Count < 1) return;
using (Transaction tr = new Transaction(m_rvtDoc, "Delete Curves"))
{
tr.Start();
foreach (var crv in lstCurve)
{
m_rvtDoc.Delete(crv.Id);
}
lstCurve.Clear();
tr.Commit();
}
}
public void SetFlexible(bool bFlexible)
{
m_bFlexible = bFlexible;
}
public void Run()
{
try
{
if (this.m_ResolverMode == EnumResolverMode.Prev)
{
DeleteCurves();
m_inx = GetIndex();
DrawRoute();
}
else if (this.m_ResolverMode == EnumResolverMode.Next)
{
DeleteCurves();
m_inx = GetIndex();
DrawRoute();
}
else if(this.m_ResolverMode == EnumResolverMode.Run)
{
basePipe = m_baseElement as Pipe;
targetPipe = m_targetElement as Pipe;
if (this.pipeType == null)
{
var pipeTypes = new FilteredElementCollector(m_rvtDoc).OfClass(typeof(PipeType)).ToElements();
if (pipeTypes.Count > 0)
{
pipeType = pipeTypes[pipeTypes.Count - 1] as PipeType;
}
}
if (this.flexPipeType == null)
{
var pipeTypes = new FilteredElementCollector(m_rvtDoc).OfClass(typeof(FlexPipeType)).ToElements();
if (pipeTypes.Count > 0)
{
flexPipeType = pipeTypes[pipeTypes.Count - 1] as FlexPipeType;
}
}
if (pipeType != null)
{
using (Transaction tr = new Transaction(m_rvtDoc, "CreatePipes"))
{
tr.Start();
CreatePipe(m_rvtDoc, lstCurve);
tr.Commit();
}
}
DeleteCurves();
App.thisApp.m_wfPipeConnector.Close();
}
else if (this.m_ResolverMode == EnumResolverMode.Close)
{
DeleteCurves();
}
m_rvtUIDoc.RefreshActiveView();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
// Clamps value between 0 and 1 and returns value
public static float Clamp01(float value)
{
if (value < 0F)
return 0F;
else if (value > 1F)
return 1F;
else
return value;
}
public static float InverseLerp(float a, float b, float value)
{
if (a != b)
return Clamp01((value - a) / (b - a));
else
return 0.0f;
}
/// <summary>
/// 주어진 arrayToCurve 점들을 이용하여 커브점을 만들어 넘겨준다.
/// </summary>
/// <param name="arrayToCurve">정점 배열</param>
/// <param name="smoothness">보간 수</param>
/// <returns></returns>
public static XYZ[] MakeSmoothCurve(XYZ[] arrayToCurve, float smoothness)
{
List<XYZ> points;
List<XYZ> curvedPoints;
int pointsLength = 0;
int curvedLength = 0;
if (smoothness < 1.0f) smoothness = 1.0f;
pointsLength = arrayToCurve.Length;
curvedLength = (pointsLength * Convert.ToInt16(Math.Round(smoothness))) - 1;
curvedPoints = new List<XYZ>(curvedLength);
float t = 0.0f;
for (int pointInTimeOnCurve = 0; pointInTimeOnCurve < curvedLength + 1; pointInTimeOnCurve++)
{
t = InverseLerp(0, curvedLength, pointInTimeOnCurve);
points = new List<XYZ>(arrayToCurve);
for (int j = pointsLength - 1; j > 0; j--)
{
for (int i = 0; i < j; i++)
{
points[i] = (1 - t) * points[i] + t * points[i + 1];
}
}
curvedPoints.Add(points[0]);
}
return (curvedPoints.ToArray());
}
/// <summary>
/// 파이프 생성
/// </summary>
/// <param name="document"></param>
/// <param name="elementList"></param>
/// <param name="basePipe"></param>
public void CreatePipe(Document document, List<Pipe> curveList)
{
//var paramLevel = m_baseElement.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
var levelId = m_baseElement.LevelId; //.IntegerValue != -1 ? m_baseElement.LevelId : m_targetElement.LevelId;
Pipe pipeBase = m_baseElement as Pipe;
if (pipeBase != null)
{
levelId = pipeBase.ReferenceLevel.Id;
}
if (pipeType == null) return;
List<XYZ> lst = new List<XYZ>();
bool isFirst = true;
foreach (var pip in curveList)
{
LocationCurve locCrv = pip.Location as LocationCurve;
XYZ sp = locCrv.Curve.GetEndPoint(0);
XYZ ep = locCrv.Curve.GetEndPoint(1);
if (isFirst)
{
if (m_baseConnector.Origin.DistanceTo(sp) > m_baseConnector.Origin.DistanceTo(ep))
{
Util.Swap(ref sp, ref ep);
}
lst.Add(sp);
lst.Add(ep);
}
else
{
XYZ pLast = lst.Last();
if(pLast.DistanceTo(sp) > pLast.DistanceTo(ep)) lst.Add(sp);
else lst.Add(ep);
}
isFirst = false;
}
Pipe newPipe = null;
XYZ start = null;
XYZ end = null;
XYZ splitpoint = null;
List<XYZ> lstTmp = new List<XYZ>();
List<XYZ> lstCrv = new List<XYZ>();
if (m_bFlexible && flexPipeType!=null)
{
//var lst = this.m_Routes[(m_inx + 1).ToString()];
if (lst.Count > 2)
{
lstTmp.Add(lst.First());
int dur = lst.Count - 1;
for (int i = 1; i < dur; i++)
{
XYZ fp0 = lst.ElementAt(i-1);
XYZ fp1 = lst.ElementAt(i);
XYZ fp2 = lst.ElementAt(i + 1);
XYZ fpInsm = fp1 + (fp0 - fp1).Normalize() * fp0.DistanceTo(fp1) * 0.5;
XYZ fpIns0 = fp1 + (fp0 - fp1).Normalize() * m_pipeDiameter * 5;
XYZ fpIns1 = fp1 + (fp0 - fp1).Normalize() * m_pipeDiameter * 4;
XYZ fpIns2 = fp1 + (fp0 - fp1).Normalize() * m_pipeDiameter * 3.0;
XYZ fpIns3 = fp1 + (fp2 - fp1).Normalize() * m_pipeDiameter * 3.0;
XYZ fpIns4 = fp1 + (fp2 - fp1).Normalize() * m_pipeDiameter * 4;
XYZ fpIns5 = fp1 + (fp2 - fp1).Normalize() * m_pipeDiameter * 5;
lstCrv.Clear();
lstCrv.Add(fpIns0);
lstCrv.Add(fpIns1);
lstCrv.Add(fpIns2);
lstCrv.Add(fpIns3);
lstCrv.Add(fpIns4);
lstCrv.Add(fpIns5);
var inArr = lstCrv.ToArray();
var arrcrv = MakeSmoothCurve(inArr, 1.5f);
lstTmp.Add(fpInsm);
lstTmp.AddRange(arrcrv);
}
XYZ plp = lst.ElementAt(lst.Count - 2);
XYZ pll = lst.Last();
lstTmp.Add(Util.Midpoint(plp, pll));
lstTmp.Add(lst.Last());
lst = lstTmp.ToList();
}
FlexPipe newFlexPipe = FlexPipe.Create(m_rvtDoc, systemTypeId, flexPipeType.Id, levelId, lst.ToArray());
if (newFlexPipe != null)
{
LocationCurve locCrv = newFlexPipe.Location as LocationCurve;
if (locCrv != null)
{
newFlexPipe.StartTangent = m_baseConnector.CoordinateSystem.BasisZ;
newFlexPipe.EndTangent = m_targetConnector.CoordinateSystem.BasisZ;
}
newFlexPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(m_pipeDiameter);
Connector pipeConnectorFirst = FindConnector(newFlexPipe, m_baseConnector.CoordinateSystem.Origin);
if (pipeConnectorFirst != null)
{
if (Util.IsEqual(m_baseConnector.Radius, pipeConnectorFirst.Radius))
{
pipeConnectorFirst.ConnectTo(m_baseConnector);
}
else
{
try{
m_rvtDoc.Create.NewTransitionFitting(pipeConnectorFirst, m_baseConnector);
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException ex)
{
MessageBox.Show("기준 커넥터 위치에 변환 피팅을 삽입할 수 없습니다.");
}
catch (Exception ex) { }
}
}
Connector pipeConnectorLast = FindConnector(newFlexPipe, m_targetConnector.CoordinateSystem.Origin);
if (Util.IsEqual(m_targetConnector.Radius, pipeConnectorLast.Radius))
{
pipeConnectorLast.ConnectTo(m_targetConnector);
}
else
{
try
{
m_rvtDoc.Create.NewTransitionFitting(pipeConnectorLast, m_targetConnector);
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException ex)
{
MessageBox.Show("대상 커넥터 위치에 변환 피팅을 삽입할 수 없습니다.");
}
catch (Exception ex) { }
}
m_rvtDoc.Regenerate();
}
return;
}
// 경로선
List<Line> lines = new List<Line>();
foreach (Pipe pipe in curveList)
{
Line line = (pipe.Location as LocationCurve).Curve as Line;
lines.Add(line);
}
//PlumbingUtils.ConvertPipePlaceholders(document, lines);
if (basePipe != null)
{
Line crv2 = lines.First();
Line crv1 = (basePipe.Location as LocationCurve).Curve as Line;
if (Util.IsParallel(crv1.Direction, crv2.Direction))
{
XYZ ptBase = m_baseConnector.CoordinateSystem.Origin;
if (crv2.GetEndPoint(0).DistanceTo(ptBase) > crv2.GetEndPoint(1).DistanceTo(ptBase))
Util.SetPipeEnd(basePipe, crv2.GetEndPoint(0));
else
Util.SetPipeEnd(basePipe, crv2.GetEndPoint(1));
lines.RemoveAt(0);
}
}
List<Pipe> pipes = new List<Pipe>();
foreach (Line line in lines)
{
start = line.GetEndPoint(0);
end = line.GetEndPoint(1);
newPipe = Pipe.Create(document, systemTypeId, pipeType.Id, levelId, start, end);
pipes.Add(newPipe);
newPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(m_pipeDiameter);
}
// 파이프 연결
for (int i = 1; i < pipes.Count(); i++)
{
Bend(pipes[i - 1], pipes[i]);
}
document.Regenerate();
if (basePipe != null)
{
var pipeFirst = pipes.First();
Bend(basePipe, pipeFirst);
}
else
{
// 베이스 커넥터와 첫번째 파이프 연결
var pipeFirst = pipes.First();
Connector pipeConnectorFirst = FindConnector(pipeFirst, m_baseConnector.CoordinateSystem.Origin);
if (pipeConnectorFirst != null)
{
if (Util.IsEqual(m_baseConnector.Radius, pipeConnectorFirst.Radius))
{
pipeConnectorFirst.ConnectTo(m_baseConnector);
}
else m_rvtDoc.Create.NewTransitionFitting(pipeConnectorFirst, m_baseConnector);
}
}
var pipeLast = pipes.Last();
if (targetPipe != null)
{
Bend(targetPipe, pipeLast);
}
else
{
Connector pipeConnectorLast = FindConnector(pipeLast, m_targetConnector.CoordinateSystem.Origin);
if (Util.IsEqual(m_targetConnector.Radius, pipeConnectorLast.Radius))
{
pipeConnectorLast.ConnectTo(m_targetConnector);
}
else m_rvtDoc.Create.NewTransitionFitting(pipeConnectorLast, m_targetConnector);
}
}
private XYZ ParallelInters(Line crv1, Line crv2)
{
XYZ itr = null;
double tol = 0.0328084; // ft = 1cm
double min_len = double.MaxValue;
if (crv1.GetEndPoint(0).DistanceTo(crv2.GetEndPoint(0)) < tol)
{
itr = crv1.GetEndPoint(0);
}
if (crv1.GetEndPoint(0).DistanceTo(crv2.GetEndPoint(1)) < tol)
{
itr = crv1.GetEndPoint(0);
}
else if (crv1.GetEndPoint(1).DistanceTo(crv2.GetEndPoint(0)) < tol)
{
itr = crv1.GetEndPoint(1);
}
else if (crv1.GetEndPoint(1).DistanceTo(crv2.GetEndPoint(1)) < tol)
{
itr = crv1.GetEndPoint(1);
}
return itr;
}
/// <summary>
/// 주어진 두개으 파이프를 엘보로 연결한다.
/// </summary>
/// <param name="pipe1"></param>
/// <param name="pipe2"></param>
public void Bend(Pipe pipe1, Pipe pipe2)
{
Autodesk.Revit.DB.Parameter paramLevel = pipe1.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
ElementId levelId = paramLevel.AsElementId();
Line crv1 = (pipe1.Location as LocationCurve).Curve as Line;
Line crv2 = (pipe2.Location as LocationCurve).Curve as Line;
XYZ itr = null;
if(Util.IsParallel(crv1.Direction, crv2.Direction)){
itr = ParallelInters(crv1, crv2);
}
else
{
itr = Util.GetCurvesIntersectionPoint(crv1, crv2);
}
// 2개의 파이프가 서로 만나는 쪽의 커텍터 찾기
Connector connector1 = FindConnector(pipe1, itr);
Connector connector2 = FindConnector(pipe2, itr);
FamilyInstance fii = null;
if (connector1 != null && connector2 != null)
{
double tol = 0.001;
if (Util.IsZero(connector1.CoordinateSystem.BasisZ.CrossProduct(connector2.CoordinateSystem.BasisZ).GetLength(), tol)) // 0.001ft = 0.3048 mm 어느 정도 2개 객체가 수평하면
{
try
{
List<Element> lstElement2BeDeleted = new List<Element>();
Resolver resolver = new Resolver(m_rvtDoc);
resolver.JoinPipeSegment(connector1, ref connector2, ref lstElement2BeDeleted);
if (lstElement2BeDeleted.Count > 0)
{
foreach (var el in lstElement2BeDeleted)
{
m_rvtDoc.Delete(el.Id);
}
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
else
{
try
{
fii = m_rvtDoc.Create.NewElbowFitting(connector1, connector2);
}
catch (ArgumentNullException ex)
{
MessageBox.Show(ex.Message);
}
catch (ArgumentException ex)
{
MessageBox.Show(ex.Message);
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.Message);
}
catch(Exception ex){
MessageBox.Show(ex.Message);
}
}
}
}
/// <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);
}
/// <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.Category.Id.IntegerValue != (int)BuiltInCategory.OST_StructuralFraming))
{
refs.RemoveAt(i);
}
}
}
private Line FindParallelLine(Section section, Autodesk.Revit.DB.XYZ dir, double height)
{
Autodesk.Revit.DB.XYZ detal = dir * height;
Line line = Line.CreateBound(section.Start + detal, section.End + detal);
return line;
}
/// <summary>
/// Find out two References, whose ProximityParameter is negative or positive,
/// And Get the minimal value from all positive reference, and get the maximal value
/// from the negative reference. if there are no such reference, using null instead.
/// </summary>
/// <param name="refs">References</param>
/// <returns>Reference array</returns>
private ReferenceWithContext[] GetClosestSectionsToOrigin(List<ReferenceWithContext> refs)
{
ReferenceWithContext[] mins = new ReferenceWithContext[2];
if (refs.Count == 0)
{
return mins;
}
if (refs[0].Proximity > 0)
{
mins[1] = refs[0];
return mins;
}
for (int i = 0; i < refs.Count - 1; i++)
{
if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0)
{
mins[0] = refs[i];
mins[1] = refs[i + 1];
return mins;
}
}
mins[0] = refs[refs.Count - 1];
return mins;
}
public void MepSystem()
{
Document doc = m_rvtDoc;
FilteredElementCollector systemCollector = new FilteredElementCollector(doc).OfClass(typeof(MEPSystem));
IEnumerable<Element> desirableSystems = systemCollector.ToElements();
foreach (Element elm in desirableSystems)
{
MEPSystem system = elm as MEPSystem;
if (system != null)
{
if (system.GetType() == typeof(Autodesk.Revit.DB.Plumbing.PipingSystem))
{
Autodesk.Revit.DB.Plumbing.PipeSystemType type = (system as Autodesk.Revit.DB.Plumbing.PipingSystem).SystemType;
}
string name = system.Name;
}
}
}
public Pipe CreateNewPipe(Document document, ElementId systemTypeId, ElementId levelId)
{
Pipe pipe = null;
PipeType pipeType = null;
// find a pipe type
var pipeTypes = new FilteredElementCollector(document).OfClass(typeof(PipeType)).ToElements();
if (pipeTypes.Count > 0)
{
pipeType = pipeTypes[pipeTypes.Count - 1] as PipeType;
}
if (pipeType == null) return null;
// create pipe between 2 points
XYZ p1 = new XYZ(0, 0, 0);
XYZ p2 = new XYZ(10, 0, 0);
pipe = Pipe.Create(document, systemTypeId, pipeType.Id, levelId, p1, p2);
return pipe;
}
/// <summary>
/// 주어진 점에서 가장 가까운 연결점을 찾는다.
/// </summary>
/// <param name="pipe"></param>
/// <param name="conXYZ"></param>
/// <returns></returns>
private Connector FindConnector(Pipe pipe, Autodesk.Revit.DB.XYZ conXYZ)
{
ConnectorSet conns = pipe.ConnectorManager.Connectors;
double minDst = double.MaxValue;
Connector closestConnector = null;
foreach (Connector conn in conns)
{
if (conn.Origin.DistanceTo(conXYZ) < minDst)
{
minDst = conn.Origin.DistanceTo(conXYZ);
closestConnector = conn;
}
}
return closestConnector;
}
/// <summary>
/// 주어진 점에서 가장 가까운 연결점을 찾는다.
/// </summary>
/// <param name="pipe"></param>
/// <param name="conXYZ"></param>
/// <returns></returns>
private Connector FindConnector(FlexPipe pipe, Autodesk.Revit.DB.XYZ conXYZ)
{
ConnectorSet conns = pipe.ConnectorManager.Connectors;
double minDst = double.MaxValue;
Connector closestConnector = null;
foreach (Connector conn in conns)
{
if (conn.Origin.DistanceTo(conXYZ) < minDst)
{
minDst = conn.Origin.DistanceTo(conXYZ);
closestConnector = conn;
}
}
return closestConnector;
}
/// <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;
}
}
}