284 lines
10 KiB
C#
284 lines
10 KiB
C#
|
|
using Autodesk.Revit.Attributes;
|
|||
|
|
using Autodesk.Revit.DB;
|
|||
|
|
using Autodesk.Revit.DB.Electrical;
|
|||
|
|
using Autodesk.Revit.UI;
|
|||
|
|
using Autodesk.Revit.UI.Selection;
|
|||
|
|
|
|||
|
|
using Nice3point.Revit.Toolkit.External;
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
|
|||
|
|
using System.Linq;
|
|||
|
|
|
|||
|
|
|
|||
|
|
namespace Szmedi.RvKits.MEPTools
|
|||
|
|
{
|
|||
|
|
[Transaction(TransactionMode.Manual)]
|
|||
|
|
|
|||
|
|
public class CableLayoutCmd : ExternalCommand
|
|||
|
|
{
|
|||
|
|
private readonly IList<Element> elems = new List<Element>();
|
|||
|
|
|
|||
|
|
public override void Execute()
|
|||
|
|
{
|
|||
|
|
CableLayoutWin win = new(Document);
|
|||
|
|
|
|||
|
|
if (win.ShowDialog() != true)
|
|||
|
|
{
|
|||
|
|
Result = Result.Cancelled;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var count = win.ViewModel.Count;
|
|||
|
|
var conduitType = win.ViewModel.SelectedConduitType;
|
|||
|
|
var size = win.ViewModel.Size;
|
|||
|
|
using Transaction trans = new(Document, "敷设电缆");
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
//Reference refer = uidoc.Selection.PickObject(ObjectType.Element, new GenericFilter<CableTray>(), "请选择桥架");
|
|||
|
|
//var ct = uidoc.doc.GetElement(refer) as CableTray;
|
|||
|
|
Reference refer = UiDocument.Selection.PickObject(ObjectType.Element, new GenericFilter<CableTray>(), "请选择需要敷设桥架");
|
|||
|
|
var ct = UiDocument.Document.GetElement(refer) as MEPCurve;
|
|||
|
|
XYZ xyz = refer.GlobalPoint;
|
|||
|
|
//Curve curve = (ct.Location as LocationCurve).Curve;
|
|||
|
|
//XYZ project = curve.Project(xyz).XYZPoint;
|
|||
|
|
elems.Add(ct);
|
|||
|
|
Connector connector = GetNearConnector(ct, xyz);
|
|||
|
|
GetAlrefsElementOrdered(connector);
|
|||
|
|
trans.Start();
|
|||
|
|
Dictionary<int, List<Conduit>> dictionary = new();
|
|||
|
|
List<Conduit> firstConduits = new();
|
|||
|
|
double interval = size.OuterDiameter;
|
|||
|
|
foreach (var elem in elems)
|
|||
|
|
{
|
|||
|
|
if (elem is MEPCurve mepCurve)
|
|||
|
|
{
|
|||
|
|
var loc = mepCurve.Location as LocationCurve;
|
|||
|
|
|
|||
|
|
Conduit conduit = Conduit.Create(
|
|||
|
|
Document,
|
|||
|
|
conduitType.Id,
|
|||
|
|
loc.Curve.GetEndPoint(0),
|
|||
|
|
loc.Curve.GetEndPoint(1),
|
|||
|
|
mepCurve.LevelId
|
|||
|
|
);
|
|||
|
|
firstConduits.Add(conduit);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
dictionary.Add(0, firstConduits);
|
|||
|
|
if (count > 2)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < count; i++)
|
|||
|
|
{
|
|||
|
|
List<Conduit> conduits = new();
|
|||
|
|
var x = Math.Pow(-1, i);
|
|||
|
|
var y = Math.Ceiling(i / 2.0);
|
|||
|
|
var offest = x * y * interval;
|
|||
|
|
if (count % 2 == 0)
|
|||
|
|
{
|
|||
|
|
offest += interval / 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
foreach (var conduit in firstConduits)
|
|||
|
|
{
|
|||
|
|
var loc = conduit.Location as LocationCurve;
|
|||
|
|
var line = loc.Curve as Line;
|
|||
|
|
var direction = line.Direction.CrossProduct(XYZ.BasisZ);
|
|||
|
|
var id = ElementTransformUtils.CopyElement(Document, conduit.Id, direction * offest).FirstOrDefault();
|
|||
|
|
var conduitCopied = Document.GetElement(id) as Conduit;
|
|||
|
|
conduits.Add(conduitCopied);
|
|||
|
|
}
|
|||
|
|
dictionary.Add(i + 1, conduits);
|
|||
|
|
}
|
|||
|
|
Document.Regenerate();
|
|||
|
|
}
|
|||
|
|
for (int i = 0; i < dictionary.Count; i++)
|
|||
|
|
{
|
|||
|
|
var conduits = dictionary[i];
|
|||
|
|
for (var j = 0; j < conduits.Count - 1; j++)
|
|||
|
|
{
|
|||
|
|
var conduit = conduits[j];
|
|||
|
|
var conduit1 = conduits[j + 1];
|
|||
|
|
|
|||
|
|
var list = GetNearestConnector(conduit, conduit1);
|
|||
|
|
if (list[0] != null && list[1] != null)
|
|||
|
|
{
|
|||
|
|
Document.Create.NewElbowFitting(list[0], list[1]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (count % 2 == 0)
|
|||
|
|
{
|
|||
|
|
Document.Delete(firstConduits.Select(e => e.Id).ToList());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
trans.Commit();
|
|||
|
|
}
|
|||
|
|
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
|||
|
|
{
|
|||
|
|
if (trans.GetStatus() == TransactionStatus.Started)
|
|||
|
|
{
|
|||
|
|
trans.Commit();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
ErrorMessage = ex.Message;
|
|||
|
|
if (trans.GetStatus() == TransactionStatus.Started)
|
|||
|
|
{
|
|||
|
|
trans.Commit();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Result = Result.Failed;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static List<Connector> GetNearestConnector(Element element1, Element element2)
|
|||
|
|
{
|
|||
|
|
List<Connector> list = new();
|
|||
|
|
Connector conn1 = null;
|
|||
|
|
Connector conn2 = null;
|
|||
|
|
var conns = ConnectorsUnused(element1).ForwardIterator();
|
|||
|
|
var conns1 = ConnectorsUnused(element2).ForwardIterator();
|
|||
|
|
|
|||
|
|
double distance = double.MaxValue;
|
|||
|
|
while (conns.MoveNext())
|
|||
|
|
{
|
|||
|
|
var connTemp1 = conns.Current as Connector;
|
|||
|
|
conns1.Reset();
|
|||
|
|
while (conns1.MoveNext())
|
|||
|
|
{
|
|||
|
|
var connTemp2 = conns1.Current as Connector;
|
|||
|
|
double tempDistance = connTemp1.Origin.DistanceTo(connTemp2.Origin);
|
|||
|
|
if (distance > tempDistance)
|
|||
|
|
{
|
|||
|
|
distance = tempDistance;
|
|||
|
|
conn1 = connTemp1;
|
|||
|
|
conn2 = connTemp2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
list.Add(conn1);
|
|||
|
|
list.Add(conn2);
|
|||
|
|
return list;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static ConnectorSet ConnectorsUnused(Element element)
|
|||
|
|
{
|
|||
|
|
if (element == null)
|
|||
|
|
{
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ConnectorSet connectorSet = null;
|
|||
|
|
if (element is FamilyInstance familyInstance && familyInstance.MEPModel != null)
|
|||
|
|
{
|
|||
|
|
connectorSet = familyInstance.MEPModel.ConnectorManager?.UnusedConnectors;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (element is MEPCurve mepcurve)
|
|||
|
|
{
|
|||
|
|
connectorSet = mepcurve.ConnectorManager.UnusedConnectors;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (element is FabricationPart fabricationPart)
|
|||
|
|
{
|
|||
|
|
connectorSet = fabricationPart.ConnectorManager.UnusedConnectors;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return connectorSet ?? null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取选择点最近的连接件
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="elem">管线</param>
|
|||
|
|
/// <param name="xyz"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private Connector GetNearConnector(Element elem, XYZ xyz)
|
|||
|
|
{
|
|||
|
|
if (elem is not MEPCurve mep)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentException("元素不是管线");
|
|||
|
|
}
|
|||
|
|
SortedDictionary<double, Connector> dictionary = new();
|
|||
|
|
|
|||
|
|
ConnectorSetIterator connectorSetIterator = mep.ConnectorManager.Connectors.ForwardIterator();
|
|||
|
|
|
|||
|
|
while (connectorSetIterator.MoveNext())
|
|||
|
|
{
|
|||
|
|
Connector connector = connectorSetIterator.Current as Connector;
|
|||
|
|
|
|||
|
|
if (connector.AllRefs.Size > 0)
|
|||
|
|
{
|
|||
|
|
dictionary.Add(connector.Origin.DistanceTo(xyz), connector);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dictionary.Values.ElementAt(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void GetAlrefsElementOrdered(Connector startConnector)
|
|||
|
|
{
|
|||
|
|
//连接的元素
|
|||
|
|
Element elem = null;
|
|||
|
|
//得到与当前连接件连接的连接件
|
|||
|
|
ConnectorSetIterator connectorSetIterator = startConnector.AllRefs.ForwardIterator();
|
|||
|
|
|
|||
|
|
while (connectorSetIterator.MoveNext())
|
|||
|
|
{
|
|||
|
|
Connector currentConn = connectorSetIterator.Current as Connector;
|
|||
|
|
|
|||
|
|
if (currentConn.Origin.IsAlmostEqualTo(startConnector.Origin))
|
|||
|
|
{
|
|||
|
|
elem = currentConn.Owner;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
elems.Add(elem);
|
|||
|
|
Connector connectorConnected = GetConnectorConnected(elem, startConnector);
|
|||
|
|
|
|||
|
|
if (connectorConnected.IsConnected)
|
|||
|
|
{
|
|||
|
|
GetAlrefsElementOrdered(connectorConnected);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private Connector GetConnectorConnected(Element elem, Connector conn)
|
|||
|
|
{
|
|||
|
|
Connector connConnected = null;
|
|||
|
|
ConnectorSet set = null;
|
|||
|
|
if (elem is MEPCurve)
|
|||
|
|
{
|
|||
|
|
MEPCurve mep = elem as MEPCurve;
|
|||
|
|
set = mep.ConnectorManager.Connectors;
|
|||
|
|
}
|
|||
|
|
else if (elem is FamilyInstance)
|
|||
|
|
{
|
|||
|
|
FamilyInstance isntance = elem as FamilyInstance;
|
|||
|
|
set = isntance.MEPModel.ConnectorManager.Connectors;
|
|||
|
|
}
|
|||
|
|
if (set != null)
|
|||
|
|
{
|
|||
|
|
ConnectorSetIterator connectorSetIterator = set.ForwardIterator();
|
|||
|
|
while (connectorSetIterator.MoveNext())
|
|||
|
|
{
|
|||
|
|
Connector currentConn = connectorSetIterator.Current as Connector;
|
|||
|
|
|
|||
|
|
if (currentConn.AllRefs.Size > 0)
|
|||
|
|
{
|
|||
|
|
if (!currentConn.Origin.IsAlmostEqualTo(conn.Origin))
|
|||
|
|
{
|
|||
|
|
connConnected = currentConn;
|
|||
|
|
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return connConnected;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|