using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Electrical; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using Nice3point.Revit.Toolkit.External; using ShrlAlgoToolkit.RevitAddins.Common.Assists; using ShrlAlgoToolkit.RevitAddins.Windows; namespace ShrlAlgoToolkit.RevitAddins.RvMEP; /// /// Revit执行命令 /// [Transaction(TransactionMode.Manual)] public class HeadroomCheckCmd : ExternalCommand { private void CheckHeadroom(IEnumerable elems, double compareMetric, double minValueMetric, double minLengthMetric) { var messages = new List(); var headroomValue = compareMetric / 304.8; var ignoreBelowValue = minValueMetric / 304.8; var minHeadroom = double.MaxValue; var minLength = minLengthMetric / 304.8; Element element = null; foreach (var item in elems) { if (item.GetCurve().Length < minLength) { continue; } var conns = item.ConnectorManager.Connectors.OfType().ToList(); var level = item.ReferenceLevel; #if REVIT2018 || REVIT2020 if (conns.Any(conn => conn.GetConnectedConnector()?.Owner.Category.Id.IntegerValue == -2001140)) #elif REVIT2025 if (conns.Any(conn => conn.GetConnectedConnector()?.Owner.Category.Id.Value == -2001140)) #endif { continue; } var s = item.get_Parameter(BuiltInParameter.RBS_DUCT_SLOPE); if (item is Duct duct && s.HasValue && Math.Atan(s.AsDouble()) < Math.PI / 3) { var p1 = item.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble(); var subtract = conns.FirstOrDefault()!.Shape switch { ConnectorProfileType.Round => duct.Diameter / 2, ConnectorProfileType.Rectangular => duct.Height / 2, ConnectorProfileType.Oval => duct.Height / 2, _ => default }; if (p1 - subtract < headroomValue && p1 - subtract > ignoreBelowValue) { var lowOffset = p1 - subtract; if (lowOffset < minHeadroom) { minHeadroom = lowOffset; element = item; } MessageModel checkElement = new(item, $"底高程: {Math.Round(lowOffset * 304.8, 1)} mm\n\r参照标高:{level.Name}"); messages.Add(checkElement); } } var p = item.get_Parameter(BuiltInParameter.RBS_PIPE_SLOPE); if (item is Pipe pipe && p.HasValue && Math.Atan(p.AsDouble()) < Math.PI / 3) { var p1 = item.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble(); if (p1 - (pipe.Diameter / 2) < headroomValue && p1 - (pipe.Diameter / 2) > ignoreBelowValue) { var lowOffset = p1 - (pipe.Diameter / 2); if (lowOffset < minHeadroom) { minHeadroom = lowOffset; element = item; } MessageModel checkElement = new(item, $"底高程:{Math.Round(lowOffset * 304.8, 1)}mm\n\r参照标高:{level.Name}"); messages.Add(checkElement); } } if (item is Conduit or CableTray) { var p1 = item.get_Parameter(BuiltInParameter.RBS_START_OFFSET_PARAM).AsDouble(); var p2 = item.get_Parameter(BuiltInParameter.RBS_END_OFFSET_PARAM).AsDouble(); if (Math.Abs(p1 - p2) < 0.00001) { var p3 = item.get_Parameter(BuiltInParameter.RBS_CTC_BOTTOM_ELEVATION).AsDouble(); if (p3 < minHeadroom) { minHeadroom = p3; element = item; } if (p3 < headroomValue && p3 > ignoreBelowValue) { MessageModel checkElement = new(item, $"底高程:{Math.Round(p3 * 304.8)}mm\n\r参照标高:{level.Name}"); messages.Add(checkElement); } } } } MessageViewModel viewmodel = new(UiDocument, messages, "净高检查结果"); if (element != null) { viewmodel.Footer = $"最低净高={Math.Round(minHeadroom * 304.8)}mm,元素:{element.Name},Id:{element.Id}"; UiDocument.Selection.SetElementIds(new List { element.Id }); } Common.Assists.WinDialogAssist.ShowModeless(viewmodel); } public override void Execute() { Common.Assists.WinDialogAssist.ShowOrActivate(UiApplication); //try //{ // InputMessageBox inputMessage = new("净高限制", "请输出净高要求高度(mm)"); // inputMessage.ShowDialog(); // if (inputMessage.DialogResult == true) // { // var elems = UiDocument.Selection // .PickElementsByRectangle(new FuncFilter(e => e is ElementToMove, (_, _) => true)) // .OfType(); // if (double.TryParse(inputMessage.InputContent, out var headroomValue)) // { // CheckHeadroom(elems, headroomValue, 1000, 300); // } // } // else // { // var elem = UiDocument.SelectObject(); // var clashFilter = new ElementIntersectsElementFilter(elem, false); // var elems = Document.OfCollector().WherePasses(clashFilter).OfType(); // if (double.TryParse(inputMessage.InputContent, out var headroomValue)) // { // CheckHeadroom(elems, headroomValue, 1000, 300); // } // } //} //catch (Autodesk.Revit.Exceptions.OperationCanceledException) //{ //} } }