前言
这个例子介绍了用广度遍历的方式遍历MEP系统。
内容
打开 Revit 自带例子,选择红框中的某条风管,不要选择机械,图中选中只是为了和遍历结果对应:
红色区域到风管机的遍历结果:
核心逻辑
遍历逻辑主函数:
public void Traverse(){
// 获取根节点
m_startingElementNode = GetStartingElementNode();
// 广度遍历
Traverse(m_startingElementNode);
}
广度遍历:
private void Traverse(TreeNode elementNode){
AppendChildren(elementNode);
foreach (TreeNode node in elementNode.ChildNodes){
Traverse(node);
}
}
添加子节点逻辑:
private void AppendChildren(TreeNode elementNode){
List<TreeNode> nodes = elementNode.ChildNodes;
ConnectorSet connectors;
// 找到相关连接,可能是管件,也可能是管线
Element element = GetElementById(elementNode.Id);
FamilyInstance fi = element as FamilyInstance;
if (fi != null){
connectors = fi.MEPModel.ConnectorManager.Connectors;
} else {
MEPCurve mepCurve = element as MEPCurve;
connectors = mepCurve.ConnectorManager.Connectors;
}
// 处理所有的连接件
foreach (Connector connector in connectors){
MEPSystem mepSystem = connector.MEPSystem;
// Ignore the connector does not belong to any MEP System or belongs to another different MEP system
if (mepSystem == null || !mepSystem.Id.IntegerValue.Equals(m_system.Id.IntegerValue)){
continue;
}
//
// 找到当前节点的方向,如果 Parent 为空,即根节点,那么就用一个连接方向作为它的方向
// 如果 Parent 不为空,则用连接的方向作为自己的方向
if (elementNode.Parent == null){
if (connector.IsConnected){
elementNode.Direction = connector.Direction;
}
} else {
if (connector.IsConnectedTo(elementNode.InputConnector)) {
elementNode.Direction = connector.Direction;
continue;
}
}
// 从当前的连接生成一个子节点
Connector connectedConnector = GetConnectedConnector(connector);
if (connectedConnector != null){
TreeNode node = new TreeNode(m_document, connectedConnector.Owner.Id);
node.InputConnector = connector;
node.Parent = elementNode;
nodes.Add(node);
}
}
}