Client/Desktop/KMBIM3.0/23.11.03/Cmd/CrossConnectT/PipeConnectT.cs

319 lines
12 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;
//using COME4Revit.WinForm;
using System.Diagnostics;
using Autodesk.Revit.UI.Selection;
using KMBIM.Revit.Tools;
using KDCS.Utils;
using KMBIM.Revit.Tools.Properties;
namespace KMBIM
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class PipeConnectT : IExternalCommand
{
UIApplication uiapp;
UIDocument uidoc;
Document doc;
Autodesk.Revit.Creation.Application creApp;
Autodesk.Revit.Creation.Document creDoc;
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
uiapp = commandData.Application;
uidoc = uiapp.ActiveUIDocument;
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
doc = uidoc.Document;
creApp = uiapp.Application.Create;
creDoc = doc.Create;
List<XYZ> MainPtLst = new List<XYZ>();
List<XYZ> BranchPtLst = new List<XYZ>();
Element MainElem = null;
List<Element> m_BranchElemLst = new List<Element>();
List<Element> m_MainElemLst = new List<Element>();
try
{
//메인 파이프 선택
Reference pickref = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeSelectionFilter(), Resources.CrossConnectT_MainSelect);
if (pickref != null)
{
ElementId MainElemID = pickref.ElementId;
MainElem = doc.GetElement(MainElemID) as Element;
//MessageBox.Show("메인 : " + MainElem.Name);
}
m_MainElemLst.Add(MainElem);
//가지 파이프 선택
IList<Reference> pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeSelectionFilter(), Resources.CrossConnectT_BranchSelect);
if (pickrefs != null)
{
foreach (Reference refer in pickrefs)
{
//메인 파이프가 가지파이프에 있으면 저장X
ElementId BranchElemID = refer.ElementId;
Element BranchElem = doc.GetElement(BranchElemID) as Element;
if (MainElem.Id.Compare(BranchElem.Id) == 0) continue;
m_BranchElemLst.Add(BranchElem);
//MessageBox.Show("가지 :" + BranchElem);
}
}
ElementId divPipeID = null;
int breakcnt = 0;
bool b_MainCutTrue = false;
using (Transaction trans = new Transaction(doc))
{
trans.Start("CreateT");
while (true)
{
foreach (Element mainElem in m_MainElemLst)
{
foreach (Element BranchElem in m_BranchElemLst)
{
//divPipeID = CreatePipeT(BranchElem, mainElem, false);
divPipeID = CreatePipeT(mainElem, BranchElem, true);
if (divPipeID != null)
{
m_BranchElemLst.Remove(BranchElem);
b_MainCutTrue = true;
break;
}
else
b_MainCutTrue = false;
}
if (b_MainCutTrue == true) break;
}
if (divPipeID != null)
m_MainElemLst.Add(doc.GetElement(divPipeID));
breakcnt++;
if (breakcnt > 100) break;
if (m_BranchElemLst.Count <= 0) break;
}//while end
//MessageBox.Show("메인 개수 :" + m_MainElemLst.Count);
trans.Commit();
}
}
catch
{
}
return Result.Succeeded;
}
//파이프T 연결 메인,가지 교차점 trim 후 Tee 삽입
public ElementId CreatePipeT(Element main_element, Element branch_element, bool MainPipe_Down)
{
ElementId m_divideElemId = null, b_divideElemId = null;
List<XYZ> mainElemPts = new List<XYZ>();
List<XYZ> branchElemPts = new List<XYZ>();
XYZ InterPt, main_InterPt, branch_InterPt;
Pipe mainPipe = main_element as Pipe;
Pipe branchPipe = branch_element as Pipe;
mainElemPts = GetPipeConnectorPts(mainPipe);
branchElemPts = GetPipeConnectorPts(branchPipe);
InterPt = GetIntersectionPoint(mainElemPts[0], mainElemPts[1], branchElemPts[0], branchElemPts[1]);
if (InterPt == null) return null;
main_InterPt = new XYZ(InterPt.X, InterPt.Y, mainElemPts[0].Z);
branch_InterPt = new XYZ(InterPt.X, InterPt.Y, branchElemPts[0].Z);
try
{
mainPipe = main_element as Pipe;
m_divideElemId = PlumbingUtils.BreakCurve(doc, mainPipe.Id, main_InterPt);
branchPipe = branch_element as Pipe;
b_divideElemId = PlumbingUtils.BreakCurve(doc, branchPipe.Id, branch_InterPt);
}
catch
{
}
//나뉜 메인관이 없을 경우 리턴
if (m_divideElemId == null) return null;
//T연결시 커넥트 3개가 필요하여 메인 가지관 교차점 사이에 파이프 작도
//잘린 메인id 파이프로 전환
Pipe mainDivide = doc.GetElement(m_divideElemId) as Pipe;
Pipe branchDivide = doc.GetElement(b_divideElemId) as Pipe;
Pipe HeadPipe = null;
Level level = new FilteredElementCollector(doc).OfClass(typeof(Level)).First() as Level;
//if (main_InterPt.IsAlmostEqualTo(branch_InterPt,0.1)) return null;
Parameter mainParam = mainPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
Parameter branchParam = branchPipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
if (mainParam.AsDouble() < branchParam.AsDouble())
{
HeadPipe = Pipe.Create(doc, mainPipe.MEPSystem.GetTypeId(), mainPipe.GetTypeId(), level.Id, main_InterPt, branch_InterPt);
Connector con = HeadPipe.ConnectorManager.Connectors.Cast<Connector>().First();
con.Radius = mainParam.AsDouble() / 2.0;
}
else
{
HeadPipe = Pipe.Create(doc, branchPipe.MEPSystem.GetTypeId(), branchPipe.GetTypeId(), level.Id, main_InterPt, branch_InterPt);
Connector con = HeadPipe.ConnectorManager.Connectors.Cast<Connector>().First();
con.Radius = branchParam.AsDouble() / 2.0;
}
CreatePipeT(mainPipe, mainDivide, HeadPipe);
CreatePipeT(branchPipe, branchDivide, HeadPipe);
return m_divideElemId;
}
//파이프 커넥터점 2개 구하기
public List<XYZ> GetPipeConnectorPts(Pipe pipe)
{
List<XYZ> ptLst = new List<XYZ>();
ConnectorManager pipe_connectorManager1 = pipe.ConnectorManager;
ConnectorSet pipe_connectorSet1 = pipe_connectorManager1.Connectors;
foreach (Connector connector1 in pipe_connectorSet1)
{
ptLst.Add(connector1.Origin);
}
return ptLst;
}
//파이프T 커넥터3개로 작도하기
public void CreatePipeT(Pipe Main1, Pipe Main2, Pipe Head)
{
//나뉘어진 메인관2개 가지관 1개 커넥트 구해 T작도
ConnectorManager pipe_connectorManager2 = Main1.ConnectorManager;
ConnectorSet pipe_connectorSet2 = pipe_connectorManager2.Connectors;
ConnectorManager pipe_connectorManager3 = Main2.ConnectorManager;
ConnectorSet pipe_connectorSet3 = pipe_connectorManager3.Connectors;
Connector pipe_main1con = null;
Connector pipe_main2con = null;
Connector pipe_branchcon = null;
double minDist = double.MaxValue;
foreach (Connector maincon1 in pipe_connectorSet2)
{
foreach (Connector maincon2 in pipe_connectorSet3)
{
double d = maincon1.Origin.DistanceTo(maincon2.Origin);
if (d < minDist)
{
pipe_main1con = maincon1;
pipe_main2con = maincon2;
minDist = d;
}
}
}
ConnectorManager New_connectorManager = Head.ConnectorManager;
ConnectorSet New_connectorSet = New_connectorManager.Connectors;
Connector New_con = null;
double minDist2 = double.MaxValue;
foreach (Connector maincon1 in pipe_connectorSet2)
{
foreach (Connector maincon3 in New_connectorSet)
{
double d = maincon1.Origin.DistanceTo(maincon3.Origin);
if (d < minDist2)
{
pipe_main1con = maincon1;
New_con = maincon3;
minDist2 = d;
}
}
}
try
{
FamilyInstance family = creDoc.NewTeeFitting(pipe_main1con, pipe_main2con, New_con);
}
catch
{
}
}
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 XYZ GetIntersectionPoint(XYZ p1, XYZ p2, XYZ p3, XYZ p4)
{
XYZ resPt = XYZ.Zero;
//p1 = Util.Polar(p1, p2, p1, 1);
//p2 = Util.Polar(p2, p1, p2, 1);
//p3 = Util.Polar(p3, p4, p3, 1);
//p4 = Util.Polar(p4, p3, p4, 1);
double d = (p1.X - p2.X) * (p3.Y - p4.Y) - (p1.Y - p2.Y) * (p3.X - p4.X);
if (d == 0) return null;
double pre = (p1.X * p2.Y - p1.Y * p2.X), post = (p3.X * p4.Y - p3.Y * p4.X);
double x = (pre * (p3.X - p4.X) - (p1.X - p2.X) * post) / d;
double y = (pre * (p3.Y - p4.Y) - (p1.Y - p2.Y) * post) / d;
resPt = new XYZ(x, y, 0);
return resPt;
}
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;
}
}
}