static IFCAnyHandle CreateLocalPlacementForConnector(ExporterIFC exporterIFC, Connector connector, IFCAnyHandle elementHandle, IFCFlowDirection flowDir) { try { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle elementPlacement = IFCAnyHandleUtil.GetObjectPlacement(elementHandle); Transform origTrf = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, elementPlacement); Transform connectorCoordinateSystem = connector.CoordinateSystem; if (flowDir == IFCFlowDirection.Sink) { // Reverse the direction of the connector. connectorCoordinateSystem.BasisX = -connectorCoordinateSystem.BasisX; connectorCoordinateSystem.BasisZ = -connectorCoordinateSystem.BasisZ; } Transform relTransform = origTrf.Inverse.Multiply(connectorCoordinateSystem); XYZ scaledOrigin = UnitUtil.ScaleLength(relTransform.Origin); IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, scaledOrigin, relTransform.BasisZ, relTransform.BasisX); return(IFCInstanceExporter.CreateLocalPlacement(file, elementPlacement, relLocalPlacement)); } catch { } return(null); }
/// <summary> /// Gererates port name from connector data /// </summary> /// <param name="flowDirection">The direction of the connector.</param> /// <param name="hostId">The connector's host id.</param> /// <param name="connectorId">The connector's id.</param> /// <returns>Generated port name.</returns> private static string GetPortNameFromFlowDirection(IFCFlowDirection flowDirection, ElementId hostId, int connectorId) { string portAutoName = "Port_"; if (flowDirection == IFCFlowDirection.Sink) { portAutoName = "InPort_"; } else if (flowDirection == IFCFlowDirection.Source) { portAutoName = "OutPort_"; } portAutoName += hostId + "_" + connectorId; return(portAutoName); }
/// <summary> /// Processes IfcDistributionPort attributes. /// </summary> /// <param name="ifcDistributionPort">The IfcDistributionPort handle.</param> protected override void Process(IFCAnyHandle ifcDistributionPort) { base.Process(ifcDistributionPort); FlowDirection = IFCEnums.GetSafeEnumerationAttribute<IFCFlowDirection>(ifcDistributionPort, "FlowDirection", IFCFlowDirection.NotDefined); }
static IFCAnyHandle CreateLocalPlacementForConnector(ExporterIFC exporterIFC, Connector connector, IFCAnyHandle elementHandle, IFCFlowDirection flowDir) { try { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle elementPlacement = IFCAnyHandleUtil.GetObjectPlacement(elementHandle); Transform origTrf = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, elementPlacement); Transform connectorCoordinateSystem = connector.CoordinateSystem; if (flowDir == IFCFlowDirection.Sink) { // Reverse the direction of the connector. connectorCoordinateSystem.BasisX = -connectorCoordinateSystem.BasisX; connectorCoordinateSystem.BasisZ = -connectorCoordinateSystem.BasisZ; } Transform relTransform = origTrf.Inverse.Multiply(connectorCoordinateSystem); XYZ scaledOrigin = UnitUtil.ScaleLength(relTransform.Origin); IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, scaledOrigin, relTransform.BasisZ, relTransform.BasisX); return IFCInstanceExporter.CreateLocalPlacement(file, elementPlacement, relLocalPlacement); } catch { } return null; }
/// <summary> /// Creates an IfcDistributionPort and assigns it to the file. /// </summary> /// <param name="file">The file.</param> /// <param name="guid">The GUID.</param> /// <param name="ownerHistory">The owner history.</param> /// <param name="name">The name.</param> /// <param name="description">The description.</param> /// <param name="objectType">The object type.</param> /// <param name="objectPlacement">The object placement.</param> /// <param name="representation">The geometric representation of the entity.</param> /// <param name="flowDirection">The flow direction.</param> /// <returns>The handle.</returns> public static IFCAnyHandle CreateDistributionPort(IFCFile file, string guid, IFCAnyHandle ownerHistory, string name, string description, string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, IFCFlowDirection? flowDirection) { ValidateProduct(guid, ownerHistory, name, description, objectType, objectPlacement, representation); IFCAnyHandle distributionPort = CreateInstance(file, IFCEntityType.IfcDistributionPort); IFCAnyHandleUtil.SetAttribute(distributionPort, "FlowDirection", flowDirection); SetProduct(distributionPort, guid, ownerHistory, name, description, objectType, objectPlacement, representation); return distributionPort; }
// 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); } } } } }
static void AddConnection(ExporterIFC exporterIFC, Connector connector, Connector connected, bool isBiDirectional, bool isElectricalDomain) { // Port connection is not allowed in IFC4RV MVD if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { return; } Element inElement = connector.Owner; Element outElement = connected.Owner; if (isElectricalDomain) { // We may get a connection back to the original element. Ignore it. if (inElement.Id == outElement.Id) { return; } // Check the outElement to see if it is a Wire; if so, get its connections and "skip" the wire. if (outElement is Wire) { if (m_ProcessedWires.Contains(outElement.Id)) { return; } m_ProcessedWires.Add(outElement.Id); try { ConnectorSet wireConnectorSet = MEPCache.GetConnectorsForWire(outElement as Wire); if (wireConnectorSet != null) { foreach (Connector connectedToWire in wireConnectorSet) { ProcessConnections(exporterIFC, connectedToWire, connector); } } } catch { } return; } } // Check if the connection already exist if (ConnectionExists(inElement.Id, outElement.Id)) { return; } if (isBiDirectional) { if (ConnectionExists(outElement.Id, inElement.Id)) { return; } } IFCAnyHandle inElementIFCHandle = ExporterCacheManager.MEPCache.Find(inElement.Id); IFCAnyHandle outElementIFCHandle = ExporterCacheManager.MEPCache.Find(outElement.Id); // Note TBD: In IFC4 the IfcRelConnectsPortToElement should be used for a dynamic connection. THe static connection should use IfcRelNests if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { if (inElementIFCHandle == null || outElementIFCHandle == null || !IFCAnyHandleUtil.IsSubTypeOf(inElementIFCHandle, IFCEntityType.IfcDistributionElement) || !IFCAnyHandleUtil.IsSubTypeOf(outElementIFCHandle, IFCEntityType.IfcDistributionElement)) { return; } } else { if (inElementIFCHandle == null || outElementIFCHandle == null || !IFCAnyHandleUtil.IsSubTypeOf(inElementIFCHandle, IFCEntityType.IfcElement) || !IFCAnyHandleUtil.IsSubTypeOf(outElementIFCHandle, IFCEntityType.IfcElement)) { return; } } IFCFile ifcFile = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle portOut = null; IFCAnyHandle portIn = null; // ----------------------- In Port ---------------------- { string guid = GUIDUtil.CreateGUID(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Sink; IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connector, inElementIFCHandle, flowDir); string portName = "InPort_" + inElement.Id; string portType = "Flow"; // Assigned as Port.Description portIn = IFCInstanceExporter.CreateDistributionPort(exporterIFC, null, guid, ownerHistory, localPlacement, null, flowDir); IFCAnyHandleUtil.OverrideNameAttribute(portIn, portName); IFCAnyHandleUtil.SetAttribute(portIn, "Description", portType); // Attach the port to the element guid = GUIDUtil.CreateGUID(); string connectionName = inElement.Id + "|" + guid; IFCAnyHandle connectorIn = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, portIn, inElementIFCHandle); } // ----------------------- Out Port---------------------- { string guid = GUIDUtil.CreateGUID(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Source; IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connected, outElementIFCHandle, flowDir); string portName = "OutPort_" + outElement.Id; string portType = "Flow"; // Assigned as Port.Description portOut = IFCInstanceExporter.CreateDistributionPort(exporterIFC, null, guid, ownerHistory, localPlacement, null, flowDir); IFCAnyHandleUtil.OverrideNameAttribute(portOut, portName); IFCAnyHandleUtil.SetAttribute(portOut, "Description", portType); // Attach the port to the element guid = GUIDUtil.CreateGUID(); string connectionName = outElement.Id + "|" + guid; IFCAnyHandle connectorOut = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, portOut, outElementIFCHandle); } // ----------------------- Out Port -> In Port ---------------------- if (portOut != null && portIn != null) { Element elemToUse = (inElement.Id.IntegerValue < outElement.Id.IntegerValue) ? inElement : outElement; string guid = GUIDUtil.CreateGUID(); IFCAnyHandle realizingElement = null; string connectionName = ExporterUtil.GetGlobalId(portIn) + "|" + ExporterUtil.GetGlobalId(portOut); string connectionType = "Flow"; // Assigned as Description IFCInstanceExporter.CreateRelConnectsPorts(ifcFile, guid, ownerHistory, connectionName, connectionType, portIn, portOut, realizingElement); AddConnectionInternal(inElement.Id, outElement.Id); } // Add the handles to the connector system. 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, inElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, outElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, portIn); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, portOut); } } else { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, inElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, outElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, portIn); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, portOut); } } }
// 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> /// Set few attributes for already created distribution port /// </summary> /// <param name="port">The handle of exported connector.</param> /// <param name="connector">The Connector object.</param> /// <param name="portAutoName">The auto gerated name with id.</param> /// <param name="portDescription">The description string to set.</param> private static void SetDistributionPortAttributes(IFCAnyHandle port, Connector connector, string portDescription, ElementId hostId, ref IFCFlowDirection flowDir) { // "Description" IFCAnyHandleUtil.SetAttribute(port, "Description", portDescription); // "Flow" (only for Electrical connectors) if (connector.Domain == Domain.DomainElectrical) { string flowString = ConnectorExporter.GetConnectorParameterFromDescription(connector, "Flow"); IFCFlowDirection parsedFlow; if (Enum.TryParse(flowString, true, out parsedFlow) && (parsedFlow == IFCFlowDirection.Sink || parsedFlow == IFCFlowDirection.Source)) { flowDir = parsedFlow; IFCAnyHandleUtil.SetAttribute(port, "FlowDirection", flowDir); } } // "Name" string portName = ConnectorExporter.GetConnectorParameterFromDescription(connector, "PortName"); if (String.IsNullOrEmpty(portName)) { portName = ConnectorExporter.GetPortNameFromFlowDirection(flowDir, hostId, connector.Id); } IFCAnyHandleUtil.OverrideNameAttribute(port, portName); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { // "PredefinedType" Toolkit.IFC4.IFCDistributionPortType portType = GetMappedIFCDistributionPortType(connector.Domain); string validatedPredefinedType = IFCValidateEntry.ValidateStrEnum <Toolkit.IFC4.IFCDistributionPortType>(portType.ToString()); IFCAnyHandleUtil.SetAttribute(port, "PredefinedType", validatedPredefinedType, true); // "SystemType" from description string systemTypeFromDescription = ConnectorExporter.GetConnectorParameterFromDescription(connector, "SystemType"); string validatedSystemType = IFCValidateEntry.ValidateStrEnum <Toolkit.IFC4.IFCDistributionSystem>(systemTypeFromDescription); if (String.IsNullOrEmpty(validatedSystemType)) { // "SystemType" from revit system classification Toolkit.IFC4.IFCDistributionSystem systemType = GetMappedIFCDistributionSystem(connector); validatedSystemType = IFCValidateEntry.ValidateStrEnum <Toolkit.IFC4.IFCDistributionSystem>(systemType.ToString()); } if (!String.IsNullOrEmpty(validatedSystemType)) { IFCAnyHandleUtil.SetAttribute(port, "SystemType", validatedSystemType, true); } } }
static void AddConnection(ExporterIFC exporterIFC, Connector connector, Connector connected, bool isBiDirectional, bool isElectricalDomain) { // 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 bool isIFC4AndAbove = !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4; Element inElement = connector.Owner; Element outElement = connected.Owner; if (isElectricalDomain) { // We may get a connection back to the original element. Ignore it. if (inElement.Id == outElement.Id) { return; } // Check the outElement to see if it is a Wire; if so, get its connections and "skip" the wire. if (outElement is Wire) { if (m_ProcessedWires.Contains(outElement.Id)) { return; } m_ProcessedWires.Add(outElement.Id); ExporterCacheManager.SystemsCache.AddElectricalSystem((outElement as Wire).MEPSystem.Id); try { ConnectorSet wireConnectorSet = MEPCache.GetConnectorsForWire(outElement as Wire); if (wireConnectorSet != null) { foreach (Connector connectedToWire in wireConnectorSet) { ProcessConnections(exporterIFC, connectedToWire, connector); } } } catch { } return; } } // Check if the connection already exist if (ConnectionExists(inElement.Id, outElement.Id)) { return; } if (isBiDirectional) { if (ConnectionExists(outElement.Id, inElement.Id)) { return; } } IFCAnyHandle inElementIFCHandle = ExporterCacheManager.MEPCache.Find(inElement.Id); IFCAnyHandle outElementIFCHandle = ExporterCacheManager.MEPCache.Find(outElement.Id); // Note: In IFC4 the IfcRelConnectsPortToElement should be used for a dynamic connection. The static connection should use IfcRelNests if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { if (inElementIFCHandle == null || outElementIFCHandle == null || !IFCAnyHandleUtil.IsSubTypeOf(inElementIFCHandle, IFCEntityType.IfcObjectDefinition) || !IFCAnyHandleUtil.IsSubTypeOf(outElementIFCHandle, IFCEntityType.IfcObjectDefinition)) { return; } } else { if (inElementIFCHandle == null || outElementIFCHandle == null || !IFCAnyHandleUtil.IsSubTypeOf(inElementIFCHandle, IFCEntityType.IfcElement) || !IFCAnyHandleUtil.IsSubTypeOf(outElementIFCHandle, IFCEntityType.IfcElement)) { return; } } IFCFile ifcFile = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle portOut = null; IFCAnyHandle portIn = null; // Note: the GUIDs below are stable under the assumption that there is only one distribution // port from element A to element B. Also, note that we don't need the "real" GUIDs for these // elements, just stable ones. string inGuid = ExportUtils.GetExportId(inElement.Document, inElement.Id).ToString(); string outGuid = ExportUtils.GetExportId(outElement.Document, outElement.Id).ToString(); string portInGuid = null; string portOutGuid = null; // ----------------------- In Port ---------------------- { portInGuid = GUIDUtil.GenerateIFCGuidFrom("InPort" + connector.Id, inElement, outElement); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Sink; IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connector, inElementIFCHandle, flowDir); portIn = IFCInstanceExporter.CreateDistributionPort(exporterIFC, null, portInGuid, ownerHistory, localPlacement, null, flowDir); string portType = "Flow"; // Assigned as Port.Description ExporterCacheManager.MEPCache.CacheConnectorHandle(connector, portIn); SetDistributionPortAttributes(portIn, connector, portType, inElement.Id, ref flowDir); // Attach the port to the element string guid = GUIDUtil.GenerateIFCGuidFrom("InPortRelConnects" + connector.Id, inElement, outElement); string connectionName = inElement.Id + "|" + guid; // 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(inElementIFCHandle, portIn); } else { IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, portIn, inElementIFCHandle); } } // ----------------------- Out Port---------------------- { portOutGuid = GUIDUtil.GenerateIFCGuidFrom("OutPort" + connector.Id, outElement, inElement); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Source; IFCAnyHandle localPlacement = CreateLocalPlacementForConnector(exporterIFC, connected, outElementIFCHandle, flowDir); portOut = IFCInstanceExporter.CreateDistributionPort(exporterIFC, null, portOutGuid, ownerHistory, localPlacement, null, flowDir); string portType = "Flow"; // Assigned as Port.Description ExporterCacheManager.MEPCache.CacheConnectorHandle(connected, portOut); SetDistributionPortAttributes(portOut, connected, portType, outElement.Id, ref flowDir); // Attach the port to the element string guid = GUIDUtil.GenerateIFCGuidFrom("OutPortRelConnects" + connector.Id.ToString(), outElement, inElement); string connectionName = outElement.Id + "|" + guid; // 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(outElementIFCHandle, portOut); } else { IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, connectionName, portType, portOut, outElementIFCHandle); } } // ----------------------- Out Port -> In Port ---------------------- if (portOut != null && portIn != null) { IFCAnyHandle realizingElement = null; string connectionName = portInGuid + "|" + portOutGuid; string connectionType = "Flow"; // Assigned as Description string guid = GUIDUtil.GenerateIFCGuidFrom(IFCEntityType.IfcRelConnectsPorts, portIn, portOut); IFCInstanceExporter.CreateRelConnectsPorts(ifcFile, guid, ownerHistory, connectionName, connectionType, portIn, portOut, realizingElement); AddConnectionInternal(inElement.Id, outElement.Id); } // Add the handles to the connector system. 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, inElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, outElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, portIn); ExporterCacheManager.SystemsCache.AddHandleToElectricalSystem(system.Id, portOut); } } else { foreach (MEPSystem system in systemList) { ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, inElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, outElementIFCHandle); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, portIn); ExporterCacheManager.SystemsCache.AddHandleToBuiltInSystem(system, portOut); } } }
/// <summary> /// Processes IfcDistributionPort attributes. /// </summary> /// <param name="ifcDistributionPort">The IfcDistributionPort handle.</param> protected override void Process(IFCAnyHandle ifcDistributionPort) { base.Process(ifcDistributionPort); FlowDirection = IFCEnums.GetSafeEnumerationAttribute <IFCFlowDirection>(ifcDistributionPort, "FlowDirection", IFCFlowDirection.NotDefined); }
/// <summary> /// Add IFC Nodes /// </summary> /// <param name="ifcFile"></param> /// <param name="exporterIFC"></param> /// <param name="inElement"></param> /// <param name="outElement"></param> /// <param name="isBiDirectional"></param> static void AddConnection(IFCFile ifcFile, ExporterIFC exporterIFC, Element inElement, Element outElement, bool isBiDirectional) { // Check if the connection already exist if (connectionExists(inElement.Id, outElement.Id)) { return; } if (isBiDirectional) { if (connectionExists(outElement.Id, inElement.Id)) { return; } } IFCAnyHandle inElementIFCHandle = ExporterCacheManager.MEPCache.Find(inElement.Id); IFCAnyHandle outElementIFCHandle = ExporterCacheManager.MEPCache.Find(outElement.Id); if (inElementIFCHandle == null || outElementIFCHandle == null || !IFCAnyHandleUtil.IsSubTypeOf(inElementIFCHandle, IFCEntityType.IfcElement) || !IFCAnyHandleUtil.IsSubTypeOf(outElementIFCHandle, IFCEntityType.IfcElement)) { return; } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); IFCAnyHandle portOut = null; IFCAnyHandle portIn = null; // ----------------------- In Port ---------------------- { // Make Source port IFCAnyHandle productRepresentation = null; string guid = ExporterIFCUtils.CreateGUID(); string objType = IFCEntityType.IfcDistributionPort.ToString(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Sink; portIn = IFCInstanceExporter.CreateDistributionPort(ifcFile, guid, ownerHistory, null, null, objType, null, productRepresentation, flowDir); // Attach the port to the element guid = ExporterIFCUtils.CreateGUID(); IFCAnyHandle connectorIn = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, null, null, portIn, inElementIFCHandle); } // ----------------------- Out Port---------------------- { IFCAnyHandle productRepresentation = null; string guid = ExporterIFCUtils.CreateGUID(); string objType = IFCEntityType.IfcDistributionPort.ToString(); IFCFlowDirection flowDir = (isBiDirectional) ? IFCFlowDirection.SourceAndSink : IFCFlowDirection.Source; portOut = IFCInstanceExporter.CreateDistributionPort(ifcFile, guid, ownerHistory, null, null, objType, null, productRepresentation, flowDir); // Attach the port to the element guid = ExporterIFCUtils.CreateGUID(); IFCAnyHandle connectorOut = IFCInstanceExporter.CreateRelConnectsPortToElement(ifcFile, guid, ownerHistory, null, null, portOut, outElementIFCHandle); } // ----------------------- Out Port -> In Port ---------------------- if (portOut != null && portIn != null) { string guid = ExporterIFCUtils.CreateGUID(); IFCAnyHandle realizingElement = null; IFCInstanceExporter.CreateRelConnectsPorts(ifcFile, guid, ownerHistory, null, null, portIn, portOut, realizingElement); addConnection(inElement.Id, outElement.Id); } }