/// <summary> /// Adds openings to an element. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="elementHandles">The parent handles.</param> /// <param name="curveLoops">The parent CurveLoops.</param> /// <param name="element">The element.</param> /// <param name="lcs">The local coordinate system.</param> /// <param name="scaledWidth">The width.</param> /// <param name="range">The range.</param> /// <param name="setter">The placement setter.</param> /// <param name="localPlacement">The local placement.</param> /// <param name="localWrapper">The wrapper.</param> public static void AddOpeningsToElement(ExporterIFC exporterIFC, IList<IFCAnyHandle> elementHandles, IList<CurveLoop> curveLoops, Element element, Transform lcs, double scaledWidth, IFCRange range, PlacementSetter setter, IFCAnyHandle localPlacement, ProductWrapper localWrapper) { IList<IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, element, lcs, range); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; foreach (IFCOpeningData openingData in openingDataList) { Element openingElem = element.Document.GetElement(openingData.OpeningElementId); if (openingElem == null) openingElem = element; bool currentWallIsHost = false; FamilyInstance openingFInst = openingElem as FamilyInstance; if (openingFInst != null && openingFInst.Host != null) { if (openingFInst.Host.Id == element.Id) currentWallIsHost = true; //continue; // If the host is not the current Wall, skip this opening } // Don't export the opening if WallSweep category has been turned off. // This is currently restricted to WallSweeps because the element responsible for the opening could be a variety of things, // including a line as part of the elevation profile of the wall. // As such, we will restrict which element types we check for CanExportElement. if ((openingElem is WallSweep) && (!ElementFilteringUtil.CanExportElement(exporterIFC, openingElem, true))) continue; IList<IFCExtrusionData> extrusionDataList = openingData.GetExtrusionData(); IFCAnyHandle parentHandle = null; if (elementHandles.Count > 1 && extrusionDataList.Count > 0) { parentHandle = FindParentHandle(elementHandles, curveLoops, extrusionDataList[0].GetLoops()[0]); } if (parentHandle == null) parentHandle = elementHandles[0]; bool isDoorOrWindowOpening = IsDoorOrWindowOpening(exporterIFC, openingElem, element); bool insertHasHost = false; bool insertInThisHost = false; if (openingElem is FamilyInstance && element is Wall) { string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, openingElem, out ifcEnumType); Element instHost = (openingElem as FamilyInstance).Host; insertHasHost = (instHost != null); insertInThisHost = (insertHasHost && instHost.Id == element.Id); isDoorOrWindowOpening = insertInThisHost && (exportType.ExportInstance == IFCEntityType.IfcDoor || exportType.ExportType == IFCEntityType.IfcDoorType || exportType.ExportInstance == IFCEntityType.IfcWindow || exportType.ExportType == IFCEntityType.IfcWindowType); } if (isDoorOrWindowOpening && currentWallIsHost) { DoorWindowDelayedOpeningCreator delayedCreator = DoorWindowDelayedOpeningCreator.Create(exporterIFC, openingData, scaledWidth, element.Id, parentHandle, setter.LevelId); if (delayedCreator != null) { ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator); continue; } } // If the opening is "filled" by another element (either a door or window as // determined above, or an embedded wall, then we can't use the element GUID // for the opening. bool canUseElementGUID = (!insertHasHost || insertInThisHost) && !isDoorOrWindowOpening && !(openingElem is Wall); IList<Solid> solids = openingData.GetOpeningSolids(); foreach (Solid solid in solids) { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null)); extrusionCreationData.ReuseLocalPlacement = true; string openingGUID = CreateOpeningGUID(openingElem, canUseElementGUID); canUseElementGUID = false; // Either it was used above, and therefore is now false, or it was already false. CreateOpening(exporterIFC, parentHandle, element, openingElem, openingGUID, solid, scaledWidth, openingData.IsRecess, extrusionCreationData, setter, localWrapper); } } foreach (IFCExtrusionData extrusionData in extrusionDataList) { if (extrusionData.ScaledExtrusionLength < MathUtil.Eps()) extrusionData.ScaledExtrusionLength = scaledWidth; string openingGUID = CreateOpeningGUID(openingElem, canUseElementGUID); canUseElementGUID = false; // Either it was used above, and therefore is now false, or it was already false. CreateOpening(exporterIFC, parentHandle, localPlacement, element, openingElem, openingGUID, extrusionData, lcs, openingData.IsRecess, setter, localWrapper); } } }
/// <summary> /// Adds openings to an element. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="elementHandles">The parent handles.</param> /// <param name="curveLoops">The parent CurveLoops.</param> /// <param name="element">The element.</param> /// <param name="plane">The plane.</param> /// <param name="scaledWidth">The width.</param> /// <param name="range">The range.</param> /// <param name="setter">The placement setter.</param> /// <param name="localPlacement">The local placement.</param> /// <param name="localWrapper">The wrapper.</param> public static void AddOpeningsToElement(ExporterIFC exporterIFC, IList <IFCAnyHandle> elementHandles, IList <CurveLoop> curveLoops, Element element, Plane plane, double scaledWidth, IFCRange range, PlacementSetter setter, IFCAnyHandle localPlacement, ProductWrapper localWrapper) { IList <IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, element, plane, range); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); foreach (IFCOpeningData openingData in openingDataList) { Element openingElem = element.Document.GetElement(openingData.OpeningElementId); if (openingElem == null) { openingElem = element; } // Don't export the opening if WallSweep category has been turned off. // This is currently restricted to WallSweeps because the element responsible for the opening could be a variety of things, including a line as part of the elevation profile of the wall. // As such, we will restrict which element types we check for CanExportElement. if ((openingElem is WallSweep) && (!ElementFilteringUtil.CanExportElement(exporterIFC, openingElem, true))) { continue; } IList <IFCExtrusionData> extrusionDataList = openingData.GetExtrusionData(); IFCAnyHandle parentHandle = null; if (elementHandles.Count > 1 && extrusionDataList.Count > 0) { parentHandle = FindParentHandle(elementHandles, curveLoops, extrusionDataList[0].GetLoops()[0]); } if (parentHandle == null) { parentHandle = elementHandles[0]; } bool isDoorOrWindowOpening = IsDoorOrWindowOpening(exporterIFC, openingElem, element); if (isDoorOrWindowOpening) { DoorWindowDelayedOpeningCreator delayedCreator = DoorWindowDelayedOpeningCreator.Create(exporterIFC, openingData, scaledWidth, element.Id, parentHandle, setter.LevelId); if (delayedCreator != null) { ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator); continue; } } bool canUseElementGUID = !isDoorOrWindowOpening; IList <Solid> solids = openingData.GetOpeningSolids(); foreach (Solid solid in solids) { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null)); extrusionCreationData.ReuseLocalPlacement = true; string openingGUID = null; if (canUseElementGUID) { openingGUID = GUIDUtil.CreateGUID(openingElem); canUseElementGUID = false; } else { openingGUID = GUIDUtil.CreateGUID(); } CreateOpening(exporterIFC, parentHandle, element, openingElem, openingGUID, solid, scaledWidth, openingData.IsRecess, extrusionCreationData, setter, localWrapper); } } foreach (IFCExtrusionData extrusionData in extrusionDataList) { if (extrusionData.ScaledExtrusionLength < MathUtil.Eps()) { extrusionData.ScaledExtrusionLength = scaledWidth; } string openingGUID = null; if (canUseElementGUID) { openingGUID = GUIDUtil.CreateGUID(element); canUseElementGUID = false; } else { openingGUID = GUIDUtil.CreateGUID(); } CreateOpening(exporterIFC, parentHandle, localPlacement, element, openingElem, openingGUID, extrusionData, plane, openingData.IsRecess, setter, localWrapper); } } }
/// <summary> /// Adds openings to an element. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="elementHandles">The parent handles.</param> /// <param name="curveLoops">The parent CurveLoops.</param> /// <param name="element">The element.</param> /// <param name="lcs">The local coordinate system.</param> /// <param name="scaledWidth">The width.</param> /// <param name="range">The range.</param> /// <param name="setter">The placement setter.</param> /// <param name="localPlacement">The local placement.</param> /// <param name="localWrapper">The wrapper.</param> public static void AddOpeningsToElement(ExporterIFC exporterIFC, IList <IFCAnyHandle> elementHandles, IList <CurveLoop> curveLoops, Element element, Transform lcs, double scaledWidth, IFCRange range, PlacementSetter setter, IFCAnyHandle localPlacement, ProductWrapper localWrapper) { if (lcs == null && ((curveLoops?.Count ?? 0) > 0)) { // assumption: first curve loop defines the plane. Plane hostObjPlane = curveLoops[0].HasPlane() ? curveLoops[0].GetPlane(): null; if (hostObjPlane != null) { lcs = GeometryUtil.CreateTransformFromPlane(hostObjPlane); } } IList <IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, element, lcs, range); IFCFile file = exporterIFC.GetFile(); int openingIndex = 0; foreach (IFCOpeningData openingData in openingDataList) { openingIndex++; Element openingElem = element.Document.GetElement(openingData.OpeningElementId); if (openingElem == null) { openingElem = element; } bool currentWallIsHost = false; FamilyInstance openingFInst = openingElem as FamilyInstance; if (openingFInst != null && openingFInst.Host != null) { if (openingFInst.Host.Id == element.Id) { currentWallIsHost = true; } } // Don't export the opening if WallSweep category has been turned off. // This is currently restricted to WallSweeps because the element responsible for the opening could be a variety of things, // including a line as part of the elevation profile of the wall. // As such, we will restrict which element types we check for CanExportElement. if ((openingElem is WallSweep) && (!ElementFilteringUtil.CanExportElement(exporterIFC, openingElem, true))) { continue; } IList <IFCExtrusionData> extrusionDataList = openingData.GetExtrusionData(); IFCAnyHandle parentHandle = FindParentHandle(elementHandles, curveLoops, extrusionDataList); string predefinedType; IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, openingElem, out predefinedType); bool exportingDoorOrWindow = (exportType.ExportInstance == IFCEntityType.IfcDoor || exportType.ExportType == IFCEntityType.IfcDoorType || exportType.ExportInstance == IFCEntityType.IfcWindow || exportType.ExportType == IFCEntityType.IfcWindowType); bool isDoorOrWindowOpening = IsDoorOrWindowOpening(openingElem, element, exportingDoorOrWindow); if (isDoorOrWindowOpening && currentWallIsHost) { DoorWindowDelayedOpeningCreator delayedCreator = DoorWindowDelayedOpeningCreator.Create(exporterIFC, openingData, scaledWidth, element.Id, parentHandle, setter.LevelId); if (delayedCreator != null) { ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator); continue; } } IList <Solid> solids = openingData.GetOpeningSolids(); int solidIndex = 0; foreach (Solid solid in solids) { solidIndex++; using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null)); extrusionCreationData.ReuseLocalPlacement = true; string openingGUID = CreateOpeningGUID(openingElem, range, openingIndex, solidIndex); CreateOpening(exporterIFC, parentHandle, element, openingElem, openingGUID, solid, scaledWidth, openingData.IsRecess, extrusionCreationData, setter, localWrapper); } } foreach (IFCExtrusionData extrusionData in extrusionDataList) { solidIndex++; if (extrusionData.ScaledExtrusionLength < MathUtil.Eps()) { extrusionData.ScaledExtrusionLength = scaledWidth; } string openingGUID = CreateOpeningGUID(openingElem, range, openingIndex, solidIndex); CreateOpening(exporterIFC, parentHandle, localPlacement, element, openingElem, openingGUID, extrusionData, lcs, openingData.IsRecess, setter, localWrapper); } } }