using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System.Collections.Generic; using System.Linq; //using COME4Revit.WinForm; using System.Diagnostics; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.DB.Mechanical; using KMBIM.Revit.Tools; using KDCS.Utils; namespace KMBIM { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] class DuctConnectT : 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 MainPtLst = new List(); List BranchPtLst = new List(); Element MainElem = null; List m_BranchElemLst = new List(); List m_MainElemLst = new List(); try { Reference pickref = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new DuctSelectionFilter()); if (pickref != null) { ElementId tt = pickref.ElementId; MainElem = doc.GetElement(tt) as Element; //MessageBox.Show("메인 : " + MainElem.Name); } m_MainElemLst.Add(MainElem); IList pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new DuctSelectionFilter()); if (pickrefs != null) { foreach (Reference refer in pickrefs) { ElementId tt = refer.ElementId; Element BranchElem = doc.GetElement(tt) as Element; if (MainElem.Id.Compare(BranchElem.Id) == 0) continue; m_BranchElemLst.Add(BranchElem); //MessageBox.Show("가지 :" + BranchElem); } } ElementId divDuctID = null; int breakcnt = 0; bool b_MainCutTrue = false; using (Transaction trans = new Transaction(doc)) { trans.Start("CreateT"); try { while (true) { foreach (Element mainElem in m_MainElemLst) { foreach (Element BranchElem in m_BranchElemLst) { divDuctID = CreateDuctT(mainElem, BranchElem, true); if (divDuctID != null) { m_BranchElemLst.Remove(BranchElem); b_MainCutTrue = true; break; } else b_MainCutTrue = false; } if (b_MainCutTrue == false) break; } if (divDuctID != null) m_MainElemLst.Add(doc.GetElement(divDuctID)); breakcnt++; if (breakcnt > 100) break; if (m_BranchElemLst.Count <= 0) break; }//while end //MessageBox.Show("메인 개수 :" + m_MainElemLst.Count); } catch { } trans.Commit(); } } catch { } return Result.Succeeded; } //덕트T 연결 메인,가지 교차점 trim 후 Tee 삽입 public ElementId CreateDuctT(Element main_element, Element branch_element, bool MainDuct_Down) { ElementId m_divideElemId = null, b_divideElemId = null; List mainElemPts = new List(); List branchElemPts = new List(); XYZ InterPt, main_InterPt, branch_InterPt; Duct mainDuct = main_element as Duct; Duct branchDuct = branch_element as Duct; mainElemPts = GetDuctConnectorPts(mainDuct); branchElemPts = GetDuctConnectorPts(branchDuct); 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 { mainDuct = main_element as Duct; m_divideElemId = MechanicalUtils.BreakCurve(doc, mainDuct.Id, main_InterPt); branchDuct = branch_element as Duct; b_divideElemId = MechanicalUtils.BreakCurve(doc, branchDuct.Id, branch_InterPt); } catch { } //나뉜 메인관이 없을 경우 리턴 if (m_divideElemId == null) return null; //T연결시 커넥트 3개가 필요하여 메인 가지관 교차점 사이에 파이프 작도 //잘린 메인id 파이프로 전환 Duct mainDivide = doc.GetElement(m_divideElemId) as Duct; Duct branchDivide = doc.GetElement(b_divideElemId) as Duct; Duct HeadDuct = null; Level level = new FilteredElementCollector(doc).OfClass(typeof(Level)).First() as Level; //if (main_InterPt.IsAlmostEqualTo(branch_InterPt,0.1)) return null; Parameter mainParam = mainDuct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM); Parameter branchParam = branchDuct.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM); if(mainParam.AsDouble() < branchParam.AsDouble()) { HeadDuct = Duct.Create(doc, mainDuct.MEPSystem.GetTypeId(), mainDuct.GetTypeId(), level.Id, main_InterPt, branch_InterPt); Connector con = HeadDuct.ConnectorManager.Connectors.Cast().First(); con.Width = branchParam.AsDouble(); mainParam = mainDuct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM); con.Height = branchParam.AsDouble(); } else { HeadDuct = Duct.Create(doc, branchDuct.MEPSystem.GetTypeId(), branchDuct.GetTypeId(), level.Id, main_InterPt, branch_InterPt); Connector con = HeadDuct.ConnectorManager.Connectors.Cast().First(); con.Width = branchParam.AsDouble(); branchParam = branchDuct.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM); con.Height = branchParam.AsDouble(); } CreateDuctT(mainDuct, mainDivide, HeadDuct); CreateDuctT(branchDuct, branchDivide, HeadDuct); return m_divideElemId; } //파이프T 커넥터3개로 작도하기 public void CreateDuctT(Duct Main1, Duct Main2, Duct Head) { //나뉘어진 메인관2개 가지관 1개 커넥트 구해 T작도 ConnectorManager duct_connectorManager2 = Main1.ConnectorManager; ConnectorSet duct_connectorSet2 = duct_connectorManager2.Connectors; ConnectorManager duct_connectorManager3 = Main2.ConnectorManager; ConnectorSet duct_connectorSet3 = duct_connectorManager3.Connectors; Connector duct_main1con = null; Connector duct_main2con = null; Connector duct_branchcon = null; double minDist = double.MaxValue; foreach (Connector maincon1 in duct_connectorSet2) { foreach (Connector maincon2 in duct_connectorSet3) { double d = maincon1.Origin.DistanceTo(maincon2.Origin); if (d < minDist) { duct_main1con = maincon1; duct_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 duct_connectorSet2) { foreach (Connector maincon3 in New_connectorSet) { double d = maincon1.Origin.DistanceTo(maincon3.Origin); if (d < minDist2) { duct_main1con = maincon1; New_con = maincon3; minDist2 = d; } } } try { FamilyInstance family = creDoc.NewTeeFitting(duct_main1con, duct_main2con, New_con); } catch { } } //덕트 커넥터점 2개 구하기 public List GetDuctConnectorPts(Duct duct) { List ptLst = new List(); ConnectorManager duct_connectorManager1 = duct.ConnectorManager; ConnectorSet duct_connectorSet1 = duct_connectorManager1.Connectors; foreach (Connector connector1 in duct_connectorSet1) { ptLst.Add(connector1.Origin); } return ptLst; } public class DuctSelectionFilter : ISelectionFilter { public bool AllowElement(Element element) { if (element.Category == null) return false; if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctCurves) { return true; } return false; } public bool AllowReference(Reference refer, XYZ point) { return false; } } public bool Pyosi(UIApplication uiapp, Document doc, XYZ pt) { using (Transaction transaction = new Transaction(doc)) { transaction.Start("Start"); XYZ pt1 = new XYZ(pt.X - 0.328084, pt.Y + 0.328084, pt.Z); XYZ pt2 = new XYZ(pt.X + Unit.MMToFeet(100), pt.Y + Unit.MMToFeet(100), pt.Z); XYZ pt3 = new XYZ(pt.X + 0.328084, pt.Y - 0.328084, pt.Z); XYZ pt4 = new XYZ(pt.X - 0.328084, pt.Y - 0.328084, pt.Z); Autodesk.Revit.DB.View view = doc.ActiveView; //Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), pt2, pt4); //Util.NewModelLine(uiapp, view.SketchPlane.GetPlane(), pt1, pt3); Util.CreateModelLine(doc, pt2, pt4); Util.CreateModelLine(doc, pt1, pt3); transaction.Commit(); } return true; } 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 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; } } }