using Autodesk.Revit.DB; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using KDCS.Utils; using KMBIM.Revit.Tools.Cmd.DuctFlexDuct; using KMBIM.Revit.Tools.Utils; using KMBIM.Utils; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace KMBIM.Revit.Tools.CmdDuct { 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 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 class DuctTerminalSelectionFilter : ISelectionFilter { public bool AllowElement(Element element) { if (element.Category == null) return false; if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_DuctTerminal) { return true; } return false; } public bool AllowReference(Reference refer, XYZ point) { return false; } } [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)] [Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)] public class FlexibleDuctDiffuserCmd : IExternalCommand { UIApplication m_pUIApp; UIDocument uidoc = null; Document doc = null; List _added_emement_ids = new List(); Duct m_duct; public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements) { if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded; m_pUIApp = commandData.Application; uidoc = m_pUIApp.ActiveUIDocument; doc = uidoc.Document; MechanicalSystemType ductSystemType = null; Selection selection = uidoc.Selection; try { // Looking for the DuctType var lstFlexDuctType = new FilteredElementCollector(doc) .OfClass(typeof(FlexDuctType)) .OfType() .ToList(); FlexDuctType flexDuctType = null; foreach (FlexDuctType fdt in lstFlexDuctType) { if (fdt.Shape == ConnectorProfileType.Round) { flexDuctType = fdt; break; } } if (flexDuctType == null) { System.Windows.Forms.MessageBox.Show("사용가능한 원형 플렉시블덕트 유형이 없습니다."); return Result.Failed; } FormFlexibleDuctSize frmFlexDuctSize = new FormFlexibleDuctSize(m_pUIApp); Process process = Process.GetCurrentProcess(); IntPtr h = process.MainWindowHandle; var hWndRevit = new WindowWrapper(h); frmFlexDuctSize.Show(hWndRevit); uidoc.RefreshActiveView(); //-------------------------------------------------------------------------------------------------------------------------------------- Reference refDuct = null; try { refDuct=selection.PickObject(ObjectType.Element, new DuctSelectionFilter(), "덕트 선택"); } catch (Exception){ } if (refDuct == null) { frmFlexDuctSize.Close(); return Result.Failed; } Duct duct = doc.GetElement(refDuct.ElementId) as Duct; if (duct == null) { frmFlexDuctSize.Close(); return Result.Failed; } var paramLevel = duct.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM); var levelId = paramLevel.AsElementId(); ElementId ductSysTypeId = duct.MEPSystem.GetTypeId(); // 덕트 선을 지나는 수직 면 var lineDuct = (duct.Location as LocationCurve).Curve as Line; XYZ faceNormaDuct = lineDuct.Direction.CrossProduct(XYZ.BasisZ); Plane planeDuct = Plane.CreateByNormalAndOrigin(faceNormaDuct, lineDuct.GetEndPoint(0)); IList lstReference = null; double flexduct_dia = Unit.MMToFeet(150d); try { lstReference = selection.PickObjects(ObjectType.Element, new DuctTerminalSelectionFilter(), "디퓨져 선택"); } catch (Exception) { } if (lstReference == null) { frmFlexDuctSize.Close(); return Result.Failed; } foreach (var refDiffuser in lstReference) { FamilyInstance fi = doc.GetElement(refDiffuser.ElementId) as FamilyInstance; if (fi != null) { if (fi.MEPModel == null) continue; Connector connDiffuser = fi.MEPModel.ConnectorManager.Connectors.Cast().First(); XYZ ptOnDuctVerticalFace = Util.Project(planeDuct, connDiffuser.Origin); XYZ ptOnDuct = lineDuct.Project(ptOnDuctVerticalFace).XYZPoint; Plane planeDiffuser = Plane.CreateByNormalAndOrigin(faceNormaDuct, connDiffuser.Origin); XYZ ptUpDiffuser = Util.Project(planeDiffuser, ptOnDuct); XYZ startTangent = (ptUpDiffuser - ptOnDuct).Normalize(); XYZ endTangent = (ptUpDiffuser - connDiffuser.Origin).Normalize(); XYZ pt1 = ptUpDiffuser - startTangent * Unit.MMToFeet(200d); XYZ pt2 = ptUpDiffuser - endTangent * Unit.MMToFeet(200d); XYZ pt3 = connDiffuser.Origin + endTangent * Unit.MMToFeet(10d); List pts = new List(); pts.Add(ptOnDuct); pts.Add(pt1); //pts.Add(ptUpDiffuser); pts.Add(pt2); pts.Add(connDiffuser.Origin); using (Transaction trans = new Transaction(doc)) { trans.Start("Create FlexDuct"); FlexDuct flexDuct = FlexDuct.Create(doc, ductSysTypeId, flexDuctType.Id, levelId, startTangent, endTangent, pts); flexduct_dia = frmFlexDuctSize.Diameter; flexDuct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).Set(flexduct_dia); // FlexDuct flexDuct = doc.Create.NewFlexDuct(pts, flexDuctType); double minDist = double.MaxValue; double maxDist = double.MinValue; double dst = 0d; flexDuctType.PreferredJunctionType = JunctionType.Tap; doc.Regenerate(); Connector conClosestFlexDuct = null; foreach (Connector conDif in flexDuct.ConnectorManager.Connectors) { dst = conDif.Origin.DistanceTo(ptOnDuct); if (dst < minDist) { conClosestFlexDuct = conDif; minDist = dst; } } if (conClosestFlexDuct != null) { doc.Create.NewTakeoffFitting(conClosestFlexDuct, duct as MEPCurve); } conClosestFlexDuct = null; minDist = double.MaxValue; foreach (Connector conDif in flexDuct.ConnectorManager.Connectors) { dst = conDif.Origin.DistanceTo(connDiffuser.Origin); if (dst < minDist) { conClosestFlexDuct = conDif; minDist = dst; } } if (conClosestFlexDuct != null) { LocationCurve locCrv = flexDuct.Location as LocationCurve; conClosestFlexDuct.ConnectTo(connDiffuser); if (locCrv.Curve.GetEndPoint(0).DistanceTo(connDiffuser.Origin) < locCrv.Curve.GetEndPoint(1).DistanceTo(connDiffuser.Origin)) flexDuct.StartTangent = connDiffuser.CoordinateSystem.BasisZ; else flexDuct.EndTangent = connDiffuser.CoordinateSystem.BasisZ; } trans.Commit(); }//end-using }//end-foreach }//end-if frmFlexDuctSize.Close(); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } return Result.Succeeded; } } }