/// <summary> /// Creates an opening from extrusion data. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="hostObjHnd">The host handle.</param> /// <param name="hostPlacement">The host placement.</param> /// <param name="hostElement">The host element.</param> /// <param name="insertElement">The opening element.</param> /// <param name="openingGUID">The opening GUID.</param> /// <param name="extrusionData">The extrusion data.</param> /// <param name="lcs">The local coordinate system of the base of the extrusion.</param> /// <param name="isRecess">True if it is a recess.</param> /// <returns>The opening handle.</returns> static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, IFCAnyHandle hostPlacement, Element hostElement, Element insertElement, string openingGUID, IFCExtrusionData extrusionData, Transform lcs, bool isRecess, PlacementSetter setter, ProductWrapper localWrapper) { IFCFile file = exporterIFC.GetFile(); IList <CurveLoop> curveLoops = extrusionData.GetLoops(); if (curveLoops.Count == 0) { return(null); } if (lcs == null) { // assumption: first curve loop defines the plane. if (!curveLoops[0].HasPlane()) { return(null); } lcs = GeometryUtil.CreateTransformFromPlane(curveLoops[0].GetPlane()); } ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement); IFCAnyHandle openingProdRepHnd = RepresentationUtil.CreateExtrudedProductDefShape(exporterIFC, insertElement, catId, curveLoops, lcs, extrusionData.ExtrusionDirection, extrusionData.ScaledExtrusionLength); string openingObjectType = isRecess ? "Recess" : "Opening"; IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string openingName = NamingUtil.GetNameOverride(insertElement, null); if (string.IsNullOrEmpty(openingName)) { openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement)); } string openingDescription = NamingUtil.GetDescriptionOverride(insertElement, null); string openingTag = NamingUtil.GetTagOverride(insertElement); IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(exporterIFC, openingGUID, ownerHistory, openingName, openingDescription, openingObjectType, ExporterUtil.CreateLocalPlacement(file, hostPlacement, null), openingProdRepHnd, openingTag); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcOpeningElement, openingObjectType); IFCExtrusionCreationData ecData = null; if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) { double height, width; ecData = new IFCExtrusionCreationData(); if (GeometryUtil.ComputeHeightWidthOfCurveLoop(curveLoops[0], lcs, out height, out width)) { ecData.ScaledHeight = UnitUtil.ScaleLength(height); ecData.ScaledWidth = UnitUtil.ScaleLength(width); } else { double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops); ecData.ScaledArea = UnitUtil.ScaleArea(area); } PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, ecData); } if (localWrapper != null) { Element elementForProperties = null; if (GUIDUtil.IsGUIDFor(insertElement, openingGUID)) { elementForProperties = insertElement; } localWrapper.AddElement(elementForProperties, openingHnd, setter, ecData, true, exportInfo); } string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd); return(openingHnd); }
/// <summary> /// Creates an opening from a solid. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="hostObjHnd">The host object handle.</param> /// <param name="hostElement">The host element.</param> /// <param name="insertElement">The insert element.</param> /// <param name="openingGUID">The GUID for the opening, depending on how the opening is created.</param> /// <param name="solid">The solid.</param> /// <param name="scaledHostWidth">The scaled host width.</param> /// <param name="isRecess">True if it is recess.</param> /// <param name="extrusionCreationData">The extrusion creation data.</param> /// <param name="setter">The placement setter.</param> /// <param name="localWrapper">The product wrapper.</param> /// <returns>The created opening handle.</returns> static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, Element hostElement, Element insertElement, string openingGUID, Solid solid, double scaledHostWidth, bool isRecess, IFCExtrusionCreationData extrusionCreationData, PlacementSetter setter, ProductWrapper localWrapper) { IFCFile file = exporterIFC.GetFile(); ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement); XYZ prepToWall; bool isLinearWall = GetOpeningDirection(hostElement, out prepToWall); if (isLinearWall) { extrusionCreationData.CustomAxis = prepToWall; extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom; } BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); BodyData bodyData = BodyExporter.ExportBody(exporterIFC, insertElement, catId, ElementId.InvalidElementId, solid, bodyExporterOptions, extrusionCreationData); IFCAnyHandle openingRepHnd = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingRepHnd)) { extrusionCreationData.ClearOpenings(); return(null); } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(openingRepHnd); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle openingPlacement = extrusionCreationData.GetLocalPlacement(); IFCAnyHandle hostObjPlacementHnd = IFCAnyHandleUtil.GetObjectPlacement(hostObjHnd); Transform relTransform = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(openingPlacement, hostObjPlacementHnd); openingPlacement = ExporterUtil.CreateLocalPlacement(file, hostObjPlacementHnd, relTransform.Origin, relTransform.BasisZ, relTransform.BasisX); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; double scaledOpeningLength = extrusionCreationData.ScaledLength; string openingObjectType = "Opening"; if (!MathUtil.IsAlmostZero(scaledHostWidth) && !MathUtil.IsAlmostZero(scaledOpeningLength)) { openingObjectType = scaledOpeningLength < (scaledHostWidth - MathUtil.Eps()) ? "Recess" : "Opening"; } else { openingObjectType = isRecess ? "Recess" : "Opening"; } string openingName = NamingUtil.GetNameOverride(insertElement, null); if (string.IsNullOrEmpty(openingName)) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjHnd)) { openingName = IFCAnyHandleUtil.GetStringAttribute(hostObjHnd, "Name"); } else { openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement)); } } string openingDescription = NamingUtil.GetDescriptionOverride(insertElement, null); string openingTag = NamingUtil.GetTagOverride(insertElement); IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(exporterIFC, openingGUID, ownerHistory, openingName, openingDescription, openingObjectType, openingPlacement, prodRep, openingTag); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcOpeningElement, openingObjectType); if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) { PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, extrusionCreationData); } if (localWrapper != null) { Element elementForProperties = null; if (GUIDUtil.IsGUIDFor(insertElement, openingGUID)) { elementForProperties = insertElement; } localWrapper.AddElement(insertElement, openingHnd, setter, extrusionCreationData, false, exportInfo); } string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd); return(openingHnd); }
/// <summary> /// Creates openings if there is necessary. /// </summary> /// <param name="elementHandle">The element handle to create openings.</param> /// <param name="element">The element to create openings.</param> /// <param name="info">The extrusion data.</param> /// <param name="extraParams">The extrusion creation data.</param> /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="originalPlacement">The original placement handle.</param> /// <param name="setter">The PlacementSetter.</param> /// <param name="wrapper">The ProductWrapper.</param> private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList <IFCExtrusionData> info, IFCExtrusionCreationData extraParams, Transform offsetTransform, ExporterIFC exporterIFC, IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle)) { return; } int sz = info.Count; if (sz == 0) { return; } using (TransformSetter transformSetter = TransformSetter.Create()) { if (offsetTransform != null) { transformSetter.Initialize(exporterIFC, offsetTransform.Inverse); } IFCFile file = exporterIFC.GetFile(); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); Document document = element.Document; string openingObjectType = "Opening"; int openingNumber = 1; for (int curr = info.Count - 1; curr >= 0; curr--) { Transform extrusionTrf = Transform.Identity; IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, info[curr], out extrusionTrf); if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle)) { continue; } BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, extrusionHandle, ElementId.InvalidElementId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(extrusionHandle); IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body"); IFCAnyHandle bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null); IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle openingRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement); string guid = GUIDUtil.CreateGUID(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string openingName = NamingUtil.GetIFCNamePlusIndex(element, openingNumber++); string openingDescription = NamingUtil.GetDescriptionOverride(element, null); string openingTag = NamingUtil.GetTagOverride(element); IFCAnyHandle openingElement = IFCInstanceExporter.CreateOpeningElement(exporterIFC, guid, ownerHistory, openingName, openingDescription, openingObjectType, openingPlacement, openingRep, openingTag); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcOpeningElement); wrapper.AddElement(null, openingElement, setter, extraParams, true, exportInfo); if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null)) { PropertyUtil.CreateOpeningQuantities(exporterIFC, openingElement, extraParams); } string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement); } } }
public static DoorWindowInfo CreateWindow(ExporterIFC exporterIFC, FamilyInstance famInst, HostObject hostObj, ElementId overrideLevelId, Transform trf, IFCExportInfoPair exportType) { DoorWindowInfo doorWindowInfo = new DoorWindowInfo(); doorWindowInfo.Initialize(false, true, famInst, hostObj, exportType); doorWindowInfo.CalculateDoorWindowInformation(exporterIFC, famInst, overrideLevelId, trf); return(doorWindowInfo); }
/// <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> /// Creates a list of ranges to split an element. /// </summary> /// <remarks> /// We may need to split an element (e.g. column) into parts by level. /// </remarks> /// <param name="exporterIFC">The ExporterIFC object. </param> /// <param name="exportType">The export type. </param> /// <param name="element">The element. </param> /// <param name="levels">The levels to split the element.</param> /// <param name="ranges">The ranges to split the element. These will be non-overlapping.</param> public static void CreateSplitLevelRangesForElement(ExporterIFC exporterIFC, IFCExportInfoPair exportType, Element element, out IList <ElementId> levels, out IList <IFCRange> ranges) { levels = new List <ElementId>(); ranges = new List <IFCRange>(); if (!ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) { return; } double extension = GetLevelExtension(); bool splitByLevel = (exportType.ExportInstance == IFCEntityType.IfcColumn || exportType.ExportInstance == IFCEntityType.IfcWall) || (exportType.ExportType == IFCEntityType.IfcDuctSegmentType); if (!splitByLevel) { return; } BoundingBoxXYZ boundingBox = element.get_BoundingBox(null); if (boundingBox == null) { return; } { IFCRange zSpan = new IFCRange(boundingBox.Min.Z, boundingBox.Max.Z); if (zSpan.Start < zSpan.End) { bool firstLevel = true; ElementId skipToNextLevel = ElementId.InvalidElementId; // If the base level of the element is set, we will start "looking" at that level. Anything below the base level will be included with the base level. // We will only do this if the base level is a building story. ElementId firstLevelId = GetBaseLevelIdForElement(element); bool foundFirstLevel = (firstLevelId == ElementId.InvalidElementId); IList <ElementId> levelIds = ExporterCacheManager.LevelInfoCache.BuildingStoriesByElevation; foreach (ElementId levelId in levelIds) { if (!foundFirstLevel) { if (levelId != firstLevelId) { continue; } else { foundFirstLevel = true; } } if (skipToNextLevel != ElementId.InvalidElementId && levelId != skipToNextLevel) { continue; } IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId); if (levelInfo == null) { continue; } // endBelowLevel if (zSpan.End < levelInfo.Elevation + extension) { continue; } // To calculate the distance to the next level, we check to see if the Level UpToLevel built-in parameter // is set. If so, we calculate the distance by getting the elevation of the UpToLevel level minus the // current elevation, and use it if it is greater than 0. If it is not greater than 0, or the built-in // parameter is not set, we use DistanceToNextLevel. double levelHeight = ExporterCacheManager.LevelInfoCache.FindHeight(levelId); if (levelHeight < 0.0) { levelHeight = CalculateDistanceToNextLevel(element.Document, levelId, levelInfo); } skipToNextLevel = ExporterCacheManager.LevelInfoCache.FindNextLevel(levelId); // startAboveLevel if ((!MathUtil.IsAlmostZero(levelHeight)) && (zSpan.Start > levelInfo.Elevation + levelHeight - extension)) { continue; } bool startBelowLevel = !firstLevel && (zSpan.Start < levelInfo.Elevation - extension); bool endAboveLevel = ((!MathUtil.IsAlmostZero(levelHeight)) && (zSpan.End > levelInfo.Elevation + levelHeight + extension)); if (!startBelowLevel && !endAboveLevel) { break; } IFCRange currentSpan = new IFCRange( startBelowLevel ? levelInfo.Elevation : zSpan.Start, endAboveLevel ? (levelInfo.Elevation + levelHeight) : zSpan.End); // We want our ranges to be non-overlapping. As such, we'll modify the start parameter // to be at least as large as the previous end parameter (if any). If this makes the // range invalid, we won't add it. if (ranges.Count > 0) { IFCRange lastSpan = ranges.Last(); if (lastSpan.End > currentSpan.End - MathUtil.Eps()) { continue; } currentSpan.Start = Math.Max(currentSpan.Start, lastSpan.End); } ranges.Add(currentSpan); levels.Add(levelId); firstLevel = false; } } } }
private void Initialize(bool isDoor, bool isWindow, FamilyInstance famInst, HostObject hostObject, IFCExportInfoPair exportType) { HostObject = hostObject; InsertInstance = famInst; ExportingDoor = isDoor; if (isDoor) { if (exportType.HasUndefinedPredefinedType()) { PreDefinedType = "DOOR"; } else { PreDefinedType = exportType.ValidatedPredefinedType; } } ExportingWindow = isWindow; if (isWindow) { if (exportType.HasUndefinedPredefinedType()) { PreDefinedType = "WINDOW"; } else { PreDefinedType = exportType.ValidatedPredefinedType; } } FlippedSymbol = false; DoorOperationTypeString = "NOTDEFINED"; WindowPartitioningTypeString = "NOTDEFINED"; FlippedX = (famInst == null) ? false : famInst.HandFlipped; FlippedY = (famInst == null) ? false : famInst.FacingFlipped; Wall wall = (hostObject == null) ? null : hostObject as Wall; Curve centerCurve = WallExporter.GetWallAxis(wall); HasRealWallHost = ((wall != null) && (centerCurve != null) && ((centerCurve is Line) || (centerCurve is Arc))); }
/// <summary> /// Add a generic element to the wrapper, with associated level and extrusion data information, and create associated internal property sets if option is set. /// </summary> /// <param name="element">The element.</param> /// <param name="handle">The element handle.</param> /// <param name="levelInfo">The level information.</param> /// <param name="data">The extrusion creation data (can be null.)</param> /// <param name="relateToLevel">Relate to the level in the setter, or not.</param> public void AddElement(Element element, IFCAnyHandle handle, IFCLevelInfo levelInfo, IFCExtrusionCreationData data, bool relateToLevel, IFCExportInfoPair exportType) { // There is a bug in the internal AddElement that requires us to do a levelInfo null check here. bool actuallyRelateToLevel = relateToLevel && (levelInfo != null); InternalWrapper.AddElement(handle, levelInfo, data, actuallyRelateToLevel); if (levelInfo == null && relateToLevel) { ExporterCacheManager.LevelInfoCache.OrphanedElements.Add(handle); } RegisterHandleWithElement(element, handle, exportType); }
/// <summary> /// Add a space to the wrapper, with associated level and extrusion data information. /// </summary> /// <param name="element">The element.</param> /// <param name="handle">The element handle.</param> /// <param name="levelInfo">The level information.</param> /// <param name="data">The extrusion creation data (can be null.)</param> /// <param name="relateToLevel">Relate to the level in the setter, or not.</param> public void AddSpace(Element element, IFCAnyHandle handle, IFCLevelInfo levelInfo, IFCExtrusionCreationData data, bool relateToLevel, IFCExportInfoPair exportType) { bool actuallyRelateToLevel = relateToLevel && (levelInfo != null); InternalWrapper.AddSpace(handle, levelInfo, data, actuallyRelateToLevel); if (levelInfo == null && relateToLevel) { ExporterCacheManager.LevelInfoCache.OrphanedSpaces.Add(handle); } RegisterHandleWithElement(element, handle, exportType); }
/// <summary> /// Add a generic element to the wrapper, and create associated internal property sets if option is set. /// </summary> /// <param name="element">The element.</param> /// <param name="handle">The handle.</param> public void AddElement(Element element, IFCAnyHandle handle, IFCExportInfoPair exportType) { CreatedHandles.Add(handle); RegisterHandleWithElement(element, handle, exportType); }
/// <summary> /// Adds the FamilyTypeInfo to the dictionary. /// </summary> /// <param name="elementId"> /// The element elementId. /// </param> /// <param name="flipped"> /// Indicates if the element is flipped. /// </param> /// <param name="exportType"> /// The export type of the element. /// </param> public void Register(ElementId elementId, bool flipped, IFCExportInfoPair exportType, FamilyTypeInfo typeInfo) { var key = new TypeObjectKey(elementId, flipped, exportType.ExportType, exportType.ValidatedPredefinedType); this[key] = typeInfo; }
/// <summary> /// Gets export type from category id. /// </summary> /// <param name="categoryId">The category id.</param> /// <param name="ifcEnumType">The string value represents the IFC type.</param> /// <returns>The export type.</returns> public static IFCExportInfoPair GetExportTypeFromCategoryId(ElementId categoryId, out string ifcEnumType) { IFCExportInfoPair exportInfoPair = new IFCExportInfoPair(); ifcEnumType = "NOTDEFINED"; if (categoryId == new ElementId(BuiltInCategory.OST_Cornices)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcBeam, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Ceilings)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcCovering, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_CurtainWallPanels)) { ifcEnumType = "CURTAIN_PANEL"; exportInfoPair.SetValueWithPair(IFCEntityType.IfcPlate, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Doors)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcDoor, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Furniture)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcFurniture, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Floors)) { ifcEnumType = "FLOOR"; exportInfoPair.SetValueWithPair(IFCEntityType.IfcSlab, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_IOSModelGroups)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcGroup, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Mass)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcBuildingElementProxy, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_CurtainWallMullions)) { ifcEnumType = "MULLION"; exportInfoPair.SetValueWithPair(IFCEntityType.IfcMember, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Railings)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcRailing, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Ramps)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcRamp, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Roofs)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcRoof, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Site)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcSite, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Stairs)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcStair, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Walls)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcWall, ifcEnumType); } else if (categoryId == new ElementId(BuiltInCategory.OST_Windows)) { exportInfoPair.SetValueWithPair(IFCEntityType.IfcWindow, ifcEnumType); } return(exportInfoPair); }
/// <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); } } }
/// <summary> /// DEPRECATED!!! /// Register an ElementType with the ProductWrapper, to create its property sets on Dispose without the information of IFCExportInfoPair /// </summary> /// <param name="elementType">The element type</param> /// <param name="prodTypeHnd">The handle</param> /// <param name="existingPropertySets">Any existing propertysets</param> public void RegisterHandleWithElementType(ElementType elementType, IFCAnyHandle prodTypeHnd, HashSet <IFCAnyHandle> existingPropertySets) { IFCExportInfoPair exportType = new IFCExportInfoPair(); RegisterHandleWithElementType(elementType, exportType, prodTypeHnd, existingPropertySets); }