259 lines
12 KiB
C#
259 lines
12 KiB
C#
using System.Linq;
|
|
|
|
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.DB.Electrical;
|
|
using Autodesk.Revit.DB.Mechanical;
|
|
using Autodesk.Revit.DB.Plumbing;
|
|
using Autodesk.Revit.UI;
|
|
|
|
|
|
using Nice3point.Revit.Toolkit.External.Handlers;
|
|
|
|
|
|
namespace Szmedi.RvKits.MEPTools
|
|
{
|
|
public partial class MEPCurveSignViewModel : ObservableValidator
|
|
{
|
|
private readonly ActionEventHandler handler;
|
|
public MEPCurveSignViewModel()
|
|
{
|
|
handler = new ActionEventHandler();
|
|
}
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(BatchSignsCommand))]
|
|
private string newSign = "生活给水管道";
|
|
[ObservableProperty]
|
|
[IsNumeric]
|
|
[NotifyDataErrorInfo]
|
|
[Minimum(0)]
|
|
[NotifyCanExecuteChangedFor(nameof(CreateSignsCommand))]
|
|
private double minSize = 50;
|
|
[ObservableProperty]
|
|
[IsNumeric]
|
|
[NotifyDataErrorInfo]
|
|
[Minimum(0)]
|
|
[NotifyCanExecuteChangedFor(nameof(CreateSignsCommand))]
|
|
private double minLength = 600;
|
|
[ObservableProperty]
|
|
private bool useArrow;
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(CreateSignsCommand))]
|
|
private bool containPipes;
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(CreateSignsCommand))]
|
|
private bool containDucts;
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(CreateSignsCommand))]
|
|
private bool containCableTrays;
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(CreateSignsCommand))]
|
|
private bool containConduits;
|
|
|
|
private bool CanCreateSigns =>
|
|
MinSize >= 0 &&
|
|
MinLength >= 0 &&
|
|
(ContainPipes || ContainDucts || ContainCableTrays || ContainConduits);
|
|
|
|
[RelayCommand(CanExecute = nameof(CanCreateSigns))]
|
|
private void CreateSigns()
|
|
{
|
|
handler.Raise(
|
|
uiapp =>
|
|
{
|
|
Document doc = uiapp.ActiveUIDocument.Document;
|
|
doc.Invoke(
|
|
_ =>
|
|
{
|
|
var family = doc.OfClass<Family>()
|
|
.Cast<Family>()
|
|
.FirstOrDefault(f => f.Name == "机电管线标识");
|
|
if (family == null)
|
|
{
|
|
var path = Path.Combine(GlobalVariables.DirAssembly, "FamilyLib", "2020", "机电管线标识.rfa");
|
|
doc.LoadFamily(path, out family);
|
|
}
|
|
var symbol = doc.GetElement(family.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol;
|
|
if (!symbol.IsActive)
|
|
{
|
|
symbol.Activate();
|
|
}
|
|
var mepCurves = doc.ActiveView
|
|
.OfCollector()
|
|
.OfClass(typeof(MEPCurve))
|
|
.Cast<MEPCurve>()
|
|
.Where(
|
|
c => (c is Duct && ContainDucts) ||
|
|
(c is CableTray && ContainCableTrays) ||
|
|
(c is Pipe && ContainPipes) ||
|
|
(c is Conduit && ContainConduits))
|
|
.ToList();
|
|
|
|
foreach (var mepCurve in mepCurves)
|
|
{
|
|
var conn = mepCurve.ConnectorManager.Connectors.OfType<Connector>().FirstOrDefault();
|
|
var shape = conn.Shape;
|
|
var locLine = mepCurve.GetLocCurve() as Line;
|
|
|
|
if (locLine.Length - MinLength / 304.8 < 10e-6)
|
|
{
|
|
continue;
|
|
}
|
|
switch (shape)
|
|
{
|
|
case ConnectorProfileType.Round:
|
|
if (mepCurve.Diameter - MinSize / 304.8 < 10e-6)
|
|
{
|
|
continue;
|
|
}
|
|
break;
|
|
default:
|
|
if (mepCurve.Width - MinSize / 304.8 < 10e-6)
|
|
{
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
var centerPoint = locLine.Evaluate(0.5, true);
|
|
Line l = Line.CreateUnbound(centerPoint, XYZ.BasisZ);
|
|
if (locLine.Direction.CrossProduct(XYZ.BasisZ).IsAlmostEqualTo(XYZ.Zero))//立管
|
|
{
|
|
l = Line.CreateUnbound(centerPoint, XYZ.BasisX);
|
|
}
|
|
|
|
XYZ loc = null;
|
|
XYZ referenceVector = XYZ.Zero;
|
|
var options = new Options() { ComputeReferences = true, };
|
|
var geoElem = mepCurve.get_Geometry(options);
|
|
|
|
Face face = null;
|
|
foreach (var obj in geoElem)
|
|
{
|
|
if (obj is Solid solid)
|
|
{
|
|
var faces = solid.Faces;
|
|
|
|
if (faces == null || faces.Size == 0)
|
|
{
|
|
continue;
|
|
}
|
|
foreach (Face cface in faces)
|
|
{
|
|
var result = cface.Intersect(l, out var array);
|
|
|
|
if (result == SetComparisonResult.Overlap)
|
|
{
|
|
face = cface;
|
|
loc = array.get_Item(0).XYZPoint;
|
|
var uv = array.get_Item(0).UVPoint;
|
|
var faceNormal = face.ComputeNormal(uv);
|
|
if (faceNormal.IsAlmostEqualTo(XYZ.BasisZ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
if (face != null && loc != null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (loc == null)
|
|
{
|
|
continue;
|
|
}
|
|
var instance = doc.Create
|
|
.NewFamilyInstance(
|
|
face, loc, referenceVector, symbol);
|
|
doc.Regenerate();
|
|
string systemName = string.Empty;
|
|
switch (conn.Domain)
|
|
{
|
|
case Domain.DomainHvac:
|
|
systemName = mepCurve.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).AsValueString();
|
|
break;
|
|
case Domain.DomainPiping:
|
|
systemName = mepCurve.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM).AsValueString();
|
|
break;
|
|
case Domain.DomainCableTrayConduit:
|
|
systemName = mepCurve.get_Parameter(BuiltInParameter.RBS_CTC_SERVICE_TYPE).AsValueString();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(systemName))
|
|
{
|
|
systemName = "未定义管线";
|
|
}
|
|
var split = systemName.Split('_', '-');
|
|
if (split.Length > 1)//具有多字段
|
|
{
|
|
systemName = split.LastOrDefault();
|
|
}
|
|
systemName = systemName.Replace("系统", "管道");
|
|
|
|
instance.LookupParameter("机电管线标识").Set(systemName);
|
|
instance.LookupParameter("显示箭头").Set(UseArrow ? 1 : 0);
|
|
|
|
var refer = instance.HandOrientation;
|
|
var normal = refer.CrossProduct(locLine.Direction);
|
|
if (normal.IsAlmostEqualTo(XYZ.Zero))
|
|
{
|
|
continue;
|
|
}
|
|
var angle = refer.AngleTo(locLine.Direction);
|
|
ElementTransformUtils.RotateElement(
|
|
doc,
|
|
instance.Id,
|
|
Line.CreateUnbound(loc, normal),
|
|
angle);
|
|
}
|
|
}, "创建管线标识");
|
|
});
|
|
}
|
|
private bool CanBatchSigns =>
|
|
!string.IsNullOrEmpty(NewSign);
|
|
[RelayCommand(CanExecute = nameof(CanBatchSigns))]
|
|
private void BatchSigns()
|
|
{
|
|
handler.Raise(
|
|
uiapp =>
|
|
{
|
|
if (string.IsNullOrEmpty(NewSign))
|
|
{
|
|
return;
|
|
}
|
|
var uidoc = uiapp.ActiveUIDocument;
|
|
var doc = uidoc.Document;
|
|
var ids = uidoc.Selection.GetElementIds();
|
|
var signs = doc.ActiveView.OfCollector().OfClass(typeof(FamilyInstance))
|
|
.Cast<FamilyInstance>()
|
|
.Where(e => e.Name == "机电管线标识")
|
|
.ToList();
|
|
if (ids.Count == 0)
|
|
{
|
|
TaskDialog.Show("提示", "请选择机电管线");
|
|
return;
|
|
}
|
|
if (signs.Count == 0)
|
|
{
|
|
TaskDialog.Show("提示", "当前视图中没有机电管线标识的实例");
|
|
return;
|
|
}
|
|
doc.Invoke(
|
|
_ =>
|
|
{
|
|
foreach (var sign in signs)
|
|
{
|
|
if (sign.Host is MEPCurve host && ids.Contains(host.Id))
|
|
{
|
|
sign.GetParameters("机电管线标识").FirstOrDefault()?.Set(NewSign);
|
|
}
|
|
}
|
|
}, "批处理标识");
|
|
});
|
|
}
|
|
}
|
|
} |