/// <summary> /// Exports spatial elements, including rooms, areas and spaces. 2nd level space boundaries. /// </summary> /// <param name="ifcExporter">The Exporter object.</param> /// <param name="exporterIFC"> The ExporterIFC object.</param> /// <param name="document">The Revit document.</param> /// <returns>The set of exported spaces. This is used to try to export using the standard routine for spaces that failed.</returns> public static ISet<ElementId> ExportSpatialElement2ndLevel(Revit.IFC.Export.Exporter.Exporter ifcExporter, ExporterIFC exporterIFC, Document document) { ISet<ElementId> exportedSpaceIds = new HashSet<ElementId>(); using (SubTransaction st = new SubTransaction(document)) { st.Start(); EnergyAnalysisDetailModel model = null; try { View filterView = ExporterCacheManager.ExportOptionsCache.FilterViewForExport; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { EnergyAnalysisDetailModelOptions options = new EnergyAnalysisDetailModelOptions(); options.Tier = EnergyAnalysisDetailModelTier.SecondLevelBoundaries; //2nd level space boundaries options.SimplifyCurtainSystems = true; try { model = EnergyAnalysisDetailModel.Create(document, options); } catch (System.Exception) { return exportedSpaceIds; } IList<EnergyAnalysisSpace> spaces = model.GetAnalyticalSpaces(); foreach (EnergyAnalysisSpace space in spaces) { SpatialElement spatialElement = document.GetElement(space.CADObjectUniqueId) as SpatialElement; if (spatialElement == null) continue; //current view only if (!ElementFilteringUtil.IsElementVisible(spatialElement)) continue; if (!ElementFilteringUtil.ShouldElementBeExported(exporterIFC, spatialElement, false)) continue; if (ElementFilteringUtil.IsRoomInInvalidPhase(spatialElement)) continue; Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); View ownerView = spatialElement.Document.GetElement(spatialElement.OwnerViewId) as View; if (ownerView != null) geomOptions.View = ownerView; GeometryElement geomElem = spatialElement.get_Geometry(geomOptions); try { exporterIFC.PushExportState(spatialElement, geomElem); using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, spatialElement)) { // We won't use the SpatialElementGeometryResults, as these are 1st level boundaries, not 2nd level. SpatialElementGeometryResults results = null; if (!CreateIFCSpace(exporterIFC, spatialElement, productWrapper, setter, out results)) continue; exportedSpaceIds.Add(spatialElement.Id); XYZ offset = GetSpaceBoundaryOffset(setter); //get boundary information from surfaces IList<EnergyAnalysisSurface> surfaces = space.GetAnalyticalSurfaces(); foreach (EnergyAnalysisSurface surface in surfaces) { Element boundingElement = GetBoundaryElement(document, surface.CADLinkUniqueId, surface.CADObjectUniqueId); IList<EnergyAnalysisOpening> openings = surface.GetAnalyticalOpenings(); IFCAnyHandle connectionGeometry = CreateConnectionSurfaceGeometry(exporterIFC, surface, openings, offset); CreateIFCSpaceBoundary(file, exporterIFC, spatialElement, boundingElement, setter.LevelId, connectionGeometry); // try to add doors and windows for host objects if appropriate. if (boundingElement is HostObject) { foreach (EnergyAnalysisOpening opening in openings) { Element openingBoundingElem = GetBoundaryElement(document, opening.CADLinkUniqueId, opening.CADObjectUniqueId); IFCAnyHandle openingConnectionGeom = CreateConnectionSurfaceGeometry(exporterIFC, opening, offset); CreateIFCSpaceBoundary(file, exporterIFC, spatialElement, openingBoundingElem, setter.LevelId, openingConnectionGeom); } } } CreateZoneInfos(exporterIFC, file, spatialElement, productWrapper); CreateSpaceOccupantInfo(exporterIFC, file, spatialElement, productWrapper); ExporterUtil.ExportRelatedProperties(exporterIFC, spatialElement, productWrapper); } } } catch (Exception ex) { ifcExporter.HandleUnexpectedException(ex, exporterIFC, spatialElement); } finally { exporterIFC.PopExportState(); } } transaction.Commit(); } } finally { if (model != null) EnergyAnalysisDetailModel.Destroy(model); } st.RollBack(); return exportedSpaceIds; } }