/// <summary> /// Gets IFCFileModelOptions from schema name. /// </summary> /// <param name="schemaName">The schema name.</param> /// <param name="schemaVersion">The calculated schema version from the schema name. Default is IFC2x3.</param> /// <returns>The IFCFileModelOptions.</returns> static IFCFileModelOptions GetIFCFileModelOptions(string schemaName, out IFCSchemaVersion schemaVersion) { IFCFileModelOptions modelOptions = new IFCFileModelOptions(); modelOptions.SchemaName = schemaName; schemaVersion = IFCSchemaVersion.IFC2x3; // Default, should be overridden. if (OverrideSchemaFileName != null) { modelOptions.SchemaFile = OverrideSchemaFileName; } else if (string.Compare(schemaName, "IFC2X3", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); schemaVersion = IFCSchemaVersion.IFC2x3; } else if (string.Compare(schemaName, "IFC2X_FINAL", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X_PROXY.exp"); schemaVersion = IFCSchemaVersion.IFC2x; } else if (string.Compare(schemaName, "IFC2X2_FINAL", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); schemaVersion = IFCSchemaVersion.IFC2x2; } else if (string.Compare(schemaName, "IFC4", true) == 0) { // We will still temporarily support the old IFC4.exp file. string ifc4Add1Path = Path.Combine(RevitProgramPath, "EDM\\IFC4_ADD1.exp"); string ifc4Add2Path = Path.Combine(RevitProgramPath, "EDM\\IFC4_ADD2.exp"); if (File.Exists(ifc4Add2Path)) { modelOptions.SchemaFile = ifc4Add2Path; schemaVersion = IFCSchemaVersion.IFC4Add2; } else if (File.Exists(ifc4Add1Path)) { modelOptions.SchemaFile = ifc4Add1Path; schemaVersion = IFCSchemaVersion.IFC4Add1; } else { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC4.exp"); schemaVersion = IFCSchemaVersion.IFC4; } } else { throw new ArgumentException("Invalid or unsupported schema: " + schemaName); } return(modelOptions); }
/// <summary> /// Gets IFCFileModelOptions from schema name. /// </summary> /// <param name="schemaName">The schema name.</param> /// <param name="schemaVersion">The calculated schema version from the schema name. Default is IFC2x3.</param> /// <returns>The IFCFileModelOptions.</returns> static IFCFileModelOptions GetIFCFileModelOptions(string schemaName, out IFCSchemaVersion schemaVersion) { IFCFileModelOptions modelOptions = new IFCFileModelOptions(); modelOptions.SchemaName = schemaName; schemaVersion = IFCSchemaVersion.IFC2x3; // Default, should be overridden. if (OverrideSchemaFileName != null) { modelOptions.SchemaFile = OverrideSchemaFileName; } else if (string.Compare(schemaName, "IFC2X3", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); schemaVersion = IFCSchemaVersion.IFC2x3; } else if (string.Compare(schemaName, "IFC2X_FINAL", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X_PROXY.exp"); schemaVersion = IFCSchemaVersion.IFC2x; } else if (string.Compare(schemaName, "IFC2X2_FINAL", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); schemaVersion = IFCSchemaVersion.IFC2x2; } else if (string.Compare(schemaName, "IFC4", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC4.exp"); schemaVersion = IFCSchemaVersion.IFC4; } else { throw new ArgumentException("Invalid or unsupported schema: " + schemaName); } return(modelOptions); }
/// <summary> /// Creates an IFCFile object from an IFC XML file. /// </summary> /// <param name="path">The file path.</param> /// <param name="schemaVersion">The schema version.</param> /// <returns>The IFCFile.</returns> static IFCFile CreateIFCFileFromIFCXML(string path, out IFCSchemaVersion schemaVersion) { IFCFile file = null; string schemaName = null; schemaVersion = IFCSchemaVersion.IFC2x3; // This is an optional location to find the schema name - it may not be supplied. using (XmlReader reader = XmlReader.Create(new StreamReader(path))) { reader.ReadToFollowing("doc:express"); reader.MoveToAttribute("schema_name"); schemaName = reader.Value.Replace(" ", "").Replace("\t", "").Replace("\r", "").Replace("\n", ""); } // This is an alternate location compatible with some MAP ifcXML files. if (string.IsNullOrEmpty(schemaName)) { using (XmlReader reader = XmlReader.Create(new StreamReader(path))) { reader.ReadToFollowing("doc:iso_10303_28"); reader.MoveToAttribute("xmlns:schemaLocation"); int ifcLoc = reader.Value.IndexOf("IFC"); if (ifcLoc >= 0) { string tmpName = reader.Value.Substring(ifcLoc); int ifcEndLoc = tmpName.IndexOf('/'); if (ifcEndLoc > 0) { schemaName = tmpName.Substring(0, ifcEndLoc); } } } } // This checks to see if we have an unsupported IFC2X3_RC1 file. if (string.IsNullOrEmpty(schemaName)) { using (XmlReader reader = XmlReader.Create(new StreamReader(path))) { reader.ReadToFollowing("ex:iso_10303_28"); reader.MoveToAttribute("xmlns:ifc"); int ifcLoc = reader.Value.IndexOf("IFC"); if (ifcLoc >= 0) { schemaName = reader.Value.Substring(ifcLoc); } } } if (!string.IsNullOrEmpty(schemaName)) { IFCFileModelOptions modelOptions = GetIFCFileModelOptions(schemaName, out schemaVersion); file = IFCFile.Create(modelOptions); } if (file == null) { throw new InvalidOperationException("Can't determine XML file schema."); } return(file); }
/// <summary> /// Creates an IFCFile object from a standard IFC file. /// </summary> /// <param name="path">The file path.</param> /// <param name="schemaVersion">The schema version.</param> /// <returns>The IFCFile.</returns> static IFCFile CreateIFCFileFromIFC(string path, out IFCSchemaVersion schemaVersion) { string schemaString = string.Empty; string schemaName = null; using (StreamReader sr = new StreamReader(path)) { string schemaKeyword = "FILE_SCHEMA(("; bool found = false; while (sr.Peek() >= 0) { string lineString = schemaString + sr.ReadLine(); lineString = lineString.Replace(" ", "").Replace("\t", "").Replace("\r", "").Replace("\n", ""); string[] schemaNames = lineString.Split(';'); for (int ii = 0; ii < schemaNames.Length; ii++) { schemaString = schemaNames[ii]; int idx = schemaString.IndexOf(schemaKeyword); int schemaIdxStart = -1; int schemaIdxEnd = -1; if (idx != -1) { idx += schemaKeyword.Length; if (idx < schemaString.Length && schemaString[idx] == '\'') { schemaIdxStart = ++idx; for (; idx < schemaString.Length; idx++) { if (schemaString[idx] == '\'') { schemaIdxEnd = idx; found = true; break; } } } } if (found) { schemaName = schemaString.Substring(schemaIdxStart, schemaIdxEnd - schemaIdxStart); break; } } if (found) { break; } } } IFCFile file = null; schemaVersion = IFCSchemaVersion.IFC2x3; if (!string.IsNullOrEmpty(schemaName)) { IFCFileModelOptions modelOptions = GetIFCFileModelOptions(schemaName, out schemaVersion); file = IFCFile.Create(modelOptions); } return(file); }
/// <summary> /// Sets the schema information for the current export options. This can be overridden. /// </summary> protected virtual IFCFileModelOptions CreateIFCFileModelOptions(ExporterIFC exporterIFC) { IFCFileModelOptions modelOptions = new IFCFileModelOptions(); if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); modelOptions.SchemaName = "IFC2x2_FINAL"; } else if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC4.exp"); modelOptions.SchemaName = "IFC4"; } else { // We leave IFC2x3 as default until IFC4 is finalized and generally supported across platforms. modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); modelOptions.SchemaName = "IFC2x3"; } return modelOptions; }
/// <summary> /// Sets the schema information for the current export options. This can be overridden. /// </summary> protected virtual IFCFileModelOptions CreateIFCFileModelOptions(ExporterIFC exporterIFC) { IFCFileModelOptions modelOptions = new IFCFileModelOptions(); if (exporterIFC.ExportAs2x2) { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); modelOptions.SchemaName = "IFC2x2_FINAL"; } else { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); modelOptions.SchemaName = "IFC2x3"; } return modelOptions; }
/// <summary> /// Gets IFCFileModelOptions from schema name. /// </summary> /// <param name="schemaName">The schema name.</param> /// <param name="schemaVersion">The calculated schema version from the schema name. Default is IFC2x3.</param> /// <returns>The IFCFileModelOptions.</returns> static IFCFileModelOptions GetIFCFileModelOptions(string schemaName, out IFCSchemaVersion schemaVersion) { IFCFileModelOptions modelOptions = new IFCFileModelOptions(); modelOptions.SchemaName = schemaName; schemaVersion = IFCSchemaVersion.IFC2x3; // Default, should be overridden. if (OverrideSchemaFileName != null) { modelOptions.SchemaFile = OverrideSchemaFileName; } else if (string.Compare(schemaName, "IFC2X3", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); schemaVersion = IFCSchemaVersion.IFC2x3; } else if (string.Compare(schemaName, "IFC2X_FINAL", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X_PROXY.exp"); schemaVersion = IFCSchemaVersion.IFC2x; } else if (string.Compare(schemaName, "IFC2X2_FINAL", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); schemaVersion = IFCSchemaVersion.IFC2x2; } else if (string.Compare(schemaName, "IFC4", true) == 0) { modelOptions.SchemaFile = Path.Combine(RevitProgramPath, "EDM\\IFC4.exp"); schemaVersion = IFCSchemaVersion.IFC4; } else throw new ArgumentException("Invalid or unsupported schema: " + schemaName); return modelOptions; }
/// <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) { 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 = new IFCFileModelOptions(); if (exporterIFC.ExportAs2x2) { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); modelOptions.SchemaName = "IFC2x2_FINAL"; } else { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); modelOptions.SchemaName = "IFC2x3"; } m_IfcFile = IFCFile.Create(modelOptions); exporterIFC.SetFile(m_IfcFile); //init common properties ExporterInitializer.InitPropertySets(ExporterCacheManager.ExportOptionsCache.FileVersion); ExporterInitializer.InitQuantities(ExporterCacheManager.ExportOptionsCache.FileVersion, ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities); IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { // create building IFCAnyHandle applicationHandle = CreateApplicationInformation(file, document.Application); CreateGlobalCartesianOrigin(exporterIFC); CreateGlobalDirection(exporterIFC); CreateGlobalDirection2D(exporterIFC); IFCAnyHandle units = CreateDefaultUnits(exporterIFC, document); // Start out relative to nothing, but replace with site later. IFCAnyHandle relativePlacement = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle buildingPlacement = IFCInstanceExporter.CreateLocalPlacement(file, null, relativePlacement); HashSet<IFCAnyHandle> repContexts = CreateContextInformation(exporterIFC, document); IFCAnyHandle ownerHistory = CreateGenericOwnerHistory(exporterIFC, document, applicationHandle); exporterIFC.SetOwnerHistoryHandle(ownerHistory); IFCAnyHandle projectHandle = IFCInstanceExporter.CreateProject(file, ExporterIFCUtils.CreateProjectLevelGUID(document, IFCProjectLevelGUIDType.Project), ownerHistory, null, null, null, null, null, repContexts, units); exporterIFC.SetProject(projectHandle); ProjectInfo projInfo = document.ProjectInformation; string projectAddress = projInfo != null ? projInfo.Address : String.Empty; SiteLocation siteLoc = document.ActiveProjectLocation.SiteLocation; string location = siteLoc != null ? siteLoc.PlaceName : String.Empty; if (projectAddress == null) projectAddress = String.Empty; if (location == null) location = String.Empty; IFCAnyHandle buildingAddress = CreateIFCAddress(file, projectAddress, location); string buildingName = String.Empty; if (projInfo != null) { try { buildingName = projInfo.BuildingName; } catch (Autodesk.Revit.Exceptions.InvalidOperationException) { } } IFCAnyHandle buildingHandle = IFCInstanceExporter.CreateBuilding(file, ExporterIFCUtils.CreateProjectLevelGUID(document, IFCProjectLevelGUIDType.Building), ownerHistory, buildingName, null, null, buildingPlacement, null, buildingName, Toolkit.IFCElementComposition.Element, null, null, buildingAddress); exporterIFC.SetBuilding(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 scaleFactor = exporterIFC.LinearScale; 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, scaleFactor, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo); } 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) { exporterIFC.AddViewIdToExport(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 = elev * scaleFactor; XYZ orig = new XYZ(0.0, 0.0, elevation); IFCAnyHandle axis2Placement3D = ExporterUtil.CreateAxis2Placement3D(file, orig); IFCAnyHandle placement = IFCInstanceExporter.CreateLocalPlacement(file, buildingPlacement, axis2Placement3D); string levelName = level.Name; string levelGUID = LevelUtil.GetLevelGUID(level); IFCAnyHandle buildingStorey = IFCInstanceExporter.CreateBuildingStorey(file, levelGUID, exporterIFC.GetOwnerHistoryHandle(), levelName, null, null, placement, null, levelName, Toolkit.IFCElementComposition.Element, elevation); // If we are using the R2009 Level GUIDs, write it to a shared paramter in the file to ensure that it is preserved. if (ExporterCacheManager.ExportOptionsCache.Use2009BuildingStoreyGUIDs) { string oldLevelGUID; ParameterUtil.GetStringValueFromElement(level, BuiltInParameter.IFC_GUID, out oldLevelGUID); if (String.IsNullOrEmpty(oldLevelGUID)) { ParameterUtil.SetStringParameter(level, BuiltInParameter.IFC_GUID, levelGUID); } } if (prevBuildingStorey == null) { foreach (Level baseLevel in unassignedBaseLevels) { levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, scaleFactor, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, baseLevel.Id, levelInfo); } } prevBuildingStorey = buildingStorey; prevPlacement = placement; prevHeight = height; prevElev = elev; levelInfo = IFCLevelInfo.Create(buildingStorey, placement, height, elev, scaleFactor, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo); // 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, scaleFactor, true); ExporterCacheManager.LevelInfoCache.AddLevelInfo(exporterIFC, level.Id, levelInfo); } ii += coincidentLevels.Count; } transaction.Commit(); } }
/// <summary> /// Sets the schema information for the current export options. This can be overridden. /// </summary> protected virtual IFCFileModelOptions CreateIFCFileModelOptions(ExporterIFC exporterIFC) { IFCFileModelOptions modelOptions = new IFCFileModelOptions(); if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X2_ADD1.exp"); modelOptions.SchemaName = "IFC2x2_FINAL"; } else if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { ExporterCacheManager.ExportOptionsCache.ExportAs4_ADD1 = true; modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC4_ADD1.exp"); // If the IFC4_ADD1 file does not exists it takes the IFC4 file as its default. if (!File.Exists(modelOptions.SchemaFile)) { modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC4.exp"); ExporterCacheManager.ExportOptionsCache.ExportAs4_ADD1 = false; } modelOptions.SchemaName = "IFC4"; } else { // We leave IFC2x3 as default until IFC4 is finalized and generally supported across platforms. modelOptions.SchemaFile = Path.Combine(ExporterUtil.RevitProgramPath, "EDM\\IFC2X3_TC1.exp"); modelOptions.SchemaName = "IFC2x3"; } return modelOptions; }