static public List <Connector> GetConnectors(ConnectorManager conMngr) { List <Connector> list = new List <Connector>(); ConnectorSetIterator csi = conMngr.Connectors.ForwardIterator(); while (csi.MoveNext()) { Connector conn = csi.Current as Connector; list.Add(conn); } return(list); }
// If originalConnector != null, use that connector for AddConnection routine, instead of connector. private static void ProcessConnections(ExporterIFC exporterIFC, Connector connector, Connector originalConnector) { Domain domain = connector.Domain; bool isElectricalDomain = (domain == Domain.DomainElectrical); bool supportsDirection = (domain == Domain.DomainHvac || domain == Domain.DomainPiping); ConnectorType connectorType = connector.ConnectorType; if (connectorType == ConnectorType.End || connectorType == ConnectorType.Curve || connectorType == ConnectorType.Physical) { if (connector.IsConnected) { ConnectorSet connectorSet = connector.AllRefs; ConnectorSetIterator csi = connectorSet.ForwardIterator(); while (csi.MoveNext()) { Connector connected = csi.Current as Connector; if (connected != null && connected.Owner != null && connector.Owner != null) { if (connected.Owner.Id != connector.Owner.Id) { // look for physical connections ConnectorType connectedType = connected.ConnectorType; if (connectedType == ConnectorType.End || connectedType == ConnectorType.Curve || connectedType == ConnectorType.Physical) { Connector originalConnectorToUse = (originalConnector != null) ? originalConnector : connector; FlowDirectionType flowDirection = supportsDirection ? connector.Direction : FlowDirectionType.Bidirectional; if (flowDirection == FlowDirectionType.Out) { AddConnection(exporterIFC, connected, originalConnectorToUse, false, isElectricalDomain); } else { bool isBiDirectional = (flowDirection == FlowDirectionType.Bidirectional); AddConnection(exporterIFC, originalConnectorToUse, connected, isBiDirectional, isElectricalDomain); } } } } } } } }
/// <summary> /// 获得某个元素的某个连接件上连接的其他元素 /// </summary> /// <param name="element"></param> /// <param name="conn"></param> /// <returns></returns> public static List <Element> GetConnLinkedElements(Element element, Connector conn) { List <Element> elements = new List <Element>(); ConnectorSetIterator connectorSetIterator = conn.AllRefs.ForwardIterator(); while (connectorSetIterator.MoveNext()) { Connector connref = connectorSetIterator.Current as Connector; Element elem = connref.Owner; if (elem != null && elem.UniqueId != element.UniqueId) { elements.Add(elem); } } return(elements); }
/// <summary> /// 获取设备上指定点的连接键 /// </summary> /// <param name="elem">设备</param> /// <param name="inspt">特定点</param> /// <returns>连接键</returns> public static Connector GetConnector(Element elem, XYZ inspt) { if (elem == null || inspt == null) { return(null); } ConnectorSet cSet = GetConnectorSet(elem); ConnectorSetIterator csi = cSet.ForwardIterator(); while (csi.MoveNext()) { Connector curConn = csi.Current as Connector; if (curConn.Origin.IsAlmostEqualTo(inspt)) { return(curConn); } } return(null); }
// If originalConnector != null, use that connector for AddConnection routine, instead of connector. private static void ProcessConnections(ExporterIFC exporterIFC, Connector connector, Connector originalConnector) { // Port connection is not allowed for IFC4RV MVD if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { return; } Domain domain = connector.Domain; bool isElectricalDomain = (domain == Domain.DomainElectrical); bool supportsDirection = (domain == Domain.DomainHvac || domain == Domain.DomainPiping); ConnectorType connectorType = connector.ConnectorType; if (connectorType == ConnectorType.End || connectorType == ConnectorType.Curve || connectorType == ConnectorType.Physical) { Connector originalConnectorToUse = (originalConnector != null) ? originalConnector : connector; FlowDirectionType flowDirection = supportsDirection ? connector.Direction : FlowDirectionType.Bidirectional; bool isBiDirectional = (flowDirection == FlowDirectionType.Bidirectional); if (connector.IsConnected) { ConnectorSet connectorSet = connector.AllRefs; ConnectorSetIterator csi = connectorSet.ForwardIterator(); while (csi.MoveNext()) { Connector connected = csi.Current as Connector; if (connected != null && connected.Owner != null && connector.Owner != null) { if (connected.Owner.Id != connector.Owner.Id) { // look for physical connections ConnectorType connectedType = connected.ConnectorType; if (connectedType == ConnectorType.End || connectedType == ConnectorType.Curve || connectedType == ConnectorType.Physical) { if (flowDirection == FlowDirectionType.Out) { AddConnection(exporterIFC, connected, originalConnectorToUse, false, isElectricalDomain); } else { AddConnection(exporterIFC, originalConnectorToUse, connected, isBiDirectional, isElectricalDomain); } } } } } } else { string guid = GUIDUtil.CreateGUID(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : (flowDirection == FlowDirectionType.Out ? IFCFlowDirection.Sink : IFCFlowDirection.Source); Element hostElement = connector.Owner; IFCAnyHandle hostElementIFCHandle = ExporterCacheManager.MEPCache.Find(hostElement.Id); if (ExporterCacheManager.ExportOptionsCache.ExportAs4 && !(IFCAnyHandleUtil.IsSubTypeOf(hostElementIFCHandle, IFCEntityType.IfcDistributionElement))) { return; } IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connector, hostElementIFCHandle, flowDir); IFCFile ifcFile = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle port = IFCInstanceExporter.CreateDistributionPort(exporterIFC, null, guid, ownerHistory, localPlacement, null, flowDir); string portName = "Port_" + hostElement.Id; IFCAnyHandleUtil.OverrideNameAttribute(port, portName); string portType = "Flow"; // Assigned as Port.Description IFCAnyHandleUtil.SetAttribute(port, "Description", portType); // Attach the port to the element guid = GUIDUtil.CreateGUID(); string connectionName = hostElement.Id + "|" + guid; IFCAnyHandle connectorHandle = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, port, hostElementIFCHandle); HashSet <MEPSystem> systemList = new HashSet <MEPSystem>(); try { MEPSystem system = connector.MEPSystem; if (system != null) { systemList.Add(system); } } catch { } if (isElectricalDomain) { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddElectricalSystem(system.Id); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, hostElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, port); } } else { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, hostElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, port); } } } } }
// If originalConnector != null, use that connector for AddConnection routine, instead of connector. private static void ProcessConnections(ExporterIFC exporterIFC, Connector connector, Connector originalConnector) { // Port connection is not allowed for IFC4RV MVD bool isIFC4AndAbove = !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4; Domain domain = connector.Domain; bool isElectricalDomain = (domain == Domain.DomainElectrical); bool supportsDirection = (domain == Domain.DomainHvac || domain == Domain.DomainPiping); ConnectorType connectorType = connector.ConnectorType; if (connectorType == ConnectorType.End || connectorType == ConnectorType.Curve || connectorType == ConnectorType.Physical) { Connector originalConnectorToUse = originalConnector ?? connector; FlowDirectionType flowDirection = supportsDirection ? connector.Direction : FlowDirectionType.Bidirectional; bool isBiDirectional = (flowDirection == FlowDirectionType.Bidirectional); if (connector.IsConnected) { ConnectorSet connectorSet = connector.AllRefs; ConnectorSetIterator csi = connectorSet.ForwardIterator(); while (csi.MoveNext()) { Connector connected = csi.Current as Connector; if (connected != null && connected.Owner != null && connector.Owner != null) { if (connected.Owner.Id != connector.Owner.Id) { // look for physical connections ConnectorType connectedType = connected.ConnectorType; if (connectedType == ConnectorType.End || connectedType == ConnectorType.Curve || connectedType == ConnectorType.Physical) { if (flowDirection == FlowDirectionType.Out) { AddConnection(exporterIFC, connected, originalConnectorToUse, false, isElectricalDomain); } else { AddConnection(exporterIFC, originalConnectorToUse, connected, isBiDirectional, isElectricalDomain); } } } } } } else { Element hostElement = connector.Owner; IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : (flowDirection == FlowDirectionType.Out ? IFCFlowDirection.Source : IFCFlowDirection.Sink); IFCAnyHandle hostElementIFCHandle = ExporterCacheManager.MEPCache.Find(hostElement.Id); string guid = GUIDUtil.GenerateIFCGuidFrom(IFCEntityType.IfcDistributionPort, connector.Id.ToString(), hostElementIFCHandle); IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connector, hostElementIFCHandle, flowDir); IFCFile ifcFile = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle port = IFCInstanceExporter.CreateDistributionPort(exporterIFC, null, guid, ownerHistory, localPlacement, null, flowDir); string portType = "Flow"; // Assigned as Port.Description ExporterCacheManager.MEPCache.CacheConnectorHandle(connector, port); SetDistributionPortAttributes(port, connector, portType, hostElement.Id, ref flowDir); // Port connection is changed in IFC4 to use IfcRelNests for static connection. IfcRelConnectsPortToElement is used for a dynamic connection and it is restricted to IfcDistributionElement // The following code collects the ports that are nested to the object to be assigned later if (isIFC4AndAbove) { AddNestedMembership(hostElementIFCHandle, port); } else { // Attach the port to the element string relGuid = GUIDUtil.GenerateIFCGuidFrom(IFCEntityType.IfcRelConnectsPortToElement, connector.Id.ToString(), port); string connectionName = hostElement.Id + "|" + guid; IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, relGuid, ownerHistory, connectionName, portType, port, hostElementIFCHandle); } HashSet <MEPSystem> systemList = new HashSet <MEPSystem>(); try { MEPSystem system = connector.MEPSystem; if (system != null) { systemList.Add(system); } } catch { } if (isElectricalDomain) { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddElectricalSystem(system.Id); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, hostElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, port); } } else { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, hostElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, port); } } } } }
/// <summary> /// Exports a connector instance. Almost verbatim exmaple from Revit 2012 API for Connector Class /// Works only for HVAC and Piping for now /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="connectors">The ConnectorSet object.</param> private static void Export(ExporterIFC exporterIFC, ConnectorSet connectors) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { foreach (Connector connector in connectors) { try { if (connector != null) { if (connector.Domain == Domain.DomainHvac || connector.Domain == Domain.DomainPiping) { if (connector.ConnectorType == ConnectorType.End || connector.ConnectorType == ConnectorType.Curve || connector.ConnectorType == ConnectorType.Physical) { if (connector.IsConnected) { ConnectorSet connectorSet = connector.AllRefs; ConnectorSetIterator csi = connectorSet.ForwardIterator(); while (csi.MoveNext()) { Connector connected = csi.Current as Connector; if (connected != null && connected.Owner != null && connector.Owner != null) { if (connected.Owner.Id != connector.Owner.Id) { // look for physical connections if (connected.ConnectorType == ConnectorType.End || connected.ConnectorType == ConnectorType.Curve || connected.ConnectorType == ConnectorType.Physical) { if (connector.Direction == FlowDirectionType.Out) { AddConnection(file, exporterIFC, connected.Owner, connector.Owner, false); } else { bool isBiDirectional = (connector.Direction == FlowDirectionType.Bidirectional); AddConnection(file, exporterIFC, connector.Owner, connected.Owner, isBiDirectional); } } } } } } } } } } catch (System.Exception) { // Log an error here } } tr.Commit(); } }
public Result Run() { Trace.Listeners.Clear(); Trace.AutoFlush = true; string outputFileName = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "AutoRoute.log"); if (File.Exists(outputFileName)) { File.Delete(outputFileName); } TextWriterTraceListener listener = new TextWriterTraceListener(outputFileName); Trace.Listeners.Add(listener); // ElementClassFilter systemTypeFilter = new ElementClassFilter(typeof(MEPSystemType)); FilteredElementCollector C = new FilteredElementCollector(m_document); C.WherePasses(systemTypeFilter); foreach (MEPSystemType type in C) { if (type.SystemClassification == MEPSystemClassification.SupplyAir) { m_systemTypeId = type.Id; //送风系统 break; } } Transaction transaction = new Transaction(m_document, "Sample_AutoRoute"); try { transaction.Start(); //标高 m_level = Level.Create(m_document, 0.0); //Element List <Autodesk.Revit.DB.ElementId> ids = new List <ElementId>(); ids.Add(new ElementId(730127)); //baseEquipment ids.Add(new ElementId(730237)); ids.Add(new ElementId(730244)); //Init Elements Info FamilyInstance[] instances = new FamilyInstance[3]; BoundingBoxXYZ[] boxes = new BoundingBoxXYZ[3]; Connector[] conns = new Connector[3]; ConnectorSetIterator csi = null; for (int i = 0; i < ids.Count; i++) { Element element = m_document.GetElement(ids[i]); if (null == element) { return(Result.Failed); } instances[i] = element as FamilyInstance; csi = ConnectorInfo.GetConnectors(element).ForwardIterator(); csi.MoveNext(); conns[i] = csi.Current as Connector; boxes[i] = instances[i].get_BoundingBox(m_document.ActiveView); } //Find the "Out" and "SupplyAir" connector on the base equipment //the first element is base equipment var baseEquipment = instances[0]; csi = ConnectorInfo.GetConnectors(baseEquipment).ForwardIterator(); while (csi.MoveNext()) { Connector conn = csi.Current as Connector; if (conn.Domain == Domain.DomainHvac || conn.Domain == Domain.DomainPiping) { //conn.Direction 只有DomainHvac和DomainPiping有 if (conn.Direction == FlowDirectionType.Out) { DuctSystemType ductSystemType = DuctSystemType.UndefinedSystemType; try { //DuctSystemType PipeSystemType ElectricalSystemType //每个连接件只有上述三个中的一个,调用其他时回报异常 ductSystemType = conn.DuctSystemType; } catch { continue; } if (ductSystemType == DuctSystemType.SupplyAir) { conns[0] = conn; break; } } } } //mechanicalSystem m_mechanicalSystem = CreateMechanicalSystem( //[378728][SupplyAir][Out][RectProfile][OST_MechanicalEquipment] new ConnectorInfo(baseEquipment, conns[0].Origin.X, conns[0].Origin.Y, conns[0].Origin.Z), new ConnectorInfo[] { //[378707][SupplyAir][In][RectProfile] new ConnectorInfo(instances[1], conns[1].Origin.X, conns[1].Origin.Y, conns[1].Origin.Z), //[378716][SupplyAir][In][RectProfile] new ConnectorInfo(instances[2], conns[2].Origin.X, conns[2].Origin.Y, conns[2].Origin.Z) }, DuctSystemType.SupplyAir ); //Get the boundary of the system double minX = conns[0].Origin.X; double minY = conns[0].Origin.Y; double maxX = conns[0].Origin.X; double maxY = conns[0].Origin.Y; double maxZ = conns[0].Origin.Z; for (int i = 1; i < boxes.Length; ++i) { if (conns[i].Origin.X < minX) { minX = conns[i].Origin.X; } if (conns[i].Origin.Y < minY) { minY = conns[i].Origin.Y; } if (conns[i].Origin.X > maxX) { maxX = conns[i].Origin.X; } if (conns[i].Origin.Y > maxY) { maxY = conns[i].Origin.Y; } if (conns[i].Origin.Z > maxZ) { maxZ = conns[i].Origin.Z; } } //Calculate the optional values(可选值) for the trunk ducts double midX = (minX + maxX) / 2; double midY = (minY + maxY) / 2; double[] baseXValues = new double[3] { midX, (minX + midX) / 2, (maxX + midX) / 2 }; double[] baseYValues = new double[3] { midY, (minY + midY) / 2, (maxY + midY) / 2 }; //ductType m_ductType = m_document.GetElement(m_ductTypeId) as DuctType; List <XYZ> points = new List <XYZ>(); //conn[0]相关点 #region conn[0] XYZ connectorDirection = conns[0].CoordinateSystem.BasisZ; if (0 == connectorDirection.DistanceTo(new XYZ(-1, 0, 0))) { points.Add(new XYZ(conns[0].Origin.X - min1FittingLength, conns[0].Origin.Y, conns[0].Origin.Z)); points.Add(new XYZ(conns[0].Origin.X - min2FittingsLength, conns[0].Origin.Y, conns[0].Origin.Z + min1FittingLength)); points.Add(new XYZ(conns[0].Origin.X - min2FittingsLength, conns[0].Origin.Y, maxZ + verticalTrunkOffset - min1FittingLength)); } else if (0 == connectorDirection.DistanceTo(new XYZ(1, 0, 0))) { points.Add(new XYZ(conns[0].Origin.X + min1FittingLength, conns[0].Origin.Y, conns[0].Origin.Z)); points.Add(new XYZ(conns[0].Origin.X + min2FittingsLength, conns[0].Origin.Y, conns[0].Origin.Z + min1FittingLength)); points.Add(new XYZ(conns[0].Origin.X + min2FittingsLength, conns[0].Origin.Y, maxZ + verticalTrunkOffset - min1FittingLength)); } else if (0 == connectorDirection.DistanceTo(new XYZ(0, -1, 0))) { points.Add(new XYZ(conns[0].Origin.X, conns[0].Origin.Y - min1FittingLength, conns[0].Origin.Z)); points.Add(new XYZ(conns[0].Origin.X, conns[0].Origin.Y - min2FittingsLength, conns[0].Origin.Z + min1FittingLength)); points.Add(new XYZ(conns[0].Origin.X, conns[0].Origin.Y - min2FittingsLength, maxZ + verticalTrunkOffset - min1FittingLength)); } else if (0 == connectorDirection.DistanceTo(new XYZ(0, 1, 0))) { points.Add(new XYZ(conns[0].Origin.X, conns[0].Origin.Y + min1FittingLength, conns[0].Origin.Z)); points.Add(new XYZ(conns[0].Origin.X, conns[0].Origin.Y + min2FittingsLength, conns[0].Origin.Z + min1FittingLength)); points.Add(new XYZ(conns[0].Origin.X, conns[0].Origin.Y + min2FittingsLength, maxZ + verticalTrunkOffset - min1FittingLength)); } #endregion //开始创建风管 List <Duct> ducts = new List <Duct>(); List <Connector> connectors = new List <Connector>(); List <Connector> baseConnectors = new List <Connector>(); ducts.Add(Duct.Create(m_document, m_ductTypeId, m_level.Id, conns[0], points[0])); ducts.Add(Duct.Create(m_document, m_systemTypeId, m_ductTypeId, m_level.Id, points[1], points[2])); connectors.Add(ConnectorInfo.GetConnector(ducts[0], points[0])); connectors.Add(ConnectorInfo.GetConnector(ducts[1], points[1])); connectors.Add(ConnectorInfo.GetConnector(ducts[1], points[2])); //连接管道,二选一,效果是一样的 //connectors[0].ConnectTo(connectors[1]); m_document.Create.NewElbowFitting(connectors[0], connectors[1]); baseConnectors.Add(connectors[2]); //Create the vertical ducts for terminals points.Clear(); ducts.Clear(); //conn[1] conn[2] 相关点 points.Add(new XYZ(conns[1].Origin.X, conns[1].Origin.Y, maxZ + verticalTrunkOffset - min1FittingLength)); points.Add(new XYZ(conns[2].Origin.X, conns[2].Origin.Y, maxZ + verticalTrunkOffset - min1FittingLength)); ducts.Add(Duct.Create(m_document, m_ductTypeId, m_level.Id, conns[1], points[0])); ducts.Add(Duct.Create(m_document, m_ductTypeId, m_level.Id, conns[2], points[1])); baseConnectors.Add(ConnectorInfo.GetConnector(ducts[0], points[0])); baseConnectors.Add(ConnectorInfo.GetConnector(ducts[1], points[1])); ////最顶部的 baseConnectors 相关 //SortConnectorsByX(baseConnectors); //for (int i = 0; i < baseYValues.Length; ++i) //{ // if (ConnectSystemOnXAxis(baseConnectors, baseYValues[i])) // { // LogUtility.WriteMechanicalSystem(m_mechanicalSystem); // return Autodesk.Revit.UI.Result.Succeeded; // } //} SortConnectorsByY(baseConnectors); for (int i = 0; i < baseXValues.Length; ++i) { if (ConnectSystemOnYAxis(baseConnectors, baseXValues[i])) { LogUtility.WriteMechanicalSystem(m_mechanicalSystem); transaction.Commit(); return(Autodesk.Revit.UI.Result.Succeeded); } } ////如果任然无法连接,把干管放到maxbbox外 //SortConnectorsByX(baseConnectors); //if (ConnectSystemOnXAxis(baseConnectors, maxY + horizontalOptionalTrunkOffset)) //{ // LogUtility.WriteMechanicalSystem(m_mechanicalSystem); // return Autodesk.Revit.UI.Result.Succeeded; //} //SortConnectorsByY(baseConnectors); //if (ConnectSystemOnYAxis(baseConnectors, maxX + horizontalOptionalTrunkOffset)) //{ // LogUtility.WriteMechanicalSystem(m_mechanicalSystem); // return Autodesk.Revit.UI.Result.Succeeded; //} ////如果任然无法连接,随便连一个,让revit报错吧 //connectors.Clear(); //SortConnectorsByX(baseConnectors); //connectors.AddRange(CreateDuct(new XYZ(baseConnectors[0].Origin.X + min1FittingLength, baseYValues[0], maxZ + verticalTrunkOffset), new XYZ(baseConnectors[1].Origin.X - min1FittingLength, baseYValues[0], maxZ + verticalTrunkOffset))); //connectors.AddRange(CreateDuct(new XYZ(baseConnectors[1].Origin.X + min1FittingLength, baseYValues[0], maxZ + verticalTrunkOffset), new XYZ(baseConnectors[2].Origin.X - min1FittingLength, baseYValues[0], maxZ + verticalTrunkOffset))); //ConnectWithElbowFittingOnXAxis(baseConnectors[0], connectors[0]); //ConnectWithElbowFittingOnXAxis(baseConnectors[2], connectors[3]); //ConnectWithTeeFittingOnXAxis(baseConnectors[1], connectors[1], connectors[2], false); } catch (Exception ex) { transaction.RollBack(); Trace.WriteLine(ex.ToString()); return(Autodesk.Revit.UI.Result.Failed); } finally { Trace.Flush(); listener.Close(); Trace.Close(); Trace.Listeners.Remove(listener); } transaction.RollBack(); return(Result.Succeeded); }