Files
ShrlAlgoToolkit/Sai.RvKits/RvMEP/BloomConnectorCmd.cs
2024-10-08 16:21:39 +08:00

467 lines
26 KiB
C#

using System.Collections;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Nice3point.Revit.Toolkit.External;
using Sai.Toolkit.Revit.Helpers;
namespace Sai.RvKits.RvMEP;
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
internal class BloomConnectorCmd : ExternalCommand //根据连接件创建一根短管
{
public override void Execute()
{
try
{
var elemIds = UiDocument.Selection.GetElementIds();
if (elemIds.Count == 0)
{
var reference = UiDocument.Selection.PickObject(ObjectType.Element, new GenericFilter<FamilyInstance>(), "请选择族实例");
elemIds.Add(Document.GetElement(reference).Id);
}
foreach (var elemId in elemIds)
{
var pipeTypeId = Document.OfClass<PipeType>().FirstElementId();
var cableTrayTypeId = Document.OfClass<CableTrayType>().FirstElementId();
var conduitTypeId = Document.OfClass<ConduitType>().FirstElementId();
var filteredElementCollector = Document.OfClass<DuctType>();
var roundTypeId = ElementId.InvalidElementId;
var rectangleTypeId = ElementId.InvalidElementId;
var ovalTypeId = ElementId.InvalidElementId;
foreach (var element2 in filteredElementCollector)
{
var ductType = (DuctType)element2;
if (ductType.FamilyName == "圆形风管" || ductType.FamilyName.Contains("Round Duct"))
{
roundTypeId = ductType.Id;
}
else if (ductType.FamilyName == "矩形风管" || ductType.FamilyName.Contains("Rectangular Duct"))
{
rectangleTypeId = ductType.Id;
}
else if (ductType.FamilyName == "椭圆形风管" || ductType.FamilyName.Contains("Oval Duct"))
{
ovalTypeId = ductType.Id;
}
}
var fabricationConfiguration = FabricationConfiguration.GetFabricationConfiguration(Document);
var elem = Document.GetElement(elemId);
if (elem.GetConnectors(true).IsEmpty && elem is not FamilyInstance)
{
continue;
}
//拿到连接的管线的类型
foreach (Connector conn in elem.GetConnectors())
{
if (conn.IsConnected)
{
var connector = conn.GetConnectedConnector();
if (connector == null)
{
continue;
}
if (conn.Domain == Domain.DomainPiping && connector.Owner is Pipe)
{
pipeTypeId = connector.Owner.GetTypeId();
}
else if (conn.Domain == Domain.DomainHvac)
{
switch (connector.Shape)
{
case ConnectorProfileType.Invalid:
break;
case ConnectorProfileType.Round:
roundTypeId = connector.Owner.GetTypeId();
break;
case ConnectorProfileType.Rectangular:
rectangleTypeId = connector.Owner.GetTypeId();
break;
case ConnectorProfileType.Oval:
ovalTypeId = connector.Owner.GetTypeId();
break;
default:
break;
}
}
else if (conn.Domain == Domain.DomainCableTrayConduit)
{
if (connector.Owner is CableTray cableTray)
{
cableTrayTypeId = cableTray.GetTypeId();
}
else if (connector.Owner is Conduit conduit)
{
conduitTypeId = conduit.GetTypeId();
}
}
}
}
Document.Invoke(
_ =>
{
var conns = elem.GetConnectors(true);
foreach (Connector connector in conns)
{
Element element = null;
if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_FabricationPipework)
{
var serviceId = (elem as FabricationPart).ServiceId;
var button = fabricationConfiguration.GetService(serviceId).GetButton(0, 0);
var fabricationPart = FabricationPart.Create(Document, button, 0, elem.LevelId);
var enumerator2 = fabricationPart.ConnectorManager.Connectors.GetEnumerator();
if (enumerator2.MoveNext())
{
var connector2 = (Connector)enumerator2.Current;
ElementTransformUtils.MoveElement(
Document,
fabricationPart.Id,
connector.Origin - connector2.Origin
);
var basisZ = connector.CoordinateSystem.BasisZ;
var basisZ2 = connector2.CoordinateSystem.BasisZ;
var num = basisZ.DotProduct(basisZ2);
if (Math.Abs(num - -1.0) < 0.0001)
{
connector2.ConnectTo(connector);
continue;
}
var xyz = basisZ.CrossProduct(basisZ2);
var line = Line.CreateBound(connector.Origin, connector.Origin + (10000000000000000.0 * xyz));
var angleTo = basisZ.AngleTo(basisZ2);
var angle = Math.PI - angleTo;
ElementTransformUtils.RotateElement(Document, fabricationPart.Id, line, angle);
if (connector2.Shape == ConnectorProfileType.Invalid)
{
connector2.Radius = connector.Radius;
}
else
{
connector2.Width = connector.Width;
connector2.Height = connector.Height;
}
}
continue;
}
var extensionLength = connector.GetExtensionLength();
var origin = connector.Origin;
var xyz2 = origin + (extensionLength * connector.CoordinateSystem.BasisZ);
var levelId = elem.LevelId;
if (levelId == ElementId.InvalidElementId)
{
var pa = elem.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
if (pa != null)
{
levelId = pa.AsElementId();
}
}
if (levelId == ElementId.InvalidElementId)
{
if (elem is FamilyInstance { Host: Level } instance)
{
levelId = instance.Host.Id;
}
}
switch (connector.Domain)
{
//未定义
case Domain.DomainUndefined:
break;
//风管
case Domain.DomainHvac:
var mechanicalSystemTypes = new FilteredElementCollector(Document)
.OfClass(typeof(MechanicalSystemType))
.Cast<MechanicalSystemType>();
//风管系统类型
var mechanicalSystem =
connector.MEPSystem == null
? connector.DuctSystemType switch
{
//送风
DuctSystemType.SupplyAir
=> mechanicalSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.SupplyAir
),
//回风
DuctSystemType.ReturnAir
=> mechanicalSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.ReturnAir
),
//排风
DuctSystemType.ExhaustAir
=> mechanicalSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.ExhaustAir
),
_
=> mechanicalSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.OtherAir
)
}
: Document.GetElement(connector.MEPSystem.GetTypeId()) as MechanicalSystemType;
//if (new FilteredElementCollector(Document).OfClass(typeof(DuctType)).FirstElement() is not DuctType)
//{
// break;
//}
//风管形状
switch (connector.Shape)
{
case ConnectorProfileType.Round:
element = Duct.Create(
Document,
mechanicalSystem.Id,
roundTypeId,
levelId,
origin,
xyz2
);
Document.Regenerate();
element.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).Set(connector.Radius * 2);
break;
case ConnectorProfileType.Rectangular:
element = Duct.Create(
Document,
mechanicalSystem.Id,
rectangleTypeId,
levelId,
origin,
xyz2
);
Document.Regenerate();
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(connector.Width);
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(connector.Height);
break;
case ConnectorProfileType.Oval:
element = Duct.Create(Document, mechanicalSystem.Id, ovalTypeId, levelId, origin, xyz2);
Document.Regenerate();
element.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).Set(connector.Width);
element.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).Set(connector.Height);
break;
default:
element = Duct.Create(
Document,
mechanicalSystem.Id,
roundTypeId,
levelId,
origin,
xyz2
);
break;
}
break;
//电气
case Domain.DomainElectrical:
break;
//水管
case Domain.DomainPiping:
var pipingSystemTypes = new FilteredElementCollector(Document)
.OfClass(typeof(PipingSystemType))
.Cast<PipingSystemType>();
if (pipeTypeId == ElementId.InvalidElementId)
{
pipeTypeId = Document.OfClass<PipeType>().WhereElementIsElementType().FirstElementId();
}
var system = connector.MEPSystem;
var pipingSystemType =
system != null
? Document.GetElement(system.GetTypeId()) as PipingSystemType
: connector.PipeSystemType switch
{
//循环供水
PipeSystemType.SupplyHydronic
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.SupplyHydronic
),
//循环回水
PipeSystemType.ReturnHydronic
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.ReturnHydronic
),
//卫生设备
PipeSystemType.Sanitary
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.Sanitary
),
//家用热水
PipeSystemType.DomesticHotWater
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.DomesticHotWater
),
//家用冷水
PipeSystemType.DomesticColdWater
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.DomesticColdWater
),
//其他
PipeSystemType.OtherPipe
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.OtherPipe
),
//湿式消防系统
PipeSystemType.FireProtectWet
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.FireProtectWet
),
//干式消防系统
PipeSystemType.FireProtectDry
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.FireProtectDry
),
//预作用消防系统
PipeSystemType.FireProtectPreaction
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.FireProtectPreaction
),
//其他消防系统
PipeSystemType.FireProtectOther
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.FireProtectOther
),
//通风孔
PipeSystemType.Vent
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.Vent
),
_
=> pipingSystemTypes.FirstOrDefault(
pst =>
pst.SystemClassification
== Autodesk.Revit.DB.MEPSystemClassification.OtherPipe
)
};
element = Pipe.Create(Document, pipingSystemType.Id, pipeTypeId, levelId, origin, xyz2);
element.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).Set(connector.Radius * 2);
break;
//电力
case Domain.DomainCableTrayConduit:
if (cableTrayTypeId == ElementId.InvalidElementId)
{
cableTrayTypeId = new FilteredElementCollector(Document)
.OfClass(typeof(CableTrayType))
.FirstElementId();
}
if (conduitTypeId == ElementId.InvalidElementId)
{
conduitTypeId = new FilteredElementCollector(Document)
.OfClass(typeof(ConduitType))
.FirstElementId();
}
//switch (connector.ElectricalSystemType)
//{
// //电力
// case ElectricalSystemType.PowerCircuit:
// break;
//}
switch (connector.Shape)
{
case ConnectorProfileType.Invalid:
break;
case ConnectorProfileType.Round:
element = Conduit.Create(Document, conduitTypeId, origin, xyz2, levelId);
break;
case ConnectorProfileType.Rectangular:
element = CableTray.Create(Document, cableTrayTypeId, origin, xyz2, levelId);
break;
case ConnectorProfileType.Oval:
break;
}
break;
}
Document.Regenerate();
//新建管线连接
if (element == null)
{
continue;
}
var curve = element as MEPCurve;
var manager = curve.ConnectorManager;
var lter = manager.UnusedConnectors.ForwardIterator();
while (lter.MoveNext())
{
var connect = lter.Current as Connector;
if (connect.Origin.IsAlmostEqualTo(connector.Origin))
{
var conn = elem.GetConnectors(true).GetNearestConnector(connector.Origin);
conn.ConnectTo(connect);
break;
}
}
}
},
"引出短管"
);
}
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
Result = Result.Cancelled;
}
}
}