/// <summary> /// Exports an element as an IFC assembly. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportAssemblyInstanceElement(ExporterIFC exporterIFC, AssemblyInstance element, IFCProductWrapper productWrapper) { if (element == null) return false; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, element)) { string guid = ExporterIFCUtils.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string name = exporterIFC.GetName(); string objectType = exporterIFC.GetFamilyName(); IFCAnyHandle localPlacement = placementSetter.GetPlacement(); IFCAnyHandle representation = null; string elementTag = NamingUtil.CreateIFCElementId(element); IFCElementAssemblyType predefinedType = GetPredefinedTypeFromObjectType(objectType); IFCAnyHandle assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(file, guid, ownerHistory, name, null, objectType, localPlacement, representation, elementTag, IFCAssemblyPlace.NotDefined, predefinedType); productWrapper.AddElement(assemblyInstanceHnd, placementSetter.GetLevelInfo(), null, true); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(element.Id, assemblyInstanceHnd); } tr.Commit(); return true; } }
/// <summary> /// Exports a FabricArea as an IfcGroup. There is no geometry to export. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportFabricArea(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { if (element == null) return false; HashSet<IFCAnyHandle> fabricSheetHandles = null; if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(element.Id, out fabricSheetHandles)) return false; if (fabricSheetHandles == null || fabricSheetHandles.Count == 0) return false; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle fabricArea = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); productWrapper.AddElement(element, fabricArea); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, fabricSheetHandles, null, fabricArea); tr.Commit(); return true; } }
/// <summary> /// Exports a Rebar, AreaReinforcement or PathReinforcement to IFC ReinforcingBar. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The product wrapper.</param> public static void Export(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { ISet<IFCAnyHandle> createdRebars = null; if (element is Rebar) { ExportRebar(exporterIFC, element, productWrapper); } else if (element is AreaReinforcement) { AreaReinforcement areaReinforcement = element as AreaReinforcement; IList<ElementId> rebarIds = areaReinforcement.GetRebarInSystemIds(); Document doc = areaReinforcement.Document; foreach (ElementId id in rebarIds) { Element rebarInSystem = doc.GetElement(id); createdRebars = ExportRebar(exporterIFC, rebarInSystem, productWrapper); } } else if (element is PathReinforcement) { PathReinforcement pathReinforcement = element as PathReinforcement; IList<ElementId> rebarIds = pathReinforcement.GetRebarInSystemIds(); Document doc = pathReinforcement.Document; foreach (ElementId id in rebarIds) { Element rebarInSystem = doc.GetElement(id); createdRebars = ExportRebar(exporterIFC, rebarInSystem, productWrapper); } } if (createdRebars != null && createdRebars.Count > 1) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle rebarGroup = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); productWrapper.AddElement(element, rebarGroup); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, createdRebars, null, rebarGroup); tr.Commit(); } } }
/// <summary> /// Exports an element as a covering of type insulation. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportDuctLining(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) return false; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return false; } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); IFCAnyHandle ductLining = IFCInstanceExporter.CreateCovering(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, "Wrapping"); ExporterCacheManager.ElementToHandleCache.Register(element.Id, ductLining); productWrapper.AddElement(element, ductLining, placementSetter.LevelInfo, ecData, true); ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, ductLining, matId); } } tr.Commit(); return true; } }
/// <summary> /// Exports an element as a covering of type insulation. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportDuctLining(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) return false; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.GetPlacement()); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geometryElement, bodyExporterOptions, null, ecData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return false; } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); IFCAnyHandle ductLining = IFCInstanceExporter.CreateCovering(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, IFCCoveringType.Wrapping); productWrapper.AddElement(ductLining, placementSetter.GetLevelInfo(), ecData, LevelUtil.AssociateElementToLevel(element)); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } } tr.Commit(); return true; } }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <remarks> /// This function is called from the Export function, but can also be called directly if you do not /// want CreateInternalPropertySets to be called. /// </remarks> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>The handle if created, null otherwise.</returns> public static IFCAnyHandle ExportBuildingElementProxy(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) return null; IFCFile file = exporterIFC.GetFile(); IFCAnyHandle buildingElementProxy = null; using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return null; } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); buildingElementProxy = IFCInstanceExporter.CreateBuildingElementProxy(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, null); productWrapper.AddElement(element, buildingElementProxy, placementSetter.LevelInfo, ecData, true); } tr.Commit(); } } return buildingElementProxy; }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <remarks> /// This function is called from the Export function, but can also be called directly if you do not /// want CreateInternalPropertySets to be called. /// </remarks> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportBuildingElementProxy(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { if (element == null || geometryElement == null) return false; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.GetPlacement()); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle representation = RepresentationUtil.CreateBRepProductDefinitionShape(element.Document.Application, exporterIFC, element, categoryId, geometryElement, bodyExporterOptions, null, ecData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return false; } string guid = ExporterIFCUtils.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string objectType = exporterIFC.GetFamilyName(); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.CreateIFCElementId(element); IFCAnyHandle buildingElementProxy = IFCInstanceExporter.CreateBuildingElementProxy(file, guid, ownerHistory, objectType, null, objectType, localPlacement, representation, elementTag, Toolkit.IFCElementComposition.Element); productWrapper.AddElement(buildingElementProxy, placementSetter.GetLevelInfo(), ecData, LevelUtil.AssociateElementToLevel(element)); } tr.Commit(); return true; } } }
/// <summary> /// Exports an element as a zone. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportZone(ExporterIFC exporterIFC, Zone element, ProductWrapper productWrapper) { if (element == null) return; HashSet<IFCAnyHandle> spaceHnds = new HashSet<IFCAnyHandle>(); SpaceSet spaces = element.Spaces; foreach (Space space in spaces) { if (space == null) continue; IFCAnyHandle spaceHnd = ExporterCacheManager.SpatialElementHandleCache.Find(space.Id); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(spaceHnd)) spaceHnds.Add(spaceHnd); } if (spaceHnds.Count == 0) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); IFCAnyHandle zoneHnd = IFCInstanceExporter.CreateZone(file, guid, ownerHistory, name, description, objectType); productWrapper.AddElement(element, zoneHnd); string relAssignsGuid = GUIDUtil.CreateSubElementGUID(element, (int) IFCZoneSubElements.RelAssignsToGroup); IFCInstanceExporter.CreateRelAssignsToGroup(file, relAssignsGuid, ownerHistory, null, null, spaceHnds, null, zoneHnd); tr.Commit(); return; } }
/// <summary> /// Exports a FabricArea as an IfcGroup. There is no geometry to export. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportFabricArea(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { if (element == null) { return(false); } HashSet <IFCAnyHandle> fabricSheetHandles = null; if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(element.Id, out fabricSheetHandles)) { return(false); } if (fabricSheetHandles == null || fabricSheetHandles.Count == 0) { return(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle fabricArea = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); productWrapper.AddElement(element, fabricArea); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, fabricSheetHandles, null, fabricArea); tr.Commit(); return(true); } }
/// <summary> /// Export the roof to IfcRoof containing its parts. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> public static void ExportRoofAsParts(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); IFCAnyHandle localPlacement = setter.GetPlacement(); using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(setter.GetPlacement()); extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY; IFCAnyHandle prodRepHnd = null; string elementGUID = ExporterIFCUtils.CreateGUID(element); string origElementName = exporterIFC.GetName(); string elementName = NamingUtil.GetNameOverride(element, origElementName); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); //need to convert the string to enum string ifcEnumType = CategoryUtil.GetIFCEnumTypeName(exporterIFC, element); IFCAnyHandle roofHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, GetIFCRoofType(ifcEnumType)); // Export the parts PartExporter.ExportHostPart(exporterIFC, element, roofHandle, productWrapper, setter, localPlacement, null); productWrapper.AddElement(roofHandle, setter, extrusionCreationData, LevelUtil.AssociateElementToLevel(element)); OpeningUtil.CreateOpeningsIfNecessary(roofHandle, element, extrusionCreationData, exporterIFC, extrusionCreationData.GetLocalPlacement(), setter, productWrapper); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } transaction.Commit(); } } }
/// <summary> /// Export the roof to IfcRoof containing its parts. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportRoofAsParts(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcRoof", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); //need to convert the string to enum string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element); ifcEnumType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle roofHandle = IFCInstanceExporter.CreateRoof(exporterIFC, element, elementGUID, ownerHistory, localPlacement, prodRepHnd, ifcEnumType); // Export the parts PartExporter.ExportHostPart(exporterIFC, element, roofHandle, productWrapper, setter, localPlacement, null); productWrapper.AddElement(element, roofHandle, setter, null, true); transaction.Commit(); } } }
/// <summary> /// Exports a curtain system to IFC curtain system. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="hostElement"> /// The curtain system element to be exported. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurtainSystem(ExporterIFC exporterIFC, CurtainSystem curtainSystem, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcCurtainWall", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { ExportBaseWithGrids(exporterIFC, curtainSystem, productWrapper); transaction.Commit(); } }
/// <summary> /// Exports a roof element to the appropriate IFC entity. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void Export(ExporterIFC exporterIFC, RoofBase roof, GeometryElement geometryElement, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // export parts or not bool exportParts = PartExporter.CanExportParts(roof); bool exportAsCurtainRoof = CurtainSystemExporter.IsCurtainSystem(roof); if (exportParts) { if (!PartExporter.CanExportElementInPartExport(roof, roof.LevelId, false)) { return; } ExportRoofAsParts(exporterIFC, roof, geometryElement, productWrapper); // Right now, only flat roof could have parts. } else if (exportAsCurtainRoof) { CurtainSystemExporter.ExportCurtainRoof(exporterIFC, roof, productWrapper); } else { IFCAnyHandle roofHnd = ExportRoofOrFloorAsContainer(exporterIFC, roof, geometryElement, productWrapper); if (IFCAnyHandleUtil.IsNullOrHasNoValue(roofHnd)) { ExportRoof(exporterIFC, roof, geometryElement, productWrapper); } // call for host objects; curtain roofs excused from call (no material information) if (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, roof, productWrapper.GetAnElement(), geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, null, null); } } tr.Commit(); } }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { bool exported = false; if (element == null || geometryElement == null) return exported; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { exported = ExportBuildingElementProxy(exporterIFC, element, geometryElement, productWrapper); if (exported) { PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); tr.Commit(); } } return exported; }
/// <summary> /// Exports a Group as an IfcGroup. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportGroupElement(ExporterIFC exporterIFC, Group element, ProductWrapper productWrapper) { if (element == null) { return(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle groupHnd = null; string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string ifcEnumType; IFCExportType exportAs = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); if (exportAs == IFCExportType.IfcGroup) { groupHnd = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); } if (groupHnd == null) { return(false); } productWrapper.AddElement(element, groupHnd); ExporterCacheManager.GroupCache.RegisterGroup(element.Id, groupHnd); tr.Commit(); return(true); } }
/// <summary> /// Exports a legacy curtain element to IFC curtain wall. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="curtainElement">The curtain element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportLegacyCurtainElement(ExporterIFC exporterIFC, Element curtainElement, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcCurtainWall", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } ICollection <ElementId> allSubElements = ExporterIFCUtils.GetLegacyCurtainSubElements(curtainElement); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { ExportBase(exporterIFC, allSubElements, curtainElement, productWrapper); transaction.Commit(); } }
/// <summary> /// Exports a ramp to IfcRamp. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The ramp element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { string ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { StairsExporter.ExportLegacyStairOrRampAsContainer(exporterIFC, ifcEnumType, element, geometryElement, productWrapper); // If we didn't create a handle here, then the element wasn't a "native" Ramp, and is likely a FamilyInstance or a DirectShape. if (IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement())) { int numFlights = GetNumFlightsForRamp(exporterIFC, element); if (numFlights > 0) { ExportRamp(exporterIFC, ifcEnumType, element, geometryElement, numFlights, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a staircase to IfcStair. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The stairs element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { string ifcEnumType = CategoryUtil.GetIFCEnumTypeName(exporterIFC, element); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { if (element is Stairs) { Stairs stair = element as Stairs; int numFlights = stair.NumberOfStories; if (numFlights > 0) { ExportStairsAsContainer(exporterIFC, ifcEnumType, stair, geometryElement, numFlights, productWrapper); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement())) ExportStairAsSingleGeometry(exporterIFC, ifcEnumType, element, geometryElement, numFlights, productWrapper); } } else if (IsLegacyStairs(element)) { ExportLegacyStairOrRampAsContainer(exporterIFC, ifcEnumType, element, geometryElement, true, productWrapper); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement())) { double defaultHeight = GetDefaultHeightForLegacyStair(exporterIFC.LinearScale); int numFlights = GetNumFlightsForLegacyStair(exporterIFC, element, defaultHeight); if (numFlights > 0) ExportStairAsSingleGeometry(exporterIFC, ifcEnumType, element, geometryElement, numFlights, productWrapper); } } else { ExportStairAsSingleGeometry(exporterIFC, ifcEnumType, element, geometryElement, 1, productWrapper); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); tr.Commit(); } }
/// <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) { ProcessConnections(exporterIFC, connector, null); } } catch (System.Exception) { // Log an error here } } tr.Commit(); } }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { bool exported = false; if (element == null || geometryElement == null) { return(exported); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { exported = (ExportBuildingElementProxy(exporterIFC, element, geometryElement, productWrapper) != null); if (exported) { tr.Commit(); } } return(exported); }
/// <summary> /// Exports an element as an IFC assembly. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportAssemblyInstanceElement(ExporterIFC exporterIFC, AssemblyInstance element, IFCProductWrapper productWrapper) { if (element == null) { return(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, element)) { string guid = ExporterIFCUtils.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string name = exporterIFC.GetName(); string objectType = exporterIFC.GetFamilyName(); IFCAnyHandle localPlacement = placementSetter.GetPlacement(); IFCAnyHandle representation = null; string elementTag = NamingUtil.CreateIFCElementId(element); IFCElementAssemblyType predefinedType = GetPredefinedTypeFromObjectType(objectType); IFCAnyHandle assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(file, guid, ownerHistory, name, null, objectType, localPlacement, representation, elementTag, IFCAssemblyPlace.NotDefined, predefinedType); productWrapper.AddElement(assemblyInstanceHnd, placementSetter.GetLevelInfo(), null, true); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(element.Id, assemblyInstanceHnd); } tr.Commit(); return(true); } }
/// <summary> /// Exports an element as a group. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportAreaScheme(ExporterIFC exporterIFC, AreaScheme element, ProductWrapper productWrapper) { if (element == null) return; HashSet<IFCAnyHandle> areaHandles = null; if (!ExporterCacheManager.AreaSchemeCache.TryGetValue(element.Id, out areaHandles)) return; if (areaHandles == null || areaHandles.Count == 0) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string name = NamingUtil.GetNameOverride(element, element.Name); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementTag = NamingUtil.CreateIFCElementId(element); IFCAnyHandle areaScheme = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); productWrapper.AddElement(element, areaScheme); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, areaHandles, null, areaScheme); tr.Commit(); return; } }
/// <summary> /// Exports a Group as an IfcGroup. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportGroupElement(ExporterIFC exporterIFC, Group element, ProductWrapper productWrapper) { if (element == null) return false; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle groupHnd = null; string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string ifcEnumType; IFCExportType exportAs = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); if (exportAs == IFCExportType.ExportGroup) { groupHnd = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); } if (groupHnd == null) return false; productWrapper.AddElement(element, groupHnd); ExporterCacheManager.GroupCache.RegisterGroup(element.Id, groupHnd); tr.Commit(); return true; } }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { bool exported = false; if (element == null || geometryElement == null) { return(exported); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { exported = ExportBuildingElementProxy(exporterIFC, element, geometryElement, productWrapper); if (exported) { PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); tr.Commit(); } } return(exported); }
/// <summary> /// Exports a curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) return; SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == null) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.GetPlane(); XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else useOffsetTrf = true; Plane plane = new Plane(planeSK.XVec, planeSK.YVec, origin); IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.CreateTranslation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } IList<IFCAnyHandle> curves = info.GetCurves(); if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet<IFCAnyHandle> curveSet = new HashSet<IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, plane, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }
/// <summary> /// Exports a CeilingAndFloor element to IFC. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } // export parts or not bool exportParts = PartExporter.CanExportParts(floorElement); if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType); using (IFCTransaction tr = new IFCTransaction(file)) { bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor)); IList <IFCAnyHandle> slabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> brepSlabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>(); using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement)) { IFCAnyHandle localPlacement = placementSetter.LocalPlacement; IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association. // Disable calling ExportSlabAsExtrusion if we can't handle potential openings. bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null; bool exportedAsInternalExtrusion = false; ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement); IList <IFCAnyHandle> prodReps = new List <IFCAnyHandle>(); IList <ShapeRepresentationType> repTypes = new List <ShapeRepresentationType>(); IList <IList <CurveLoop> > extrusionLoops = new List <IList <CurveLoop> >(); IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>(); Plane floorPlane = GeometryUtil.CreateDefaultPlane(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); if (canExportAsContainerOrWithExtrusionAnalyzer) { Floor floor = floorElement as Floor; // First, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only. // Also limited to cases with line and arc boundaries. // SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); if (solids.Count == 1 && meshes.Count == 0) { bool completelyClipped; // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor XYZ floorExtrusionDirection = new XYZ(0, 0, -1); XYZ modelOrigin = XYZ.Zero; XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); if (floorOrigin == null) { // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't // go thruough te Revit model orgigin. We'll try the midpoint of the bounding box instead. BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null); modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0; floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); } if (floorOrigin != null) { XYZ floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top); Plane extrusionAnalyzerFloorPlane = new Plane(floorDir, floorOrigin); HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, catId, solids[0], extrusionAnalyzerFloorPlane, floorExtrusionDirection, null, out completelyClipped); if (completelyClipped) { return; } if (floorAndProperties.Handle != null) { IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(floorAndProperties.Handle); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); prodReps.Add(prodRep); repTypes.Add(ShapeRepresentationType.SweptSolid); if (floorAndProperties.Data != null) { loopExtraParams.Add(floorAndProperties.Data); } } } } } // Use internal routine as backup that handles openings. if (prodReps.Count == 0 && canExportAsInternalExtrusion) { exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement, geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps, out extrusionLoops, out loopExtraParams, floorPlane); for (int ii = 0; ii < prodReps.Count; ii++) { // all are extrusions repTypes.Add(ShapeRepresentationType.SweptSolid); } } if (prodReps.Count == 0) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; IFCAnyHandle prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } prodReps.Add(prodDefHnd); repTypes.Add(bodyData.ShapeRepresentationType); } } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(floorElement); int numReps = exportParts ? 1 : prodReps.Count; string entityType = null; switch (exportType) { case IFCExportType.IfcFooting: if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null); } else { entityType = IFCValidateEntry.GetValidIFCType <IFCFootingType>(floorElement, ifcEnumType, null); } break; case IFCExportType.IfcCovering: entityType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING"); break; case IFCExportType.IfcRamp: if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null); } else { entityType = IFCValidateEntry.GetValidIFCType <IFCRampType>(floorElement, ifcEnumType, null); } break; default: bool isBaseSlab = false; AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel(); if (analyticalModel != null) { AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs(); isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat); } entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR"); break; } for (int ii = 0; ii < numReps; ii++) { string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1)); string ifcDescription = NamingUtil.GetDescriptionOverride(floorElement, null); string ifcObjectType = NamingUtil.GetObjectTypeOverride(floorElement, exporterIFC.GetFamilyName()); string ifcTag = NamingUtil.GetTagOverride(floorElement, NamingUtil.CreateIFCElementId(floorElement)); string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID(); IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = null; // TODO: replace with CreateGenericBuildingElement. switch (exportType) { case IFCExportType.IfcFooting: slabHnd = IFCInstanceExporter.CreateFooting(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; case IFCExportType.IfcCovering: slabHnd = IFCInstanceExporter.CreateCovering(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; case IFCExportType.IfcRamp: slabHnd = IFCInstanceExporter.CreateRamp(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; default: slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; } if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null); } slabHnds.Add(slabHnd); if (!exportParts) { if (repTypes[ii] == ShapeRepresentationType.Brep) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } } for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true); } // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not // controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View if (exportedAsInternalExtrusion) { ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); } } if (!exportParts) { if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true); } } } tr.Commit(); return; } }
/// <summary> /// Exports the IFC element quantities. /// </summary> /// <param name="exporterIFC">The IFC exporter object.</param> /// <param name="element ">The element whose quantities are exported.</param> /// <param name="productWrapper">The ProductWrapper object.</param> private static void ExportElementQuantities(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { if (productWrapper.IsEmpty()) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { Document doc = element.Document; ElementType elemType = doc.GetElement(element.GetTypeId()) as ElementType; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ICollection<IFCAnyHandle> productSet = productWrapper.GetAllObjects(); IList<IList<QuantityDescription>> quantitiesToCreate = ExporterCacheManager.ParameterCache.Quantities; foreach (IList<QuantityDescription> currStandard in quantitiesToCreate) { foreach (QuantityDescription currDesc in currStandard) { foreach (IFCAnyHandle prodHnd in productSet) { if (currDesc.IsAppropriateType(prodHnd)) { IFCExtrusionCreationData ifcParams = productWrapper.FindExtrusionCreationParameters(prodHnd); HashSet<IFCAnyHandle> quantities = currDesc.ProcessEntries(file, exporterIFC, ifcParams, element, elemType); if (quantities.Count > 0) { string paramSetName = currDesc.Name; string methodName = currDesc.MethodOfMeasurement; IFCAnyHandle propertySet = IFCInstanceExporter.CreateElementQuantity(file, GUIDUtil.CreateGUID(), ownerHistory, paramSetName, methodName, null, quantities); IFCAnyHandle prodHndToUse = prodHnd; DescriptionCalculator ifcRDC = currDesc.DescriptionCalculator; if (ifcRDC != null) { IFCAnyHandle overrideHnd = ifcRDC.RedirectDescription(exporterIFC, element); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(overrideHnd)) prodHndToUse = overrideHnd; } HashSet<IFCAnyHandle> relatedObjects = new HashSet<IFCAnyHandle>(); relatedObjects.Add(prodHndToUse); IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relatedObjects, propertySet); } } } } } transaction.Commit(); } }
/// <summary> /// Exports Pset_Draughting for IFC 2x2 standard. /// </summary> /// <param name="exporterIFC">The IFC exporter object.</param> /// <param name="element ">The element whose properties are exported.</param> /// <param name="productWrapper">The ProductWrapper object.</param> private static void ExportPsetDraughtingFor2x2(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string catName = CategoryUtil.GetCategoryName(element); Color color = CategoryUtil.GetElementColor(element); HashSet<IFCAnyHandle> nameAndColorProps = new HashSet<IFCAnyHandle>(); nameAndColorProps.Add(PropertyUtil.CreateLabelPropertyFromCache(file, null, "Layername", catName, PropertyValueType.SingleValue, true, null)); //color { HashSet<IFCAnyHandle> colorProps = new HashSet<IFCAnyHandle>(); colorProps.Add(PropertyUtil.CreateIntegerPropertyFromCache(file, "Red", color.Red, PropertyValueType.SingleValue)); colorProps.Add(PropertyUtil.CreateIntegerPropertyFromCache(file, "Green", color.Green, PropertyValueType.SingleValue)); colorProps.Add(PropertyUtil.CreateIntegerPropertyFromCache(file, "Blue", color.Blue, PropertyValueType.SingleValue)); string propertyName = "Color"; nameAndColorProps.Add(IFCInstanceExporter.CreateComplexProperty(file, propertyName, null, propertyName, colorProps)); } string name = "Pset_Draughting"; // IFC 2x2 standard IFCAnyHandle propertySet2 = IFCInstanceExporter.CreatePropertySet(file, GUIDUtil.CreateGUID(), ownerHistory, name, null, nameAndColorProps); HashSet<IFCAnyHandle> relatedObjects = new HashSet<IFCAnyHandle>(productWrapper.GetAllObjects()); IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relatedObjects, propertySet2); transaction.Commit(); } }
/// <summary> /// Exports text note elements. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="textNote"> /// The text note element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, TextNote textNote, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI string predefinedType = null; IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, textNote, out predefinedType); if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(exportType.ExportInstance)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string textString = textNote.Text; if (String.IsNullOrEmpty(textString)) { throw new Exception("TextNote does not have test string."); } ElementId symId = textNote.GetTypeId(); if (symId == ElementId.InvalidElementId) { throw new Exception("TextNote does not have valid type id."); } PresentationStyleAssignmentCache cache = ExporterCacheManager.PresentationStyleAssignmentCache; IFCAnyHandle presHnd = cache.Find(symId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(presHnd)) { TextElementType textElemType = textNote.Symbol; CreatePresentationStyleAssignmentForTextElementType(exporterIFC, textElemType, cache); presHnd = cache.Find(symId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(presHnd)) { throw new Exception("Failed to create presentation style assignment for TextElementType."); } } HashSet <IFCAnyHandle> presHndSet = new HashSet <IFCAnyHandle>(); presHndSet.Add(presHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, textNote)) { const double planScale = 100.0; // currently hardwired. XYZ orig = UnitUtil.ScaleLength(textNote.Coord); XYZ yDir = textNote.UpDirection; XYZ xDir = textNote.BaseDirection; XYZ zDir = xDir.CrossProduct(yDir); double sizeX = UnitUtil.ScaleLength(textNote.Width * planScale); double sizeY = UnitUtil.ScaleLength(textNote.Height * planScale); // When we display text on screen, we "flip" it if the xDir is negative with relation to // the X-axis. So if it is, we'll flip x and y. bool flipOrig = false; if (xDir.X < 0) { xDir = xDir.Multiply(-1.0); yDir = yDir.Multiply(-1.0); flipOrig = true; } // xFactor, yFactor only used if flipOrig. double xFactor = 0.0, yFactor = 0.0; string boxAlignment = ConvertTextNoteAlignToBoxAlign(textNote, out xFactor, out yFactor); // modify the origin to match the alignment. In Revit, the origin is at the top-left (unless flipped, // then bottom-right). if (flipOrig) { orig = orig.Add(xDir.Multiply(sizeX * xFactor)); orig = orig.Add(yDir.Multiply(sizeY * yFactor)); } IFCAnyHandle origin = ExporterUtil.CreateAxis(file, orig, zDir, xDir); IFCAnyHandle extent = IFCInstanceExporter.CreatePlanarExtent(file, sizeX, sizeY); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateTextLiteralWithExtent(file, textString, origin, Toolkit.IFCTextPath.Left, extent, boxAlignment); IFCAnyHandle annoTextOccHnd = IFCInstanceExporter.CreateStyledItem(file, repItemHnd, presHndSet, null); ElementId catId = textNote.Category != null ? textNote.Category.Id : ElementId.InvalidElementId; HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(repItemHnd); IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, textNote, catId, exporterIFC.Get2DContextHandle(), bodyItems); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) { throw new Exception("Failed to create shape representation."); } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(bodyRepHnd); IFCAnyHandle prodShapeHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle instHnd; if (exportType.ExportInstance == Common.Enums.IFCEntityType.IfcAnnotation) { instHnd = IFCInstanceExporter.CreateAnnotation(exporterIFC, textNote, GUIDUtil.CreateGUID(), ExporterCacheManager.OwnerHistoryHandle, setter.LocalPlacement, prodShapeHnd); } else { instHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, textNote, GUIDUtil.CreateGUID(), ExporterCacheManager.OwnerHistoryHandle, setter.LocalPlacement, prodShapeHnd); } productWrapper.AddAnnotation(instHnd, setter.LevelInfo, true); } tr.Commit(); } }
/// <summary> /// Base implementation to export IFC site object. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="document">The Revit document. It may be null if element isn't.</param> /// <param name="element">The element. It may be null if document isn't.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> private static void ExportSiteBase(ExporterIFC exporterIFC, Document document, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { IFCAnyHandle siteHandle = ExporterCacheManager.SiteHandle; // Nothing to do if we've already created an IfcSite, and have no site element to try to // export or append to the existing site. if (element == null && !IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { return; } Document doc = document; if (doc == null) { if (element != null) { doc = element.Document; } else { throw new ArgumentException("Both document and element are null."); } } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcSite; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle siteRepresentation = null; if (element != null) { // It would be possible that they actually represent several different sites with different buildings, // but until we have a concept of a building in Revit, we have to assume 0-1 sites, 1 building. bool appendedToSite = false; bool exportAsFacetation = !ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { IList <IFCAnyHandle> representations = IFCAnyHandleUtil.GetProductRepresentations(siteHandle); if (representations.Count > 0) { IFCAnyHandle bodyRep = representations[0]; IFCAnyHandle boundaryRep = null; if (representations.Count > 1) { boundaryRep = representations[1]; } siteRepresentation = RepresentationUtil.CreateSurfaceProductDefinitionShape(exporterIFC, element, geometryElement, true, exportAsFacetation, ref bodyRep, ref boundaryRep); if (representations.Count == 1 && !IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryRep)) { // If the first site has no boundaryRep, // we will add the boundaryRep from second site to it. representations.Clear(); representations.Add(boundaryRep); IFCAnyHandleUtil.AddProductRepresentations(siteHandle, representations); } appendedToSite = true; } } if (!appendedToSite) { siteRepresentation = RepresentationUtil.CreateSurfaceProductDefinitionShape(exporterIFC, element, geometryElement, true, exportAsFacetation); } } List <int> latitude = new List <int>(); List <int> longitude = new List <int>(); ProjectLocation projLocation = doc.ActiveProjectLocation; IFCAnyHandle relativePlacement = null; double unscaledElevation = 0.0; if (projLocation != null) { const double scaleToDegrees = 180 / Math.PI; double latitudeInDeg = projLocation.GetSiteLocation().Latitude *scaleToDegrees; double longitudeInDeg = projLocation.GetSiteLocation().Longitude *scaleToDegrees; ExporterUtil.GetSafeProjectPositionElevation(doc, out unscaledElevation); int latDeg = ((int)latitudeInDeg); latitudeInDeg -= latDeg; latitudeInDeg *= 60; int latMin = ((int)latitudeInDeg); latitudeInDeg -= latMin; latitudeInDeg *= 60; int latSec = ((int)latitudeInDeg); latitudeInDeg -= latSec; latitudeInDeg *= 1000000; int latFracSec = ((int)latitudeInDeg); latitude.Add(latDeg); latitude.Add(latMin); latitude.Add(latSec); if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { latitude.Add(latFracSec); } int longDeg = ((int)longitudeInDeg); longitudeInDeg -= longDeg; longitudeInDeg *= 60; int longMin = ((int)longitudeInDeg); longitudeInDeg -= longMin; longitudeInDeg *= 60; int longSec = ((int)longitudeInDeg); longitudeInDeg -= longSec; longitudeInDeg *= 1000000; int longFracSec = ((int)longitudeInDeg); longitude.Add(longDeg); longitude.Add(longMin); longitude.Add(longSec); if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { longitude.Add(longFracSec); } ExportOptionsCache.SiteTransformBasis transformBasis = ExporterCacheManager.ExportOptionsCache.SiteTransformation; Transform siteSharedCoordinatesTrf = Transform.Identity; if (transformBasis != ExportOptionsCache.SiteTransformBasis.Internal) { BasePoint basePoint = null; if (transformBasis == ExportOptionsCache.SiteTransformBasis.Project) { basePoint = new FilteredElementCollector(doc).WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_ProjectBasePoint)).First() as BasePoint; } else if (transformBasis == ExportOptionsCache.SiteTransformBasis.Site) { basePoint = new FilteredElementCollector(doc).WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_SharedBasePoint)).First() as BasePoint; } if (basePoint != null) { BoundingBoxXYZ bbox = basePoint.get_BoundingBox(null); XYZ xyz = bbox.Min; siteSharedCoordinatesTrf = Transform.CreateTranslation(new XYZ(-xyz.X, -xyz.Y, unscaledElevation - xyz.Z)); } else { siteSharedCoordinatesTrf = projLocation.GetTransform().Inverse; } } if (!siteSharedCoordinatesTrf.IsIdentity) { double unscaledSiteElevation = ExporterCacheManager.ExportOptionsCache.IncludeSiteElevation ? 0.0 : unscaledElevation; XYZ orig = UnitUtil.ScaleLength(siteSharedCoordinatesTrf.Origin - new XYZ(0, 0, unscaledSiteElevation)); relativePlacement = ExporterUtil.CreateAxis2Placement3D(file, orig, siteSharedCoordinatesTrf.BasisZ, siteSharedCoordinatesTrf.BasisX); } } // Get elevation for site. double elevation = UnitUtil.ScaleLength(unscaledElevation); if (IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement)) { relativePlacement = ExporterUtil.CreateAxis2Placement3D(file); } IFCAnyHandle localPlacement = IFCInstanceExporter.CreateLocalPlacement(file, null, relativePlacement); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string siteObjectType = null; ProjectInfo projectInfo = doc.ProjectInformation; Element mainSiteElement = (element != null) ? element : projectInfo; bool exportSite = false; string siteGUID = null; string siteName = null; string siteLongName = null; string siteLandTitleNumber = null; string siteDescription = null; if (element != null) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { exportSite = true; // We will use the Project Information site name as the primary name, if it exists. siteGUID = GUIDUtil.CreateSiteGUID(doc, element); siteName = NamingUtil.GetOverrideStringValue(projectInfo, "SiteName", NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element))); siteDescription = NamingUtil.GetDescriptionOverride(element, null); // Look in site element for "IfcLongName" or project information for either "IfcLongName" or "SiteLongName". siteLongName = NamingUtil.GetLongNameOverride(projectInfo, NamingUtil.GetLongNameOverride(element, null)); if (string.IsNullOrWhiteSpace(siteLongName)) { siteLongName = NamingUtil.GetOverrideStringValue(projectInfo, "SiteLongName", null); } siteDescription = NamingUtil.GetOverrideStringValue(projectInfo, "SiteDescription", null); siteObjectType = NamingUtil.GetOverrideStringValue(projectInfo, "SiteObjectType", null); // Look in site element for "IfcLandTitleNumber" or project information for "SiteLandTitleNumber". siteLandTitleNumber = NamingUtil.GetOverrideStringValue(element, "IfcLandTitleNumber", null); if (string.IsNullOrWhiteSpace(siteLandTitleNumber)) { siteLandTitleNumber = NamingUtil.GetOverrideStringValue(projectInfo, "SiteLandTitleNumber", null); } } } else { exportSite = true; siteGUID = GUIDUtil.CreateProjectLevelGUID(doc, IFCProjectLevelGUIDType.Site); siteName = NamingUtil.GetOverrideStringValue(projectInfo, "SiteName", "Default"); siteLongName = NamingUtil.GetLongNameOverride(projectInfo, NamingUtil.GetOverrideStringValue(projectInfo, "SiteLongName", null)); siteDescription = NamingUtil.GetOverrideStringValue(projectInfo, "SiteDescription", null); siteObjectType = NamingUtil.GetOverrideStringValue(projectInfo, "SiteObjectType", null); siteLandTitleNumber = NamingUtil.GetOverrideStringValue(projectInfo, "SiteLandTitleNumber", null); // don't bother if we have nothing in the site whatsoever. if ((latitude.Count == 0 || longitude.Count == 0) && IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement) && string.IsNullOrWhiteSpace(siteLongName) && string.IsNullOrWhiteSpace(siteLandTitleNumber)) { return; } } COBieProjectInfo cobieProjectInfo = ExporterCacheManager.ExportOptionsCache.COBieProjectInfo; // Override Site information when it is a special COBie export if (ExporterCacheManager.ExportOptionsCache.ExportAs2x3COBIE24DesignDeliverable && cobieProjectInfo != null) { siteName = cobieProjectInfo.SiteLocation; siteDescription = cobieProjectInfo.SiteDescription; } if (exportSite) { IFCAnyHandle address = null; if (Exporter.NeedToCreateAddressForSite(doc)) { address = Exporter.CreateIFCAddress(file, doc, projectInfo); } siteHandle = IFCInstanceExporter.CreateSite(exporterIFC, element, siteGUID, ownerHistory, siteName, siteDescription, siteObjectType, localPlacement, siteRepresentation, siteLongName, IFCElementComposition.Element, latitude, longitude, elevation, siteLandTitleNumber, address); productWrapper.AddSite(mainSiteElement, siteHandle); ExporterCacheManager.SiteHandle = siteHandle; // Getting Pset_SiteCommon data from parameters // IFC2x3: BuildableArea, TotalArea, BuildingHeightLimit HashSet <IFCAnyHandle> properties = new HashSet <IFCAnyHandle>(); IFCAnyHandle propSingleValue; propSingleValue = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, projectInfo, "Pset_SiteCommon.BuildableArea", "BuildableArea", PropertyValueType.SingleValue); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) { properties.Add(propSingleValue); } propSingleValue = PropertyUtil.CreateAreaMeasurePropertyFromElement(file, exporterIFC, projectInfo, "Pset_SiteCommon.TotalArea", "TotalArea", PropertyValueType.SingleValue); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) { properties.Add(propSingleValue); } propSingleValue = PropertyUtil.CreatePositiveLengthMeasurePropertyFromElement(file, exporterIFC, projectInfo, "Pset_SiteCommon.BuildingHeightLimit", null, "BuildingHeightLimit", PropertyValueType.SingleValue); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) { properties.Add(propSingleValue); } if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { propSingleValue = PropertyUtil.CreateIdentifierPropertyFromElement(file, projectInfo, "Pset_SiteCommon.Reference", "Reference", PropertyValueType.SingleValue); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) { properties.Add(propSingleValue); } propSingleValue = PropertyUtil.CreatePositiveRatioPropertyFromElement(file, exporterIFC, projectInfo, "Pset_SiteCommon.SiteCoverageRatio", "SiteCoverageRatio", PropertyValueType.SingleValue); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) { properties.Add(propSingleValue); } propSingleValue = PropertyUtil.CreatePositiveRatioPropertyFromElement(file, exporterIFC, projectInfo, "Pset_SiteCommon.FloorAreaRatio", "FloorAreaRatio", PropertyValueType.SingleValue); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(propSingleValue)) { properties.Add(propSingleValue); } } if (properties.Count > 0) { IFCInstanceExporter.CreatePropertySet(file, GUIDUtil.CreateGUID(), ExporterCacheManager.OwnerHistoryHandle, "Pset_SiteCommon", null, properties); } } tr.Commit(); } }
/// <summary> /// Exports an element as an IfcReinforcingMesh. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet, GeometryElement geometryElement, ProductWrapper productWrapper) { if (sheet == null || geometryElement == null) { return(false); } Document doc = sheet.Document; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, sheet, null, null, ExporterUtil.GetBaseLevelIdForElement(sheet))) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.GetPlacement()); ElementId categoryId = CategoryUtil.GetSafeCategoryId(sheet); ElementId materialId = ElementId.InvalidElementId; ParameterUtil.GetElementIdValueFromElementOrSymbol(sheet, BuiltInParameter.MATERIAL_ID_PARAM, out materialId); double scale = exporterIFC.LinearScale; string guid = GUIDUtil.CreateGUID(sheet); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(sheet, revitObjectType); string description = NamingUtil.GetDescriptionOverride(sheet, null); string objectType = NamingUtil.GetObjectTypeOverride(sheet, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.CreateIFCElementId(sheet); string steelGrade = NamingUtil.GetOverrideStringValue(sheet, "SteelGrade", null); double?meshLength = sheet.CutOverallLength; double?meshWidth = sheet.CutOverallWidth; Element fabricSheetTypeElem = doc.GetElement(sheet.GetTypeId()); FabricSheetType fabricSheetType = (fabricSheetTypeElem == null) ? null : (fabricSheetTypeElem as FabricSheetType); double longitudinalBarNominalDiameter = 0.0; double transverseBarNominalDiameter = 0.0; double longitudinalBarCrossSectionArea = 0.0; double transverseBarCrossSectionArea = 0.0; double longitudinalBarSpacing = 0.0; double transverseBarSpacing = 0.0; if (fabricSheetType != null) { Element majorFabricWireTypeElem = doc.GetElement(fabricSheetType.MajorDirectionWireType); FabricWireType majorFabricWireType = (majorFabricWireTypeElem == null) ? null : (majorFabricWireTypeElem as FabricWireType); if (majorFabricWireType != null) { longitudinalBarNominalDiameter = majorFabricWireType.WireDiameter * scale; double localRadius = longitudinalBarNominalDiameter / 2.0; longitudinalBarCrossSectionArea = localRadius * localRadius * Math.PI; } Element minorFabricWireTypeElem = doc.GetElement(fabricSheetType.MinorDirectionWireType); FabricWireType minorFabricWireType = (minorFabricWireTypeElem == null) ? null : (minorFabricWireTypeElem as FabricWireType); if (minorFabricWireType != null) { transverseBarNominalDiameter = minorFabricWireType.WireDiameter * scale; double localRadius = transverseBarNominalDiameter / 2.0; transverseBarCrossSectionArea = localRadius * localRadius * Math.PI; } longitudinalBarSpacing = fabricSheetType.MajorSpacing * scale; transverseBarSpacing = fabricSheetType.MinorSpacing * scale; } IList <IFCAnyHandle> bodyItems = new List <IFCAnyHandle>(); IList <Curve> wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Major); foreach (Curve wireCenterline in wireCenterlines) { IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, longitudinalBarNominalDiameter); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) { bodyItems.Add(bodyItem); } } wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Minor); foreach (Curve wireCenterline in wireCenterlines) { IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, transverseBarNominalDiameter); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) { bodyItems.Add(bodyItem); } } IFCAnyHandle shapeRep = (bodyItems.Count > 0) ? RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, sheet, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null) : null; IList <IFCAnyHandle> shapeReps = null; if (shapeRep != null) { shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); } IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null; IFCAnyHandle fabricSheet = IFCInstanceExporter.CreateReinforcingMesh(file, guid, ownerHistory, name, description, objectType, localPlacement, prodRep, elementTag, steelGrade, meshLength, meshWidth, longitudinalBarNominalDiameter, transverseBarNominalDiameter, longitudinalBarCrossSectionArea, transverseBarCrossSectionArea, longitudinalBarSpacing, transverseBarSpacing); ElementId fabricAreaId = sheet.FabricAreaOwnerId; if (fabricAreaId != ElementId.InvalidElementId) { HashSet <IFCAnyHandle> fabricSheets = null; if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out fabricSheets)) { fabricSheets = new HashSet <IFCAnyHandle>(); ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets; } fabricSheets.Add(fabricSheet); } productWrapper.AddElement(sheet, fabricSheet, placementSetter.GetLevelInfo(), ecData, true); CategoryUtil.CreateMaterialAssociation(exporterIFC, fabricSheet, materialId); } } tr.Commit(); return(true); } }
/// <summary> /// Exports materials for host object. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="hostObject">The host object.</param> /// <param name="elemHnds">The host IFC handles.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <param name="levelId">The level id.</param> /// <param name="direction">The IFCLayerSetDirection.</param> /// <param name="containsBRepGeometry">True if the geometry contains BRep geoemtry. If so, we will export an IfcMaterialList</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportHostObjectMaterials(ExporterIFC exporterIFC, HostObject hostObject, IList<IFCAnyHandle> elemHnds, GeometryElement geometryElement, ProductWrapper productWrapper, ElementId levelId, Toolkit.IFCLayerSetDirection direction, bool containsBRepGeometry) { if (hostObject == null) return true; //nothing to do if (elemHnds == null || (elemHnds.Count == 0)) return true; //nothing to do IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { if (productWrapper != null) productWrapper.ClearFinishMaterials(); double scaledOffset = 0.0, scaledWallWidth = 0.0, wallHeight = 0.0; Wall wall = hostObject as Wall; if (wall != null) { scaledWallWidth = UnitUtil.ScaleLength(wall.Width); scaledOffset = -scaledWallWidth / 2.0; BoundingBoxXYZ boundingBox = wall.get_BoundingBox(null); if (boundingBox != null) wallHeight = boundingBox.Max.Z - boundingBox.Min.Z; } ElementId typeElemId = hostObject.GetTypeId(); IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialLayerSetCache.Find(typeElemId); // Roofs with no components are only allowed one material. We will arbitrarily choose the thickest material. IFCAnyHandle primaryMaterialHnd = ExporterCacheManager.MaterialLayerSetCache.FindPrimaryMaterialHnd(typeElemId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet)) { HostObjAttributes hostObjAttr = hostObject.Document.GetElement(typeElemId) as HostObjAttributes; if (hostObjAttr == null) return true; //nothing to do List<ElementId> matIds = new List<ElementId>(); List<double> widths = new List<double>(); List<MaterialFunctionAssignment> functions = new List<MaterialFunctionAssignment>(); ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(hostObject); CompoundStructure cs = hostObjAttr.GetCompoundStructure(); if (cs != null) { //TODO: Vertically compound structures are not yet supported by export. if (!cs.IsVerticallyHomogeneous() && !MathUtil.IsAlmostZero(wallHeight)) cs = cs.GetSimpleCompoundStructure(wallHeight, wallHeight / 2.0); for (int i = 0; i < cs.LayerCount; ++i) { ElementId matId = cs.GetMaterialId(i); if (matId != ElementId.InvalidElementId) { matIds.Add(matId); } else { matIds.Add(baseMatId); } widths.Add(cs.GetLayerWidth(i)); // save layer function into ProductWrapper, // it's used while exporting "Function" of Pset_CoveringCommon functions.Add(cs.GetLayerFunction(i)); } } if (matIds.Count == 0) { matIds.Add(baseMatId); widths.Add(cs != null ? cs.GetWidth() : 0); functions.Add(MaterialFunctionAssignment.None); } // We can't create IfcMaterialLayers without creating an IfcMaterialLayerSet. So we will simply collate here. IList<IFCAnyHandle> materialHnds = new List<IFCAnyHandle>(); IList<int> widthIndices = new List<int>(); double thickestLayer = 0.0; for (int ii = 0; ii < matIds.Count; ++ii) { // Require positive width for IFC2x3 and before, and non-negative width for IFC4. if (widths[ii] < -MathUtil.Eps()) continue; bool almostZeroWidth = MathUtil.IsAlmostZero(widths[ii]); if (ExporterCacheManager.ExportOptionsCache.FileVersion != IFCVersion.IFC4 && almostZeroWidth) continue; if (almostZeroWidth) widths[ii] = 0.0; IFCAnyHandle materialHnd = CategoryUtil.GetOrCreateMaterialHandle(exporterIFC, matIds[ii]); if (primaryMaterialHnd == null || (widths[ii] > thickestLayer)) { primaryMaterialHnd = materialHnd; thickestLayer = widths[ii]; } widthIndices.Add(ii); materialHnds.Add(materialHnd); if ((productWrapper != null) && (functions[ii] == MaterialFunctionAssignment.Finish1 || functions[ii] == MaterialFunctionAssignment.Finish2)) { productWrapper.AddFinishMaterial(materialHnd); } } int numLayersToCreate = widthIndices.Count; if (numLayersToCreate == 0) return false; if (!containsBRepGeometry) { IList<IFCAnyHandle> layers = new List<IFCAnyHandle>(numLayersToCreate); for (int ii = 0; ii < numLayersToCreate; ii++) { int widthIndex = widthIndices[ii]; double scaledWidth = UnitUtil.ScaleLength(widths[widthIndex]); IFCAnyHandle materialLayer = IFCInstanceExporter.CreateMaterialLayer(file, materialHnds[ii], scaledWidth, null); layers.Add(materialLayer); } string layerSetName = exporterIFC.GetFamilyName(); materialLayerSet = IFCInstanceExporter.CreateMaterialLayerSet(file, layers, layerSetName); ExporterCacheManager.MaterialLayerSetCache.Register(typeElemId, materialLayerSet); ExporterCacheManager.MaterialLayerSetCache.RegisterPrimaryMaterialHnd(typeElemId, primaryMaterialHnd); } else { foreach (IFCAnyHandle elemHnd in elemHnds) { CategoryUtil.CreateMaterialAssociations(exporterIFC, elemHnd, matIds); } } } // IfcMaterialLayerSetUsage is not supported for IfcWall, only IfcWallStandardCase. IFCAnyHandle layerSetUsage = null; for (int ii = 0; ii < elemHnds.Count; ii++) { IFCAnyHandle elemHnd = elemHnds[ii]; if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd)) continue; SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, elemHnd, hostObject.Id, levelId); if (containsBRepGeometry) continue; HashSet<IFCAnyHandle> relDecomposesSet = IFCAnyHandleUtil.GetRelDecomposes(elemHnd); IList<IFCAnyHandle> subElemHnds = null; if (relDecomposesSet != null && relDecomposesSet.Count == 1) { IFCAnyHandle relAggregates = relDecomposesSet.First(); if (IFCAnyHandleUtil.IsTypeOf(relAggregates, IFCEntityType.IfcRelAggregates)) subElemHnds = IFCAnyHandleUtil.GetAggregateInstanceAttribute<List<IFCAnyHandle>>(relAggregates, "RelatedObjects"); } bool hasSubElems = (subElemHnds != null && subElemHnds.Count != 0); bool isRoof = IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcRoof); if (!hasSubElems && !isRoof && !IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcWall)) { if (layerSetUsage == null) { bool flipDirSense = true; if (wall != null) { // if we have flipped the center curve on export, we need to take that into account here. // We flip the center curve on export if it is an arc and it has a negative Z direction. LocationCurve locCurve = wall.Location as LocationCurve; if (locCurve != null) { Curve curve = locCurve.Curve; Plane defPlane = new Plane(XYZ.BasisX, XYZ.BasisY, XYZ.Zero); bool curveFlipped = GeometryUtil.MustFlipCurve(defPlane, curve); flipDirSense = !(wall.Flipped ^ curveFlipped); } } else if (hostObject is Floor) { flipDirSense = false; } double offsetFromReferenceLine = flipDirSense ? -scaledOffset : scaledOffset; IFCDirectionSense sense = flipDirSense ? IFCDirectionSense.Negative : IFCDirectionSense.Positive; layerSetUsage = IFCInstanceExporter.CreateMaterialLayerSetUsage(file, materialLayerSet, direction, sense, offsetFromReferenceLine); } ExporterCacheManager.MaterialLayerRelationsCache.Add(layerSetUsage, elemHnd); } else { if (hasSubElems) { foreach (IFCAnyHandle subElemHnd in subElemHnds) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(subElemHnd)) ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, subElemHnd); } } else if (!isRoof) { ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, elemHnd); } else if (primaryMaterialHnd != null) { ExporterCacheManager.MaterialLayerRelationsCache.Add(primaryMaterialHnd, elemHnd); } } } tr.Commit(); return true; } }
/// <summary> /// Exports a Rebar Coupler, /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="coupler">The RebarCoupler element.</param> /// <param name="productWrapper">The product wrapper.</param> public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, ProductWrapper productWrapper) { if (coupler == null) { return; } FamilySymbol familySymbol = ExporterCacheManager.Document.GetElement(coupler.GetTypeId()) as FamilySymbol; if (familySymbol == null) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcMechanicalFastener", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } ElementId categoryId = CategoryUtil.GetSafeCategoryId(coupler); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; Options options = GeometryUtil.GetIFCExportGeometryOptions();; string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, coupler, out ifcEnumType); using (IFCTransaction tr = new IFCTransaction(file)) { FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(coupler.GetTypeId(), false, exportType.ExportType); bool found = currentTypeInfo.IsValid(); if (!found) { string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, familySymbol); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); GeometryElement exportGeometry = familySymbol.get_Geometry(options); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); bodyData = BodyExporter.ExportBody(exporterIFC, coupler, categoryId, ElementId.InvalidElementId, exportGeometry, bodyExporterOptions, null); List <IFCAnyHandle> repMap = new List <IFCAnyHandle>(); IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file);; repMap.Add(IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyData.RepresentationHnd)); IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMap, coupler, familySymbol); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { string applicableOccurrence = NamingUtil.GetObjectTypeOverride(familySymbol, typeObjectType); if (!string.IsNullOrEmpty(applicableOccurrence)) { IFCAnyHandleUtil.SetAttribute(styleHandle, "ApplicableOccurrence", applicableOccurrence); } currentTypeInfo.Style = styleHandle; ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(coupler.GetTypeId(), false, exportType.ExportType, currentTypeInfo); } } int nCouplerQuantity = coupler.GetCouplerQuantity(); if (nCouplerQuantity <= 0) { return; } ISet <IFCAnyHandle> createdRebarCouplerHandles = new HashSet <IFCAnyHandle>(); string origInstanceName = NamingUtil.GetNameOverride(coupler, NamingUtil.GetIFCName(coupler)); for (int idx = 0; idx < nCouplerQuantity; idx++) { string instanceGUID = GUIDUtil.CreateSubElementGUID(coupler, idx); IFCAnyHandle style = currentTypeInfo.Style; if (IFCAnyHandleUtil.IsNullOrHasNoValue(style)) { return; } IList <IFCAnyHandle> repMapList = GeometryUtil.GetRepresentationMaps(style); if (repMapList == null) { return; } if (repMapList.Count == 0) { return; } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); IFCAnyHandle contextOfItems3d = exporterIFC.Get3DContextHandle("Body"); ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>(); representations.Add(ExporterUtil.CreateDefaultMappedItem(file, repMapList[0], XYZ.Zero)); IFCAnyHandle shapeRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, coupler, categoryId, contextOfItems3d, representations); shapeReps.Add(shapeRep); IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, shapeReps); Transform trf = coupler.GetCouplerPositionTransform(idx); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null)) { IFCAnyHandle instanceHandle = null; IFCExportInfoPair exportMechFastener = new IFCExportInfoPair(); exportMechFastener.SetValueWithPair(IFCEntityType.IfcMechanicalFastener); instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportMechFastener, exporterIFC, coupler, instanceGUID, ownerHistory, setter.LocalPlacement, productRepresentation); string instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName + ": " + idx); IFCAnyHandleUtil.SetAttribute(instanceHandle, "Name", instanceName); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { // In IFC4 NominalDiameter and NominalLength attributes have been deprecated. PredefinedType attribute was added. IFCAnyHandleUtil.SetAttribute(instanceHandle, "PredefinedType", Revit.IFC.Export.Toolkit.IFC4.IFCMechanicalFastenerType.USERDEFINED); } else { IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalDiameter", familySymbol.get_Parameter(BuiltInParameter.COUPLER_WIDTH).AsDouble()); IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalLength", familySymbol.get_Parameter(BuiltInParameter.COUPLER_LENGTH).AsDouble()); } createdRebarCouplerHandles.Add(instanceHandle); productWrapper.AddElement(coupler, instanceHandle, setter, null, true); } } string couplerGUID = GUIDUtil.CreateGUID(coupler); if (nCouplerQuantity > 1) { // Create a group to hold all of the created IFC entities, if the coupler aren't already in an assembly. // We want to avoid nested groups of groups of couplers. if (coupler.AssemblyInstanceId == ElementId.InvalidElementId) { string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(coupler, revitObjectType); string description = NamingUtil.GetDescriptionOverride(coupler, null); string objectType = NamingUtil.GetObjectTypeOverride(coupler, revitObjectType); IFCAnyHandle rebarGroup = IFCInstanceExporter.CreateGroup(file, couplerGUID, ownerHistory, name, description, objectType); productWrapper.AddElement(coupler, rebarGroup); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, createdRebarCouplerHandles, null, rebarGroup); } } else { // We will update the GUID of the one created element to be the element GUID. // This will allow the IfcGUID parameter to be use/set if appropriate. ExporterUtil.SetGlobalId(createdRebarCouplerHandles.ElementAt(0), couplerGUID); } tr.Commit(); } }
/// <summary> /// Exports a roof to IfcRoof. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportRoof(ExporterIFC exporterIFC, string ifcEnumType, Element roof, GeometryElement geometryElement, ProductWrapper productWrapper) { if (roof == null || geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // If the roof is an in-place family, we will allow any arbitrary orientation. While this may result in some // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be // used for this reason in the first place. ecData.PossibleExtrusionAxes = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ; ecData.AreInnerRegionsOpenings = true; ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); BodyData bodyData; IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof, categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return; } bool exportSlab = ecData.ScaledLength > MathUtil.Eps(); string guid = GUIDUtil.CreateGUID(roof); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string roofName = NamingUtil.GetNameOverride(roof, NamingUtil.GetIFCName(roof)); string roofDescription = NamingUtil.GetDescriptionOverride(roof, null); string roofObjectType = NamingUtil.GetObjectTypeOverride(roof, NamingUtil.CreateIFCObjectName(exporterIFC, roof)); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(roof, NamingUtil.CreateIFCElementId(roof)); string roofType = GetIFCRoofType(ifcEnumType); roofType = IFCValidateEntry.GetValidIFCType(roof, ifcEnumType); IFCAnyHandle roofHnd = IFCInstanceExporter.CreateRoof(file, guid, ownerHistory, roofName, roofDescription, roofObjectType, localPlacement, exportSlab ? null : representation, elementTag, roofType); productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true); // will export its host object materials later if it is a roof if (!(roof is RoofBase)) { CategoryUtil.CreateMaterialAssociations(exporterIFC, roofHnd, bodyData.MaterialIds); } if (exportSlab) { string slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart); string slabName = roofName + ":1"; IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, slabName, roofDescription, roofObjectType, slabLocalPlacementHnd, representation, elementTag, "ROOF"); Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform, exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper); ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd); productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false); CategoryUtil.CreateMaterialAssociations(exporterIFC, slabHnd, bodyData.MaterialIds); } } tr.Commit(); } } }
/// <summary> /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="element">The roof or floor element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks> public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); // We support ExtrusionRoofs, FootPrintRoofs, and Floors only. bool elementIsRoof = (element is ExtrusionRoof) || (element is FootPrintRoof); bool elementIsFloor = (element is Floor); if (!elementIsRoof && !elementIsFloor) { return(null); } using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null; try { hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); } catch { return(null); } if (hostObjectSubcomponents == null) { return(null); } int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) { return(null); } try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); string elementName = NamingUtil.GetIFCName(element); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); string hostObjectType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle hostObjectHandle = null; if (elementIsRoof) { hostObjectHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType); } else { hostObjectHandle = IFCInstanceExporter.CreateSlab(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) { return(null); } IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(hostObjectHandle); // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>(); double maximumScaledDepth = 0.0; using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; int loopNum = 0; int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; string subSlabType = elementIsRoof ? "ROOF" : hostObjectType; foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = hostObjectSubcomponent.GetPlane(); Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); IList <CurveLoop> curveLoops = new List <CurveLoop>(); CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); curveLoops.Add(slabCurveLoop); double slope = Math.Abs(plane.Normal.Z); double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); double scaledExtrusionDepth = scaledDepth * slope; IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(shapeRep); shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs. string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.CreateGUID(); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName, elementDescription, elementObjectType, slabPlacement, repHnd, elementId, subSlabType); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop)); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); hostObjectOpeningLoops.Add(slabCurveLoop); maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth); loopNum++; } } productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(hostObjectHandle); } } } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } }
/// <summary> /// Exports a Group as an IfcGroup. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportGroupElement(ExporterIFC exporterIFC, Group element, ProductWrapper productWrapper) { if (element == null) { return(false); } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcGroup; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle groupHnd = null; string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.GetFamilyAndTypeName(element)); string longName = NamingUtil.GetLongNameOverride(element, null); string ifcEnumType; IFCExportInfoPair exportAs = ExporterUtil.GetObjectExportType(exporterIFC, element, out ifcEnumType); if (exportAs.ExportInstance == IFCEntityType.IfcGroup) { groupHnd = IFCInstanceExporter.CreateGroup(file, guid, ownerHistory, name, description, objectType); } else if (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { if (exportAs.ExportInstance == IFCEntityType.IfcBuildingSystem) { groupHnd = IFCInstanceExporter.CreateBuildingSystem(file, exportAs, guid, ownerHistory, name, description, objectType, longName); } else if (exportAs.ExportInstance == IFCEntityType.IfcFurniture) { groupHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportAs, exporterIFC, element, guid, ownerHistory, null, null); } } if (groupHnd == null) { return(false); } GroupInfo groupInfo = ExporterCacheManager.GroupCache.RegisterGroup(element.Id, groupHnd); if (IFCAnyHandleUtil.IsSubTypeOf(groupHnd, IFCEntityType.IfcProduct)) { IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacementToUse; ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); bool containedInSpace = (roomId != ElementId.InvalidElementId); productWrapper.AddElement(element, groupHnd, setter.LevelInfo, null, !containedInSpace, exportAs); if (containedInSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, groupHnd); } } } else { productWrapper.AddElement(element, groupHnd, exportAs); } // Check or set the cached Group's export type if (groupInfo.GroupType.ExportInstance == IFCEntityType.UnKnown) { ExporterCacheManager.GroupCache.RegisterOrUpdateGroupType(element.Id, exportAs); } else if (groupInfo.GroupType.ExportInstance != exportAs.ExportInstance) { throw new InvalidOperationException("Inconsistent Group export entity type"); } tr.Commit(); return(true); } }
/// <summary> /// Exports an element as an IfcReinforcingMesh. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet, GeometryElement geometryElement, ProductWrapper productWrapper) { if (sheet == null || geometryElement == null) return false; Document doc = sheet.Document; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, sheet, null, null, ExporterUtil.GetBaseLevelIdForElement(sheet))) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.GetPlacement()); ElementId categoryId = CategoryUtil.GetSafeCategoryId(sheet); ElementId materialId = ElementId.InvalidElementId; ParameterUtil.GetElementIdValueFromElementOrSymbol(sheet, BuiltInParameter.MATERIAL_ID_PARAM, out materialId); double scale = exporterIFC.LinearScale; string guid = GUIDUtil.CreateGUID(sheet); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(sheet, revitObjectType); string description = NamingUtil.GetDescriptionOverride(sheet, null); string objectType = NamingUtil.GetObjectTypeOverride(sheet, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.CreateIFCElementId(sheet); string steelGrade = NamingUtil.GetOverrideStringValue(sheet, "SteelGrade", null); double? meshLength = sheet.CutOverallLength; double? meshWidth = sheet.CutOverallWidth; Element fabricSheetTypeElem = doc.GetElement(sheet.GetTypeId()); FabricSheetType fabricSheetType = (fabricSheetTypeElem == null) ? null : (fabricSheetTypeElem as FabricSheetType); double longitudinalBarNominalDiameter = 0.0; double transverseBarNominalDiameter = 0.0; double longitudinalBarCrossSectionArea = 0.0; double transverseBarCrossSectionArea = 0.0; double longitudinalBarSpacing = 0.0; double transverseBarSpacing = 0.0; if (fabricSheetType != null) { Element majorFabricWireTypeElem = doc.GetElement(fabricSheetType.MajorDirectionWireType); FabricWireType majorFabricWireType = (majorFabricWireTypeElem == null) ? null : (majorFabricWireTypeElem as FabricWireType); if (majorFabricWireType != null) { longitudinalBarNominalDiameter = majorFabricWireType.WireDiameter * scale; double localRadius = longitudinalBarNominalDiameter / 2.0; longitudinalBarCrossSectionArea = localRadius * localRadius * Math.PI; } Element minorFabricWireTypeElem = doc.GetElement(fabricSheetType.MinorDirectionWireType); FabricWireType minorFabricWireType = (minorFabricWireTypeElem == null) ? null : (minorFabricWireTypeElem as FabricWireType); if (minorFabricWireType != null) { transverseBarNominalDiameter = minorFabricWireType.WireDiameter * scale; double localRadius = transverseBarNominalDiameter / 2.0; transverseBarCrossSectionArea = localRadius * localRadius * Math.PI; } longitudinalBarSpacing = fabricSheetType.MajorSpacing * scale; transverseBarSpacing = fabricSheetType.MinorSpacing * scale; } IList<IFCAnyHandle> bodyItems = new List<IFCAnyHandle>(); IList<Curve> wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Major); foreach (Curve wireCenterline in wireCenterlines) { IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, longitudinalBarNominalDiameter); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) bodyItems.Add(bodyItem); } wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Minor); foreach (Curve wireCenterline in wireCenterlines) { IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, transverseBarNominalDiameter); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) bodyItems.Add(bodyItem); } IFCAnyHandle shapeRep = (bodyItems.Count > 0) ? RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, sheet, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null) : null; IList<IFCAnyHandle> shapeReps = null; if (shapeRep != null) { shapeReps = new List<IFCAnyHandle>(); shapeReps.Add(shapeRep); } IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null; IFCAnyHandle fabricSheet = IFCInstanceExporter.CreateReinforcingMesh(file, guid, ownerHistory, name, description, objectType, localPlacement, prodRep, elementTag, steelGrade, meshLength, meshWidth, longitudinalBarNominalDiameter, transverseBarNominalDiameter, longitudinalBarCrossSectionArea, transverseBarCrossSectionArea, longitudinalBarSpacing, transverseBarSpacing); ElementId fabricAreaId = sheet.FabricAreaOwnerId; if (fabricAreaId != ElementId.InvalidElementId) { HashSet<IFCAnyHandle> fabricSheets = null; if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out fabricSheets)) { fabricSheets = new HashSet<IFCAnyHandle>(); ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets; } fabricSheets.Add(fabricSheet); } productWrapper.AddElement(sheet, fabricSheet, placementSetter.GetLevelInfo(), ecData, true); CategoryUtil.CreateMaterialAssociation(exporterIFC, fabricSheet, materialId); } } tr.Commit(); return true; } }
/// <summary> /// Exports Walls. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="wallElement"> /// The wall element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Wall wallElement, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { //stacked wall is not supported yet. if (wallElement.WallType.Kind == WallKind.Stacked) return; bool exportAsCurtainWall = wallElement.CurtainGrid != null; bool isOldCurtainWall = IsLegacyCurtainWall(wallElement); ; if (exportAsCurtainWall) { if (!isOldCurtainWall) CurtainSystemExporter.ExportWall(exporterIFC, wallElement, productWrapper); else CurtainSystemExporter.ExportLegacyCurtainElement(exporterIFC, wallElement, productWrapper); } else ExportWall(exporterIFC, wallElement, geometryElement, productWrapper); // create join information. ElementId id = wallElement.Id; IList<IList<IFCConnectedWallData>> connectedWalls = new List<IList<IFCConnectedWallData>>(); connectedWalls.Add(ExporterIFCUtils.GetConnectedWalls(wallElement, IFCConnectedWallDataLocation.Start)); connectedWalls.Add(ExporterIFCUtils.GetConnectedWalls(wallElement, IFCConnectedWallDataLocation.End)); for (int ii = 0; ii < 2; ii++) { int count = connectedWalls[ii].Count; IFCConnectedWallDataLocation currConnection = (ii == 0) ? IFCConnectedWallDataLocation.Start : IFCConnectedWallDataLocation.End; for (int jj = 0; jj < count; jj++) { ElementId otherId = connectedWalls[ii][jj].ElementId; IFCConnectedWallDataLocation joinedEnd = connectedWalls[ii][jj].Location; if ((otherId == id) && (joinedEnd == currConnection)) //self-reference continue; ExporterCacheManager.WallConnectionDataCache.Add(new WallConnectionData(id, otherId, GetIFCConnectionTypeFromLocation(currConnection), GetIFCConnectionTypeFromLocation(joinedEnd), null)); } } // look for connected columns. Note that this is only for columns that interrupt the wall path. IList<FamilyInstance> attachedColumns = ExporterIFCUtils.GetAttachedColumns(wallElement); int numAttachedColumns = attachedColumns.Count; for (int ii = 0; ii < numAttachedColumns; ii++) { ElementId otherId = attachedColumns[ii].Id; IFCConnectionType connect1 = IFCConnectionType.NotDefined; // can't determine at the moment. IFCConnectionType connect2 = IFCConnectionType.NotDefined; // meaningless for column ExporterCacheManager.WallConnectionDataCache.Add(new WallConnectionData(id, otherId, connect1, connect2, null)); } tr.Commit(); } }
/// <summary> /// Completes the export process by writing information stored incrementally during export to the file. /// </summary> /// <param name="exporterIFC">The IFC exporter object.</param> /// <param name="document">The document to export.</param> private void EndExport(ExporterIFC exporterIFC, Document document) { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); using (IFCTransaction transaction = new IFCTransaction(file)) { // In some cases, like multi-story stairs and ramps, we may have the same Pset used for multiple levels. // If ifcParams is null, re-use the property set. ISet<string> locallyUsedGUIDs = new HashSet<string>(); // Relate Ducts and Pipes to their coverings (insulations and linings) foreach (ElementId ductOrPipeId in ExporterCacheManager.MEPCache.CoveredElementsCache) { IFCAnyHandle ductOrPipeHandle = ExporterCacheManager.MEPCache.Find(ductOrPipeId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(ductOrPipeHandle)) continue; HashSet<IFCAnyHandle> coveringHandles = new HashSet<IFCAnyHandle>(); try { ICollection<ElementId> liningIds = InsulationLiningBase.GetLiningIds(document, ductOrPipeId); GetElementHandles(liningIds, coveringHandles); } catch { } try { ICollection<ElementId> insulationIds = InsulationLiningBase.GetInsulationIds(document, ductOrPipeId); GetElementHandles(insulationIds, coveringHandles); } catch { } if (coveringHandles.Count > 0) IFCInstanceExporter.CreateRelCoversBldgElements(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, ductOrPipeHandle, coveringHandles); } // Relate stair components to stairs foreach (KeyValuePair<ElementId, StairRampContainerInfo> stairRamp in ExporterCacheManager.StairRampContainerInfoCache) { StairRampContainerInfo stairRampInfo = stairRamp.Value; IList<IFCAnyHandle> hnds = stairRampInfo.StairOrRampHandles; for (int ii = 0; ii < hnds.Count; ii++) { IFCAnyHandle hnd = hnds[ii]; if (IFCAnyHandleUtil.IsNullOrHasNoValue(hnd)) continue; IList<IFCAnyHandle> comps = stairRampInfo.Components[ii]; if (comps.Count == 0) continue; Element elem = document.GetElement(stairRamp.Key); string guid = GUIDUtil.CreateSubElementGUID(elem, (int)IFCStairSubElements.ContainmentRelation); if (locallyUsedGUIDs.Contains(guid)) guid = GUIDUtil.CreateGUID(); else locallyUsedGUIDs.Add(guid); ExporterUtil.RelateObjects(exporterIFC, guid, hnd, comps); } } ProjectInfo projectInfo = document.ProjectInformation; IFCAnyHandle buildingHnd = ExporterCacheManager.BuildingHandle; // relate assembly elements to assemblies foreach (KeyValuePair<ElementId, AssemblyInstanceInfo> assemblyInfoEntry in ExporterCacheManager.AssemblyInstanceCache) { AssemblyInstanceInfo assemblyInfo = assemblyInfoEntry.Value; if (assemblyInfo == null) continue; IFCAnyHandle assemblyInstanceHandle = assemblyInfo.AssemblyInstanceHandle; HashSet<IFCAnyHandle> elementHandles = assemblyInfo.ElementHandles; if (elementHandles != null && assemblyInstanceHandle != null && elementHandles.Contains(assemblyInstanceHandle)) elementHandles.Remove(assemblyInstanceHandle); if (assemblyInstanceHandle != null && elementHandles != null && elementHandles.Count != 0) { Element assemblyInstance = document.GetElement(assemblyInfoEntry.Key); string guid = GUIDUtil.CreateSubElementGUID(assemblyInstance, (int)IFCAssemblyInstanceSubElements.RelContainedInSpatialStructure); if (IFCAnyHandleUtil.IsSubTypeOf(assemblyInstanceHandle, IFCEntityType.IfcSystem)) { IFCInstanceExporter.CreateRelAssignsToGroup(file, guid, ownerHistory, null, null, elementHandles, null, assemblyInstanceHandle); } else { ExporterUtil.RelateObjects(exporterIFC, guid, assemblyInstanceHandle, elementHandles); // Set the PlacementRelTo of assembly elements to assembly instance. IFCAnyHandle assemblyPlacement = IFCAnyHandleUtil.GetObjectPlacement(assemblyInstanceHandle); AssemblyInstanceExporter.SetLocalPlacementsRelativeToAssembly(exporterIFC, assemblyPlacement, elementHandles); } // We don't do this in RegisterAssemblyElement because we want to make sure that the IfcElementAssembly has been created. ExporterCacheManager.ElementsInAssembliesCache.UnionWith(elementHandles); } } // relate group elements to groups foreach (KeyValuePair<ElementId, GroupInfo> groupEntry in ExporterCacheManager.GroupCache) { GroupInfo groupInfo = groupEntry.Value; if (groupInfo == null) continue; if (groupInfo.GroupHandle != null && groupInfo.ElementHandles != null && groupInfo.ElementHandles.Count != 0) { Element group = document.GetElement(groupEntry.Key); string guid = GUIDUtil.CreateSubElementGUID(group, (int)IFCGroupSubElements.RelAssignsToGroup); IFCAnyHandle groupHandle = groupInfo.GroupHandle; HashSet<IFCAnyHandle> elementHandles = groupInfo.ElementHandles; if (elementHandles != null && groupHandle != null && elementHandles.Contains(groupHandle)) elementHandles.Remove(groupHandle); if (elementHandles != null && groupHandle != null && elementHandles.Count > 0) { IFCInstanceExporter.CreateRelAssignsToGroup(file, guid, ownerHistory, null, null, elementHandles, null, groupHandle); } } } // create spatial structure holder ICollection<IFCAnyHandle> relatedElements = exporterIFC.GetRelatedElements(); if (relatedElements.Count > 0) { HashSet<IFCAnyHandle> relatedElementSet = new HashSet<IFCAnyHandle>(relatedElements); string guid = GUIDUtil.CreateSubElementGUID(projectInfo, (int)IFCBuildingSubElements.RelContainedInSpatialStructure); IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, guid, ownerHistory, null, null, relatedElementSet, buildingHnd); } ICollection<IFCAnyHandle> relatedProducts = exporterIFC.GetRelatedProducts(); if (relatedProducts.Count > 0) { string guid = GUIDUtil.CreateSubElementGUID(projectInfo, (int)IFCBuildingSubElements.RelAggregatesProducts); ExporterCacheManager.ContainmentCache.SetGUIDForRelation(buildingHnd, guid); ExporterCacheManager.ContainmentCache.AddRelations(buildingHnd, relatedProducts); } // create a default site if we have latitude and longitude information. if (IFCAnyHandleUtil.IsNullOrHasNoValue(exporterIFC.GetSite())) { using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { SiteExporter.ExportDefaultSite(exporterIFC, document, productWrapper); } } IFCAnyHandle siteHandle = exporterIFC.GetSite(); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { ExporterCacheManager.ContainmentCache.AddRelation(exporterIFC.GetProject(), siteHandle); // assoc. site to the building. ExporterCacheManager.ContainmentCache.AddRelation(siteHandle, buildingHnd); ExporterUtil.UpdateBuildingRelToPlacement(buildingHnd, siteHandle); } else { // relate building and project if no site ExporterCacheManager.ContainmentCache.AddRelation(exporterIFC.GetProject(), buildingHnd); } // relate levels and products. RelateLevels(exporterIFC, document); // relate objects in containment cache. foreach (KeyValuePair<IFCAnyHandle, ICollection<IFCAnyHandle>> container in ExporterCacheManager.ContainmentCache) { if (container.Value.Count() > 0) { string relationGUID = ExporterCacheManager.ContainmentCache.GetGUIDForRelation(container.Key); ExporterUtil.RelateObjects(exporterIFC, relationGUID, container.Key, container.Value); } } // These elements are created internally, but we allow custom property sets for them. Create them here. using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { productWrapper.AddBuilding(projectInfo, buildingHnd); if (projectInfo != null) ExporterUtil.ExportRelatedProperties(exporterIFC, projectInfo, productWrapper); } // create material layer associations foreach (IFCAnyHandle materialSetLayerUsageHnd in ExporterCacheManager.MaterialLayerRelationsCache.Keys) { IFCInstanceExporter.CreateRelAssociatesMaterial(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, ExporterCacheManager.MaterialLayerRelationsCache[materialSetLayerUsageHnd], materialSetLayerUsageHnd); } // create material associations foreach (IFCAnyHandle materialHnd in ExporterCacheManager.MaterialRelationsCache.Keys) { IFCInstanceExporter.CreateRelAssociatesMaterial(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, ExporterCacheManager.MaterialRelationsCache[materialHnd], materialHnd); } // create type relations foreach (IFCAnyHandle typeObj in ExporterCacheManager.TypeRelationsCache.Keys) { IFCInstanceExporter.CreateRelDefinesByType(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, ExporterCacheManager.TypeRelationsCache[typeObj], typeObj); } // create type property relations foreach (TypePropertyInfo typePropertyInfo in ExporterCacheManager.TypePropertyInfoCache.Values) { if (typePropertyInfo.AssignedToType) continue; ICollection<IFCAnyHandle> propertySets = typePropertyInfo.PropertySets; ISet<IFCAnyHandle> elements = typePropertyInfo.Elements; if (elements.Count == 0) continue; foreach (IFCAnyHandle propertySet in propertySets) { try { IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, elements, propertySet); } catch { } } } // create space boundaries foreach (SpaceBoundary boundary in ExporterCacheManager.SpaceBoundaryCache) { SpatialElementExporter.ProcessIFCSpaceBoundary(exporterIFC, boundary, file); } // create wall/wall connectivity objects if (ExporterCacheManager.WallConnectionDataCache.Count > 0) { IList<IDictionary<ElementId, IFCAnyHandle>> hostObjects = exporterIFC.GetHostObjects(); List<int> relatingPriorities = new List<int>(); List<int> relatedPriorities = new List<int>(); foreach (WallConnectionData wallConnectionData in ExporterCacheManager.WallConnectionDataCache) { foreach (IDictionary<ElementId, IFCAnyHandle> mapForLevel in hostObjects) { IFCAnyHandle wallElementHandle, otherElementHandle; if (!mapForLevel.TryGetValue(wallConnectionData.FirstId, out wallElementHandle)) continue; if (!mapForLevel.TryGetValue(wallConnectionData.SecondId, out otherElementHandle)) continue; // NOTE: Definition of RelConnectsPathElements has the connection information reversed // with respect to the order of the paths. string connectionName = IFCAnyHandleUtil.GetStringAttribute(wallElementHandle, "GlobalId") + "|" + IFCAnyHandleUtil.GetStringAttribute(otherElementHandle, "GlobalId"); string connectionType = "Structural"; // Assigned as Description IFCInstanceExporter.CreateRelConnectsPathElements(file, GUIDUtil.CreateGUID(), ownerHistory, connectionName, connectionType, wallConnectionData.ConnectionGeometry, wallElementHandle, otherElementHandle, relatingPriorities, relatedPriorities, wallConnectionData.SecondConnectionType, wallConnectionData.FirstConnectionType); } } } // create Zones { string relAssignsToGroupName = "Spatial Zone Assignment"; foreach (string zoneName in ExporterCacheManager.ZoneInfoCache.Keys) { ZoneInfo zoneInfo = ExporterCacheManager.ZoneInfoCache.Find(zoneName); if (zoneInfo != null) { IFCAnyHandle zoneHandle = IFCInstanceExporter.CreateZone(file, GUIDUtil.CreateGUID(), ownerHistory, zoneName, zoneInfo.Description, zoneInfo.ObjectType); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, relAssignsToGroupName, null, zoneInfo.RoomHandles, null, zoneHandle); HashSet<IFCAnyHandle> zoneHnds = new HashSet<IFCAnyHandle>(); zoneHnds.Add(zoneHandle); foreach (KeyValuePair<string, IFCAnyHandle> classificationReference in zoneInfo.ClassificationReferences) { IFCAnyHandle relAssociates = IFCInstanceExporter.CreateRelAssociatesClassification(file, GUIDUtil.CreateGUID(), ownerHistory, classificationReference.Key, "", zoneHnds, classificationReference.Value); } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(zoneInfo.EnergyAnalysisProperySetHandle)) { IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, zoneHnds, zoneInfo.EnergyAnalysisProperySetHandle); } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(zoneInfo.ZoneCommonProperySetHandle)) { IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, zoneHnds, zoneInfo.ZoneCommonProperySetHandle); } } } } // create Space Occupants { foreach (string spaceOccupantName in ExporterCacheManager.SpaceOccupantInfoCache.Keys) { SpaceOccupantInfo spaceOccupantInfo = ExporterCacheManager.SpaceOccupantInfoCache.Find(spaceOccupantName); if (spaceOccupantInfo != null) { IFCAnyHandle person = IFCInstanceExporter.CreatePerson(file, null, spaceOccupantName, null, null, null, null, null, null); IFCAnyHandle spaceOccupantHandle = IFCInstanceExporter.CreateOccupant(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, spaceOccupantName, person, IFCOccupantType.NotDefined); IFCInstanceExporter.CreateRelOccupiesSpaces(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, spaceOccupantInfo.RoomHandles, null, spaceOccupantHandle, null); HashSet<IFCAnyHandle> spaceOccupantHandles = new HashSet<IFCAnyHandle>(); spaceOccupantHandles.Add(spaceOccupantHandle); foreach (KeyValuePair<string, IFCAnyHandle> classificationReference in spaceOccupantInfo.ClassificationReferences) { IFCAnyHandle relAssociates = IFCInstanceExporter.CreateRelAssociatesClassification(file, GUIDUtil.CreateGUID(), ownerHistory, classificationReference.Key, "", spaceOccupantHandles, classificationReference.Value); } if (spaceOccupantInfo.SpaceOccupantProperySetHandle != null && spaceOccupantInfo.SpaceOccupantProperySetHandle.HasValue) { IFCAnyHandle relHnd = IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, spaceOccupantHandles, spaceOccupantInfo.SpaceOccupantProperySetHandle); } } } } // Create systems. HashSet<IFCAnyHandle> relatedBuildings = new HashSet<IFCAnyHandle>(); relatedBuildings.Add(buildingHnd); using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { foreach (KeyValuePair<ElementId, ISet<IFCAnyHandle>> system in ExporterCacheManager.SystemsCache.BuiltInSystemsCache) { MEPSystem systemElem = document.GetElement(system.Key) as MEPSystem; if (systemElem == null) continue; Element baseEquipment = systemElem.BaseEquipment; if (baseEquipment != null) { IFCAnyHandle memberHandle = ExporterCacheManager.MEPCache.Find(baseEquipment.Id); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(memberHandle)) system.Value.Add(memberHandle); } ElementType systemElemType = document.GetElement(systemElem.GetTypeId()) as ElementType; string name = NamingUtil.GetNameOverride(systemElem, systemElem.Name); string desc = NamingUtil.GetDescriptionOverride(systemElem, null); string objectType = NamingUtil.GetObjectTypeOverride(systemElem, (systemElemType != null) ? systemElemType.Name : ""); string systemGUID = GUIDUtil.CreateGUID(systemElem); IFCAnyHandle systemHandle = IFCInstanceExporter.CreateSystem(file, systemGUID, ownerHistory, name, desc, objectType); // Create classification reference when System has classification filed name assigned to it ClassificationUtil.CreateClassification(exporterIFC, file, systemElem, systemHandle); productWrapper.AddSystem(systemElem, systemHandle); IFCAnyHandle relServicesBuildings = IFCInstanceExporter.CreateRelServicesBuildings(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, systemHandle, relatedBuildings); IFCObjectType? objType = null; if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2) objType = IFCObjectType.Product; IFCAnyHandle relAssignsToGroup = IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, system.Value, objType, systemHandle); } } using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { foreach (KeyValuePair<ElementId, ISet<IFCAnyHandle>> entries in ExporterCacheManager.SystemsCache.ElectricalSystemsCache) { ElementId systemId = entries.Key; MEPSystem systemElem = document.GetElement(systemId) as MEPSystem; if (systemElem == null) continue; Element baseEquipment = systemElem.BaseEquipment; if (baseEquipment != null) { IFCAnyHandle memberHandle = ExporterCacheManager.MEPCache.Find(baseEquipment.Id); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(memberHandle)) entries.Value.Add(memberHandle); } // The Elements property below can throw an InvalidOperationException in some cases, which could // crash the export. Protect against this without having too generic a try/catch block. try { ElementSet members = systemElem.Elements; foreach (Element member in members) { IFCAnyHandle memberHandle = ExporterCacheManager.MEPCache.Find(member.Id); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(memberHandle)) entries.Value.Add(memberHandle); } } catch { } if (entries.Value.Count == 0) continue; ElementType systemElemType = document.GetElement(systemElem.GetTypeId()) as ElementType; string name = NamingUtil.GetNameOverride(systemElem, systemElem.Name); string desc = NamingUtil.GetDescriptionOverride(systemElem, null); string objectType = NamingUtil.GetObjectTypeOverride(systemElem, (systemElemType != null) ? systemElemType.Name : ""); string systemGUID = GUIDUtil.CreateGUID(systemElem); IFCAnyHandle systemHandle = IFCInstanceExporter.CreateSystem(file, systemGUID, ownerHistory, name, desc, objectType); // Create classification reference when System has classification filed name assigned to it ClassificationUtil.CreateClassification(exporterIFC, file, systemElem, systemHandle); productWrapper.AddSystem(systemElem, systemHandle); IFCAnyHandle relServicesBuildings = IFCInstanceExporter.CreateRelServicesBuildings(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, systemHandle, relatedBuildings); IFCObjectType? objType = null; if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2) objType = IFCObjectType.Product; IFCAnyHandle relAssignsToGroup = IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, entries.Value, objType, systemHandle); } } // Add presentation layer assignments - this is in addition to those added in EndExportInternal, and will // eventually replace the internal routine. foreach (KeyValuePair<string, ICollection<IFCAnyHandle>> presentationLayerSet in ExporterCacheManager.PresentationLayerSetCache) { ISet<IFCAnyHandle> validHandles = new HashSet<IFCAnyHandle>(); foreach (IFCAnyHandle handle in presentationLayerSet.Value) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(handle)) validHandles.Add(handle); } if (validHandles.Count > 0) IFCInstanceExporter.CreatePresentationLayerAssignment(file, presentationLayerSet.Key, null, validHandles, null); } // Add door/window openings. ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.ExecuteCreators(exporterIFC, document); foreach (SpaceInfo spaceInfo in ExporterCacheManager.SpaceInfoCache.SpaceInfos.Values) { if (spaceInfo.RelatedElements.Count > 0) { IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, spaceInfo.RelatedElements, spaceInfo.SpaceHandle); } } // Potentially modify elements with GUID values. if (ExporterCacheManager.GUIDsToStoreCache.Count > 0 && !ExporterCacheManager.ExportOptionsCache.ExportingLink) { using (SubTransaction st = new SubTransaction(document)) { st.Start(); foreach (KeyValuePair<KeyValuePair<Element, BuiltInParameter>, string> elementAndGUID in ExporterCacheManager.GUIDsToStoreCache) { if (elementAndGUID.Key.Key == null || elementAndGUID.Key.Value == BuiltInParameter.INVALID || elementAndGUID.Value == null) continue; ParameterUtil.SetStringParameter(elementAndGUID.Key.Key, elementAndGUID.Key.Value, elementAndGUID.Value); } st.Commit(); } } // Allow native code to remove some unused handles, assign presentation map information and clear internal caches. ExporterIFCUtils.EndExportInternal(exporterIFC); //create header ExportOptionsCache exportOptionsCache = ExporterCacheManager.ExportOptionsCache; string coordinationView = null; if (exportOptionsCache.ExportAsCoordinationView2) coordinationView = "CoordinationView_V2.0"; else coordinationView = "CoordinationView"; List<string> descriptions = new List<string>(); if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || ExporterUtil.DoCodeChecking(exportOptionsCache)) { descriptions.Add("IFC2X_PLATFORM"); } else { string currentLine; if (ExporterUtil.IsFMHandoverView()) { currentLine = string.Format("ViewDefinition [{0}{1}{2}{3}]", coordinationView, exportOptionsCache.ExportBaseQuantities ? ", QuantityTakeOffAddOnView" : "", ", ", "FMHandOverView"); } else { currentLine = string.Format("ViewDefinition [{0}{1}]", coordinationView, exportOptionsCache.ExportBaseQuantities ? ", QuantityTakeOffAddOnView" : ""); } descriptions.Add(currentLine); } string projectNumber = (projectInfo != null) ? projectInfo.Number : null; string projectName = (projectInfo != null) ? projectInfo.Name : null; string projectStatus = (projectInfo != null) ? projectInfo.Status : null; if (projectNumber == null) projectNumber = string.Empty; if (projectName == null) projectName = exportOptionsCache.FileName; if (projectStatus == null) projectStatus = string.Empty; IFCAnyHandle project = exporterIFC.GetProject(); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(project)) IFCAnyHandleUtil.UpdateProject(project, projectNumber, projectName, projectStatus); IFCInstanceExporter.CreateFileSchema(file); IFCInstanceExporter.CreateFileDescription(file, descriptions); // Get stored File Header information from the UI and use it for export IFCFileHeader fHeader = new IFCFileHeader(); IFCFileHeaderItem fHItem = null; fHeader.GetSavedFileHeader(document, out fHItem); List<string> author = new List<string>(); if (String.IsNullOrEmpty(fHItem.AuthorName) == false) { author.Add(fHItem.AuthorName); if (String.IsNullOrEmpty(fHItem.AuthorEmail) == false) author.Add(fHItem.AuthorEmail); } else author.Add(String.Empty); List<string> organization = new List<string>(); if (String.IsNullOrEmpty(fHItem.Organization) == false) organization.Add(fHItem.Organization); else organization.Add(String.Empty); string versionInfos = document.Application.VersionBuild + " - " + ExporterCacheManager.ExportOptionsCache.ExporterVersion + " - " + ExporterCacheManager.ExportOptionsCache.ExporterUIVersion; if (fHItem.Authorization == null) fHItem.Authorization = String.Empty; IFCInstanceExporter.CreateFileName(file, projectNumber, author, organization, document.Application.VersionName, versionInfos, fHItem.Authorization); transaction.Commit(); IFCFileWriteOptions writeOptions = new IFCFileWriteOptions(); writeOptions.FileName = exportOptionsCache.FileName; writeOptions.FileFormat = exportOptionsCache.IFCFileFormat; if (writeOptions.FileFormat == IFCFileFormat.IfcXML || writeOptions.FileFormat == IFCFileFormat.IfcXMLZIP) { writeOptions.XMLConfigFileName = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\ifcXMLconfiguration.xml"); } file.Write(writeOptions); // Reuse almost all of the information above to write out extra copies of the IFC file. if (exportOptionsCache.ExportingLink) { int numRevitLinkInstances = exportOptionsCache.GetNumLinkInstanceInfos(); for (int ii = 1; ii < numRevitLinkInstances; ii++) { Transform linkTrf = ExporterCacheManager.ExportOptionsCache.GetLinkInstanceTransform(ii); IFCAnyHandle relativePlacement = ExporterUtil.CreateAxis2Placement3D(file, linkTrf.Origin, linkTrf.BasisZ, linkTrf.BasisX); ExporterUtil.UpdateBuildingRelativePlacement(buildingHnd, relativePlacement); writeOptions.FileName = exportOptionsCache.GetLinkInstanceFileName(ii); file.Write(writeOptions); } } } }
/// <summary> /// Initializes the common properties at the beginning of the export process. /// </summary> /// <param name="exporterIFC">The IFC exporter object.</param> /// <param name="document">The document to export.</param> private void BeginExport(ExporterIFC exporterIFC, Document document, Autodesk.Revit.DB.View filterView) { // cache options ExportOptionsCache exportOptionsCache = ExportOptionsCache.Create(exporterIFC, document, filterView); ExporterCacheManager.ExportOptionsCache = exportOptionsCache; // Set language. Application app = document.Application; string pathName = document.PathName; LanguageType langType = LanguageType.Unknown; if (!String.IsNullOrEmpty(pathName)) { try { BasicFileInfo basicFileInfo = BasicFileInfo.Extract(pathName); if (basicFileInfo != null) langType = basicFileInfo.LanguageWhenSaved; } catch { } } if (langType == LanguageType.Unknown) langType = app.Language; ExporterCacheManager.LanguageType = langType; ElementFilteringUtil.InitCategoryVisibilityCache(); ExporterCacheManager.Document = document; String writeIFCExportedElementsVar = Environment.GetEnvironmentVariable("WriteIFCExportedElements"); if (writeIFCExportedElementsVar != null && writeIFCExportedElementsVar.Length > 0) { m_Writer = new StreamWriter(@"c:\ifc-output-filters.txt"); } IFCFileModelOptions modelOptions = CreateIFCFileModelOptions(exporterIFC); m_IfcFile = IFCFile.Create(modelOptions); exporterIFC.SetFile(m_IfcFile); //init common properties InitializePropertySets(ExporterCacheManager.ExportOptionsCache.FileVersion); InitializeQuantities(ExporterCacheManager.ExportOptionsCache.FileVersion); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { // create building IFCAnyHandle applicationHandle = CreateApplicationInformation(file, document); CreateGlobalCartesianOrigin(exporterIFC); CreateGlobalDirection(exporterIFC); CreateGlobalDirection2D(exporterIFC); // Set relative transform depending on whether it is a linked transform or not. IFCAnyHandle relativePlacement = null; if (ExporterCacheManager.ExportOptionsCache.ExportingLink) { Transform linkTrf = ExporterCacheManager.ExportOptionsCache.GetLinkInstanceTransform(0); relativePlacement = ExporterUtil.CreateAxis2Placement3D(file, linkTrf.Origin, linkTrf.BasisZ, linkTrf.BasisX); } else relativePlacement = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle buildingPlacement = IFCInstanceExporter.CreateLocalPlacement(file, null, relativePlacement); CreateProject(exporterIFC, document, applicationHandle); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ProjectInfo projectInfo = document.ProjectInformation; string buildingName = String.Empty; string buildingDescription = null; string buildingLongName = null; if (projectInfo != null) { try { buildingName = projectInfo.BuildingName; } catch (Autodesk.Revit.Exceptions.InvalidOperationException) { } buildingDescription = NamingUtil.GetOverrideStringValue(projectInfo, "BuildingDescription", null); buildingLongName = NamingUtil.GetOverrideStringValue(projectInfo, "BuildingLongName", buildingName); } IFCAnyHandle buildingAddress = CreateIFCAddress(file, document, projectInfo); string buildingGUID = GUIDUtil.CreateProjectLevelGUID(document, IFCProjectLevelGUIDType.Building); IFCAnyHandle buildingHandle = IFCInstanceExporter.CreateBuilding(file, buildingGUID, ownerHistory, buildingName, buildingDescription, null, buildingPlacement, null, buildingLongName, Toolkit.IFCElementComposition.Element, null, null, buildingAddress); ExporterCacheManager.BuildingHandle = buildingHandle; // create levels List<Level> levels = LevelUtil.FindAllLevels(document); bool exportAllLevels = true; for (int ii = 0; ii < levels.Count && exportAllLevels; ii++) { Level level = levels[ii]; Parameter isBuildingStorey = level.get_Parameter(BuiltInParameter.LEVEL_IS_BUILDING_STORY); if (isBuildingStorey == null || (isBuildingStorey.AsInteger() != 0)) { exportAllLevels = false; break; } } IList<Element> unassignedBaseLevels = new List<Element>(); ExporterCacheManager.ExportOptionsCache.ExportAllLevels = exportAllLevels; double lengthScale = UnitUtil.ScaleLengthForRevitAPI(); IFCAnyHandle prevBuildingStorey = null; IFCAnyHandle prevPlacement = null; double prevHeight = 0.0; double prevElev = 0.0; for (int ii = 0; ii < levels.Count; ii++) { Level level = levels[ii]; if (level == null) continue; IFCLevelInfo levelInfo = null; if (!LevelUtil.IsBuildingStory(level)) { if (prevBuildingStorey == null) unassignedBaseLevels.Add(level); else { levelInfo = IFCLevelInfo.Create(prevBuildingStorey, prevPlacement, prevHeight, prevElev, lengthScale, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo, false); } continue; } // When exporting to IFC 2x3, we have a limited capability to export some Revit view-specific // elements, specifically Filled Regions and Text. However, we do not have the // capability to choose which views to export. As such, we will choose (up to) one DBView per // exported level. // TODO: Let user choose which view(s) to export. Ensure that the user know that only one view // per level is supported. View view = LevelUtil.FindViewByLevel(document, ViewType.FloorPlan, level); if (view != null) { ExporterCacheManager.DBViewsToExport[view.Id] = level.Id; } double elev = level.ProjectElevation; double height = 0.0; List<ElementId> coincidentLevels = new List<ElementId>(); for (int jj = ii + 1; jj < levels.Count; jj++) { Level nextLevel = levels[jj]; if (!LevelUtil.IsBuildingStory(nextLevel)) continue; double nextElev = nextLevel.ProjectElevation; if (!MathUtil.IsAlmostEqual(nextElev, elev)) { height = nextElev - elev; break; } else if (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) coincidentLevels.Add(nextLevel.Id); } double elevation = UnitUtil.ScaleLength(elev); XYZ orig = new XYZ(0.0, 0.0, elevation); IFCAnyHandle placement = ExporterUtil.CreateLocalPlacement(file, buildingPlacement, orig, null, null); string levelName = NamingUtil.GetNameOverride(level, level.Name); string objectType = NamingUtil.GetObjectTypeOverride(level, null); string description = NamingUtil.GetDescriptionOverride(level, null); string longName = level.Name; string levelGUID = GUIDUtil.GetLevelGUID(level); IFCAnyHandle buildingStorey = IFCInstanceExporter.CreateBuildingStorey(file, levelGUID, exporterIFC.GetOwnerHistoryHandle(), levelName, description, objectType, placement, null, longName, Toolkit.IFCElementComposition.Element, elevation); // Create classification reference when level has classification filed name assigned to it ClassificationUtil.CreateClassification(exporterIFC, file, level, buildingStorey); if (prevBuildingStorey == null) { foreach (Level baseLevel in unassignedBaseLevels) { levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, lengthScale, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, baseLevel.Id, levelInfo, false); } } prevBuildingStorey = buildingStorey; prevPlacement = placement; prevHeight = height; prevElev = elev; levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, lengthScale, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo, true); // if we have coincident levels, add buildingstoreys for them but use the old handle. for (int jj = 0; jj < coincidentLevels.Count; jj++) { level = levels[ii + jj + 1]; levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, lengthScale, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo, true); } ii += coincidentLevels.Count; // We will export element properties, quantities and classifications when we decide to keep the level - we may delete it later. } transaction.Commit(); } }
/// <summary> /// Exports a family instance to corresponding IFC object. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="familyInstance"> /// The family instance to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportFamilyInstanceElement(ExporterIFC exporterIFC, FamilyInstance familyInstance, GeometryElement geometryElement, ProductWrapper productWrapper) { // Don't export family if it is invisible, or has a null geometry. if (familyInstance.Invisible || geometryElement == null) return; // Don't export mullions and panels if they have a host and their host is not a mass // as they will be exported with the host (curtain wall/roof). if (familyInstance.Category.Id == new ElementId(BuiltInCategory.OST_CurtainWallMullions) || familyInstance.Category.Id == new ElementId(BuiltInCategory.OST_CurtainWallPanels)) { Element host = familyInstance.Host; if (host != null && host.Category.Id != new ElementId(BuiltInCategory.OST_Mass)) return; } FamilySymbol familySymbol = familyInstance.Symbol; Family family = familySymbol.Family; if (family == null) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, familyInstance, out ifcEnumType); if (exportType == IFCExportType.DontExport) return; if (ExportFamilyInstanceAsStandardElement(exporterIFC, familyInstance, geometryElement, exportType, ifcEnumType, productWrapper)) { tr.Commit(); return; } // If we are exporting a column, we may need to split it into parts by level. Create a list of ranges. IList<ElementId> levels = new List<ElementId>(); IList<IFCRange> ranges = new List<IFCRange>(); // We will not split walls and columns if the assemblyId is set, as we would like to keep the original wall // associated with the assembly, on the level of the assembly. bool splitColumn = (exportType == IFCExportType.ExportColumnType) && (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) && (familyInstance.AssemblyInstanceId == ElementId.InvalidElementId); if (splitColumn) { LevelUtil.CreateSplitLevelRangesForElement(exporterIFC, exportType, familyInstance, out levels, out ranges); } int numPartsToExport = ranges.Count; if (numPartsToExport == 0) { ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, ifcEnumType, productWrapper, ElementId.InvalidElementId, null, null); } else { for (int ii = 0; ii < numPartsToExport; ii++) { ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, ifcEnumType, productWrapper, levels[ii], ranges[ii], null); } if (ExporterCacheManager.DummyHostCache.HasRegistered(familyInstance.Id)) { List<KeyValuePair<ElementId, IFCRange>> levelRangeList = ExporterCacheManager.DummyHostCache.Find(familyInstance.Id); foreach (KeyValuePair<ElementId, IFCRange> levelRange in levelRangeList) { ExportFamilyInstanceAsMappedItem(exporterIFC, familyInstance, exportType, ifcEnumType, productWrapper, levelRange.Key, levelRange.Value, null); } } } tr.Commit(); } }
/// <summary> /// Exports an element as a covering of type insulation. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportDuctLining(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) { return(false); } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcCovering", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return(false); } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return(false); } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); IFCAnyHandle ductLining = IFCInstanceExporter.CreateCovering(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, "Wrapping"); ExporterCacheManager.ElementToHandleCache.Register(element.Id, ductLining); productWrapper.AddElement(element, ductLining, placementSetter.LevelInfo, ecData, true); ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, ductLining, matId); } } tr.Commit(); return(true); } }
/// <summary> /// Exports a MEP family instance. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacementToUse = setter.GetPlacement(); using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle productRepresentation = RepresentationUtil.CreateBRepProductDefinitionShape(element.Document.Application, exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation)) { extraParams.ClearOpenings(); return; } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false); bool found = currentTypeInfo.IsValid(); if (!found) { string typeGUID = ExporterIFCUtils.CreateGUID(type); string origTypeName = exporterIFC.GetName(); string typeName = NamingUtil.GetNameOverride(type, origTypeName); string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type); string applicableOccurance = NamingUtil.GetObjectTypeOverride(type, typeObjectType); string typeDescription = NamingUtil.GetDescriptionOverride(type, null); string typeElemId = NamingUtil.CreateIFCElementId(type); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>(); IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(file, exportType, ifcEnumType, typeGUID, ownerHistory, typeName, typeDescription, applicableOccurance, propertySetsOpt, repMapListOpt, typeElemId, typeName, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { currentTypeInfo.Style = styleHandle; ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo); } } string instanceGUID = ExporterIFCUtils.CreateGUID(element); string origInstanceName = exporterIFC.GetName(); string instanceName = NamingUtil.GetNameOverride(element, origInstanceName); string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, objectType); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceElemId = NamingUtil.CreateIFCElementId(element); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; if (FamilyExporterUtil.IsFurnishingElementSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFurnishingElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsDistributionFlowElementSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateDistributionFlowElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsEnergyConversionDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateEnergyConversionDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowFittingSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowFitting(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowMovingDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowMovingDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowSegmentSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowSegment(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowStorageDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowStorageDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowTerminalSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowTerminal(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowTreatmentDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowTreatmentDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowControllerSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowController(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { return; } if (roomId != ElementId.InvalidElementId) { exporterIFC.RelateSpatialElement(roomId, instanceHandle); productWrapper.AddElement(instanceHandle, setter, extraParams, false); } else { productWrapper.AddElement(instanceHandle, setter, extraParams, LevelUtil.AssociateElementToLevel(element)); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, exporterIFC, localPlacementToUse, setter, productWrapper); if (currentTypeInfo.IsValid()) { ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); ExporterCacheManager.MEPCache.Register(element, instanceHandle); tr.Commit(); } } } }
/// <summary> /// Exports a MEP family instance. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacementToUse = setter.GetPlacement(); using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle productRepresentation = RepresentationUtil.CreateBRepProductDefinitionShape(element.Document.Application, exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation)) { extraParams.ClearOpenings(); return; } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false); bool found = currentTypeInfo.IsValid(); if (!found) { string typeGUID = ExporterIFCUtils.CreateGUID(type); string origTypeName = exporterIFC.GetName(); string typeName = NamingUtil.GetNameOverride(type, origTypeName); string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type); string applicableOccurance = NamingUtil.GetObjectTypeOverride(type, typeObjectType); string typeDescription = NamingUtil.GetDescriptionOverride(type, null); string typeElemId = NamingUtil.CreateIFCElementId(type); HashSet<IFCAnyHandle> propertySetsOpt = new HashSet<IFCAnyHandle>(); IList<IFCAnyHandle> repMapListOpt = new List<IFCAnyHandle>(); IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(file, exportType, ifcEnumType, typeGUID, ownerHistory, typeName, typeDescription, applicableOccurance, propertySetsOpt, repMapListOpt, typeElemId, typeName, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { currentTypeInfo.Style = styleHandle; ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo); } } string instanceGUID = ExporterIFCUtils.CreateGUID(element); string origInstanceName = exporterIFC.GetName(); string instanceName = NamingUtil.GetNameOverride(element, origInstanceName); string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, objectType); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceElemId = NamingUtil.CreateIFCElementId(element); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; if (FamilyExporterUtil.IsFurnishingElementSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFurnishingElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsDistributionFlowElementSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateDistributionFlowElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsEnergyConversionDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateEnergyConversionDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowFittingSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowFitting(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowMovingDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowMovingDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowSegmentSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowSegment(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowStorageDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowStorageDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowTerminalSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowTerminal(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowTreatmentDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowTreatmentDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowControllerSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowController(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) return; if (roomId != ElementId.InvalidElementId) { exporterIFC.RelateSpatialElement(roomId, instanceHandle); productWrapper.AddElement(instanceHandle, setter, extraParams, false); } else { productWrapper.AddElement(instanceHandle, setter, extraParams, LevelUtil.AssociateElementToLevel(element)); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, exporterIFC, localPlacementToUse, setter, productWrapper); if (currentTypeInfo.IsValid()) ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); ExporterCacheManager.MEPCache.Register(element, instanceHandle); tr.Commit(); } } } }
/// <summary> /// Exports the element properties. /// </summary> /// <param name="exporterIFC">The IFC exporter object.</param> /// <param name="element">The element whose properties are exported.</param> /// <param name="productWrapper">The ProductWrapper object.</param> private static void ExportElementProperties(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { if (productWrapper.IsEmpty()) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { Document doc = element.Document; ElementType elemType = doc.GetElement(element.GetTypeId()) as ElementType; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ICollection<IFCAnyHandle> productSet = productWrapper.GetAllObjects(); IList<IList<PropertySetDescription>> psetsToCreate = ExporterCacheManager.ParameterCache.PropertySets; // In some cases, like multi-story stairs and ramps, we may have the same Pset used for multiple levels. // If ifcParams is null, re-use the property set. ISet<string> locallyUsedGUIDs = new HashSet<string>(); IDictionary<Tuple<Element, Element, string>, IFCAnyHandle> createdPropertySets = new Dictionary<Tuple<Element, Element, string>, IFCAnyHandle>(); IDictionary<IFCAnyHandle, HashSet<IFCAnyHandle>> relDefinesByPropertiesMap = new Dictionary<IFCAnyHandle, HashSet<IFCAnyHandle>>(); foreach (IFCAnyHandle prodHnd in productSet) { IList<PropertySetDescription> currPsetsToCreate = GetCurrPSetsToCreate(prodHnd, psetsToCreate); if (currPsetsToCreate.Count == 0) continue; ElementId overrideElementId = ExporterCacheManager.HandleToElementCache.Find(prodHnd); Element elementToUse = (overrideElementId == ElementId.InvalidElementId) ? element : doc.GetElement(overrideElementId); ElementType elemTypeToUse = (overrideElementId == ElementId.InvalidElementId) ? elemType : doc.GetElement(elementToUse.GetTypeId()) as ElementType; if (elemTypeToUse == null) elemTypeToUse = elemType; IFCExtrusionCreationData ifcParams = productWrapper.FindExtrusionCreationParameters(prodHnd); foreach (PropertySetDescription currDesc in currPsetsToCreate) { // Last conditional check: if the property set comes from a ViewSchedule, check if the element is in the schedule. if (currDesc.ViewScheduleId != ElementId.InvalidElementId) if (!ExporterCacheManager.ViewScheduleElementCache[currDesc.ViewScheduleId].Contains(elementToUse.Id)) continue; Tuple<Element, Element, string> propertySetKey = new Tuple<Element, Element, string>(elementToUse, elemTypeToUse, currDesc.Name); IFCAnyHandle propertySet = null; if ((ifcParams != null) || (!createdPropertySets.TryGetValue(propertySetKey, out propertySet))) { HashSet<IFCAnyHandle> props = currDesc.ProcessEntries(file, exporterIFC, ifcParams, elementToUse, elemTypeToUse); if (props.Count > 0) { int subElementIndex = CheckElementTypeValidityForSubIndex(currDesc, prodHnd, element); string guid = GUIDUtil.CreateSubElementGUID(elementToUse, subElementIndex); if (locallyUsedGUIDs.Contains(guid)) guid = GUIDUtil.CreateGUID(); else locallyUsedGUIDs.Add(guid); string paramSetName = currDesc.Name; propertySet = IFCInstanceExporter.CreatePropertySet(file, guid, ownerHistory, paramSetName, null, props); if (ifcParams == null) createdPropertySets[propertySetKey] = propertySet; } } if (propertySet != null) { IFCAnyHandle prodHndToUse = prodHnd; DescriptionCalculator ifcRDC = currDesc.DescriptionCalculator; if (ifcRDC != null) { IFCAnyHandle overrideHnd = ifcRDC.RedirectDescription(exporterIFC, elementToUse); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(overrideHnd)) prodHndToUse = overrideHnd; } HashSet<IFCAnyHandle> relatedObjects = null; if (!relDefinesByPropertiesMap.TryGetValue(propertySet, out relatedObjects)) { relatedObjects = new HashSet<IFCAnyHandle>(); relDefinesByPropertiesMap[propertySet] = relatedObjects; } relatedObjects.Add(prodHndToUse); } } } foreach (KeyValuePair<IFCAnyHandle, HashSet<IFCAnyHandle>> relDefinesByProperties in relDefinesByPropertiesMap) { IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relDefinesByProperties.Value, relDefinesByProperties.Key); } transaction.Commit(); } if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) ExportPsetDraughtingFor2x2(exporterIFC, element, productWrapper); }
/// <summary> /// Base implementation to export IFC site object. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="document">The Revit document. It may be null if element isn't.</param> /// <param name="element">The element. It may be null if document isn't.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> private static void ExportSiteBase(ExporterIFC exporterIFC, Document document, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { IFCAnyHandle siteHandle = ExporterCacheManager.SiteHandle; int numSiteElements = (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle) ? 1 : 0); if (element == null && (numSiteElements != 0)) { return; } Document doc = document; if (doc == null) { if (element != null) { doc = element.Document; } else { throw new ArgumentException("Both document and element are null."); } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle siteRepresentation = null; if (element != null) { // It would be possible that they actually represent several different sites with different buildings, // but until we have a concept of a building in Revit, we have to assume 0-1 sites, 1 building. bool appendedToSite = false; bool exportAsFacetation = !ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { IList <IFCAnyHandle> representations = IFCAnyHandleUtil.GetProductRepresentations(siteHandle); if (representations.Count > 0) { IFCAnyHandle bodyRep = representations[0]; IFCAnyHandle boundaryRep = null; if (representations.Count > 1) { boundaryRep = representations[1]; } siteRepresentation = RepresentationUtil.CreateSurfaceProductDefinitionShape(exporterIFC, element, geometryElement, true, exportAsFacetation, ref bodyRep, ref boundaryRep); if (representations.Count == 1 && !IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryRep)) { // If the first site has no boundaryRep, // we will add the boundaryRep from second site to it. representations.Clear(); representations.Add(boundaryRep); IFCAnyHandleUtil.AddProductRepresentations(siteHandle, representations); } appendedToSite = true; } } if (!appendedToSite) { siteRepresentation = RepresentationUtil.CreateSurfaceProductDefinitionShape(exporterIFC, element, geometryElement, true, exportAsFacetation); } } List <int> latitude = new List <int>(); List <int> longitude = new List <int>(); ProjectLocation projLocation = doc.ActiveProjectLocation; IFCAnyHandle relativePlacement = null; double unscaledElevation = 0.0; if (projLocation != null) { const double scaleToDegrees = 180 / Math.PI; double latitudeInDeg = projLocation.SiteLocation.Latitude * scaleToDegrees; double longitudeInDeg = projLocation.SiteLocation.Longitude * scaleToDegrees; ExporterUtil.GetSafeProjectPositionElevation(doc, out unscaledElevation); int latDeg = ((int)latitudeInDeg); latitudeInDeg -= latDeg; latitudeInDeg *= 60; int latMin = ((int)latitudeInDeg); latitudeInDeg -= latMin; latitudeInDeg *= 60; int latSec = ((int)latitudeInDeg); latitudeInDeg -= latSec; latitudeInDeg *= 1000000; int latFracSec = ((int)latitudeInDeg); latitude.Add(latDeg); latitude.Add(latMin); latitude.Add(latSec); if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { latitude.Add(latFracSec); } int longDeg = ((int)longitudeInDeg); longitudeInDeg -= longDeg; longitudeInDeg *= 60; int longMin = ((int)longitudeInDeg); longitudeInDeg -= longMin; longitudeInDeg *= 60; int longSec = ((int)longitudeInDeg); longitudeInDeg -= longSec; longitudeInDeg *= 1000000; int longFracSec = ((int)longitudeInDeg); longitude.Add(longDeg); longitude.Add(longMin); longitude.Add(longSec); if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { longitude.Add(longFracSec); } Transform siteSharedCoordinatesTrf = projLocation.GetTransform().Inverse; if (!siteSharedCoordinatesTrf.IsIdentity) { double unscaledSiteElevation = ExporterCacheManager.ExportOptionsCache.IncludeSiteElevation ? 0.0 : unscaledElevation; XYZ orig = UnitUtil.ScaleLength(siteSharedCoordinatesTrf.Origin - new XYZ(0, 0, unscaledSiteElevation)); relativePlacement = ExporterUtil.CreateAxis2Placement3D(file, orig, siteSharedCoordinatesTrf.BasisZ, siteSharedCoordinatesTrf.BasisX); } } // Get elevation for site. double elevation = UnitUtil.ScaleLength(unscaledElevation); if (IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement)) { relativePlacement = ExporterUtil.CreateAxis2Placement3D(file); } IFCAnyHandle localPlacement = IFCInstanceExporter.CreateLocalPlacement(file, null, relativePlacement); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string siteObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); ProjectInfo projectInfo = doc.ProjectInformation; Element mainSiteElement = (element != null) ? element : projectInfo; bool exportSite = false; string siteGUID = null; string siteName = null; string siteLongName = null; string siteLandTitleNumber = null; string siteDescription = null; if (element != null) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { exportSite = true; // We will use the Project Information site name as the primary name, if it exists. siteGUID = GUIDUtil.CreateSiteGUID(doc, element); siteName = NamingUtil.GetOverrideStringValue(projectInfo, "SiteName", NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element))); siteDescription = NamingUtil.GetDescriptionOverride(element, null); siteObjectType = NamingUtil.GetObjectTypeOverride(element, siteObjectType); // Look in site element for "IfcLongName" or project information for either "IfcLongName" or "SiteLongName". siteLongName = NamingUtil.GetLongNameOverride(projectInfo, NamingUtil.GetLongNameOverride(element, null)); if (string.IsNullOrWhiteSpace(siteLongName)) { siteLongName = NamingUtil.GetOverrideStringValue(projectInfo, "SiteLongName", null); } // Look in site element for "IfcLandTitleNumber" or project information for "SiteLandTitleNumber". siteLandTitleNumber = NamingUtil.GetOverrideStringValue(element, "IfcLandTitleNumber", null); if (string.IsNullOrWhiteSpace(siteLandTitleNumber)) { siteLandTitleNumber = NamingUtil.GetOverrideStringValue(projectInfo, "SiteLandTitleNumber", null); } } } else { exportSite = true; siteGUID = GUIDUtil.CreateProjectLevelGUID(doc, IFCProjectLevelGUIDType.Site); siteName = NamingUtil.GetOverrideStringValue(projectInfo, "SiteName", "Default"); siteLongName = NamingUtil.GetLongNameOverride(projectInfo, NamingUtil.GetOverrideStringValue(projectInfo, "SiteLongName", null)); siteLandTitleNumber = NamingUtil.GetOverrideStringValue(projectInfo, "SiteLandTitleNumber", null); // don't bother if we have nothing in the site whatsoever. if ((latitude.Count == 0 || longitude.Count == 0) && IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement) && string.IsNullOrWhiteSpace(siteLongName) && string.IsNullOrWhiteSpace(siteLandTitleNumber)) { return; } } if (exportSite) { siteHandle = IFCInstanceExporter.CreateSite(file, siteGUID, ownerHistory, siteName, siteDescription, siteObjectType, localPlacement, siteRepresentation, siteLongName, Toolkit.IFCElementComposition.Element, latitude, longitude, elevation, siteLandTitleNumber, null); productWrapper.AddSite(mainSiteElement, siteHandle); ExporterCacheManager.SiteHandle = siteHandle; } tr.Commit(); } }
private static void ExportElementClassifications(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper) { if (productWrapper.IsEmpty()) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { ICollection<IFCAnyHandle> productSet = productWrapper.GetAllObjects(); foreach (IFCAnyHandle prodHnd in productSet) { // No need to check the subtype since Classification can be assigned to IfcRoot // if (IFCAnyHandleUtil.IsSubTypeOf(prodHnd, IFCEntityType.IfcElement)) ClassificationUtil.CreateClassification(exporterIFC, file, element, prodHnd); } transaction.Commit(); } }
/// <summary> /// Base implementation to export IFC site object. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="document"> /// The Revit document. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> private static void ExportSiteBase(ExporterIFC exporterIFC, Document document, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCAnyHandle siteHandle = exporterIFC.GetSite(); int numSiteElements = (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle) ? 1 : 0); if (element == null && (numSiteElements != 0)) return; Document doc = document; if (doc == null) { if (element != null) doc = element.Document; else throw new ArgumentException("Both document and element are null."); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { IFCAnyHandle siteRepresentation = null; if (element != null) { // It would be possible that they actually represent several different sites with different buildings, // but until we have a concept of a building in Revit, we have to assume 0-1 sites, 1 building. bool appendedToSite = false; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { IList<IFCAnyHandle> representations = IFCAnyHandleUtil.GetProductRepresentations(siteHandle); if (representations.Count > 0) { IFCAnyHandle bodyRep = representations[0]; IFCAnyHandle boundaryRep = null; if (representations.Count > 1) boundaryRep = representations[1]; siteRepresentation = RepresentationUtil.CreateSurfaceProductDefinitionShape(exporterIFC, element, geometryElement, true, true, ref bodyRep, ref boundaryRep); appendedToSite = true; } } if (!appendedToSite) { siteRepresentation = RepresentationUtil.CreateSurfaceProductDefinitionShape(exporterIFC, element, geometryElement, true, true); } } List<int> latitude = new List<int>(); List<int> longitude = new List<int>(); ProjectLocation projLocation = doc.ActiveProjectLocation; IFCAnyHandle relativePlacement = null; double elevation = 0.0; if (projLocation != null) { double latitudeInDeg = projLocation.SiteLocation.Latitude * 180 / Math.PI; double longitudeInDeg = projLocation.SiteLocation.Longitude * 180 / Math.PI; int latDeg = ((int)latitudeInDeg); latitudeInDeg -= latDeg; latitudeInDeg *= 60; int latMin = ((int)latitudeInDeg); latitudeInDeg -= latMin; latitudeInDeg *= 60; int latSec = ((int)latitudeInDeg); latitudeInDeg -= latSec; latitudeInDeg *= 1000000; int latFracSec = ((int)latitudeInDeg); latitude.Add(latDeg); latitude.Add(latMin); latitude.Add(latSec); if (!exporterIFC.ExportAs2x2) latitude.Add(latFracSec); int longDeg = ((int)longitudeInDeg); longitudeInDeg -= longDeg; longitudeInDeg *= 60; int longMin = ((int)longitudeInDeg); longitudeInDeg -= longMin; longitudeInDeg *= 60; int longSec = ((int)longitudeInDeg); longitudeInDeg -= longSec; longitudeInDeg *= 1000000; int longFracSec = ((int)longitudeInDeg); longitude.Add(longDeg); longitude.Add(longMin); longitude.Add(longSec); if (!exporterIFC.ExportAs2x2) longitude.Add(longFracSec); Transform siteSharedCoordinatesTrf = projLocation.GetTransform().Inverse; if (!siteSharedCoordinatesTrf.IsIdentity) { XYZ orig = siteSharedCoordinatesTrf.Origin; orig = orig.Multiply(exporterIFC.LinearScale); relativePlacement = ExporterUtil.CreateAxis2Placement3D(file, orig, siteSharedCoordinatesTrf.BasisZ, siteSharedCoordinatesTrf.BasisX); } } // Get elevation for site. elevation = -LevelUtil.GetReferenceHeightForRelativeElevation(doc) * exporterIFC.LinearScale; if (IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement)) relativePlacement = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle localPlacement = IFCInstanceExporter.CreateLocalPlacement(file, null, relativePlacement); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); if (element != null) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { string instanceGUID = ExporterIFCUtils.CreateGUID(element); string origInstanceName = exporterIFC.GetName(); string instanceName = NamingUtil.GetNameOverride(element, origInstanceName); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, objectType); string instanceElemId = NamingUtil.CreateIFCElementId(element); siteHandle = IFCInstanceExporter.CreateSite(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacement, siteRepresentation, null, Toolkit.IFCElementComposition.Element, latitude, longitude, elevation, null, null); } } else { // don't bother if we have nothing in the site whatsoever. if ((latitude.Count == 0 || longitude.Count == 0) && IFCAnyHandleUtil.IsNullOrHasNoValue(relativePlacement)) return; string defaultSiteName = "Default"; siteHandle = IFCInstanceExporter.CreateSite(file, ExporterIFCUtils.CreateProjectLevelGUID(doc, IFCProjectLevelGUIDType.Site), ownerHistory, defaultSiteName, null, objectType, localPlacement, null, null, Toolkit.IFCElementComposition.Element, latitude, longitude, elevation, null, null); } productWrapper.AddSite(siteHandle); exporterIFC.SetSite(siteHandle); tr.Commit(); } }
/// <summary> /// Exports a generic element as an IfcSlab.</summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="ifcEnumType">The string value represents the IFC type.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if the floor is exported successfully, false otherwise.</returns> public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { if (geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { bool exportParts = PartExporter.CanExportParts(slabElement); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = placementSetter.LocalPlacement; IFCAnyHandle prodDefHnd = null; bool isBRepSlabHnd = false; if (!exportParts) { ecData.SetLocalPlacement(localPlacement); ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } isBRepSlabHnd = (bodyData.ShapeRepresentationType == ShapeRepresentationType.Brep); } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(slabElement); string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR"); string ifcName = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCName(slabElement)); string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null); string ifcObjectType = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName()); string ifcTag = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement)); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, ifcGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacement, exportParts ? null : prodDefHnd, ifcTag, entityType); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacement, null); } productWrapper.AddElement(slabElement, slabHnd, placementSetter, ecData, true); if (!exportParts) { if (slabElement is HostObject) { HostObject hostObject = slabElement as HostObject; HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, slabHnd, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, isBRepSlabHnd); } else if (slabElement is FamilyInstance) { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement); Document doc = slabElement.Document; CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId); } OpeningUtil.CreateOpeningsIfNecessary(slabHnd, slabElement, ecData, null, exporterIFC, ecData.GetLocalPlacement(), placementSetter, productWrapper); } } } tr.Commit(); return; } } }
/// <summary> /// Exports a gutter element. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(); IFCAnyHandle bodyRep = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryElement, bodyExporterOptions, ecData).RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) ecData.ClearOpenings(); return; } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string originalTag = NamingUtil.CreateIFCElementId(element); // In Revit, we don't have a corresponding type, so we create one for every gutter. IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep); List<IFCAnyHandle> repMapList = new List<IFCAnyHandle>(); repMapList.Add(repMap3dHnd); string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element); string typeGuid = GUIDUtil.CreateSubElementGUID(element, (int) IFCHostedSweepSubElements.PipeSegmentType); IFCAnyHandle style = IFCInstanceExporter.CreatePipeSegmentType(file, typeGuid, ownerHistory, elementTypeName, null, null, null, repMapList, originalTag, elementTypeName, IFCPipeSegmentType.Gutter); List<IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style); IFCAnyHandle mappedItem = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]); ISet<IFCAnyHandle> representations = new HashSet<IFCAnyHandle>(); representations.Add(mappedItem); IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep)) return; List<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>(); shapeReps.Add(bodyMappedItemRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) shapeReps.Add(boundingBoxRep); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle localPlacementToUse; ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); if (roomId == ElementId.InvalidElementId) localPlacementToUse = ecData.GetLocalPlacement(); string guid = GUIDUtil.CreateGUID(element); string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, elementTypeName); string tag = NamingUtil.GetTagOverride(element, originalTag); IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(file, guid, ownerHistory, name, description, objectType, localPlacementToUse, prodRep, tag); bool containedInSpace = (roomId != ElementId.InvalidElementId); productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace); if (containedInSpace) ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd); // Associate segment with type. ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd); OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null, exporterIFC, localPlacementToUse, setter, productWrapper); } tr.Commit(); } } }
/// <summary> /// Exports a floor to IFC slab. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="floor"> /// The floor element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> /// <returns> /// True if the floor is exported successfully, false otherwise. /// </returns> public static void ExportFloor(ExporterIFC exporterIFC, Floor floor, GeometryElement geometryElement, IFCProductWrapper productWrapper) { if (geometryElement == null) return; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, floor)) { IFCAnyHandle localPlacement = placementSetter.GetPlacement(); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string ifcEnumType = CategoryUtil.GetIFCEnumTypeName(exporterIFC, floor); double scale = exporterIFC.LinearScale; ElementId catId = CategoryUtil.GetSafeCategoryId(floor); IList<IFCAnyHandle> reps = new List<IFCAnyHandle>(); IList<IList<CurveLoop>> extrusionLoops = new List<IList<CurveLoop>>(); IList<IFCExtrusionCreationData> loopExtraParams = new List<IFCExtrusionCreationData>(); Plane floorPlane = GeometryUtil.CreateDefaultPlane(); IList<IFCAnyHandle> localPlacements = new List<IFCAnyHandle>(); bool exportedAsExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floor, geometryElement, transformSetter, localPlacement, out localPlacements, out reps, out extrusionLoops, out loopExtraParams, floorPlane); // We will use the ExtrusionAnalyzer when it is ready. // XYZ extrusionDirection = { 0, 0, -1 }; // XYZ modelOrigin = { 0, 0, 0 }; // XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); // XYZ floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top); // Plane floorPlane(floorDir, floorOrigin); // ExtrusionAnalyzer floorExtrusion = // ExtrusionAnalyzer.Create(geometryElement, floorPlane, extrusionDirection); if (!exportedAsExtrusion) { IFCAnyHandle bodyRep = null; IList<GeometryObject> geomObjects = new List<GeometryObject>(); geomObjects.Add(geometryElement); bodyRep = BodyExporter.ExportBody(floor.Document.Application, exporterIFC, catId, geomObjects, true, null); if (bodyRep == null || !bodyRep.HasValue) { tr.Commit(); return; } IFCAnyHandle prodDefHnd = file.CreateProductDefinitionShape(bodyRep); if (!prodDefHnd.HasValue) return; reps.Add(prodDefHnd); } // Create the slab from either the extrusion or the BRep information. IFCLabel ifcGUID = IFCLabel.CreateGUID(floor); IList<IFCAnyHandle> slabHnds = new List<IFCAnyHandle>(); int numReps = reps.Count; for (int ii = 0; ii < numReps; ii++) { IFCLabel ifcName = NamingUtil.GetNameOverride(floor, NamingUtil.CreateIFCName(exporterIFC, ii == 0 ? -1 : ii + 1)); IFCLabel ifcDescription = NamingUtil.GetDescriptionOverride(floor, IFCLabel.Create()); IFCLabel ifcObjectType = NamingUtil.GetObjectTypeOverride(floor, exporterIFC.GetFamilyNameFromExportState()); IFCLabel ifcElemId = NamingUtil.CreateIFCElementId(floor); IFCLabel currentGUID = (ii == 0) ? ifcGUID : IFCLabel.CreateGUID(); IFCAnyHandle localPlacementHnd = exportedAsExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = file.CreateSlab(currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, ifcElemId, ifcEnumType, reps[ii]); if (!slabHnd.HasValue) return; slabHnds.Add(slabHnd); } for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(slabHnds[ii], placementSetter, loopExtraParam, true); } if (exportedAsExtrusion) ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floor, placementSetter, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper); ExporterIFCUtils.CreateGenericElementPropertySet(exporterIFC, floor, productWrapper); ExporterIFCUtils.ExportHostObject(exporterIFC, floor, geometryElement, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a Rebar to IFC ReinforcingMesh. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element to be exported. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportRebar(ExporterIFC exporterIFC, Element element, Autodesk.Revit.DB.View filterView, ProductWrapper productWrapper) { try { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { if (element is Rebar) { GeometryElement rebarGeometry = ExporterIFCUtils.GetRebarGeometry(element as Rebar, filterView); // only options are: Not Export, BuildingElementProxy, or ReinforcingBar/Mesh, depending on layout. // Not Export is handled previously, and ReinforcingBar vs Mesh will be determined below. string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); if (exportType == IFCExportType.ExportBuildingElementProxy) { if (rebarGeometry != null) { ProxyElementExporter.ExportBuildingElementProxy(exporterIFC, element, rebarGeometry, productWrapper); transaction.Commit(); } return; } } IFCAnyHandle prodRep = null; double scale = exporterIFC.LinearScale; double totalBarLengthUnscale = GetRebarTotalLength(element); double volumeUnscale = GetRebarVolume(element); double totalBarLength = totalBarLengthUnscale * scale; if (MathUtil.IsAlmostZero(totalBarLength)) return; ElementId typeId = element.GetTypeId(); RebarBarType elementType = element.Document.GetElement(element.GetTypeId()) as RebarBarType; double diameter = (elementType == null ? 1.0 / 12.0 : elementType.BarDiameter) * scale; double radius = diameter / 2.0; double longitudinalBarNominalDiameter = diameter; double longitudinalBarCrossSectionArea = (volumeUnscale / totalBarLengthUnscale) * scale * scale; double barLength = totalBarLength / GetRebarQuantity(element); IList<Curve> baseCurves = GetRebarCenterlineCurves(element, true, false, false); int numberOfBarPositions = GetNumberOfBarPositions(element); for (int i = 0; i < numberOfBarPositions; i++) { if (!DoesBarExistAtPosition(element, i)) continue; Transform barTrf = GetBarPositionTransform(element, i); IList<Curve> curves = new List<Curve>(); foreach (Curve baseCurve in baseCurves) { curves.Add(baseCurve.get_Transformed(barTrf)); } IFCAnyHandle compositeCurve = GeometryUtil.CreateCompositeCurve(exporterIFC, curves); IFCAnyHandle sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, radius, null, 0, 1); HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>(); bodyItems.Add(sweptDiskSolid); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>(); shapeReps.Add(shapeRep); prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); string steelGradeOpt = null; IFCAnyHandle elemHnd = null; string rebarGUID = GUIDUtil.CreateGUID(element); string rebarName = NamingUtil.GetIFCName(element); string rebarDescription = NamingUtil.GetDescriptionOverride(element, null); string rebarObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element)); string rebarElemId = NamingUtil.CreateIFCElementId(element); IFCReinforcingBarRole role = IFCReinforcingBarRole.NotDefined; elemHnd = IFCInstanceExporter.CreateReinforcingBar(file, rebarGUID, exporterIFC.GetOwnerHistoryHandle(), rebarName, rebarDescription, rebarObjectType, setter.GetPlacement(), prodRep, rebarElemId, steelGradeOpt, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea, barLength, role, null); productWrapper.AddElement(elemHnd, setter.GetLevelInfo(), null, true); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } } transaction.Commit(); } } catch (Exception) { // It will throw exception at GetBarPositionTransform when exporting rebars with Revit 2013 UR1 and before versions, so we skip the export. // It should not come here and will export the rebars properly at Revit later versions. } }
/// <summary> /// Exports a ramp to IfcRamp, without decomposing into separate runs and landings. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The ramp type.</param> /// <param name="ramp">The ramp element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="numFlights">The number of flights for a multistory ramp.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportRamp(ExporterIFC exporterIFC, string ifcEnumType, Element ramp, GeometryElement geometryElement, int numFlights, ProductWrapper productWrapper) { if (ramp == null || geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, ramp)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ecData.ReuseLocalPlacement = false; GeometryElement rampGeom = GeometryUtil.GetOneLevelGeometryElement(geometryElement, numFlights); BodyData bodyData; ElementId categoryId = CategoryUtil.GetSafeCategoryId(ramp); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, ramp, categoryId, rampGeom, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return; } string containedRampGuid = GUIDUtil.CreateSubElementGUID(ramp, (int)IFCRampSubElements.ContainedRamp); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string rampName = NamingUtil.GetNameOverride(ramp, NamingUtil.GetIFCName(ramp)); string rampDescription = NamingUtil.GetDescriptionOverride(ramp, null); string rampObjectType = NamingUtil.GetObjectTypeOverride(ramp, NamingUtil.CreateIFCObjectName(exporterIFC, ramp)); IFCAnyHandle containedRampLocalPlacement = ExporterUtil.CreateLocalPlacement(file, ecData.GetLocalPlacement(), null); string elementTag = NamingUtil.GetTagOverride(ramp, NamingUtil.CreateIFCElementId(ramp)); string rampType = GetIFCRampType(ifcEnumType); List <IFCAnyHandle> components = new List <IFCAnyHandle>(); IList <IFCExtrusionCreationData> componentExtrusionData = new List <IFCExtrusionCreationData>(); IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(file, containedRampGuid, ownerHistory, rampName, rampDescription, rampObjectType, containedRampLocalPlacement, representation, elementTag, rampType); components.Add(containedRampHnd); componentExtrusionData.Add(ecData); //productWrapper.AddElement(containedRampHnd, placementSetter.LevelInfo, ecData, false); CategoryUtil.CreateMaterialAssociations(exporterIFC, containedRampHnd, bodyData.MaterialIds); string guid = GUIDUtil.CreateGUID(ramp); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(file, guid, ownerHistory, rampName, rampDescription, rampObjectType, localPlacement, null, elementTag, rampType); productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true); StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampHnd, components, localPlacement); ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(ramp.Id, stairRampInfo); ExportMultistoryRamp(exporterIFC, ramp, numFlights, rampHnd, components, componentExtrusionData, placementSetter, productWrapper); } tr.Commit(); } } }
/// <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) ProcessConnections(exporterIFC, connector, null); } catch (System.Exception) { // Log an error here } } tr.Commit(); } }
/// <summary> /// Export one IFCGrid in one level. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="levelId">The level ID.</param> /// <param name="sameDirectionAxesU">The U axes of grids.</param> /// <param name="sameDirectionAxesV">The V axes of grids.</param> /// <param name="sameDirectionAxesW">The W axes of grids.</param> public static void ExportGrid(ExporterIFC exporterIFC, ElementId levelId, string gridName, List <Grid> sameDirectionAxesU, List <Grid> sameDirectionAxesV, List <Grid> sameDirectionAxesW) { List <IFCAnyHandle> axesU = null; List <IFCAnyHandle> axesV = null; List <IFCAnyHandle> axesW = null; List <IFCAnyHandle> representations = new List <IFCAnyHandle>(); using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { IFCFile ifcFile = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(ifcFile)) { GridRepresentationData gridRepresentationData = new GridRepresentationData(); axesU = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesU, representations, gridRepresentationData); axesV = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesV, representations, gridRepresentationData); if (sameDirectionAxesW != null) { axesW = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesW, representations, gridRepresentationData); } IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint"); string identifierOpt = "FootPrint"; string representationTypeOpt = "GeometricCurveSet"; int numGridsToExport = gridRepresentationData.m_Grids.Count; if (numGridsToExport == 0) { return; } bool useIFCCADLayer = !string.IsNullOrWhiteSpace(gridRepresentationData.m_IFCCADLayer); IFCAnyHandle shapeRepresentation = null; HashSet <IFCAnyHandle> allCurves = new HashSet <IFCAnyHandle>(); for (int ii = 0; ii < numGridsToExport; ii++) { allCurves.UnionWith(gridRepresentationData.m_curveSets[ii]); } if (useIFCCADLayer) { shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, contextOfItemsFootPrint, identifierOpt, representationTypeOpt, allCurves, gridRepresentationData.m_IFCCADLayer); } else { ElementId catId = CategoryUtil.GetSafeCategoryId(gridRepresentationData.m_Grids[0]); shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, gridRepresentationData.m_Grids[0], catId, contextOfItemsFootPrint, identifierOpt, representationTypeOpt, allCurves); } representations.Add(shapeRepresentation); IFCAnyHandle productRep = IFCInstanceExporter.CreateProductDefinitionShape(ifcFile, null, null, representations); // We will associate the grid with its level, unless there are no levels in the file, in which case we'll associate it with the building. IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId); bool useLevelInfo = (levelInfo != null); string gridGUID = GUIDUtil.CreateGUID(); //// Get the first grid's override name, if cannot find it, use null. //string gridName = GetGridName(sameDirectionAxesU, sameDirectionAxesV, sameDirectionAxesW); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle gridLevelHandle = useLevelInfo ? levelInfo.GetBuildingStorey() : ExporterCacheManager.BuildingHandle; IFCAnyHandle levelObjectPlacement = IFCAnyHandleUtil.GetObjectPlacement(gridLevelHandle); double elev = useLevelInfo ? levelInfo.Elevation : 0.0; double elevation = UnitUtil.ScaleLength(elev); XYZ orig = new XYZ(0.0, 0.0, elevation); IFCAnyHandle copyLevelPlacement = ExporterUtil.CopyLocalPlacement(ifcFile, levelObjectPlacement); IFCAnyHandle ifcGrid = IFCInstanceExporter.CreateGrid(exporterIFC, gridGUID, ownerHistory, gridName, copyLevelPlacement, productRep, axesU, axesV, axesW); productWrapper.AddElement(null, ifcGrid, levelInfo, null, true, null); transaction.Commit(); } } }
/// <summary> /// Exports a CeilingAndFloor element to IFC. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } // export parts or not bool exportParts = PartExporter.CanExportParts(floorElement); if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType); IFCAnyHandle type = null; MaterialLayerSetInfo layersetInfo = null; if (!ElementFilteringUtil.IsElementVisible(floorElement)) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ExportInstance.ToString(), out elementClassTypeEnum) || Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ExportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } Document doc = floorElement.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { // For IFC4RV export, Floor will be split into its parts(temporarily) in order to export the floor by its parts bool exportByComponents = ExporterUtil.ShouldExportByComponents(floorElement, exportParts); using (IFCTransaction tr = new IFCTransaction(file)) { bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor)); if (canExportAsContainerOrWithExtrusionAnalyzer) { // Try to export the Floor slab as a container. If that succeeds, we are done. // If we do export the floor as a container, it will take care of the local placement and transform there, so we need to leave // this out of the IFCTransformSetter and PlacementSetter scopes below, or else we'll get double transforms. IFCAnyHandle floorHnd = RoofExporter.ExportRoofOrFloorAsContainer(exporterIFC, floorElement, geometryElement, productWrapper); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(floorHnd)) { tr.Commit(); return; } } IList <IFCAnyHandle> slabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> brepSlabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, floorElement, out overrideContainerHnd); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = placementSetter.LocalPlacement; // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association. // Disable calling ExportSlabAsExtrusion if we can't handle potential openings. bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null; bool exportedAsInternalExtrusion = false; ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement); IList <IFCAnyHandle> prodReps = new List <IFCAnyHandle>(); IList <ShapeRepresentationType> repTypes = new List <ShapeRepresentationType>(); IList <IList <CurveLoop> > extrusionLoops = new List <IList <CurveLoop> >(); IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>(); Plane floorPlane = GeometryUtil.CreateDefaultPlane(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); if (canExportAsContainerOrWithExtrusionAnalyzer) { Floor floor = floorElement as Floor; // Next, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only. // Also limited to cases with line and arc boundaries. // SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); IList <GeometryObject> gObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(floorElement.Document, exporterIFC, ref solids, ref meshes); if (solids.Count == 1 && meshes.Count == 0) { bool completelyClipped; // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor XYZ floorExtrusionDirection = new XYZ(0, 0, -1); XYZ modelOrigin = XYZ.Zero; XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); if (floorOrigin == null) { // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't // go through the Revit model origin. We'll try the midpoint of the bounding box instead. BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null); modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0; floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); } if (floorOrigin != null) { XYZ floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top); Plane extrusionAnalyzerFloorBasePlane = GeometryUtil.CreatePlaneByNormalAtOrigin(floorDir); GenerateAdditionalInfo additionalInfo = GenerateAdditionalInfo.GenerateBody; additionalInfo |= ExporterCacheManager.ExportOptionsCache.ExportAs4 ? GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None; // Skip generate body item for IFC4RV. It will be handled later in PartExporter.ExportHostPartAsShapeAspects() if (exportByComponents) { additionalInfo &= ~GenerateAdditionalInfo.GenerateBody; } HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out completelyClipped, addInfo: additionalInfo); if (completelyClipped) { return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); if (floorAndProperties.Handle != null) { representations.Add(floorAndProperties.Handle); repTypes.Add(ShapeRepresentationType.SweptSolid); } // Footprint representation will only be exported in export to IFC4 if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintInfo != null)) { IFCAnyHandle footprintShapeRep = floorAndProperties.FootprintInfo.CreateFootprintShapeRepresentation(exporterIFC); representations.Add(footprintShapeRep); } if (exportByComponents) { IFCAnyHandle prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, representations); prodReps.Add(prodRep); } else if (representations.Count > 0 && floorAndProperties.Handle != null) // Only when at least the body rep exists will come here { IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); prodReps.Add(prodRep); } if (floorAndProperties.Data != null) { loopExtraParams.Add(floorAndProperties.Data); } } } } // Use internal routine as backup that handles openings. if (prodReps.Count == 0 && canExportAsInternalExtrusion && !exportByComponents) { exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement, geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps, out extrusionLoops, out loopExtraParams, floorPlane); PotentiallyFixPresentationLayerAssignment(floorElement, prodReps); for (int ii = 0; ii < prodReps.Count; ii++) { // all are extrusions repTypes.Add(ShapeRepresentationType.SweptSolid); // Footprint representation will only be exported in export to IFC4 if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { if (extrusionLoops.Count > ii) { if (extrusionLoops[ii].Count > 0) { // Get the extrusion footprint using the first Curveloop. Transform needs to be obtained from the returned local placement Transform lcs = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, localPlacements[ii]); IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionLoops[ii][0], lcs, floorPlane.Normal); IFCAnyHandle contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint"); ISet <IFCAnyHandle> repItem = new HashSet <IFCAnyHandle>(); repItem.Add(footprintGeomRepItem); IFCAnyHandle footprintShapeRepresentation = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint, "FootPrint", "Curve2D", repItem); IList <IFCAnyHandle> reps = new List <IFCAnyHandle>(); reps.Add(footprintShapeRepresentation); IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps); } } } } } IFCAnyHandle prodDefHnd; if (prodReps.Count == 0) { if (exportByComponents) { prodDefHnd = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, null); prodReps.Add(prodDefHnd); } else { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } prodReps.Add(prodDefHnd); repTypes.Add(bodyData.ShapeRepresentationType); } } } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(floorElement); int numReps = exportParts ? 1 : prodReps.Count; // Deal with a couple of cases that have non-standard defaults. switch (exportType.ExportInstance) { case IFCEntityType.IfcCovering: exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING"); break; case IFCEntityType.IfcSlab: bool isBaseSlab = false; AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel(); if (analyticalModel != null) { AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs(); isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat); } exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR"); break; } for (int ii = 0; ii < numReps; ii++) { string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1)); string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID(); IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = null; slabHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, floorElement, currentGUID, ownerHistory, localPlacementHnd, exportParts ? null : prodReps[ii]); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (!string.IsNullOrEmpty(ifcName)) { IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, ifcName); } // Pre IFC4 Slab does not have PredefinedType if (!string.IsNullOrEmpty(exportType.ValidatedPredefinedType) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { IFCAnyHandleUtil.SetAttribute(slabHnd, "PredefinedType", exportType.ValidatedPredefinedType, true); } if (exportParts && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null); } else if (exportByComponents) { IFCExtrusionCreationData partECData = new IFCExtrusionCreationData(); IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, floorElement, prodReps[ii], productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, out layersetInfo, partECData); loopExtraParams.Add(partECData); } slabHnds.Add(slabHnd); // For IFC4RV, export of the geometry is already handled in PartExporter.ExportHostPartAsShapeAspects() if (!exportParts && !exportByComponents) { if (repTypes[ii] == ShapeRepresentationType.Brep || repTypes[ii] == ShapeRepresentationType.Tessellation) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } } for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true, exportType); type = ExporterUtil.CreateGenericTypeFromElement(floorElement, exportType, file, ownerHistory, exportType.ValidatedPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(type, slabHnds[ii]); ExporterUtil.AddIntoComplexPropertyCache(slabHnds[ii], layersetInfo); } // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not // controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View if (exportedAsInternalExtrusion) { ISet <IFCAnyHandle> oldCreatedObjects = productWrapper.GetAllObjects(); ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); ISet <IFCAnyHandle> newCreatedObjects = productWrapper.GetAllObjects(); newCreatedObjects.ExceptWith(oldCreatedObjects); PotentiallyFixPresentationLayerAssignment(floorElement, newCreatedObjects); } } if (!exportParts) { if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, productWrapper.GetAnElement(), geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false, type); } else { if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false, type); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true, type); } } } } tr.Commit(); return; } } }
/// <summary> /// Exports materials for host object. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="hostObject">The host object.</param> /// <param name="elemHnds">The host IFC handles.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <param name="levelId">The level id.</param> /// <param name="direction">The IFCLayerSetDirection.</param> /// <param name="containsBRepGeometry">True if the geometry contains BRep geoemtry. If so, we will export an IfcMaterialList</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportHostObjectMaterials(ExporterIFC exporterIFC, HostObject hostObject, IList <IFCAnyHandle> elemHnds, GeometryElement geometryElement, ProductWrapper productWrapper, ElementId levelId, Toolkit.IFCLayerSetDirection direction, bool containsBRepGeometry) { if (hostObject == null) { return(true); //nothing to do } if (elemHnds == null || (elemHnds.Count == 0)) { return(true); //nothing to do } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { if (productWrapper != null) { productWrapper.ClearFinishMaterials(); } double scaledOffset = 0.0, scaledWallWidth = 0.0, wallHeight = 0.0; Wall wall = hostObject as Wall; if (wall != null) { scaledWallWidth = UnitUtil.ScaleLength(wall.Width); scaledOffset = -scaledWallWidth / 2.0; BoundingBoxXYZ boundingBox = wall.get_BoundingBox(null); if (boundingBox != null) { wallHeight = boundingBox.Max.Z - boundingBox.Min.Z; } } ElementId typeElemId = hostObject.GetTypeId(); IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialLayerSetCache.Find(typeElemId); // Roofs with no components are only allowed one material. We will arbitrarily choose the thickest material. IFCAnyHandle primaryMaterialHnd = ExporterCacheManager.MaterialLayerSetCache.FindPrimaryMaterialHnd(typeElemId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet)) { HostObjAttributes hostObjAttr = hostObject.Document.GetElement(typeElemId) as HostObjAttributes; if (hostObjAttr == null) { return(true); //nothing to do } List <ElementId> matIds = new List <ElementId>(); List <double> widths = new List <double>(); List <MaterialFunctionAssignment> functions = new List <MaterialFunctionAssignment>(); ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(hostObject); CompoundStructure cs = hostObjAttr.GetCompoundStructure(); if (cs != null) { //TODO: Vertically compound structures are not yet supported by export. if (!cs.IsVerticallyHomogeneous() && !MathUtil.IsAlmostZero(wallHeight)) { cs = cs.GetSimpleCompoundStructure(wallHeight, wallHeight / 2.0); } for (int i = 0; i < cs.LayerCount; ++i) { ElementId matId = cs.GetMaterialId(i); if (matId != ElementId.InvalidElementId) { matIds.Add(matId); } else { matIds.Add(baseMatId); } widths.Add(cs.GetLayerWidth(i)); // save layer function into ProductWrapper, // it's used while exporting "Function" of Pset_CoveringCommon functions.Add(cs.GetLayerFunction(i)); } } if (matIds.Count == 0) { matIds.Add(baseMatId); widths.Add(cs != null ? cs.GetWidth() : 0); functions.Add(MaterialFunctionAssignment.None); } // We can't create IfcMaterialLayers without creating an IfcMaterialLayerSet. So we will simply collate here. IList <IFCAnyHandle> materialHnds = new List <IFCAnyHandle>(); IList <int> widthIndices = new List <int>(); double thickestLayer = 0.0; for (int ii = 0; ii < matIds.Count; ++ii) { // Require positive width for IFC2x3 and before, and non-negative width for IFC4. if (widths[ii] < -MathUtil.Eps()) { continue; } bool almostZeroWidth = MathUtil.IsAlmostZero(widths[ii]); if (ExporterCacheManager.ExportOptionsCache.FileVersion != IFCVersion.IFC4 && almostZeroWidth) { continue; } if (almostZeroWidth) { widths[ii] = 0.0; } IFCAnyHandle materialHnd = CategoryUtil.GetOrCreateMaterialHandle(exporterIFC, matIds[ii]); if (primaryMaterialHnd == null || (widths[ii] > thickestLayer)) { primaryMaterialHnd = materialHnd; thickestLayer = widths[ii]; } widthIndices.Add(ii); materialHnds.Add(materialHnd); if ((productWrapper != null) && (functions[ii] == MaterialFunctionAssignment.Finish1 || functions[ii] == MaterialFunctionAssignment.Finish2)) { productWrapper.AddFinishMaterial(materialHnd); } } int numLayersToCreate = widthIndices.Count; if (numLayersToCreate == 0) { return(false); } if (!containsBRepGeometry) { IList <IFCAnyHandle> layers = new List <IFCAnyHandle>(numLayersToCreate); for (int ii = 0; ii < numLayersToCreate; ii++) { int widthIndex = widthIndices[ii]; double scaledWidth = UnitUtil.ScaleLength(widths[widthIndex]); IFCAnyHandle materialLayer = IFCInstanceExporter.CreateMaterialLayer(file, materialHnds[ii], scaledWidth, null); layers.Add(materialLayer); } string layerSetName = exporterIFC.GetFamilyName(); materialLayerSet = IFCInstanceExporter.CreateMaterialLayerSet(file, layers, layerSetName); ExporterCacheManager.MaterialLayerSetCache.Register(typeElemId, materialLayerSet); ExporterCacheManager.MaterialLayerSetCache.RegisterPrimaryMaterialHnd(typeElemId, primaryMaterialHnd); } else { foreach (IFCAnyHandle elemHnd in elemHnds) { CategoryUtil.CreateMaterialAssociations(exporterIFC, elemHnd, matIds); } } } // IfcMaterialLayerSetUsage is not supported for IfcWall, only IfcWallStandardCase. IFCAnyHandle layerSetUsage = null; for (int ii = 0; ii < elemHnds.Count; ii++) { IFCAnyHandle elemHnd = elemHnds[ii]; if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd)) { continue; } SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, elemHnd, hostObject.Id, levelId); if (containsBRepGeometry) { continue; } HashSet <IFCAnyHandle> relDecomposesSet = IFCAnyHandleUtil.GetRelDecomposes(elemHnd); IList <IFCAnyHandle> subElemHnds = null; if (relDecomposesSet != null && relDecomposesSet.Count == 1) { IFCAnyHandle relAggregates = relDecomposesSet.First(); if (IFCAnyHandleUtil.IsTypeOf(relAggregates, IFCEntityType.IfcRelAggregates)) { subElemHnds = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(relAggregates, "RelatedObjects"); } } bool hasSubElems = (subElemHnds != null && subElemHnds.Count != 0); bool isRoof = IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcRoof); if (!hasSubElems && !isRoof && !IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcWall)) { if (layerSetUsage == null) { bool flipDirSense = true; if (wall != null) { // if we have flipped the center curve on export, we need to take that into account here. // We flip the center curve on export if it is an arc and it has a negative Z direction. LocationCurve locCurve = wall.Location as LocationCurve; if (locCurve != null) { Curve curve = locCurve.Curve; Plane defPlane = new Plane(XYZ.BasisX, XYZ.BasisY, XYZ.Zero); bool curveFlipped = GeometryUtil.MustFlipCurve(defPlane, curve); flipDirSense = !(wall.Flipped ^ curveFlipped); } } else if (hostObject is Floor) { flipDirSense = false; } double offsetFromReferenceLine = flipDirSense ? -scaledOffset : scaledOffset; IFCDirectionSense sense = flipDirSense ? IFCDirectionSense.Negative : IFCDirectionSense.Positive; layerSetUsage = IFCInstanceExporter.CreateMaterialLayerSetUsage(file, materialLayerSet, direction, sense, offsetFromReferenceLine); } ExporterCacheManager.MaterialLayerRelationsCache.Add(layerSetUsage, elemHnd); } else { if (hasSubElems) { foreach (IFCAnyHandle subElemHnd in subElemHnds) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(subElemHnd)) { ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, subElemHnd); } } } else if (!isRoof) { ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, elemHnd); } else if (primaryMaterialHnd != null) { ExporterCacheManager.MaterialLayerRelationsCache.Add(primaryMaterialHnd, elemHnd); } } } tr.Commit(); return(true); } }
/// <summary> /// Export the individual part (IfcBuildingElementPart). /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="partElement">The part element to export.</param> /// <param name="geometryElement">The geometry of part.</param> /// <param name="productWrapper">The ProductWrapper object.</param> public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper, PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes, Element hostElement, ElementId overrideLevelId, bool asBuildingElement) { if (!ElementFilteringUtil.IsElementVisible(partElement)) { return; } Part part = partElement as Part; if (part == null) { return; } if (!asBuildingElement) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcBuildingElementPart", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } else { string ifcEnumType = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } PlacementSetter standalonePlacementSetter = null; bool standaloneExport = hostElement == null && !asBuildingElement; ElementId partExportLevel = null; if (standaloneExport || asBuildingElement) { partExportLevel = partElement.LevelId; } else { if (part.OriginalCategoryId != hostElement.Category.Id) { return; } partExportLevel = hostElement.LevelId; } if (overrideLevelId != null) { partExportLevel = overrideLevelId; } if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel)) { return; } Options options = GeometryUtil.GetIFCExportGeometryOptions(); View ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View; if (ownerView != null) { options.View = ownerView; } GeometryElement geometryElement = partElement.get_Geometry(options); if (geometryElement == null) { return; } try { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IFCAnyHandle partPlacement = null; if (standaloneExport || asBuildingElement) { Transform orientationTrf = Transform.Identity; standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel); partPlacement = standalonePlacementSetter.LocalPlacement; } else { partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null); } bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); SolidMeshGeometryInfo solidMeshInfo; if (validRange) { solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0) { return; } } else { solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); } using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(partPlacement); extrusionCreationData.ReuseLocalPlacement = false; extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes; IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); ElementId catId = CategoryUtil.GetSafeCategoryId(partElement); ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, extrusionCreationData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, extrusionCreationData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extrusionCreationData.ClearOpenings(); return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string partGUID = GUIDUtil.CreateGUID(partElement); string partName = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement)); string partDescription = NamingUtil.GetDescriptionOverride(partElement, null); string partObjectType = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement)); string partTag = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement)); IFCAnyHandle ifcPart = null; if (!asBuildingElement) { ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag); } else { string ifcEnumType = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); string defaultValue = null; // This replicates old functionality before IFC4 addition, where the default for slab was "FLOOR". // Really the export layer table should be fixed for this case. if (string.IsNullOrWhiteSpace(ifcEnumType) && hostCatId == new ElementId(BuiltInCategory.OST_Floors)) { ifcEnumType = "FLOOR"; } ifcEnumType = IFCValidateEntry.GetValidIFCType(hostElement, ifcEnumType, defaultValue); switch (exportType) { case IFCExportType.IfcColumnType: ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcCovering: ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcFooting: ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcPile: ifcPart = IFCInstanceExporter.CreatePile(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType, null); break; case IFCExportType.IfcRoof: ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcSlab: ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcWall: ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null); break; } } bool containedInLevel = (standaloneExport || asBuildingElement); PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter; productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel); OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper); //Add the exported part to exported cache. TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id); CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds); transaction.Commit(); } } } finally { if (standalonePlacementSetter != null) { standalonePlacementSetter.Dispose(); } } }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if exported successfully, false otherwise.</returns> public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { bool exported = false; if (element == null || geometryElement == null) return exported; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { exported = (ExportBuildingElementProxy(exporterIFC, element, geometryElement, productWrapper) != null); if (exported) tr.Commit(); } return exported; }
/// <summary> /// Exports an element to IFC footing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string footingType = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming footingType = IFCValidateEntry.GetValidIFCType(element, footingType); IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(), instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, footingType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId); } } productWrapper.AddElement(element, footing, setter, ecData, true); OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }