Client/Desktop/KMBIM3.0/23.10.16/Cmd/SprinklerConnect/Sprinkler_Downward_Manual.cs

778 lines
38 KiB
C#

using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
using Autodesk.Revit.UI.Selection;
//using SpinKler;
using Autodesk.Revit.DB.Plumbing;
using KDCS.Utils;
using Autodesk.Revit.DB.Structure;
using KMBIM.Revit.Tools.Cmd.SprinklerConnect;
using KMBIM.Revit.Tools;
namespace KMBIM
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
class Sprinkler_Downward_Manual : IExternalCommand
{
UIApplication uiapp;
UIDocument uidoc;
Autodesk.Revit.DB.Document doc;
Autodesk.Revit.Creation.Application creApp;
Autodesk.Revit.Creation.Document creDoc;
Autodesk.Revit.UI.ExternalCommandData m_commandData;
double m_MainHgt = 0, m_BranchHgt = 0, m_HeadOffset = 0, m_ConnectDist, m_CapDist = 0, m_Tol = 0, m_TReducerDist = 0;
int m_Mode = 0;
Connector mainSpCon = null, mainEpCon = null;
XYZ MainVec = null;
//이격 방향
XYZ SeparationVec = null;
List<ObjSprinKler> lst_objSprinkler = new List<ObjSprinKler>();
ObjSprinKler FirstObj = new ObjSprinKler();
SprinKler_Function Spkr_Func = new SprinKler_Function();
List<ElementId> RemoveElemIdLst = new List<ElementId>();
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
m_commandData = commandData;
uiapp = commandData.Application;
uidoc = uiapp.ActiveUIDocument;
doc = uidoc.Document;
creApp = uiapp.Application.Create;
creDoc = doc.Create;
try
{
//메인 파이프
Reference pickMainRef = commandData.Application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, new SelectionMainPipe(), "기준 교차배관 선택 : ");
if (pickMainRef == null) return Result.Succeeded;
Element MainElem = doc.GetElement(pickMainRef.ElementId) as Element;
Pipe mainPipe = MainElem as Pipe;
Line mainLine = (mainPipe.Location as LocationCurve).Curve as Line;
XYZ DirectVec = null, ReverseVec = null;
DirectVec = (mainLine.GetEndPoint(1) - mainLine.GetEndPoint(0)).Normalize();
ReverseVec = (mainLine.GetEndPoint(0) - mainLine.GetEndPoint(1)).Normalize();
XYZ SpExtension = Util.Polar(mainLine.GetEndPoint(0), ReverseVec, 1000);
XYZ EpExtension = Util.Polar(mainLine.GetEndPoint(1), DirectVec, 1000);
Line NewMainLine = Line.CreateBound(SpExtension, EpExtension);
Util.GetStartEndConnector(mainPipe, ref mainSpCon, ref mainEpCon);//메인 시작 끝 커넥터
//m_MainHgt = NewMainLine.GetEndPoint(0).Z;//메인 높이
m_MainHgt = mainPipe.LevelOffset;//메인 파이프 오프셋 값
//현재 레벨의 높이 구하기.(active Level을 구하면 3D에서 작도가 안됌.)
double GenLevElevation = Unit.FeetToMM(NewMainLine.GetEndPoint(0).Z - mainPipe.LevelOffset);
MainVec = (mainEpCon.Origin - mainSpCon.Origin).Normalize();//메인 시작-끝 벡터
//처음 관경25는 헤드쪽때문에 기입
List<double> headDiaLst = new List<double>();
headDiaLst.Add(25); headDiaLst.Add(25); headDiaLst.Add(25); headDiaLst.Add(32); headDiaLst.Add(40); headDiaLst.Add(40);
headDiaLst.Add(50); headDiaLst.Add(50); headDiaLst.Add(50); headDiaLst.Add(50); headDiaLst.Add(50); headDiaLst.Add(65);
headDiaLst.Add(65); headDiaLst.Add(65); headDiaLst.Add(65); headDiaLst.Add(65); headDiaLst.Add(65); headDiaLst.Add(65);
//대화상자
Form_Downward dlg = new Form_Downward();
dlg.MainHeight = Math.Round(Unit.FeetToMM(m_MainHgt), 3);
dlg.BranchHeight = Math.Round(Unit.FeetToMM(m_MainHgt), 3) + 300;
dlg.HeaderOffset = 150;
dlg.ConnectDist = 150;
dlg.CapDist = 100;
dlg.SpkrTol = 5;
dlg.TeeReducerDist = 100;
//플렉시블 파이프 유형 로드 유무
ICollection<Element> FlexPipeTypeLst = new FilteredElementCollector(doc).OfClass(typeof(FlexPipeType)).ToElements();
if (FlexPipeTypeLst.Count() > 0) dlg.m_FlexPipeLoad = true;
dlg.ShowDialog();
if (dlg.DialogResult == DialogResult.Cancel) return Result.Cancelled;
//대화상자 값 가져오기
m_MainHgt = dlg.MainHeight;
m_BranchHgt = dlg.BranchHeight;
m_HeadOffset = dlg.HeaderOffset;
m_ConnectDist = dlg.ConnectDist;
m_CapDist = dlg.CapDist;
m_Mode = dlg.m_RadIdx;
m_Tol = dlg.SpkrTol;
m_TReducerDist = dlg.TeeReducerDist;
//교차배관,가지배관 높이 재지정
m_MainHgt = m_MainHgt + GenLevElevation;
m_BranchHgt = m_BranchHgt + GenLevElevation;
//SprinKler_Function 변수값 넘겨주기
Spkr_Func.doc = uidoc.Document;
Spkr_Func.creDoc = doc.Create;
Spkr_Func.uiapp = commandData.Application;
Spkr_Func.MainPipeTypeId = mainPipe.PipeType.Id;
Spkr_Func.MainSystemTypeId = mainPipe.MEPSystem.GetTypeId();
Spkr_Func.MainLevelId = mainPipe.ReferenceLevel.Id;
Element pickFirstElem = null;
while (true)
{
//첫번째 헤드
Reference pickFirstRef = commandData.Application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, new SelectionFilter(), "스프링클러 헤드 선택 : ");
if (pickFirstRef == null) return Result.Succeeded;
pickFirstElem = doc.GetElement(pickFirstRef.ElementId);
List<Connector> firstHeadCon = Util.GetElementConnectors(pickFirstElem);
if (firstHeadCon == null)
{
MessageBox.Show("스프링클러에 커넥터가 존재하지 않습니다.", "오류");
continue;
}
else
{
Connector HeadCon = firstHeadCon.First();
if (HeadCon.Origin.Z > Unit.MMToFeet(m_BranchHgt + m_HeadOffset))
{
MessageBox.Show("스프링클러에 커넥터의 높이가 (가지배관 높이 + 헤드 간격 띄우기) 값보다 높습니다.", "오류");
continue;
}
else
break;
}
}//while end
//이격 거리 방향 지정
XYZ SeparatePt = commandData.Application.ActiveUIDocument.Selection.PickPoint("가지배관 방향 지정 : ");
if (SeparatePt == null) return Result.Succeeded;
if (pickFirstElem is FamilyInstance)
{
FamilyInstance firstHeadfam = pickFirstElem as FamilyInstance;
List<Connector> ConLst = Util.GetElementConnectors(firstHeadfam);
//헤드 커넥터
Connector HeadCon = ConLst.First();
//메인관-커넥터 가까운 점
IntersectionResult interRes = NewMainLine.Project(HeadCon.Origin);
XYZ interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, HeadCon.Origin.Z);
//첫번째 헤드 정보
FirstObj.HeadCon = HeadCon;
FirstObj.m_Headpt = HeadCon.Origin;
FirstObj.m_SpID = firstHeadfam.Id;
XYZ InterZ0 = new XYZ(interPt.X, interPt.Y, 0);
XYZ HeadZ0 = new XYZ(FirstObj.m_Headpt.X, FirstObj.m_Headpt.Y, 0);
XYZ SeparatePtZ0 = new XYZ(SeparatePt.X, SeparatePt.Y, 0);
SeparationVec = (InterZ0 - HeadZ0).Normalize();
bool isRight = Util.isRightPoint(SeparatePtZ0, HeadZ0, InterZ0);
if (isRight == true)
SeparationVec = Util.RotateVector(SeparationVec, Util.DTR(-90.0));
else
SeparationVec = Util.RotateVector(SeparationVec, Util.DTR(90.0));
XYZ SepaPt = Util.Polar(FirstObj.m_Headpt, SeparationVec, Unit.MMToFeet(m_ConnectDist));
//이격점에서 메인 교차점
interRes = NewMainLine.Project(SepaPt);
interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, SepaPt.Z);
FirstObj.m_InterPt = interPt;
FirstObj.SeparateionPt = SepaPt;
lst_objSprinkler.Add(FirstObj);
}
//Util.Pyosi(doc, FirstObj.SeparateionPt, 1);
//MessageBox.Show("1");
//Util.Pyosi(doc, FirstObj.m_InterPt, 1);
//MessageBox.Show("2");
ObjSprinKler objspkr = new ObjSprinKler();
objspkr = FirstObj;
//두번째 헤드부터 반복문
List<XYZ> BranchPtLst = new List<XYZ>();
int sp_in = 0;
int HeadCnt = 1;
while (true)
{
Reference pickRef = commandData.Application.ActiveUIDocument.Selection.PickObject(ObjectType.Element, new SelectionFilter(), "스프링클러 헤드 선택 : ");
Element pickElem = doc.GetElement(pickRef.ElementId);
List<Connector> spkrCon = Util.GetElementConnectors(pickElem);
if (spkrCon == null)
{
MessageBox.Show("스프링클러 헤드에 커넥터가 존재하지 않습니다.", "오류");
continue;
}
else
{
Connector firstCon = spkrCon.First();
if (firstCon.Origin.Z > Unit.MMToFeet(m_BranchHgt + m_HeadOffset))
{
MessageBox.Show("스프링클러에 커넥터의 높이가 (가지배관 높이 + 헤드 간격 띄우기) 값보다 높습니다.", "오류");
continue;
}
}
//헤드 선택했을 때
if (pickElem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Sprinklers)
{
FamilyInstance Headfamily = pickElem as FamilyInstance;
List<Connector> ConLst = Util.GetElementConnectors(Headfamily);
//헤드 커넥터
Connector HeadCon = ConLst.First();
//메인관-커넥터 가까운 점
IntersectionResult interRes = NewMainLine.Project(HeadCon.Origin);
XYZ interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, HeadCon.Origin.Z);
ObjSprinKler NextObjSpkr = new ObjSprinKler();
//헤드 정보
NextObjSpkr.HeadCon = HeadCon;
NextObjSpkr.m_Headpt = HeadCon.Origin;
NextObjSpkr.m_SpID = Headfamily.Id;
//이격거리 적용된 점
XYZ SepaPt = Util.Polar(NextObjSpkr.m_Headpt, SeparationVec, Unit.MMToFeet(m_ConnectDist));
//이격점에서 메인 교차점
interRes = NewMainLine.Project(SepaPt);
interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, SepaPt.Z);
//이격거리 적용하여 헤드정보 추가
NextObjSpkr.m_InterPt = interPt;
NextObjSpkr.SeparateionPt = SepaPt;
List<Pipe> pipeLst = new List<Pipe>();
using (Transaction trans = new Transaction(doc))
{
trans.Start("Pipe");
{
double firstDist = objspkr.m_InterPt.DistanceTo(mainLine.GetEndPoint(1));
double nextDist = NextObjSpkr.m_InterPt.DistanceTo(mainLine.GetEndPoint(1));
//첫번째 두번째 스프링클러의 거리가 허용오차 보다 작으면 옮김.
if (Math.Abs(firstDist - nextDist) <= Unit.MMToFeet(m_Tol))
{
//using(Transaction trans = new Transaction(doc))
//{
// trans.Start("SortSpkr");
XYZ moveVec = (objspkr.m_InterPt - NextObjSpkr.m_InterPt).Normalize();
XYZ movePt = Util.Polar(NextObjSpkr.m_Headpt, moveVec, Math.Abs(firstDist - nextDist));
FamilyInstance family = doc.GetElement(NextObjSpkr.m_SpID) as FamilyInstance;
LocationPoint locpt = family.Location as LocationPoint;
locpt.Point = movePt;
doc.Regenerate();
List<Connector> conLst = Util.GetElementConnectors(family);
Connector MoveHeadCon = conLst.First();
//메인관-커넥터 가까운 점
interRes = NewMainLine.Project(MoveHeadCon.Origin);
interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, MoveHeadCon.Origin.Z);
//헤드 정보
NextObjSpkr.HeadCon = MoveHeadCon;
NextObjSpkr.m_Headpt = MoveHeadCon.Origin;
NextObjSpkr.m_SpID = Headfamily.Id;
//이격거리 적용된 점
SepaPt = Util.Polar(NextObjSpkr.m_Headpt, SeparationVec, Unit.MMToFeet(m_ConnectDist));
//이격점에서 메인 교차점
interRes = NewMainLine.Project(SepaPt);
interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, SepaPt.Z);
//이격거리 적용하여 헤드정보 추가
NextObjSpkr.m_InterPt = interPt;
NextObjSpkr.SeparateionPt = SepaPt;
// trans.Commit();
//}
}
}
//헤드 리스트에 추가
lst_objSprinkler.Add(NextObjSpkr);
//틀어진 경우 점 2개 일직선일 경우 0개
List<XYZ> pts = Spkr_Func.DownSPJOIN(objspkr, NextObjSpkr, m_BranchHgt, ref sp_in, HeadCnt, headDiaLst);
if (pts == null) continue;
XYZ objSpkr_offsetpt = new XYZ(objspkr.SeparateionPt.X, objspkr.SeparateionPt.Y, Unit.MMToFeet(m_BranchHgt));
XYZ NextobjSpkr_offsetpt = new XYZ(NextObjSpkr.SeparateionPt.X, NextObjSpkr.SeparateionPt.Y, Unit.MMToFeet(m_BranchHgt));
if (pts.Count() == 2)
{
BranchPtLst.AddRange(pts);
}
//예시 작도점
List<XYZ> DrawPts = new List<XYZ>();
DrawPts.Add(objSpkr_offsetpt);
DrawPts.AddRange(pts);
DrawPts.Add(NextobjSpkr_offsetpt);
pipeLst = Util.CreatePipe(uiapp, doc, DrawPts, Spkr_Func.MainSystemTypeId, Spkr_Func.MainPipeTypeId, Spkr_Func.MainLevelId);
trans.Commit();
}
//지울 객체 찾아서 마무리에서 삭제할 리스트에 담기
List<ElementId> RemoveIDLst = Spkr_Func.getFamilyAndPipe(pipeLst.First());
RemoveElemIdLst.AddRange(RemoveIDLst);
HeadCnt++;
objspkr = NextObjSpkr;
}
//파이프(메인) 선택했을 때
else if (pickElem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves)
{
Pipe PickMainPipe = pickElem as Pipe;
//이전에 작도된 파이프와 엘보는 삭제하고 작업
Util.DeleteElement(doc, RemoveElemIdLst);
//삭제된 리스트 초기화;
RemoveElemIdLst.Clear();
XYZ CapPt = Spkr_Func.DownGetCAPpoint(FirstObj, m_BranchHgt, m_CapDist);
//캡 포인트 리스트 담기
if (BranchPtLst.Count() > 0)
{
//리스트에 값이 있으면 처음에 pt넣음
BranchPtLst.Reverse();
BranchPtLst.Add(CapPt);
BranchPtLst.Reverse();
}
else
BranchPtLst.Add(CapPt);
//메인 연결될 가지파이프
XYZ LastPt = Spkr_Func.DownGetMain2LastpipePoint(objspkr, m_BranchHgt);
BranchPtLst.Add(LastPt);
//가지배관 헤드 연결
List<ElementId> ElemIdLst = new List<ElementId>();
using (Transaction trans = new Transaction(doc))
{
trans.Start("Connect");
List<ObjSprinKler> sort_objspkrLst = SprinklerTolSort(lst_objSprinkler, mainLine, m_Tol);
List<Pipe> DrawPipeLst = Util.CreatePipe(uiapp, doc, BranchPtLst, Spkr_Func.MainSystemTypeId, Spkr_Func.MainPipeTypeId, Spkr_Func.MainLevelId);
ElemIdLst = Spkr_Func.DownConnectHead2pipe(lst_objSprinkler, DrawPipeLst, headDiaLst, m_HeadOffset, m_ConnectDist, m_BranchHgt,m_TReducerDist, m_Mode);
Connector lastspCon = null, lastepCon = null;
Util.GetStartEndConnector(doc.GetElement(ElemIdLst.Last()) as Pipe, ref lastspCon, ref lastepCon);
trans.Commit();
}
//가지배관 교차배관 연결
using (Transaction trans = new Transaction(doc))
{
trans.Start("1");
Connector lastspCon = null, lastepCon = null;
Util.GetStartEndConnector(doc.GetElement(ElemIdLst.Last()) as Pipe, ref lastspCon, ref lastepCon);
//MainConnectElbow(MainElem, doc.GetElement(ElemIdLst.Last()));
Line MainElemLine = ((MainElem as Pipe).Location as LocationCurve).Curve as Line;
IntersectionResult interRes = MainElemLine.Project(lastepCon.Origin);
XYZ closePt1 = interRes.XYZPoint;
Line PickElemLine = ((pickElem as Pipe).Location as LocationCurve).Curve as Line;
interRes = PickElemLine.Project(lastepCon.Origin);
XYZ closePt2 = interRes.XYZPoint;
double main2EpConDist = lastepCon.Origin.DistanceTo(closePt1);
double pick2EpConDist = lastepCon.Origin.DistanceTo(closePt2);
if (main2EpConDist > pick2EpConDist)
MainConnectElbow(pickElem, doc.GetElement(ElemIdLst.Last()));
else
MainConnectElbow(MainElem, doc.GetElement(ElemIdLst.Last()));
trans.Commit();
}
break;
}
//엘보를 선택했을 때
else if (pickElem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeFitting)
{
FamilyInstance ElbowFamily = doc.GetElement(pickRef) as FamilyInstance;
string elbowFamStr = ElbowFamily.Category.Name;
Line ExtensionLine = NewMainLine;
//이전에 작도된 파이프와 엘보는 삭제하고 작업
Util.DeleteElement(doc, RemoveElemIdLst);
//삭제된 리스트 초기화;
RemoveElemIdLst.Clear();
//캡 생성
XYZ CapPt = Spkr_Func.DownGetCAPpoint(FirstObj, m_BranchHgt, m_CapDist);
//캡 포인트 리스트 담기
if (BranchPtLst.Count() > 0)
{
//리스트에 값이 있으면 처음에 pt넣음
BranchPtLst.Reverse();
BranchPtLst.Add(CapPt);
BranchPtLst.Reverse();
}
else
BranchPtLst.Add(CapPt);
//메인 연결될 가지파이프
XYZ LastPt = Spkr_Func.DownGetMain2LastpipePoint(objspkr, m_BranchHgt);
BranchPtLst.Add(LastPt);
List<ElementId> ElemIdLst = new List<ElementId>();
//가지배관 헤드 연결
using (Transaction trans = new Transaction(doc))
{
trans.Start("HeadConnectBranch");
List<Pipe> DrawPipeLst = Util.CreatePipe(uiapp, doc, BranchPtLst, Spkr_Func.MainSystemTypeId, Spkr_Func.MainPipeTypeId, Spkr_Func.MainLevelId);
//헤드 가지배관 연결
ElemIdLst = Spkr_Func.DownConnectHead2pipe(lst_objSprinkler, DrawPipeLst, headDiaLst, m_HeadOffset, m_ConnectDist, m_BranchHgt, m_TReducerDist, m_Mode);
//교차배관 가지배관 연결
//MainConnectElbow(MainElem, doc.GetElement(ElemIdLst.Last()));
trans.Commit();
}
//XYZ InterPt = Util.GetPointOnLine(ExtensionLine, LastPt);
////Util.Pyosi(doc, InterPt, 1);
//
////생성되어있는 T 찾기
//FamilyInstance CrossTee = null;
//
//IList<Element> instances = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_PipeFitting).ToElements();
//foreach (Element elem in instances)
//{
// bool b_Type = Util.GetFamilyPartType(elem, PartType.Tee);
// if (b_Type == false) continue;
//
// FamilyInstance Teefam = elem as FamilyInstance;
// LocationPoint locpt = Teefam.Location as LocationPoint;
//
// if (locpt.Point.IsAlmostEqualTo(InterPt, Unit.MMToFeet(0.01)))
// {
// CrossTee = elem as FamilyInstance;
// break;
// }
//}
//
//if (CrossTee != null)
//{
// Connector ColumnCon = null;
//
// Connector PipeCon = null;
// Connector BranchTeeCon = GetTeeBranchConnector(CrossTee, MainVec, ReverseVec);
// Connector NextOtherCon = null;
// //Util.Pyosi(doc, BranchTeeCon.Origin, 1);
// int cnt = 0;
// while (true)
// {
// Connector NextCon = Util.GetNextElementConnector(BranchTeeCon);
//
// //선택한 엘보 패밀리가 나올 때 까지 반복
// if (!(NextCon.Owner is FamilyInstance))
// {
// NextOtherCon = Util.GetOtherConnector(NextCon);
// BranchTeeCon = NextOtherCon;
// continue;
// }
// if (Util.GetFamilyPartType(NextCon, PartType.Elbow) == true)
// {
// FamilyInstance family = NextCon.Owner as FamilyInstance;
//
// if (family.Id == ElbowFamily.Id)
// {
// //엘보에 붙어있는 파이프 커넥터 구하기
// ColumnCon = BranchTeeCon;
// Connector ElbowCon = NextCon;
// Connector ElbowOtherCon = Util.GetOtherConnector(ElbowCon);
// PipeCon = Util.GetNextElementConnector(ElbowOtherCon);
//
// //Util.Pyosi(doc, NextCon.Origin,1);
// //Util.Pyosi(doc, ElbowOtherCon.Origin,1);
// break;
// }
// }
//
// NextOtherCon = Util.GetOtherConnector(NextCon);
// BranchTeeCon = NextOtherCon;
//
// cnt++;
// if (cnt > 3000) break;
// }//while end
//
// Connector lastSpCon = null, lastEpCon = null;
// using (Transaction trans = new Transaction(doc))
// {
// trans.Start("1");
// //doc.Regenerate();
// List<Pipe> DrawPipeLst = Util.CreatePipe(uiapp, doc, BranchPtLst, Spkr_Func.MainSystemTypeId, Spkr_Func.MainPipeTypeId, Spkr_Func.MainLevelId);
//
// List<ElementId> ElemIdLst = Spkr_Func.DownConnectHead2pipe(lst_objSprinkler, DrawPipeLst, headDiaLst, m_HeadOffset, m_ConnectDist, m_BranchHgt);
//
// //Util.Pyosi(doc, ElbowPipeCon.Origin, 0);
// doc.Delete(ElbowFamily.Id);
//
// Pipe LastPipe = doc.GetElement(ElemIdLst.Last()) as Pipe;
// //작도된 파이프 중 메인에 가까운 파이프 끝점
// Util.GetStartEndConnector(LastPipe, ref lastSpCon, ref lastEpCon);
//
// //파이프 관경이 다를경우 레듀셔일 수 있어 다음객체 찾고 레듀셔 지움
// if (!(PipeCon.Owner is Pipe))
// {
// Connector OtherCon = Util.GetOtherConnector(PipeCon);
// PipeCon = Util.GetNextElementConnector(OtherCon);
// doc.Delete(OtherCon.Owner.Id);
// }
//
// if (!(ColumnCon.Owner is Pipe))
// {
// Connector OtherCon = Util.GetOtherConnector(ColumnCon);
// ColumnCon = Util.GetNextElementConnector(OtherCon);
// doc.Delete(OtherCon.Owner.Id);
// }
//
//
// XYZ MoveElbowPt = Util.Polar(PipeCon.Origin,
// lastEpCon.Origin, lastSpCon.Origin, PipeCon.Origin.DistanceTo(lastEpCon.Origin));
// //엘보에 붙어있던 파이프 위치 조정
// PipeCon.Origin = MoveElbowPt;
//
// Connector ColumnOtherCon = Util.GetOtherConnector(ColumnCon);
// XYZ MoveColumnPt = Util.Polar(ColumnCon.Origin,
// ColumnOtherCon.Origin, ColumnCon.Origin, ColumnCon.Origin.DistanceTo(lastEpCon.Origin));
// //Tee 기둥 위치 조정
// ColumnCon.Origin = MoveColumnPt;
// //Tee 기둥 관경 큰 관경 변경
// if (lastEpCon.Radius > PipeCon.Radius)
// ColumnCon.Radius = lastEpCon.Radius;
// else
// ColumnCon.Radius = PipeCon.Radius;
// //Tee 작도
// FamilyInstance familyTee = creDoc.NewTeeFitting(lastEpCon, PipeCon, ColumnCon);
//
// if (Math.Abs(lastEpCon.Origin.Z - PipeCon.Origin.Z) > Unit.MMToFeet(0.1))
// {
// MessageBox.Show("양쪽의 가지관 높이가 다릅니다.");
// return Result.Failed;
// }
//
// //왼쪽 오른쪽 관경이 다를 경우 레듀셔와 Tee 사이 간격 띄우기
// if (!(Math.Abs(lastEpCon.Radius - PipeCon.Radius) < Unit.MMToFeet(0.01)))
// {
// Spkr_Func.CreatePipeBetweenTeeAndReducer(familyTee, 100);
// //Util.Pyosi(doc, lastEpCon.Origin);
// }
//
// trans.Commit();
// }
//}
break;
}
}//while end
}
catch (Exception e)
{
using (Transaction trans = new Transaction(doc))
{
trans.Start("delete");
if (RemoveElemIdLst.Count() > 0)
doc.Delete(RemoveElemIdLst);
trans.Commit();
}
//MessageBox.Show("" + e);
}
return Result.Succeeded;
}
//기준 커넥터에서 FlowVec 방향 커넥터 구하기(Tee 또는 Cross에서 사용)
public Connector GetTeeBranchConnector(FamilyInstance familyTee, XYZ FlowVec, XYZ ReverseVec)
{
Connector resCon = null;
ConnectorSet ConSet = null;
FamilyInstance family = null;
Pipe pipe = null;
List<Connector> TeeConLst = Util.GetElementConnectors(familyTee);
foreach (Connector TeeCon in TeeConLst)
{
if (TeeCon.IsConnected == true)
{
family = TeeCon.Owner as FamilyInstance;
ConSet = family.MEPModel.ConnectorManager.Connectors;
foreach (Connector con in ConSet)
{
if (TeeCon.Origin.IsAlmostEqualTo(con.Origin, Unit.MMToFeet(0.01))) continue;
XYZ CurVec = (con.Origin - TeeCon.Origin).Normalize();
if (!(CurVec.IsAlmostEqualTo(FlowVec, Unit.MMToFeet(0.01)) || CurVec.IsAlmostEqualTo(ReverseVec, Unit.MMToFeet(0.01))))
resCon = con;
}
}
}
return resCon;
}
//메인과 가지관 엘보 작도
public void MainConnectElbow(Element MainPipeElem, Element BranchElem)
{
Connector SpCon = null, EpCon = null;
Pipe NewPipe = null;
Util.GetStartEndConnector(BranchElem as Pipe, ref SpCon, ref EpCon);
NewPipe = Spkr_Func.CreatePipeFromNearPt(MainPipeElem, EpCon);
//파이프 엘보 관경 맞추고 연결
Connector NewSpCon = null, NewEpCon = null;
Util.GetStartEndConnector(NewPipe, ref NewSpCon, ref NewEpCon);
NewSpCon.Radius = EpCon.Radius;
Util.ElbowFitting(doc, EpCon, NewSpCon);
//메인관에 T연결
Connector pipeSpCon = null, pipeEpCon = null;
bool b_Cons = Util.GetStartEndConnector(NewPipe, ref pipeSpCon, ref pipeEpCon);
Line DirectLine = ((MainPipeElem as Pipe).Location as LocationCurve).Curve as Line;
XYZ DivPt = Util.GetPointOnLine(DirectLine, pipeEpCon.Origin);
ElementId divID = PlumbingUtils.BreakCurve(doc, MainPipeElem.Id, DivPt);
Connector MainCon1 = null, MainCon2 = null;
List<Connector> MainCon1Lst = Util.GetElementConnectors(doc.GetElement(divID));
List<Connector> MainCon2Lst = Util.GetElementConnectors(MainPipeElem);
foreach (Connector con1 in MainCon1Lst)
{
foreach (Connector con2 in MainCon2Lst)
{
if (con1.Origin.IsAlmostEqualTo(con2.Origin, Unit.MMToFeet(0.01)))
{
MainCon1 = con1;
MainCon2 = con2;
}
}
}
Util.CreateTee(creDoc, MainCon1, MainCon2, pipeEpCon);
}
public List<ObjSprinKler> SprinklerTolSort(List<ObjSprinKler> GroupSpkr, Line MainLine, double m_Tol)
{
List<ObjSprinKler> resLst = new List<ObjSprinKler>();
ObjSprinKler FirstSpkr = GroupSpkr.First();
XYZ newEpt = new XYZ(MainLine.GetEndPoint(1).X, MainLine.GetEndPoint(1).Y, FirstSpkr.m_InterPt.Z);
double firstDist = FirstSpkr.m_InterPt.DistanceTo(newEpt);
foreach (ObjSprinKler spkr in GroupSpkr)
{
if (spkr.m_SpID.Equals(FirstSpkr.m_SpID))
{
resLst.Add(spkr);
continue;
}
double nextDist = spkr.m_InterPt.DistanceTo(newEpt);
if (Math.Abs(firstDist - nextDist) > Unit.MMToFeet(m_Tol) || Math.Abs(firstDist - nextDist) < Unit.MMToFeet(0.01))
{
resLst.Add(spkr);
continue;
}
XYZ moveVec = (FirstSpkr.m_InterPt - spkr.m_InterPt).Normalize();
XYZ movePt = Util.Polar(spkr.m_Headpt, moveVec, Math.Abs(firstDist - nextDist));
FamilyInstance family = doc.GetElement(spkr.m_SpID) as FamilyInstance;
LocationPoint locpt = family.Location as LocationPoint;
locpt.Point = movePt;
doc.Regenerate();
List<Connector> spkrCon = Util.GetElementConnectors(family);
//메인관-커넥터 가까운 점
IntersectionResult interRes = MainLine.Project(spkrCon.First().Origin);
XYZ interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, spkrCon.First().Origin.Z);
//스프링클러 헤드 정보
spkr.HeadCon = spkrCon.First();
spkr.m_Headpt = spkrCon.First().Origin;
spkr.m_InterPt = interPt;
spkr.m_SpID = family.Id;
resLst.Add(spkr);
}
return resLst;
}
public class SelectionMainPipe : ISelectionFilter
{
public bool AllowElement(Element element)
{
if (element.Category == null) return false;
if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves)
{
return true;
}
return false;
}
public bool AllowReference(Reference refer, XYZ point)
{
return false;
}
}
public class SelectionFilter : ISelectionFilter
{
public bool AllowElement(Element element)
{
if (element.Category == null) return false;
if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Sprinklers
|| element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves
|| element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeFitting)
{
return true;
}
return false;
}
public bool AllowReference(Reference refer, XYZ point)
{
return false;
}
}
}
}