/// <summary> /// Relate levels and products. /// </summary> /// <param name="exporterIFC">The IFC exporter object.</param> /// <param name="document">The document to relate the levels.</param> private void RelateLevels(ExporterIFC exporterIFC, Document document) { HashSet<IFCAnyHandle> buildingStoreys = new HashSet<IFCAnyHandle>(); List<ElementId> levelIds = ExporterCacheManager.LevelInfoCache.LevelsByElevation; for (int ii = 0; ii < levelIds.Count; ii++) { ElementId levelId = levelIds[ii]; IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId); if (levelInfo == null) continue; // remove products that are aggregated (e.g., railings in stairs). Element level = document.GetElement(levelId); ICollection<IFCAnyHandle> relatedProductsToCheck = levelInfo.GetRelatedProducts(); ICollection<IFCAnyHandle> relatedElementsToCheck = levelInfo.GetRelatedElements(); // get coincident levels, if any. double currentElevation = levelInfo.Elevation; int nextLevelIdx = ii + 1; for (int jj = ii + 1; jj < levelIds.Count; jj++, nextLevelIdx++) { ElementId nextLevelId = levelIds[jj]; IFCLevelInfo levelInfo2 = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, nextLevelId); if (levelInfo2 == null) continue; if (MathUtil.IsAlmostEqual(currentElevation, levelInfo2.Elevation)) { foreach (IFCAnyHandle relatedProduct in levelInfo2.GetRelatedProducts()) { relatedProductsToCheck.Add(relatedProduct); } foreach (IFCAnyHandle relatedElement in levelInfo2.GetRelatedElements()) { relatedElementsToCheck.Add(relatedElement); } } else break; } // We may get stale handles in here; protect against this. HashSet<IFCAnyHandle> relatedProducts = new HashSet<IFCAnyHandle>(); foreach (IFCAnyHandle relatedProduct in relatedProductsToCheck) { try { if (!IFCAnyHandleUtil.HasRelDecomposes(relatedProduct)) relatedProducts.Add(relatedProduct); } catch { } } HashSet<IFCAnyHandle> relatedElements = new HashSet<IFCAnyHandle>(); foreach (IFCAnyHandle relatedElement in relatedElementsToCheck) { try { if (!IFCAnyHandleUtil.HasRelDecomposes(relatedElement)) relatedElements.Add(relatedElement); } catch { } } // skip coincident levels, if any. for (int jj = ii + 1; jj < nextLevelIdx; jj++) { ElementId nextLevelId = levelIds[jj]; IFCLevelInfo levelInfo2 = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, nextLevelId); if (levelInfo2 == null) continue; if (!levelInfo.GetBuildingStorey().Equals(levelInfo2.GetBuildingStorey())) levelInfo2.GetBuildingStorey().Delete(); } ii = nextLevelIdx - 1; if (relatedProducts.Count == 0 && relatedElements.Count == 0) { levelInfo.GetBuildingStorey().Delete(); } else { bool added = buildingStoreys.Add(levelInfo.GetBuildingStorey()); if (added) { using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, false)) { productWrapper.AddElement(levelInfo.GetBuildingStorey(), levelInfo, null, false); Element element = document.GetElement(levelId); ExportElementProperties(exporterIFC, element, productWrapper); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } } } if (relatedProducts.Count > 0) { IFCAnyHandle buildingStorey = levelInfo.GetBuildingStorey(); string guid = ExporterIFCUtils.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelAggregates); ExporterCacheManager.ContainmentCache.SetGUIDForRelation(buildingStorey, guid); ExporterCacheManager.ContainmentCache.AddRelations(buildingStorey, relatedProducts); } if (relatedElements.Count > 0) { string guid = ExporterIFCUtils.CreateSubElementGUID(level, (int)IFCBuildingStoreySubElements.RelContainedInSpatialStructure); IFCInstanceExporter.CreateRelContainedInSpatialStructure(exporterIFC.GetFile(), guid, exporterIFC.GetOwnerHistoryHandle(), null, null, relatedElements, levelInfo.GetBuildingStorey()); } } if (buildingStoreys.Count > 0) { IFCAnyHandle building = exporterIFC.GetBuilding(); ProjectInfo projectInfo = document.ProjectInformation; string guid = ExporterIFCUtils.CreateSubElementGUID(projectInfo, (int)IFCBuildingSubElements.RelAggregatesBuildingStoreys); ExporterCacheManager.ContainmentCache.SetGUIDForRelation(building, guid); ExporterCacheManager.ContainmentCache.AddRelations(building, buildingStoreys); } }
/// <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(); using (IFCTransaction transaction = new IFCTransaction(file)) { 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 = ExporterIFCUtils.CreateSubElementGUID(elem, (int)IFCStairSubElements.ContainmentRelation); ExporterUtil.RelateObjects(exporterIFC, guid, hnd, comps); } } ProjectInfo projectInfo = document.ProjectInformation; IFCAnyHandle buildingHnd = exporterIFC.GetBuilding(); // relate assembly elements to assemblies foreach (KeyValuePair<ElementId, AssemblyInstanceInfo> assemblyInfoEntry in ExporterCacheManager.AssemblyInstanceCache) { AssemblyInstanceInfo assemblyInfo = assemblyInfoEntry.Value; if (assemblyInfo == null) continue; if (assemblyInfo.AssemblyInstanceHandle != null && assemblyInfo.ElementHandles != null && assemblyInfo.ElementHandles.Count != 0) { Element assemblyInstance = document.GetElement(assemblyInfoEntry.Key); string guid = ExporterIFCUtils.CreateSubElementGUID(assemblyInstance, (int)IFCAssemblyInstanceSubElements.RelContainedInSpatialStructure); ExporterUtil.RelateObjects(exporterIFC, guid, assemblyInfo.AssemblyInstanceHandle, assemblyInfo.ElementHandles); // Set the PlacementRelTo of assembly elements to assembly instance. IFCAnyHandle assemblyPlacement = IFCAnyHandleUtil.GetObjectPlacement(assemblyInfo.AssemblyInstanceHandle); foreach (IFCAnyHandle elementHandle in assemblyInfo.ElementHandles) { // NOTE: caution that old IFCAXIS2PLACEMENT3D will be unused as the new one replace it. // But we cannot delete it safely yet because we don't know if any handle is referencing it. IFCAnyHandle elementPlacement = IFCAnyHandleUtil.GetObjectPlacement(elementHandle); Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(assemblyPlacement, elementPlacement); Transform inverseTrf = relTrf.Inverse; IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); IFCAnyHandleUtil.SetAttribute(elementPlacement, "PlacementRelTo", assemblyPlacement); GeometryUtil.SetRelativePlacement(elementPlacement, relLocalPlacement); } } } // create spatial structure holder ICollection<IFCAnyHandle> relatedElements = exporterIFC.GetRelatedElements(); if (relatedElements.Count > 0) { HashSet<IFCAnyHandle> relatedElementSet = new HashSet<IFCAnyHandle>(relatedElements); IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, ExporterIFCUtils.CreateSubElementGUID(projectInfo, (int)IFCBuildingSubElements.RelContainedInSpatialStructure), exporterIFC.GetOwnerHistoryHandle(), null, null, relatedElementSet, buildingHnd); } ICollection<IFCAnyHandle> relatedProducts = exporterIFC.GetRelatedProducts(); if (relatedProducts.Count > 0) { string guid = ExporterIFCUtils.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.UpdateBuildingPlacement(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(buildingHnd); ExportElementProperties(exporterIFC, document.ProjectInformation, productWrapper); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, document.ProjectInformation, productWrapper); } // create material layer associations foreach (IFCAnyHandle materialSetLayerUsageHnd in ExporterCacheManager.MaterialLayerRelationsCache.Keys) { IFCInstanceExporter.CreateRelAssociatesMaterial(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, ExporterCacheManager.MaterialLayerRelationsCache[materialSetLayerUsageHnd], materialSetLayerUsageHnd); } // create material associations foreach (IFCAnyHandle materialHnd in ExporterCacheManager.MaterialRelationsCache.Keys) { IFCInstanceExporter.CreateRelAssociatesMaterial(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, ExporterCacheManager.MaterialRelationsCache[materialHnd], materialHnd); } // create type relations foreach (IFCAnyHandle typeObj in ExporterCacheManager.TypeRelationsCache.Keys) { IFCInstanceExporter.CreateRelDefinesByType(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, ExporterCacheManager.TypeRelationsCache[typeObj], typeObj); } // create type property relations foreach (TypePropertyInfo typePropertyInfo in ExporterCacheManager.TypePropertyInfoCache.Values) { ICollection<IFCAnyHandle> propertySets = typePropertyInfo.PropertySets; ICollection<IFCAnyHandle> elements = typePropertyInfo.Elements; if (elements.Count == 0) continue; foreach (IFCAnyHandle propertySet in propertySets) { IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, elements, propertySet); } } // 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. IFCInstanceExporter.CreateRelConnectsPathElements(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, 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(), exporterIFC.GetOwnerHistoryHandle(), zoneName, zoneInfo.Description, zoneInfo.ObjectType); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), 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(), exporterIFC.GetOwnerHistoryHandle(), classificationReference.Key, "", zoneHnds, classificationReference.Value); } if (zoneInfo.EnergyAnalysisProperySetHandle != null && zoneInfo.EnergyAnalysisProperySetHandle.HasValue) { IFCAnyHandle relHnd = IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, zoneHnds, zoneInfo.EnergyAnalysisProperySetHandle); } } } } // 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(), exporterIFC.GetOwnerHistoryHandle(), null, null, spaceOccupantName, person, IFCOccupantType.NotDefined); IFCInstanceExporter.CreateRelOccupiesSpaces(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), 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(), exporterIFC.GetOwnerHistoryHandle(), classificationReference.Key, "", spaceOccupantHandles, classificationReference.Value); } if (spaceOccupantInfo.SpaceOccupantProperySetHandle != null && spaceOccupantInfo.SpaceOccupantProperySetHandle.HasValue) { IFCAnyHandle relHnd = IFCInstanceExporter.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, spaceOccupantHandles, spaceOccupantInfo.SpaceOccupantProperySetHandle); } } } } // Create systems. HashSet<IFCAnyHandle> relatedBuildings = new HashSet<IFCAnyHandle>(); relatedBuildings.Add(buildingHnd); foreach (KeyValuePair<ElementId, ICollection<IFCAnyHandle>> system in ExporterCacheManager.SystemsCache.BuiltInSystemsCache) { MEPSystem systemElem = document.GetElement(system.Key) as MEPSystem; if (systemElem == null) continue; string desc = ""; ElementType systemElemType = document.GetElement(systemElem.GetTypeId()) as ElementType; string objectType = (systemElemType != null) ? systemElemType.Name : ""; IFCAnyHandle systemHandle = IFCInstanceExporter.CreateSystem(file, GUIDUtil.CreateGUID(systemElem), exporterIFC.GetOwnerHistoryHandle(), systemElem.Name, desc, objectType); ICollection<IFCAnyHandle> systemHandles = new List<IFCAnyHandle>(); systemHandles.Add(systemHandle); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, systemElem, systemHandles); IFCAnyHandle relServicesBuildings = IFCInstanceExporter.CreateRelServicesBuildings(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, systemHandle, relatedBuildings); IFCAnyHandle relAssignsToGroup = IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, system.Value, IFCObjectType.Product, 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) { ICollection<IFCAnyHandle> validHandles = new List<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); } ExporterIFCUtils.EndExportInternal(exporterIFC); //create header ExportOptionsCache exportOptionsCache = ExporterCacheManager.ExportOptionsCache; string coordinationView = null; if (exportOptionsCache.ExportAs2x3CoordinationView2) coordinationView = "CoordinationView_V2.0"; else coordinationView = "CoordinationView"; List<string> descriptions = new List<string>(); if (exportOptionsCache.ExportAs2x2 || ExporterUtil.DoCodeChecking(exportOptionsCache)) { descriptions.Add("IFC2X_PLATFORM"); } else { string currentLine; if (String.Compare(exportOptionsCache.SelectedConfigName, "FMHandOverView") == 0) { currentLine = string.Format("ViewDefinition [{0}{1}{2}{3}]", coordinationView, exportOptionsCache.ExportBaseQuantities ? ", QuantityTakeOffAddOnView" : "", ", ", exportOptionsCache.SelectedConfigName); } else { currentLine = string.Format("ViewDefinition [{0}{1}]", coordinationView, exportOptionsCache.ExportBaseQuantities ? ", QuantityTakeOffAddOnView" : ""); } descriptions.Add(currentLine); } string projectNumber = projectInfo.Number; string projectName = projectInfo.Name; string projectStatus = projectInfo.Status; 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; 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); } }
/// <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(); using (IFCTransaction transaction = new IFCTransaction(file)) { 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 = ExporterIFCUtils.CreateSubElementGUID(elem, (int) IFCStairSubElements.ContainmentRelation); ExporterUtil.RelateObjects(exporterIFC, guid, hnd, comps); } } ProjectInfo projectInfo = document.ProjectInformation; // relate assembly elements to assemblies foreach (KeyValuePair<ElementId, AssemblyInstanceInfo> assemblyInfoEntry in ExporterCacheManager.AssemblyInstanceCache) { AssemblyInstanceInfo assemblyInfo = assemblyInfoEntry.Value; if (assemblyInfo == null) continue; if (assemblyInfo.AssemblyInstanceHandle != null && assemblyInfo.ElementHandles != null && assemblyInfo.ElementHandles.Count != 0) { Element assemblyInstance = document.GetElement(assemblyInfoEntry.Key); string guid = ExporterIFCUtils.CreateSubElementGUID(assemblyInstance, (int)IFCAssemblyInstanceSubElements.RelContainedInSpatialStructure); ExporterUtil.RelateObjects(exporterIFC, guid, assemblyInfo.AssemblyInstanceHandle, assemblyInfo.ElementHandles); } } // create spatial structure holder ICollection<IFCAnyHandle> relatedElements = exporterIFC.GetRelatedElements(); if (relatedElements.Count > 0) { HashSet<IFCAnyHandle> relatedElementSet = new HashSet<IFCAnyHandle>(relatedElements); IFCInstanceExporter.CreateRelContainedInSpatialStructure(file, ExporterIFCUtils.CreateSubElementGUID(projectInfo, (int)IFCBuildingSubElements.RelContainedInSpatialStructure), exporterIFC.GetOwnerHistoryHandle(), null, null, relatedElementSet, exporterIFC.GetBuilding()); } ICollection<IFCAnyHandle> relatedProducts = exporterIFC.GetRelatedProducts(); if (relatedProducts.Count > 0) { string guid = ExporterIFCUtils.CreateSubElementGUID(projectInfo, (int)IFCBuildingSubElements.RelAggregatesProducts); ExporterUtil.RelateObjects(exporterIFC, guid, exporterIFC.GetBuilding(), relatedProducts); } // create a default site if we have latitude and longitude information. if (IFCAnyHandleUtil.IsNullOrHasNoValue(exporterIFC.GetSite())) { using (IFCProductWrapper productWrapper = IFCProductWrapper.Create(exporterIFC, true)) { SiteExporter.ExportDefaultSite(exporterIFC, document, productWrapper); } } IFCAnyHandle siteHandle = exporterIFC.GetSite(); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(siteHandle)) { ExporterUtil.RelateObject(exporterIFC, exporterIFC.GetProject(), siteHandle); // assoc. site to the building. ExporterUtil.RelateObject(exporterIFC, siteHandle, exporterIFC.GetBuilding()); ExporterIFCUtils.UpdateBuildingPlacement(exporterIFC); } else { // relate building and project if no site ExporterUtil.RelateObject(exporterIFC, exporterIFC.GetProject(), exporterIFC.GetBuilding()); } // relate levels and products. RelateLevels(exporterIFC, document); // These elements are created internally, but we allow custom property sets for them. Create them here. using (IFCProductWrapper productWrapper = IFCProductWrapper.Create(exporterIFC, true)) { IFCAnyHandle buildingHnd = exporterIFC.GetBuilding(); productWrapper.AddBuilding(buildingHnd); ExportElementProperties(exporterIFC, document.ProjectInformation, productWrapper); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, document.ProjectInformation, productWrapper); } // create material layer associations foreach (IFCAnyHandle materialSetLayerUsageHnd in ExporterCacheManager.MaterialLayerRelationsCache.Keys) { IFCInstanceExporter.CreateRelAssociatesMaterial(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, ExporterCacheManager.MaterialLayerRelationsCache[materialSetLayerUsageHnd], materialSetLayerUsageHnd); } // create material associations foreach (IFCAnyHandle materialHnd in ExporterCacheManager.MaterialRelationsCache.Keys) { IFCInstanceExporter.CreateRelAssociatesMaterial(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, ExporterCacheManager.MaterialRelationsCache[materialHnd], materialHnd); } // create type relations foreach (IFCAnyHandle typeObj in ExporterCacheManager.TypeRelationsCache.Keys) { IFCInstanceExporter.CreateRelDefinesByType(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, ExporterCacheManager.TypeRelationsCache[typeObj], typeObj); } // create type property relations foreach (TypePropertyInfo typePropertyInfo in ExporterCacheManager.TypePropertyInfoCache.Values) { HashSet<IFCAnyHandle> propertySets = typePropertyInfo.PropertySets; HashSet<IFCAnyHandle> elements = typePropertyInfo.Elements; foreach (IFCAnyHandle propertySet in propertySets) { IFCInstanceExporter.CreateRelDefinesByProperties(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, elements, propertySet); } } // 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. IFCInstanceExporter.CreateRelConnectsPathElements(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, 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, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), zoneName, zoneInfo.ObjectType, zoneInfo.Description); IFCInstanceExporter.CreateRelAssignsToGroup(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), 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, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), classificationReference.Key, "", zoneHnds, classificationReference.Value); } if (zoneInfo.EnergyAnalysisProperySetHandle != null && zoneInfo.EnergyAnalysisProperySetHandle.HasValue) { IFCAnyHandle relHnd = IFCInstanceExporter.CreateRelDefinesByProperties(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, zoneHnds, zoneInfo.EnergyAnalysisProperySetHandle); } } } } // 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, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, spaceOccupantName, person, IFCOccupantType.NotDefined); IFCInstanceExporter.CreateRelOccupiesSpaces(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), 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, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), classificationReference.Key, "", spaceOccupantHandles, classificationReference.Value); } if (spaceOccupantInfo.SpaceOccupantProperySetHandle != null && spaceOccupantInfo.SpaceOccupantProperySetHandle.HasValue) { IFCAnyHandle relHnd = IFCInstanceExporter.CreateRelDefinesByProperties(file, ExporterIFCUtils.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(), null, null, spaceOccupantHandles, spaceOccupantInfo.SpaceOccupantProperySetHandle); } } } } ExporterIFCUtils.EndExportInternal(exporterIFC); //create header ExportOptionsCache exportOptionsCache = ExporterCacheManager.ExportOptionsCache; string coordinationView = null; if (exportOptionsCache.ExportAs2x3CoordinationView2) coordinationView = "CoordinationView_V2.0"; else coordinationView = "CoordinationView"; List<string> descriptions = new List<string>(); if (exportOptionsCache.ExportAs2x2 || ExporterUtil.DoCodeChecking(exportOptionsCache)) { descriptions.Add("IFC2X_PLATFORM"); } else { string currentLine; currentLine = string.Format("ViewDefinition [{0}{1}]", coordinationView, exportOptionsCache.ExportBaseQuantities ? ", QuantityTakeOffAddOnView" : ""); descriptions.Add(currentLine); } string projectNumber = projectInfo.Number; string projectName = projectInfo.Name; string projectStatus = projectInfo.Status; 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); List<string> author = new List<string>(); author.Add(string.Empty); List<string> orginization = new List<string>(); orginization.Add(string.Empty); IFCInstanceExporter.CreateFileSchema(file); IFCInstanceExporter.CreateFileDescription(file, descriptions); IFCInstanceExporter.CreateFileName(file, projectNumber, author, orginization, document.Application.VersionName, document.Application.VersionBuild, string.Empty); 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); } }