如何从整体上去分析 Revit 的管道和风管系统。
在 Revit 中,水暖两个专业有极大的相似性。从API层面上来说,他们有共同的基类 MEPCurve
。
MEPSystem
用来表示当前的 MEPCurve
是什么系统类型,水、暖、电。ConnectorManager
用来管理连接性。Diameter
和 Height
Width
是互斥的,表示圆形或者矩形。
namespace Autodesk.Revit.DB
{
public class MEPCurve : HostObject
{
public MEPSystem MEPSystem { get; }
public Level ReferenceLevel { get; set; }
public double LevelOffset { get; set; }
public double Diameter { get; }
public double Height { get; }
public double Width { get; }
public ConnectorManager ConnectorManager { get; }
}
}
MEPSystem
的继承关系:
以下面这个机械送风系统为例,选中的是这个矩形风管,它是这个风管的一个属性。而 MEPSystem
是继承 Element
,它更像是一组 Element
的集合,从概念上和 Group
、Assembly
很接近。
水、暖作为系统,在绘制的过程中,会涉及到管段、弯头、首选连接类型、连接、四通、过渡件、活接头、法兰、管帽。这些内容都附加给了管道,即管道表示了一个抽象的系统。下图实际上选中的是一个管段,布管系统设置是管段类型的一个参数。
管道系统:
风管系统:
如何获取布管系统配置:
PipeType
RoutingPreferenceManager
RoutingPreferenceRule
Segment
private List<double> GetAvailablePipeSegmentSizesFromDocument(Document document)
{
System.Collections.Generic.HashSet<double> sizes = new HashSet<double>();
FilteredElementCollector collectorPipeType = new FilteredElementCollector(document);
collectorPipeType.OfClass(typeof(PipeType));
IEnumerable<PipeType> pipeTypes = collectorPipeType.ToElements().Cast<PipeType>();
foreach (PipeType pipeType in pipeTypes)
{
RoutingPreferenceManager rpm = pipeType.RoutingPreferenceManager;
int segmentCount = rpm.GetNumberOfRules(RoutingPreferenceRuleGroupType.Segments);
for (int index = 0; index != segmentCount; ++index)
{
RoutingPreferenceRule segmentRule = rpm.GetRule(RoutingPreferenceRuleGroupType.Segments, index);
Segment segment = document.GetElement(segmentRule.MEPPartId) as Segment;
foreach (MEPSize size in segment.GetSizes())
{
sizes.Add(size.NominalDiameter); //Use a hash-set to remove duplicate sizes among Segments and PipeTypes.
}
}
}
List<double> sizesSorted = sizes.ToList();
sizesSorted.Sort();
return sizesSorted;
}
注:Segment
也是一个抽象的存在,文件中没有任何构件实例,依然可以在文件找到 PipeSegment
,应该是从属于构件类型的。
ConnectorManager
维持和其它构件的连接关系。
namespace Autodesk.Revit.DB
{
//
// 摘要:
// Provides access to the Connector Manager
public class ConnectorManager : IDisposable
{
public Element Owner { get; }
public ConnectorSet UnusedConnectors { get; }
public ConnectorSet Connectors { get; }
public Connector Lookup(int index);
~ConnectorManager();
public bool IsValidObject { get; }
public sealed override void Dispose();
[HandleProcessCorruptedStateExceptions]
protected virtual void Dispose(bool A_0);
protected virtual void ReleaseUnmanagedResources(bool disposing);
}
}
Connector
管理了和连接所有相关的内容,接口比较丰富。下面如何从Connector
获取对应的 Element
。
public void GetElementAtConnector(Autodesk.Revit.DB.Connector connector)
{
MEPSystem mepSystem = connector.MEPSystem;
if (null != mepSystem)
{
string message = "Connector is owned by: " + connector.Owner.Name;
if (connector.IsConnected == true)
{
ConnectorSet connectorSet = connector.AllRefs;
ConnectorSetIterator csi = connectorSet.ForwardIterator();
while (csi.MoveNext())
{
Connector connected = csi.Current as Connector;
if (null != connected)
{
// look for physical connections
if (connected.ConnectorType == ConnectorType.End ||
connected.ConnectorType == ConnectorType.Curve ||
connected.ConnectorType == ConnectorType.Physical)
{
message += "\nConnector is connected to: " + connected.Owner.Name;
message += "\nConnection type is: " + connected.ConnectorType;
}
}
}
}
else
{
message += "\nConnector is not connected to anything.";
}
TaskDialog.Show("Revit", message);
}
}
从设计思路上看,Pipe & Duct -管道和风管本身有对应的构件,但他们的类型分别作为管道系统和机械系统的入口。而结构中的梁系统则不同,是一个单独的可被选中的构件,且有独立的入口按钮。因此,可以认为 Revit 这里针对抽象的系统,有两种不同类型的实现。