1278 lines
58 KiB
C#
1278 lines
58 KiB
C#
using Autodesk.Revit.ApplicationServices;
|
|
using Autodesk.Revit.Creation;
|
|
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.DB.Plumbing;
|
|
using Autodesk.Revit.DB.Structure;
|
|
using Autodesk.Revit.UI;
|
|
using Autodesk.Revit.UI.Selection;
|
|
using KDCS.Utils;
|
|
using KMBIM.Revit.Tools;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using View = Autodesk.Revit.DB.View;
|
|
|
|
namespace KMBIM
|
|
{
|
|
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
|
public class DrainConnect : 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;
|
|
|
|
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
|
{
|
|
m_commandData = commandData;
|
|
uiapp = commandData.Application;
|
|
uidoc = uiapp.ActiveUIDocument;
|
|
doc = uidoc.Document;
|
|
creApp = uiapp.Application.Create;
|
|
creDoc = doc.Create;
|
|
|
|
try
|
|
{
|
|
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
|
|
List<FamilySymbol> WyeFamSymLst = new List<FamilySymbol>();
|
|
//콤보박스에 뿌릴 Y 패밀리 심볼 리스트 구하기
|
|
ICollection<Element> WyeCollector = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).ToElements();
|
|
|
|
foreach (Element e in WyeCollector)
|
|
{
|
|
FamilySymbol FamSym = e as FamilySymbol;
|
|
if (FamSym == null) continue;
|
|
bool b_Wye = Util.GetFamilyPartType(FamSym, PartType.Wye);
|
|
if (b_Wye)
|
|
{
|
|
WyeFamSymLst.Add(e as FamilySymbol);
|
|
}
|
|
}
|
|
|
|
Form_DrainConnect dlg = new Form_DrainConnect();
|
|
dlg.YFamSymLst = WyeFamSymLst;
|
|
dlg.document = doc;
|
|
|
|
if (dlg.ShowDialog() == DialogResult.Cancel) return Result.Cancelled;
|
|
|
|
int Connect_Type = dlg.Rad_Idx;
|
|
double m_D1 = dlg.m_D1;
|
|
string ComboFamName = dlg.m_YFamName;
|
|
|
|
FamilySymbol YFamSymbol = null;
|
|
foreach (FamilySymbol sym in WyeFamSymLst)
|
|
{
|
|
if (ComboFamName == sym.FamilyName)
|
|
YFamSymbol = sym;
|
|
}
|
|
|
|
//부착할 메인 배관 선택
|
|
Reference pickRef = commandData.Application.ActiveUIDocument.Selection.PickObject
|
|
(ObjectType.Element, new PipeSelectionFilter(), "배수관 연결할 메인관 선택 : ");
|
|
|
|
Pipe pickPipe = doc.GetElement(pickRef) as Pipe;
|
|
|
|
//위생기기 선택
|
|
IList<Reference> pickRefs = commandData.Application.ActiveUIDocument.Selection.PickObjects
|
|
(ObjectType.Element, new HygienicSelectionFilter(), "위생기기 선택 : ");
|
|
|
|
//패밀리 리스트로 저장
|
|
List<FamilyInstance> FamLst = new List<FamilyInstance>();
|
|
foreach (Reference refer in pickRefs)
|
|
{
|
|
Element elem = doc.GetElement(refer);
|
|
if (elem is FamilyInstance)
|
|
FamLst.Add(elem as FamilyInstance);
|
|
}
|
|
|
|
//패밀리 중 가장 아래쪽 커넥터 리스트 저장
|
|
List<Connector> bottomConLst = new List<Connector>();
|
|
foreach (FamilyInstance fam in FamLst)
|
|
{
|
|
Connector bottomCon = GetBottonConnector(fam);
|
|
if (bottomCon != null)
|
|
bottomConLst.Add(bottomCon);
|
|
}
|
|
|
|
////메인관 offset 값 > 가장 아래쪽 커넥터 + 65mm 면 오류메시지 후 종료
|
|
//foreach (Connector con in bottomConLst)
|
|
//{
|
|
// //65mm 는 관경100 배관 엘보 길이
|
|
// if (pickPipe.LevelOffset > con.Origin.Z - Unit.MMToFeet(65))
|
|
// {
|
|
// MessageBox.Show("연결할 메인배관과 위생기구 사이의 거리가 좁습니다.", "오류");
|
|
// return Result.Cancelled;
|
|
// }
|
|
//}
|
|
|
|
XYZ DirPt = pickRef.GlobalPoint;
|
|
XYZ sp = null, ep = null;
|
|
Util.GetStartEndPoint(doc.GetElement(pickRef) as Pipe, ref sp, ref ep);
|
|
XYZ dirpt = (sp - ep).Normalize();
|
|
|
|
//T,YT에 따른 작업
|
|
if (Connect_Type == 0)
|
|
TeeType1Process(pickPipe, DirPt, bottomConLst);
|
|
else if (Connect_Type == 1)
|
|
TeeType2Process(pickPipe, dirpt, m_D1, bottomConLst);
|
|
else if (Connect_Type == 2)
|
|
YTeeType1Process(pickPipe, m_D1, DirPt, bottomConLst, YFamSymbol);
|
|
else if (Connect_Type == 3)
|
|
YTeeType2Process(pickPipe, m_D1, DirPt, bottomConLst, YFamSymbol);
|
|
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//MessageBox.Show("" + e);
|
|
}
|
|
|
|
|
|
return Result.Succeeded;
|
|
}
|
|
|
|
/// <summary>
|
|
/// YTee 타입1 연결 프로세스
|
|
/// </summary>
|
|
/// <param name="mainPipe"></param> 메인관
|
|
/// <param name="bottomConLst"></param> 위생기기 가장 아래쪽 커넥터
|
|
void TeeType1Process(Pipe mainPipe, XYZ Dirpt, List<Connector> bottomConLst)
|
|
{
|
|
|
|
ElementId PipeSystemTypeId = mainPipe.MEPSystem.GetTypeId();
|
|
ElementId PipeTypeId = mainPipe.PipeType.Id;
|
|
ElementId ViewId = mainPipe.ReferenceLevel.Id;
|
|
|
|
int idx_Error1 = 0, idx_Error2 = 0, idx_Error3 = 0;
|
|
XYZ mainSp = null, mainEp = null;
|
|
Util.GetStartEndPoint(mainPipe, ref mainSp, ref mainEp);
|
|
|
|
bool isDir = false;
|
|
//중간점에서
|
|
if (Dirpt.DistanceTo(mainEp) < Dirpt.DistanceTo(mainSp))
|
|
isDir = true;
|
|
|
|
|
|
try
|
|
{
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("t");
|
|
List<XYZ> pts = new List<XYZ>();
|
|
//foreach (Connector con in bottomConLst)
|
|
for (int i = 0; i < bottomConLst.Count; i++)
|
|
{
|
|
pts.Clear();
|
|
Connector con = bottomConLst[i];
|
|
Line mainLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
|
|
IntersectionResult interRes = mainLine.Project(con.Origin);
|
|
if (interRes == null) continue;
|
|
|
|
//메인과 커넥터 교차점
|
|
XYZ MainInterPt = interRes.XYZPoint;
|
|
|
|
//위생기기 커넥터와 메인배관 가까운 점이 메인배관의 시작 또는 끝 점 일 경우
|
|
if (MainInterPt.IsAlmostEqualTo(mainSp) || MainInterPt.IsAlmostEqualTo(mainEp))
|
|
{
|
|
idx_Error1++;
|
|
continue;
|
|
}
|
|
|
|
//위생기기 커넥터 높이가 메인배관 교차점+여유길이보다 같거나 낮을 때
|
|
if (MainInterPt.Z + Unit.MMToFeet(79) > con.Origin.Z)
|
|
{
|
|
idx_Error2++;
|
|
continue;
|
|
}
|
|
|
|
XYZ pipeEpt = Util.Polar(con.Origin, con.Origin,
|
|
new XYZ(con.Origin.X, con.Origin.Y, con.Origin.Z - Unit.MMToFeet(1)), Math.Abs(MainInterPt.Z - con.Origin.Z));
|
|
//Util.Pyosi(doc, pipeEpt, 0);
|
|
//Util.Pyosi(doc, MainInterPt, 0);
|
|
|
|
if (pipeEpt.DistanceTo(MainInterPt) < Unit.MMToFeet(140))
|
|
{
|
|
idx_Error3++;
|
|
continue;
|
|
}
|
|
|
|
Parameter paramMainDia = mainPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
|
|
|
|
pts.Add(con.Origin);
|
|
pts.Add(pipeEpt);
|
|
pts.Add(MainInterPt);
|
|
|
|
//배관 생성
|
|
List<Pipe> pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, PipeSystemTypeId, PipeTypeId, ViewId);
|
|
|
|
//T연결
|
|
Pipe LastPipe = pipeLst.Last();
|
|
Connector spCon = null, epCon = null;
|
|
Util.GetStartEndConnector(LastPipe, ref spCon, ref epCon);
|
|
|
|
List<ElementId> divLst = Util.DivideElement(doc, mainPipe, epCon.Origin);
|
|
doc.Regenerate();
|
|
|
|
List<Connector> crossConLst = new List<Connector>();
|
|
foreach (ElementId id in divLst)
|
|
{
|
|
//Pipe divPipe = doc.GetElement(id) as Pipe;
|
|
List<Connector> ConLst = Util.GetElementConnectors(doc.GetElement(id));
|
|
foreach (Connector DivCon in ConLst)
|
|
{
|
|
if (epCon.Origin.IsAlmostEqualTo(DivCon.Origin))
|
|
crossConLst.Add(DivCon);
|
|
}
|
|
}
|
|
|
|
FamilyInstance tee = null;
|
|
if (isDir == true)
|
|
tee = doc.Create.NewTeeFitting(crossConLst.Last(), crossConLst.First(), epCon);
|
|
else
|
|
tee = doc.Create.NewTeeFitting(crossConLst.First(), crossConLst.Last(), epCon);
|
|
|
|
|
|
doc.Regenerate();
|
|
|
|
|
|
//자른 파이프로 변경
|
|
mainPipe = doc.GetElement(divLst.First()) as Pipe;
|
|
|
|
//자른 파이프가 다음 커넥터와 교차점이 없으면 다음 자른파이프로 변경
|
|
if (bottomConLst.Count > i + 1)
|
|
{
|
|
Line divLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
Connector cons = bottomConLst[i + 1];
|
|
IntersectionResult intersection = divLine.Project(cons.Origin);
|
|
if (intersection != null)
|
|
{
|
|
XYZ interpt = intersection.XYZPoint;
|
|
List<Connector> divMainConLst = Util.GetElementConnectors(mainPipe);
|
|
foreach (Connector mainCon in divMainConLst)
|
|
{
|
|
if (interpt.IsAlmostEqualTo(mainCon.Origin))
|
|
{
|
|
mainPipe = doc.GetElement(divLst.Last()) as Pipe;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
trans.Commit();
|
|
|
|
string error_str = "";
|
|
if (idx_Error1 != 0)
|
|
error_str += idx_Error1 + "개의 위생기기와 메인배관이 교차하지 않습니다.";
|
|
if (idx_Error2 != 0)
|
|
error_str += "\n" + idx_Error2 + "개의 위생기기와 배관사이 연결할 높이가 좁습니다.";
|
|
if (idx_Error3 != 0)
|
|
error_str += "\n" + idx_Error3 + "개의 위생기기와 배관사이 연결할 거리가 좁습니다.";
|
|
|
|
if (error_str != "")
|
|
MessageBox.Show(error_str, "오류");
|
|
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// MessageBox.Show("" + e);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// YTee 타입2 연결 프로세스
|
|
/// </summary>
|
|
/// <param name="mainPipe"></param> 메인관
|
|
/// <param name="bottomConLst"></param> 위생기기 가장 아래쪽 커넥터
|
|
void TeeType2Process(Pipe mainPipe, XYZ Dirpt, double dist_D1, List<Connector> bottomConLst)
|
|
{
|
|
ElementId PipeSystemTypeId = mainPipe.MEPSystem.GetTypeId();
|
|
ElementId PipeTypeId = mainPipe.PipeType.Id;
|
|
ElementId ViewId = mainPipe.ReferenceLevel.Id;
|
|
int idx_Error1 = 0, idx_Error2 = 0;
|
|
|
|
XYZ mainSp = null, mainEp = null;
|
|
Util.GetStartEndPoint(mainPipe, ref mainSp, ref mainEp);
|
|
|
|
bool isDir = false;
|
|
//중간점에서
|
|
if (Dirpt.DistanceTo(mainEp) < Dirpt.DistanceTo(mainSp))
|
|
isDir = true;
|
|
|
|
try
|
|
{
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("t");
|
|
List<XYZ> pts = new List<XYZ>();
|
|
//foreach (Connector con in bottomConLst)
|
|
|
|
for (int i = 0; i < bottomConLst.Count; i++)
|
|
{
|
|
pts.Clear();
|
|
Connector con = bottomConLst[i];
|
|
Line mainLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
|
|
IntersectionResult interRes = mainLine.Project(con.Origin);
|
|
if (interRes == null) continue;
|
|
|
|
//메인과 커넥터 교차점
|
|
XYZ MainInterPt = interRes.XYZPoint;
|
|
|
|
//D1 길이만큼 아래로 이동한 점
|
|
XYZ dist1pt = new XYZ(con.Origin.X, con.Origin.Y, con.Origin.Z - Unit.MMToFeet(1));
|
|
XYZ pipeD1pt = Util.Polar(con.Origin, con.Origin, dist1pt, Unit.MMToFeet(dist_D1));
|
|
|
|
XYZ pipeMainZpt = Util.Polar(con.Origin, con.Origin, pipeD1pt, con.Origin.Z - MainInterPt.Z);
|
|
//Util.Pyosi(doc, pipeMainZpt, 0);
|
|
|
|
//메인관 교차점과 D1pt 벡터 방향
|
|
XYZ interZD1pt = new XYZ(MainInterPt.X, MainInterPt.Y, pipeD1pt.Z);
|
|
XYZ vec = (interZD1pt - pipeD1pt).Normalize();
|
|
|
|
// D1+엘보 여유분이 위생기기-메인관 거리보다 클 경우
|
|
if (con.Origin.DistanceTo(pipeMainZpt) <= Unit.MMToFeet(dist_D1 + 100))
|
|
{
|
|
idx_Error1++;
|
|
//MessageBox.Show("위생기기와 배관사이 연결할 거리가 좁습니다.", "오류");
|
|
continue;
|
|
}
|
|
|
|
// 45도 절단점이 메인관 시작 또는 끝점일 경우 작업 취소
|
|
if (MainInterPt.IsAlmostEqualTo(mainSp) || MainInterPt.IsAlmostEqualTo(mainEp))
|
|
{
|
|
idx_Error2++;
|
|
continue;
|
|
}
|
|
|
|
pts.Add(con.Origin);
|
|
pts.Add(pipeD1pt);
|
|
pts.Add(interZD1pt);
|
|
pts.Add(MainInterPt);
|
|
//파이프 생성
|
|
List<Pipe> pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, PipeSystemTypeId, PipeTypeId, ViewId);
|
|
|
|
//T연결
|
|
Pipe LastPipe = pipeLst.Last();
|
|
Connector spCon = null, epCon = null;
|
|
Util.GetStartEndConnector(LastPipe, ref spCon, ref epCon);
|
|
|
|
List<ElementId> divLst = Util.DivideElement(doc, mainPipe, epCon.Origin);
|
|
doc.Regenerate();
|
|
|
|
List<Connector> crossConLst = new List<Connector>();
|
|
foreach (ElementId id in divLst)
|
|
{
|
|
//Pipe divPipe = doc.GetElement(id) as Pipe;
|
|
List<Connector> ConLst = Util.GetElementConnectors(doc.GetElement(id));
|
|
foreach (Connector DivCon in ConLst)
|
|
{
|
|
if (epCon.Origin.IsAlmostEqualTo(DivCon.Origin))
|
|
crossConLst.Add(DivCon);
|
|
}
|
|
}
|
|
|
|
FamilyInstance tee = null;
|
|
if (isDir == true)
|
|
tee = doc.Create.NewTeeFitting(crossConLst.Last(), crossConLst.First(), epCon);
|
|
else
|
|
tee = doc.Create.NewTeeFitting(crossConLst.First(), crossConLst.Last(), epCon);
|
|
|
|
|
|
doc.Regenerate();
|
|
|
|
|
|
//자른 파이프로 변경
|
|
mainPipe = doc.GetElement(divLst.First()) as Pipe;
|
|
|
|
//자른 파이프가 다음 커넥터와 교차점이 없으면 다음 자른파이프로 변경
|
|
if (bottomConLst.Count > i + 1)
|
|
{
|
|
Line divLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
Connector cons = bottomConLst[i + 1];
|
|
IntersectionResult intersection = divLine.Project(cons.Origin);
|
|
if (intersection != null)
|
|
{
|
|
XYZ interpt = intersection.XYZPoint;
|
|
List<Connector> divMainConLst = Util.GetElementConnectors(mainPipe);
|
|
foreach (Connector mainCon in divMainConLst)
|
|
{
|
|
if (interpt.IsAlmostEqualTo(mainCon.Origin))
|
|
{
|
|
mainPipe = doc.GetElement(divLst.Last()) as Pipe;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
trans.Commit();
|
|
|
|
string error_str = "";
|
|
if (idx_Error1 != 0)
|
|
error_str += idx_Error1 + "개의 위생기기와 배관사이 연결할 거리가 좁습니다.";
|
|
else if (idx_Error2 != 0)
|
|
error_str += "\n" + idx_Error2 + "개의 파이프와 메인배관이 교차하지 않습니다.";
|
|
|
|
if (error_str != "")
|
|
MessageBox.Show(error_str, "오류");
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Y관 타입1 연결 프로세스
|
|
/// </summary>
|
|
/// <param name="mainPipe"></param> 메인관
|
|
/// <param name="m_YTdist"></param> 위생기기-메인관 직교 길이
|
|
/// <param name="bottomConLst"></param> 위생기기기 가장 아래쪽 커넥터
|
|
void YTeeType1Process(Pipe mainPipe, double dist_D1, XYZ Dirpt, List<Connector> bottomConLst, FamilySymbol Ysymbol)
|
|
{
|
|
ElementId PipeSystemTypeId = mainPipe.MEPSystem.GetTypeId();
|
|
ElementId PipeTypeId = mainPipe.PipeType.Id;
|
|
ElementId ViewId = mainPipe.ReferenceLevel.Id;
|
|
int idx_Error1 = 0, idx_Error2 = 0;
|
|
|
|
|
|
XYZ Sp = null, Ep = null;
|
|
Util.GetStartEndPoint(mainPipe, ref Sp, ref Ep);
|
|
|
|
bool isDir = false;
|
|
//중간점에서
|
|
if (Dirpt.DistanceTo(Ep) < Dirpt.DistanceTo(Sp))
|
|
isDir = true;
|
|
|
|
XYZ mainVec = null;
|
|
if (isDir == true)
|
|
mainVec = (Sp - Ep).Normalize();
|
|
else
|
|
mainVec = (Ep - Sp).Normalize();
|
|
|
|
|
|
try
|
|
{
|
|
|
|
List<XYZ> pts = new List<XYZ>();
|
|
List<ElementId> dividePipeLst = new List<ElementId>();
|
|
Line mainLine = null;
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("start");
|
|
|
|
|
|
for (int i = 0; i < bottomConLst.Count; i++)
|
|
{
|
|
pts.Clear();
|
|
Connector con = bottomConLst[i];
|
|
|
|
mainLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
XYZ mainSp = null, mainEp = null;
|
|
Util.GetStartEndPoint(mainPipe, ref mainSp, ref mainEp);
|
|
//Util.Pyosi(doc, mainSp, 1);
|
|
//MessageBox.Show("1");
|
|
|
|
IntersectionResult interRes = mainLine.Project(con.Origin);
|
|
if (interRes == null) continue;
|
|
|
|
//메인과 커넥터 교차점
|
|
XYZ MainInterPt = interRes.XYZPoint;
|
|
|
|
XYZ pipeEpt = Util.Polar(con.Origin, con.Origin,
|
|
new XYZ(con.Origin.X, con.Origin.Y, con.Origin.Z - Unit.MMToFeet(1)), Math.Abs(MainInterPt.Z - con.Origin.Z));
|
|
//Util.Pyosi(doc, pipeEpt, 1);
|
|
|
|
//D1+엘보 여유분이 위생기기-메인관 거리보다 클 경우
|
|
if (pipeEpt.DistanceTo(MainInterPt) <= Unit.MMToFeet(dist_D1 + 100))
|
|
{
|
|
//위생기기와 메인배관 사이 거리가 좁습니다.
|
|
idx_Error1++;
|
|
continue;
|
|
}
|
|
|
|
pts.Add(con.Origin);
|
|
pts.Add(pipeEpt);
|
|
|
|
interRes = mainLine.Project(pipeEpt);
|
|
//메인관과 배관 끝 꾜차점
|
|
XYZ mainDivPt = interRes.XYZPoint;
|
|
XYZ vec = (mainDivPt - pipeEpt).Normalize();
|
|
|
|
//D1 길이 이동 점
|
|
XYZ D1pt = Util.Polar(pipeEpt, vec, Unit.MMToFeet(dist_D1));
|
|
pts.Add(D1pt);
|
|
//Util.Pyosi(doc, D1pt, 0);
|
|
//List<Pipe> pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, mainPipe.MEPSystem.GetTypeId(), mainPipe.PipeType.Id, mainPipe.ReferenceLevel.Id);
|
|
|
|
//if (isDir == true)
|
|
XYZ newVec = (D1pt - pipeEpt).Normalize();
|
|
XYZ RevNewVec = (pipeEpt - D1pt).Normalize();
|
|
XYZ rotVec1 = Util.RotateVector(newVec, Util.DTR(45));
|
|
XYZ plrpt1 = Util.Polar(D1pt, rotVec1, 200);
|
|
XYZ rotVec2 = Util.RotateVector(newVec, Util.DTR(-45));
|
|
XYZ plrpt2 = Util.Polar(D1pt, rotVec2, 200);
|
|
|
|
XYZ interPt1 = null, interPt2 = null;
|
|
interRes = mainLine.Project(plrpt1);
|
|
if (interRes == null)
|
|
continue;
|
|
|
|
interPt1 = interRes.XYZPoint;
|
|
|
|
interRes = mainLine.Project(plrpt2);
|
|
if (interRes == null)
|
|
continue;
|
|
|
|
interPt2 = interRes.XYZPoint;
|
|
//배관 시작-끝 방향인지
|
|
XYZ isDirPoint = null;
|
|
if (isDir == true)
|
|
isDirPoint = mainEp;
|
|
else
|
|
isDirPoint = mainSp;
|
|
|
|
//Util.Pyosi(doc, isDirPoint, 0);
|
|
XYZ Cur45Pt = null;
|
|
|
|
if (isDirPoint.DistanceTo(interPt1) < isDirPoint.DistanceTo(interPt2))
|
|
Cur45Pt = plrpt1;
|
|
else
|
|
Cur45Pt = plrpt2;
|
|
|
|
//45도 라인과와 메인관 라인의 교차점(45피팅 절단점 찾기)
|
|
XYZ inter45pt = Util.GetIntersectionPoint(mainSp, mainEp, D1pt, Cur45Pt);
|
|
XYZ LineOnPt = Util.GetPointOnLine(mainLine, inter45pt);
|
|
|
|
if (LineOnPt.IsAlmostEqualTo(mainEp) || LineOnPt.IsAlmostEqualTo(mainSp))
|
|
{
|
|
idx_Error2++;
|
|
//MessageBox.Show("메인관에 45도 파이프가 교차하지 않습니다.", "오류");
|
|
continue;
|
|
}
|
|
|
|
|
|
//Util.Pyosi(doc, aa, 0);
|
|
pts.Add(inter45pt);
|
|
|
|
List<Pipe> pipeLst = new List<Pipe>();
|
|
|
|
//위생기기-45도 파이프까지 생성
|
|
//List<Pipe> pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, PipeSystemTypeId, PipeTypeId, ViewId);
|
|
pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, PipeSystemTypeId, PipeTypeId, ViewId);
|
|
|
|
|
|
Pipe LastPipe = pipeLst.Last();
|
|
Connector spCon = null, epCon = null;
|
|
Util.GetStartEndConnector(LastPipe, ref spCon, ref epCon);
|
|
Curve LastPipeLine = (LastPipe.Location as LocationCurve).Curve;
|
|
|
|
FamilyInstance yTeeFam = null;
|
|
|
|
|
|
if (Ysymbol.IsActive == false)
|
|
Ysymbol.Activate();
|
|
|
|
//FamilyInstance yTeeFam = uidoc.Document.Create.NewFamilyInstance(inter45pt, Ysymbol, mainVec, LastPipe, StructuralType.NonStructural);
|
|
yTeeFam = uidoc.Document.Create.NewFamilyInstance(inter45pt, Ysymbol, mainVec, LastPipe, StructuralType.NonStructural);
|
|
doc.Regenerate();
|
|
|
|
//y관 메인 커넥터 관경 변경
|
|
Definition df = GetDefinition(yTeeFam, "NomRad1");
|
|
Parameter param = yTeeFam.get_Parameter(df);
|
|
if (param != null)
|
|
param.Set(mainPipe.Diameter / 2.0);
|
|
//y관 가지 커넥터 관경 변경
|
|
df = GetDefinition(yTeeFam, "NomRad2");
|
|
param = yTeeFam.get_Parameter(df);
|
|
if (param != null)
|
|
param.Set(LastPipe.Diameter / 2.0);
|
|
|
|
doc.Regenerate();
|
|
|
|
|
|
//45도 파이프 시작-끝 방향 벡터
|
|
XYZ Vec_45Pipe = (epCon.Origin - spCon.Origin).Normalize();
|
|
List<Connector> branchConLst = Util.GetBranchConnector(yTeeFam, mainPipe);
|
|
|
|
//List<Connector> branchConLst = Util.GetBranchConnector(yTeeFam);
|
|
//삽입된 Y관Tee의 45도커넥터-Y관삽입점 방향 벡터
|
|
XYZ Vec_45TeeCon = ((yTeeFam.Location as LocationPoint).Point - branchConLst.First().Origin).Normalize();
|
|
|
|
//Y관 가지커넥터의 위치가 메인관의 오른쪽인가
|
|
bool b_BranchConRight = Util.isRightPoint(branchConLst.First().Origin, mainSp, mainEp);
|
|
//45도 배관 시작점 위치가 메인관의 오른쪽인가
|
|
bool b_MainRight = Util.isRightPoint(spCon.Origin, mainSp, mainEp);
|
|
|
|
|
|
//패밀리 삽입점
|
|
XYZ FamLoc = (yTeeFam.Location as LocationPoint).Point;
|
|
|
|
//위의 Y관 가지커넥터, 45도 배관 시작점 둘 중 하나가 오른쪽이 아니면 Mirror로 변경
|
|
if (b_BranchConRight != b_MainRight)
|
|
{
|
|
//45도벡터와 메인과 벡터 교차로 z벡터구하기
|
|
XYZ crossVec1 = Vec_45TeeCon.CrossProduct(mainVec);
|
|
//메인 벡터와 z벡터로 x또는y벡터 구하기
|
|
XYZ crossVec2 = mainVec.CrossProduct(crossVec1);
|
|
|
|
Plane plane = Plane.CreateByNormalAndOrigin(crossVec2, FamLoc);
|
|
//Y관 대칭
|
|
ElementTransformUtils.MirrorElements(doc, new List<ElementId> { yTeeFam.Id }, plane, false);
|
|
doc.Regenerate();
|
|
}
|
|
|
|
|
|
XYZ plr45pt = Util.Polar(epCon.Origin, epCon.Origin, spCon.Origin, spCon.Origin.DistanceTo(epCon.Origin) / 2.0);
|
|
//Util.Pyosi(doc, plr45pt, 0);
|
|
IntersectionResult interResult = mainLine.Project(plr45pt);
|
|
if (interResult != null)
|
|
{
|
|
XYZ interpt = interResult.XYZPoint;
|
|
XYZ interVec = (plr45pt - interpt).Normalize();
|
|
XYZ RevInterVec = interVec.Negate();
|
|
XYZ VecPt = Util.Polar(FamLoc, interVec, 500);
|
|
XYZ ReVecPt = Util.Polar(FamLoc, RevInterVec, 500);
|
|
|
|
//Y관 가지커넥터의 위치가 메인관의 오른쪽인가
|
|
bool b_Vir_BranchConRight = Util.isRightPoint(branchConLst.First().Origin, VecPt, ReVecPt);
|
|
//45도 배관 시작점 위치가 메인관의 오른쪽인가
|
|
bool b_Vir_MainRight = Util.isRightPoint(spCon.Origin, VecPt, ReVecPt);
|
|
|
|
if (b_Vir_BranchConRight != b_Vir_MainRight)
|
|
{
|
|
Plane plane = Plane.CreateByNormalAndOrigin(mainVec, FamLoc);
|
|
ElementTransformUtils.MirrorElements(doc, new List<ElementId> { yTeeFam.Id }, plane, false);
|
|
doc.Regenerate();
|
|
}
|
|
}
|
|
|
|
|
|
List<ElementId> divLst = new List<ElementId>();
|
|
|
|
|
|
//메인관 자르기
|
|
divLst = Util.DivideElement(doc, mainPipe, inter45pt);
|
|
if (divLst.Count == 0) continue;
|
|
foreach (ElementId id in divLst)
|
|
{
|
|
bool b_contain = dividePipeLst.Contains(id);
|
|
if (b_contain == false) dividePipeLst.Add(id);
|
|
}
|
|
doc.Regenerate();
|
|
|
|
//자른 파이프로 변경
|
|
//mainPipe = doc.GetElement(divLst.First()) as Pipe;
|
|
//자른 파이프 리스트에서 교차점이 있는 파이프 메인파이프로 변경
|
|
for (int j = 0; j < dividePipeLst.Count; j++)
|
|
{
|
|
if (bottomConLst.Count > i + 1)
|
|
{
|
|
Line divLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
Connector cons = bottomConLst[i + 1];
|
|
IntersectionResult intersection = divLine.Project(cons.Origin);
|
|
if (intersection != null)
|
|
{
|
|
XYZ interpt = intersection.XYZPoint;
|
|
List<Connector> divMainConLst = Util.GetElementConnectors(mainPipe);
|
|
foreach (Connector mainCon in divMainConLst)
|
|
{
|
|
if (interpt.IsAlmostEqualTo(mainCon.Origin))
|
|
{
|
|
mainPipe = doc.GetElement(dividePipeLst[j]) as Pipe;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//잘린 파이프 리스트에 45도 파이프 추가
|
|
List<ElementId> YTeeConPipeLst = new List<ElementId>();
|
|
YTeeConPipeLst.AddRange(divLst);
|
|
YTeeConPipeLst.Add(LastPipe.Id);
|
|
//divLst.Add(LastPipe.Id);
|
|
|
|
foreach (ElementId id in YTeeConPipeLst)
|
|
{
|
|
Pipe Connect45Pipe = doc.GetElement(id) as Pipe;
|
|
//파이프 커넥터
|
|
List<Connector> conLst = Util.GetElementConnectors(Connect45Pipe);
|
|
foreach (Connector PipeCon in conLst)
|
|
{
|
|
//Y관 패밀리 삽입점과 같은 커넥터 찾기
|
|
if (PipeCon.Origin.IsAlmostEqualTo(FamLoc))
|
|
{
|
|
//파이프 역방향 벡터 구하기
|
|
XYZ LineDirReVec = null;
|
|
Connector pipeSpCon = null, pipeEpCon = null;
|
|
Util.GetStartEndConnector(PipeCon.Owner as Pipe, ref pipeSpCon, ref pipeEpCon);
|
|
|
|
if (PipeCon.Origin.IsAlmostEqualTo(pipeSpCon.Origin))
|
|
LineDirReVec = (pipeEpCon.Origin - pipeSpCon.Origin).Normalize();
|
|
else
|
|
LineDirReVec = (pipeSpCon.Origin - pipeEpCon.Origin).Normalize();
|
|
|
|
|
|
//파이프 역방향으로 50mm이동한 점
|
|
XYZ plr100Pt = Util.Polar(PipeCon.Origin, LineDirReVec, Unit.MMToFeet(100));
|
|
//파이프 커넥터 위치 변경
|
|
PipeCon.Origin = plr100Pt;
|
|
//파이프 커넥터와 가까운 Y관 커넥터 구하기.
|
|
double minDist = double.MaxValue;
|
|
Connector closeCon = null;
|
|
List<Connector> yFamConLst = Util.GetElementConnectors(yTeeFam);
|
|
foreach (Connector yFamCon in yFamConLst)
|
|
{
|
|
if (yFamCon.Origin.DistanceTo(plr100Pt) < minDist)
|
|
{
|
|
minDist = yFamCon.Origin.DistanceTo(plr100Pt);
|
|
closeCon = yFamCon;
|
|
}
|
|
}
|
|
//파이프 커넥터 위치를 Y관 커넥터 위치로 변경
|
|
PipeCon.Origin = closeCon.Origin;
|
|
//파이프 커넥퇑 Y관 커넥터 연결
|
|
PipeCon.ConnectTo(closeCon);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
trans.Commit();
|
|
}
|
|
|
|
string error_str = "";
|
|
if (idx_Error1 != 0)
|
|
error_str += idx_Error1 + "개의 위생기기와 메인배관 사이 거리가 좁습니다.";
|
|
if (idx_Error2 != 0)
|
|
error_str += "\n" + idx_Error2 + "개의 45도 파이프가 메인관에 교차하지 않습니다.";
|
|
|
|
if (error_str != "")
|
|
MessageBox.Show(error_str, "오류");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//MessageBox.Show("" + e);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Y관 타입2 연결 프로세스
|
|
/// </summary>
|
|
/// <param name="mainPipe"></param> 메인관
|
|
/// <param name="m_YTdist"></param> 위생기기-메인관 직교 길이
|
|
/// <param name="bottomConLst"></param> 위생기기기 가장 아래쪽 커넥터
|
|
void YTeeType2Process(Pipe mainPipe, double dist_D1, XYZ Dirpt, List<Connector> bottomConLst, FamilySymbol Ysymbol)
|
|
{
|
|
ElementId PipeSystemTypeId = mainPipe.MEPSystem.GetTypeId();
|
|
ElementId PipeTypeId = mainPipe.PipeType.Id;
|
|
ElementId ViewId = mainPipe.ReferenceLevel.Id;
|
|
int idx_Error1 = 0, idx_Error2 = 0, idx_Error3 = 0, idx_Error4 = 0;
|
|
string str_Error4 = "";
|
|
double chg_MainDia = 0, chg_SubDia = 0;
|
|
|
|
|
|
XYZ Sp = null, Ep = null;
|
|
Util.GetStartEndPoint(mainPipe, ref Sp, ref Ep);
|
|
|
|
bool isDir = false;
|
|
//중간점에서
|
|
if (Dirpt.DistanceTo(Ep) < Dirpt.DistanceTo(Sp))
|
|
isDir = true;
|
|
|
|
XYZ mainVec = null;
|
|
if (isDir == true)
|
|
mainVec = (Sp - Ep).Normalize();
|
|
else
|
|
mainVec = (Ep - Sp).Normalize();
|
|
|
|
using (Transaction transGruop = new Transaction(doc))
|
|
{
|
|
transGruop.Start("Start");
|
|
|
|
try
|
|
{
|
|
List<XYZ> pts = new List<XYZ>();
|
|
List<ElementId> dividePipeLst = new List<ElementId>();
|
|
Line mainLine = null;
|
|
|
|
for (int i = 0; i < bottomConLst.Count; i++)
|
|
{
|
|
pts.Clear();
|
|
Connector con = bottomConLst[i];
|
|
|
|
mainLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
XYZ mainSp = null, mainEp = null;
|
|
Util.GetStartEndPoint(mainPipe, ref mainSp, ref mainEp);
|
|
|
|
//메인관 방향 파이프 점 구할 때 파이프 길이가 짧으면 틀어져서 구해지는 현상때문에 확장 라인 생성
|
|
XYZ ExtendMainSp = Util.Polar(mainSp, mainEp, mainSp, 200);
|
|
XYZ ExtendMainEp = Util.Polar(mainEp, mainSp, mainEp, 200);
|
|
Line ExtMainLine = Line.CreateBound(ExtendMainSp, ExtendMainEp);
|
|
|
|
IntersectionResult interRes = ExtMainLine.Project(con.Origin);
|
|
if (interRes == null) continue;
|
|
|
|
//메인과 커넥터 교차점
|
|
XYZ MainInterPt = interRes.XYZPoint;
|
|
|
|
//D1 길이만큼 아래로 이동한 점
|
|
XYZ pipeD1pt = Util.Polar(con.Origin, con.Origin,
|
|
new XYZ(con.Origin.X, con.Origin.Y, con.Origin.Z - Unit.MMToFeet(1)), Unit.MMToFeet(dist_D1));
|
|
|
|
|
|
//메인관 교차점과 D1pt 벡터 방향
|
|
XYZ interZD1pt = new XYZ(MainInterPt.X, MainInterPt.Y, pipeD1pt.Z);
|
|
XYZ connectVec = (interZD1pt - pipeD1pt).Normalize();
|
|
|
|
// D1+엘보 여유분이 위생기기-메인관 거리보다 클 경우
|
|
if (pipeD1pt.DistanceTo(interZD1pt) <= Unit.MMToFeet(dist_D1 + 100))
|
|
{
|
|
//위생기기와 메인배관 사이 거리가 좁습니다.
|
|
idx_Error1++;
|
|
continue;
|
|
}
|
|
|
|
pts.Add(con.Origin);
|
|
pts.Add(pipeD1pt);
|
|
pts.Add(interZD1pt);
|
|
|
|
//파이프 생성
|
|
//List<Pipe> pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, PipeSystemTypeId, PipeTypeId, ViewId);
|
|
|
|
XYZ newVec = (pipeD1pt - con.Origin).Normalize();
|
|
XYZ RevNewVec = (con.Origin - pipeD1pt).Normalize();
|
|
XYZ rotXVec1 = Util.RotateVectorX(newVec, Util.DTR(45));
|
|
XYZ plrpt1 = Util.Polar(interZD1pt, rotXVec1, 200);
|
|
XYZ rotXVec2 = Util.RotateVectorX(newVec, Util.DTR(-45));
|
|
XYZ plrpt2 = Util.Polar(interZD1pt, rotXVec2, 200);
|
|
|
|
ExtendMainSp = Util.Polar(mainSp, mainEp, mainSp, 200);
|
|
ExtendMainEp = Util.Polar(mainEp, mainSp, mainEp, 200);
|
|
|
|
XYZ interpt1 = null, interpt2 = null;
|
|
|
|
|
|
//45도 라인과 메인관 라인의 교차점(45피팅 절단점 찾기)
|
|
Line line1 = Line.CreateBound(ExtendMainSp, ExtendMainEp);
|
|
Line line2 = Line.CreateBound(interZD1pt, plrpt1);
|
|
Line line3 = Line.CreateBound(interZD1pt, plrpt2);
|
|
interpt1 = Util.GetCurvesIntersectionPoint(line1, line2);
|
|
if (interpt1 == null)
|
|
{
|
|
XYZ rotYVec1 = Util.RotateVectorY(newVec, Util.DTR(45));
|
|
plrpt1 = Util.Polar(interZD1pt, rotYVec1, 200);
|
|
|
|
line2 = Line.CreateBound(interZD1pt, plrpt1);
|
|
interpt1 = Util.GetCurvesIntersectionPoint(line1, line2);
|
|
|
|
if (interpt1 == null) continue;
|
|
}
|
|
|
|
interpt2 = Util.GetCurvesIntersectionPoint(line1, line3);
|
|
if (interpt2 == null)
|
|
{
|
|
XYZ rotYVec2 = Util.RotateVectorY(newVec, Util.DTR(-45));
|
|
plrpt2 = Util.Polar(interZD1pt, rotYVec2, 200);
|
|
line3 = Line.CreateBound(interZD1pt, plrpt2);
|
|
|
|
interpt2 = Util.GetCurvesIntersectionPoint(line1, line3);
|
|
|
|
if (interpt2 == null) continue;
|
|
}
|
|
|
|
//XYZ LineOnPt = Util.GetPointOnLine(mainLine, interpt1);
|
|
//Util.Pyosi(doc, interpt1, 0);
|
|
|
|
//배관 시작-끝 방향인지
|
|
XYZ isDirPoint = null;
|
|
if (isDir == true)
|
|
isDirPoint = mainEp;
|
|
else
|
|
isDirPoint = mainSp;
|
|
|
|
//파이프 선택 시 위치에 따른 45도 절단점 위치 설정
|
|
XYZ Cur45Pt = null;
|
|
if (isDirPoint.DistanceTo(interpt1) < isDirPoint.DistanceTo(interpt2))
|
|
Cur45Pt = interpt1;
|
|
else
|
|
Cur45Pt = interpt2;
|
|
|
|
|
|
|
|
Cur45Pt = Util.GetPointOnLine(mainLine, Cur45Pt);
|
|
|
|
//45도 절단점이 메인관 시작 또는 끝점일 경우 작업 취소
|
|
if (Cur45Pt.IsAlmostEqualTo(mainEp) || Cur45Pt.IsAlmostEqualTo(mainSp))
|
|
{
|
|
idx_Error2++;
|
|
continue;
|
|
}
|
|
|
|
//(45도 점 Z - D1 점 Z) 거리가 100보다 작을 때
|
|
if (Math.Abs(pipeD1pt.Z - Cur45Pt.Z) <= Unit.MMToFeet(100))
|
|
{
|
|
idx_Error3++;
|
|
continue;
|
|
}
|
|
|
|
pts.Add(Cur45Pt);
|
|
|
|
List<Pipe> pipeLst = new List<Pipe>();
|
|
Transaction trans = new Transaction(doc);
|
|
//trans.Start("1");
|
|
|
|
//위생기기 -45도 파이프까지 생성
|
|
pipeLst = Util.CreatePipe2(uiapp, doc, pts, con.Radius * 2, PipeSystemTypeId, PipeTypeId, ViewId);
|
|
doc.Regenerate();
|
|
|
|
//trans.Commit();
|
|
|
|
Pipe LastPipe = pipeLst.Last();
|
|
Connector spCon = null, epCon = null;
|
|
Util.GetStartEndConnector(LastPipe, ref spCon, ref epCon);
|
|
Curve lastPipeLine = (LastPipe.Location as LocationCurve).Curve;
|
|
|
|
FamilyInstance yTeeFam = null;
|
|
|
|
|
|
if (Ysymbol.IsActive == false)
|
|
Ysymbol.Activate();
|
|
|
|
yTeeFam = uidoc.Document.Create.NewFamilyInstance(Cur45Pt, Ysymbol, mainVec, LastPipe, StructuralType.NonStructural);
|
|
|
|
chg_MainDia = Unit.FeetToMM(mainPipe.Diameter / 2.0);
|
|
chg_SubDia = Unit.FeetToMM(LastPipe.Diameter / 2.0);
|
|
|
|
if (mainPipe.Diameter == Unit.MMToFeet(35)
|
|
|| mainPipe.Diameter == Unit.MMToFeet(40)
|
|
|| mainPipe.Diameter == Unit.MMToFeet(50)
|
|
|| mainPipe.Diameter == Unit.MMToFeet(75)
|
|
|| mainPipe.Diameter == Unit.MMToFeet(80)
|
|
|| mainPipe.Diameter == Unit.MMToFeet(100)
|
|
|| mainPipe.Diameter == Unit.MMToFeet(125))
|
|
{
|
|
//Y관 메인 커넥터 관경 변경
|
|
Definition df = GetDefinition(yTeeFam, "NomRad1");
|
|
Parameter param = yTeeFam.get_Parameter(df);
|
|
if (param != null)
|
|
param.Set(mainPipe.Diameter / 2.0);
|
|
}
|
|
else
|
|
{
|
|
//Y관 삭제
|
|
Util.Delete(doc, yTeeFam);
|
|
idx_Error4++;
|
|
|
|
string tmp = Unit.FeetToMM(mainPipe.Diameter) + "x"
|
|
+ Unit.FeetToMM(LastPipe.Diameter) + " Y관은 지원하지 않습니다.";
|
|
|
|
bool b_error = str_Error4.Contains(tmp);
|
|
if(b_error==false)
|
|
str_Error4 += tmp;
|
|
|
|
//trans.Commit();
|
|
continue;
|
|
}
|
|
|
|
|
|
if (LastPipe.Diameter == Unit.MMToFeet(35)
|
|
|| LastPipe.Diameter == Unit.MMToFeet(40)
|
|
|| LastPipe.Diameter == Unit.MMToFeet(50)
|
|
|| LastPipe.Diameter == Unit.MMToFeet(75)
|
|
|| LastPipe.Diameter == Unit.MMToFeet(80)
|
|
|| LastPipe.Diameter == Unit.MMToFeet(100)
|
|
|| LastPipe.Diameter == Unit.MMToFeet(125))
|
|
{
|
|
//Y관 가지 커넥터 관경 변경
|
|
Definition df = GetDefinition(yTeeFam, "NomRad2");
|
|
Parameter param = yTeeFam.get_Parameter(df);
|
|
if (param != null)
|
|
param.Set(LastPipe.Diameter / 2.0);
|
|
}
|
|
else
|
|
{
|
|
//Y관 삭제
|
|
Util.Delete(doc, yTeeFam);
|
|
idx_Error4++;
|
|
|
|
string tmp = Unit.FeetToMM(mainPipe.Diameter) + "x"
|
|
+ Unit.FeetToMM(LastPipe.Diameter) + " Y관은 지원하지 않습니다.";
|
|
|
|
bool b_error = str_Error4.Contains(tmp);
|
|
if (b_error == false)
|
|
str_Error4 += tmp;
|
|
|
|
//trans.Commit();
|
|
continue;
|
|
}
|
|
|
|
|
|
doc.Regenerate();
|
|
|
|
//trans.Start("3");
|
|
|
|
//45도 파이프 시작-끝 방향 벡터
|
|
XYZ Vec_45Pipe = (epCon.Origin - spCon.Origin).Normalize();
|
|
|
|
List<Connector> branchConLst = Util.GetBranchConnector(yTeeFam, mainPipe);
|
|
|
|
//패밀리 삽입점
|
|
XYZ FamLoc = (yTeeFam.Location as LocationPoint).Point;
|
|
|
|
interRes = mainLine.Project(spCon.Origin);
|
|
|
|
//메인관 교차점과 D1pt방향 벡터와 반대반향 벡터
|
|
//XYZ connectVec = (interZD1pt - pipeD1pt).Normalize();
|
|
XYZ ReConnectVec = connectVec.Negate();
|
|
|
|
XYZ VecPt = Util.Polar(FamLoc, connectVec, Unit.MMToFeet(500));
|
|
XYZ ReVecPt = Util.Polar(FamLoc, ReConnectVec, Unit.MMToFeet(500));
|
|
//Y관 가지 커넥터 위치가 메인관의 오른쪽인가
|
|
bool b_Vir_BranchConRIght = Util.isRightPoint(branchConLst.First().Origin, VecPt, ReVecPt);
|
|
//45도 배관 시작점 위치가 메인관의 오른쪽인가
|
|
bool b_Vir_MainRight = Util.isRightPoint(spCon.Origin, VecPt, ReVecPt);
|
|
//다를 경우 Mirror로 돌리기
|
|
if (b_Vir_BranchConRIght != b_Vir_MainRight)
|
|
{
|
|
Plane plane = Plane.CreateByNormalAndOrigin(mainVec, FamLoc);
|
|
ElementTransformUtils.MirrorElements(doc, new List<ElementId> { yTeeFam.Id }, plane, false);
|
|
doc.Regenerate();
|
|
}
|
|
|
|
//45도 파이프 시작-끝 방향 벡터와 삽입된 Y관Tee의 45도커넥터-Y관삽입점 방향 벡터가
|
|
//같을 때까지 반복하여90도로 돌리기
|
|
while (true)
|
|
{
|
|
ElementTransformUtils.RotateElement(doc, yTeeFam.Id, mainLine, Util.DTR(90));
|
|
doc.Regenerate();
|
|
|
|
//삽입된 Y관Tee의 45도커넥터-Y관삽입점 방향 벡터
|
|
XYZ Vec_45TeeCon = ((yTeeFam.Location as LocationPoint).Point - branchConLst.First().Origin).Normalize();
|
|
|
|
if (Vec_45Pipe.IsAlmostEqualTo(Vec_45TeeCon)) break;
|
|
}//while end
|
|
|
|
|
|
List<ElementId> divLst = new List<ElementId>();
|
|
|
|
//메인관 자르기
|
|
divLst = Util.DivideElement(doc, mainPipe, epCon.Origin);
|
|
if (divLst.Count == 0) continue;
|
|
foreach (ElementId id in divLst)
|
|
{
|
|
bool b_contain = dividePipeLst.Contains(id);
|
|
if (b_contain == false) dividePipeLst.Add(id);
|
|
}
|
|
doc.Regenerate();
|
|
|
|
//trans.Commit();
|
|
|
|
//자른 파이프로 변경
|
|
//자른 파이프 리스트에서 교차점이 있는 파이프 메인파이프로 변경
|
|
for (int j = 0; j < dividePipeLst.Count; j++)
|
|
{
|
|
if (bottomConLst.Count > i + 1)
|
|
{
|
|
Line divLine = (mainPipe.Location as LocationCurve).Curve as Line;
|
|
Connector cons = bottomConLst[i + 1];
|
|
IntersectionResult intersection = divLine.Project(cons.Origin);
|
|
if (intersection != null)
|
|
{
|
|
XYZ interpt = intersection.XYZPoint;
|
|
List<Connector> divMainConLst = Util.GetElementConnectors(mainPipe);
|
|
foreach (Connector mainCon in divMainConLst)
|
|
{
|
|
if (interpt.IsAlmostEqualTo(mainCon.Origin))
|
|
{
|
|
mainPipe = doc.GetElement(dividePipeLst[j]) as Pipe;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}//for end
|
|
|
|
//잘린 파이프 리스트에 45도 파이프 추가
|
|
List<ElementId> YteeConPipeLst = new List<ElementId>();
|
|
YteeConPipeLst.AddRange(divLst);
|
|
YteeConPipeLst.Add(LastPipe.Id);
|
|
|
|
//trans.Start("4");
|
|
|
|
foreach (ElementId id in YteeConPipeLst)
|
|
{
|
|
Pipe Connect45Pipe = doc.GetElement(id) as Pipe;
|
|
//파이프 커넥터
|
|
List<Connector> conLst = Util.GetElementConnectors(Connect45Pipe);
|
|
foreach (Connector PipeCon in conLst)
|
|
{
|
|
//Y관 패밀리 삽입점과 같은 커넥터 찾기
|
|
if (PipeCon.Origin.IsAlmostEqualTo(FamLoc))
|
|
{
|
|
//파이프 역방향 벡터 구하기
|
|
XYZ LineDirReVec = null;
|
|
Connector pipeSpCon = null, pipeEpCon = null;
|
|
Util.GetStartEndConnector(PipeCon.Owner as Pipe, ref pipeSpCon, ref pipeEpCon);
|
|
|
|
if (PipeCon.Origin.IsAlmostEqualTo(pipeSpCon.Origin))
|
|
LineDirReVec = (pipeEpCon.Origin - pipeSpCon.Origin).Normalize();
|
|
else
|
|
LineDirReVec = (pipeSpCon.Origin - pipeEpCon.Origin).Normalize();
|
|
|
|
//파이프 역방향으로 100mm 이동한 점
|
|
XYZ plr100Pt = Util.Polar(PipeCon.Origin, LineDirReVec, Unit.MMToFeet(100));
|
|
//파이프 커넥터 위치 변경
|
|
PipeCon.Origin = plr100Pt;
|
|
//파이프 커넥터와 가까운 Y관 커넥터 구하기.
|
|
double mainDist = double.MaxValue;
|
|
Connector closeCon = null;
|
|
List<Connector> yFamConLst = Util.GetElementConnectors(yTeeFam);
|
|
foreach (Connector yFamCon in yFamConLst)
|
|
{
|
|
if (yFamCon.Origin.DistanceTo(plr100Pt) < mainDist)
|
|
{
|
|
mainDist = yFamCon.Origin.DistanceTo(plr100Pt);
|
|
closeCon = yFamCon;
|
|
}
|
|
}
|
|
//파이프 커넥터 위치를 Y관 커넥터 위치로 변경
|
|
PipeCon.Origin = closeCon.Origin;
|
|
//파이프 커넥퇑 Y관 커넥터 연결
|
|
PipeCon.ConnectTo(closeCon);
|
|
break;
|
|
}
|
|
}
|
|
}//foreach end
|
|
|
|
//trans.Commit();
|
|
|
|
}//for end
|
|
|
|
|
|
|
|
string error_str = "";
|
|
if (idx_Error1 != 0)
|
|
error_str += idx_Error1 + "개의 위생기기와 배관사이 연결할 높이가 좁습니다.";
|
|
//MessageBox.Show(idx_Error + "개의 45도 파이프가 메인관에 교차하지 않습니다.", "오류");
|
|
if (idx_Error2 != 0)
|
|
error_str += "\n" + idx_Error2 + "개의 45도 파이프와 메인배관이 교차하지 않습니다.";
|
|
if (idx_Error3 != 0)
|
|
error_str += "\n" + idx_Error3 + "개의 45도 파이프가 작도할 높이가 좁습니다.";
|
|
if (idx_Error4 != 0)
|
|
error_str += "\n" + str_Error4;
|
|
|
|
if (error_str != "")
|
|
MessageBox.Show(error_str, "오류");
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//MessageBox.Show("" + e);
|
|
}
|
|
|
|
transGruop.Commit();
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
//패밀리 커넥터 중 가장 아래쪽 커넥터 구하기.
|
|
Connector GetBottonConnector(FamilyInstance family)
|
|
{
|
|
List<Connector> FamConLst = Util.GetElementConnectors(family);
|
|
|
|
double minOffset = double.MaxValue;
|
|
Connector bottomCon = null;
|
|
foreach (Connector con in FamConLst)
|
|
{
|
|
if (con.Origin.Z < minOffset)
|
|
{
|
|
bottomCon = con;
|
|
minOffset = con.Origin.Z;
|
|
}
|
|
}
|
|
|
|
//Util.Pyosi(doc, bottomCon.Origin, 1);
|
|
return bottomCon;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 매개 변수 정의를 반환합니다.
|
|
/// 주어진 요소와 매개 변수 이름.
|
|
/// </summary>
|
|
static Definition GetDefinition(Element elem, string parameter_name)
|
|
{
|
|
IList<Parameter> ps = elem.GetParameters(parameter_name);
|
|
|
|
int n = ps.Count;
|
|
|
|
Debug.Assert(1 >= n, "expected maximum one shared parameters" + "named " + parameter_name);
|
|
|
|
Definition d = (0 == n) ? null
|
|
: ps[0].Definition;
|
|
|
|
return d;
|
|
}
|
|
|
|
public class PipeSelectionFilter : 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 HygienicSelectionFilter : ISelectionFilter
|
|
{
|
|
public bool AllowElement(Element element)
|
|
{
|
|
if (element.Category == null) return false;
|
|
if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PlumbingFixtures)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
public bool AllowReference(Reference refer, XYZ point)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|