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.Common.Controls;
using ShrlAlgoToolkit.RevitAddins.RvMEP;
using ShrlAlgoToolkit;
using ShrlAlgoToolkit.RevitAddins;
namespace ShrlAlgoToolkit.RevitAddins.Mep;
///
/// 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)
//{
//}
}
}