152 lines
5.0 KiB
C#
152 lines
5.0 KiB
C#
|
|
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 Sai.RvKits.Windows;
|
|||
|
|
|
|||
|
|
namespace Sai.RvKits.RvMEP;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Revit执行命令
|
|||
|
|
/// </summary>
|
|||
|
|
[Transaction(TransactionMode.Manual)]
|
|||
|
|
[Regeneration(RegenerationOption.Manual)]
|
|||
|
|
public class HeadroomCheckCmd : ExternalCommand
|
|||
|
|
{
|
|||
|
|
private void CheckHeadroom(IEnumerable<MEPCurve> elems, double compareMetric, double minValueMetric, double minLengthMetric)
|
|||
|
|
{
|
|||
|
|
var messages = new List<MessageModel>();
|
|||
|
|
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.GetLocCurve().Length < minLength)
|
|||
|
|
{
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var conns = item.ConnectorManager.Connectors.OfType<Connector>().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<ElementId> { element.Id });
|
|||
|
|
}
|
|||
|
|
WinDialogHelper.ShowModeless<MessageWin>(viewmodel);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override void Execute()
|
|||
|
|
{
|
|||
|
|
WinDialogHelper.ShowModeless<HeadroomCheckView>(new HeadroomCheckViewModel(UiApplication));
|
|||
|
|
//try
|
|||
|
|
//{
|
|||
|
|
// InputMessageBox inputMessage = new("净高限制", "请输出净高要求高度(mm)");
|
|||
|
|
// inputMessage.ShowDialog();
|
|||
|
|
// if (inputMessage.DialogResult == true)
|
|||
|
|
// {
|
|||
|
|
// var elems = UiDocument.Selection
|
|||
|
|
// .PickElementsByRectangle(new FuncFilter(e => e is MEPCurve, (_, _) => true))
|
|||
|
|
// .OfType<MEPCurve>();
|
|||
|
|
// if (double.TryParse(inputMessage.InputContent, out var headroomValue))
|
|||
|
|
// {
|
|||
|
|
// CheckHeadroom(elems, headroomValue, 1000, 300);
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// else
|
|||
|
|
// {
|
|||
|
|
// var elem = UiDocument.SelectObject<DirectShape>();
|
|||
|
|
// var clashFilter = new ElementIntersectsElementFilter(elem, false);
|
|||
|
|
// var elems = Document.OfCollector().WherePasses(clashFilter).OfType<MEPCurve>();
|
|||
|
|
// if (double.TryParse(inputMessage.InputContent, out var headroomValue))
|
|||
|
|
// {
|
|||
|
|
// CheckHeadroom(elems, headroomValue, 1000, 300);
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
//}
|
|||
|
|
//catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
|||
|
|
//{
|
|||
|
|
//}
|
|||
|
|
}
|
|||
|
|
}
|