/// <summary> /// Creates an IFCImportFile from a file on the disk. /// </summary> /// <param name="ifcFilePath">The path of the file.</param> /// <param name="options">The IFC import options.</param> /// <param name="doc">The optional document argument. If importing into Revit, not supplying a document may reduce functionality later.</param> /// <returns>The IFCImportFile.</returns> public static IFCImportFile Create(string ifcFilePath, IFCImportOptions options, Document doc) { m_sIFCImportFile = new IFCImportFile(); bool success = TheFile.Process(ifcFilePath, options, doc); if (success) { // Store the original levels in the template file for Open IFC. On export, we will delete these levels if we created any. // Note that we always have to preserve one level, regardless of what the ActiveView is. // TODO: Only for open, not import. if (doc != null) { IFCBuildingStorey.ExistingLevelIdToReuse = ElementId.InvalidElementId; View activeView = doc.ActiveView; if (activeView != null) { Level genLevel = activeView.GenLevel; if (genLevel != null) { IFCBuildingStorey.ExistingLevelIdToReuse = genLevel.Id; } } FilteredElementCollector levelCollector = new FilteredElementCollector(doc); ICollection <Element> levels = levelCollector.OfClass(typeof(Level)).ToElements(); ICollection <ElementId> levelIdsToDelete = new HashSet <ElementId>(); foreach (Element level in levels) { if (IFCBuildingStorey.ExistingLevelIdToReuse == ElementId.InvalidElementId) { IFCBuildingStorey.ExistingLevelIdToReuse = level.Id; } else if (level.Id != IFCBuildingStorey.ExistingLevelIdToReuse) { levelIdsToDelete.Add(level.Id); } } doc.Delete(levelIdsToDelete); // Collect material names, to avoid reusing. FilteredElementCollector materialCollector = new FilteredElementCollector(doc); ICollection <Element> materials = materialCollector.OfClass(typeof(Material)).ToElements(); foreach (Element materialAsElem in materials) { Material material = materialAsElem as Material; IFCMaterialInfo info = IFCMaterialInfo.Create(material.Color, material.Transparency, material.Shininess, material.Smoothness, material.Id); Importer.TheCache.CreatedMaterials.Add(material.Name, info); } } } else { // Close up the log file, set m_sIFCImportFile to null. TheFile.Close(); } return(m_sIFCImportFile); }
/// <summary> /// The main entry point into the .NET IFC import code /// </summary> /// <param name="importer">The internal ImporterIFC class that contains information necessary for the import process.</param> public void ImportIFC(ImporterIFC importer) { TheImporter = this; IDictionary <String, String> options = importer.GetOptions(); TheOptions = m_ImportOptions = IFCImportOptions.Create(options); // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it. try { string fullIFCFileName = importer.FullFileName; if (!TheOptions.ForceImport && !NeedsReload(importer.Document, fullIFCFileName)) { return; } // Clear the category mapping table, to force reload of options. IFCCategoryUtil.Clear(); if (TheOptions.Intent != IFCImportIntent.Reference) { IFCImportFile.Import(importer); } else { ReferenceIFC(importer.Document, fullIFCFileName, options); } } catch (Exception ex) { if (Importer.TheLog != null) { Importer.TheLog.LogError(-1, ex.Message, false); } // The following message can sometimes occur when reloading some IFC files // from external resources. In this case, we should silently fail, and not // throw. if (!ex.Message.Contains("Starting a new transaction is not permitted")) { throw; } } finally { if (Importer.TheLog != null) { Importer.TheLog.Close(); } if (IFCImportFile.TheFile != null) { IFCImportFile.TheFile.Close(); } } }
/// <summary> /// The main entry point into the .NET IFC import code /// </summary> /// <param name="importer">The internal ImporterIFC class that contains information necessary for the import process.</param> public void ImportIFC(ImporterIFC importer) { TheImporter = this; IDictionary <String, String> options = importer.GetOptions(); TheOptions = m_ImportOptions = IFCImportOptions.Create(options); // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it. try { string fullFileName = importer.FullFileName; string revitFileName = IFCImportFile.GetRevitFileName(fullFileName); if (!TheOptions.ForceImport && !NeedsReload(fullFileName, revitFileName)) { return; } // Clear the category mapping table, to force reload of options. IFCCategoryUtil.Clear(); if (TheOptions.Intent != IFCImportIntent.Reference) { IFCImportFile.Import(importer); } else { ReferenceIFC(importer.Document, fullFileName, options); } } catch (Exception ex) { if (Importer.TheLog != null) { Importer.TheLog.LogError(-1, ex.Message, false); } } finally { if (Importer.TheLog != null) { Importer.TheLog.Close(); } if (IFCImportFile.TheFile != null) { IFCImportFile.TheFile.Close(); } } }
/// <summary> /// Allow for the creation of an Importer class for external API use. /// </summary> /// <param name="originalDocument">The document to import into.</param> /// <param name="ifcFileName">The name of the IFC file.</param> /// <param name="importOptions">The import options associated with this Importer.</param> /// <returns>The Importer class.</returns> public static Importer CreateImporter(Document originalDocument, string ifcFileName, IDictionary <string, string> importOptions) { if (originalDocument == null || ifcFileName == null || importOptions == null) { return(null); } Importer importer = new Importer(); TheImporter = importer; TheCache = IFCImportCache.Create(originalDocument, ifcFileName); TheOptions = importer.m_ImportOptions = IFCImportOptions.Create(importOptions); TheLog = IFCImportLog.CreateLog(ifcFileName, "log.html", !TheOptions.DisableLogging); return(importer); }
private bool Process(string ifcFilePath, IFCImportOptions options, Document doc) { TheFileName = ifcFilePath; TheBrepCounter = 0; try { IFCSchemaVersion schemaVersion; m_IfcFile = CreateIFCFile(ifcFilePath, out schemaVersion); SchemaVersion = schemaVersion; } catch (Exception ex) { Importer.TheLog.LogError(-1, "There was an error reading the IFC file: " + ex.Message + ". Aborting import.", false); return(false); } Options = options; // The DirectShapeLibrary must be reset to potentially remove stale pointers from the last use. Document = doc; ShapeLibrary = DirectShapeLibrary.GetDirectShapeLibrary(doc); ShapeLibrary.Reset(); bool readFile = ProcessFile(ifcFilePath); if (!readFile) { return(false); } m_Transaction = new Transaction(doc); bool success = true; switch (options.Intent) { case IFCImportIntent.Reference: success = ProcessReference(); break; } if (success) { StoreIFCCreatorInfo(m_IfcFile, doc.ProjectInformation); } return(success); }
/// <summary> /// Creates an IFCImportFile from a file on the disk. /// </summary> /// <param name="ifcFilePath">The path of the file.</param> /// <param name="options">The IFC import options.</param> /// <param name="doc">The optional document argument. If importing into Revit, not supplying a document may reduce functionality later.</param> /// <returns>The IFCImportFile.</returns> public static IFCImportFile Create(string ifcFilePath, IFCImportOptions options, Document doc) { m_sIFCImportFile = new IFCImportFile(); bool success = TheFile.Process(ifcFilePath, options, doc); if (success) { // Store the original levels in the template file for Open IFC. On export, we will delete these levels if we created any. // Note that we always have to preserve one level, regardless of what the ActiveView is. if (doc != null) { IFCBuildingStorey.ExistingLevelIdToReuse = ElementId.InvalidElementId; View activeView = doc.ActiveView; if (activeView != null) { Level genLevel = activeView.GenLevel; if (genLevel != null) { IFCBuildingStorey.ExistingLevelIdToReuse = genLevel.Id; } } // For Link IFC, we will delete any unused levels at the end. Instead, we want to try to reuse them. // The for loop does a little unnecessary work if deleteLevelsNow, but the performance implications are very small. bool deleteLevelsNow = (Importer.TheOptions.Action != IFCImportAction.Link); FilteredElementCollector levelCollector = new FilteredElementCollector(doc); ICollection <Element> levels = levelCollector.OfClass(typeof(Level)).ToElements(); ICollection <ElementId> levelIdsToDelete = new HashSet <ElementId>(); foreach (Element level in levels) { if (level == null) { continue; } if (IFCBuildingStorey.ExistingLevelIdToReuse == ElementId.InvalidElementId) { IFCBuildingStorey.ExistingLevelIdToReuse = level.Id; } else if (level.Id != IFCBuildingStorey.ExistingLevelIdToReuse) { levelIdsToDelete.Add(level.Id); } } if (deleteLevelsNow) { doc.Delete(levelIdsToDelete); } // Collect material names, to avoid reusing. FilteredElementCollector materialCollector = new FilteredElementCollector(doc); ICollection <Element> materials = materialCollector.OfClass(typeof(Material)).ToElements(); foreach (Element materialAsElem in materials) { Material material = materialAsElem as Material; IFCMaterialInfo info = IFCMaterialInfo.Create(material.Color, material.Transparency, material.Shininess, material.Smoothness, material.Id); Importer.TheCache.CreatedMaterials.Add(material.Name, info); } } } else { // Close up the log file, set m_sIFCImportFile to null. TheFile.Close(); } return(m_sIFCImportFile); }
/// <summary> /// Creates an IFCImportFile from a file on the disk. /// </summary> /// <param name="ifcFilePath">The path of the file.</param> /// <param name="options">The IFC import options.</param> /// <param name="doc">The optional document argument. If importing into Revit, not supplying a document may reduce functionality later.</param> /// <returns>The IFCImportFile.</returns> public static IFCImportFile Create(string ifcFilePath, IFCImportOptions options, Document doc) { m_sIFCImportFile = new IFCImportFile(); bool success = TheFile.Process(ifcFilePath, options, doc); if (success) { // Store the original levels in the template file for Open IFC. On export, we will delete these levels if we created any. // Note that we always have to preserve one level, regardless of what the ActiveView is. // TODO: Only for open, not import. if (doc != null) { IFCBuildingStorey.ExistingLevelIdToReuse = ElementId.InvalidElementId; View activeView = doc.ActiveView; if (activeView != null) { Level genLevel = activeView.GenLevel; if (genLevel != null) IFCBuildingStorey.ExistingLevelIdToReuse = genLevel.Id; } FilteredElementCollector levelCollector = new FilteredElementCollector(doc); ICollection<Element> levels = levelCollector.OfClass(typeof(Level)).ToElements(); ICollection<ElementId> levelIdsToDelete = new HashSet<ElementId>(); foreach (Element level in levels) { if (IFCBuildingStorey.ExistingLevelIdToReuse == ElementId.InvalidElementId) IFCBuildingStorey.ExistingLevelIdToReuse = level.Id; else if (level.Id != IFCBuildingStorey.ExistingLevelIdToReuse) levelIdsToDelete.Add(level.Id); } doc.Delete(levelIdsToDelete); // Collect material names, to avoid reusing. FilteredElementCollector materialCollector = new FilteredElementCollector(doc); ICollection<Element> materials = materialCollector.OfClass(typeof(Material)).ToElements(); foreach (Element materialAsElem in materials) { Material material = materialAsElem as Material; IFCMaterialInfo info = IFCMaterialInfo.Create(material.Color, material.Transparency, material.Shininess, material.Smoothness, material.Id); Importer.TheCache.CreatedMaterials.Add(material.Name, info); } } } else { // Close up the log file, set m_sIFCImportFile to null. TheFile.Close(); } return m_sIFCImportFile; }
/// <summary> /// The main entry point into the .NET IFC import code /// </summary> /// <param name="importer">The internal ImporterIFC class that contains information necessary for the import process.</param> public void ImportIFC(ImporterIFC importer) { TheImporter = this; IDictionary<String, String> options = importer.GetOptions(); TheOptions = m_ImportOptions = IFCImportOptions.Create(options); // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it. try { string fullFileName = importer.FullFileName; string revitFileName = IFCImportFile.GetRevitFileName(fullFileName); if (!TheOptions.ForceImport && !NeedsReload(fullFileName, revitFileName)) return; // Clear the category mapping table, to force reload of options. IFCCategoryUtil.Clear(); if (TheOptions.Intent != IFCImportIntent.Reference) { IFCImportFile.Import(importer); } else { ReferenceIFC(importer.Document, fullFileName, options); } } catch (Exception ex) { if (Importer.TheLog != null) Importer.TheLog.LogError(-1, ex.Message, false); } finally { if (Importer.TheLog != null) Importer.TheLog.Close(); if (IFCImportFile.TheFile != null) IFCImportFile.TheFile.Close(); } }
private bool Process(string ifcFilePath, IFCImportOptions options, Document doc) { // Manually set to false if necessary for debugging. CleanEntitiesAfterCreate = true; TheFileName = ifcFilePath; TheBrepCounter = 0; Log = IFCImportLog.CreateLog(ifcFilePath + ".log.html"); try { IFCSchemaVersion schemaVersion; m_IfcFile = CreateIFCFile(ifcFilePath, out schemaVersion); SchemaVersion = schemaVersion; } catch (Exception ex) { Log.LogError(-1, "There was an error reading the IFC file: " + ex.Message + ". Aborting import.", false); return false; } Options = options; Document = doc; ShapeLibrary = DirectShapeLibrary.GetDirectShapeLibrary(doc); ShapeLibrary.Reset(); IFCFileReadOptions readOptions = new IFCFileReadOptions(); readOptions.FileName = ifcFilePath; readOptions.XMLConfigFileName = Path.Combine(RevitProgramPath, "EDM\\ifcXMLconfiguration.xml"); int numErrors = 0; int numWarnings = 0; try { Importer.TheCache.StatusBar.Set(String.Format(Resources.IFCReadingFile, TheFileName)); m_IfcFile.Read(readOptions, out numErrors, out numWarnings); } catch (Exception ex) { Log.LogError(-1, "There was an error reading the IFC file: " + ex.Message + ". Aborting import.", false); return false; } if (numErrors > 0 || numWarnings > 0) { if (numErrors > 0) { if (numWarnings > 0) Log.LogError(-1, "There were " + numErrors + " errors and " + numWarnings + " reading the IFC file. Please look at the log information at the end of this report for more information.", false); else Log.LogError(-1, "There were " + numErrors + " errors reading the IFC file. Please look at the log information at the end of this report for more information.", false); } else { Log.LogWarning(-1, "There were " + numWarnings + " warnings reading the IFC file. Please look at the log information at the end of this report for more information.", false); } } m_Transaction = new Transaction(doc); switch (options.Intent) { case IFCImportIntent.Reference: InitializeOpenTransaction("Open IFC Reference File"); //If there is more than one project, we will be ignoring all but the first one. IList<IFCAnyHandle> projects = IFCImportFile.TheFile.GetInstances(IFCEntityType.IfcProject, false); if (projects.Count == 0) { Log.LogError(-1, "There were no IfcProjects found in the file. Aborting import.", false); return false; } else IFCProject.ProcessIFCProject(projects[0]); break; } return true; }
private bool Process(string ifcFilePath, IFCImportOptions options, Document doc) { TheFileName = ifcFilePath; TheBrepCounter = 0; try { IFCSchemaVersion schemaVersion; m_IfcFile = CreateIFCFile(ifcFilePath, out schemaVersion); SchemaVersion = schemaVersion; } catch (Exception ex) { Importer.TheLog.LogError(-1, "There was an error reading the IFC file: " + ex.Message + ". Aborting import.", false); return false; } Options = options; // The DirectShapeLibrary must be reset to potentially remove stale pointers from the last use. Document = doc; ShapeLibrary = DirectShapeLibrary.GetDirectShapeLibrary(doc); ShapeLibrary.Reset(); bool readFile = ProcessFile(ifcFilePath); if (!readFile) return false; m_Transaction = new Transaction(doc); switch (options.Intent) { case IFCImportIntent.Reference: return ProcessReference(); } return true; }
private bool Process(string ifcFilePath, IFCImportOptions options, Document doc) { // Manually set to false if necessary for debugging. CleanEntitiesAfterCreate = true; TheFileName = ifcFilePath; TheBrepCounter = 0; Log = IFCImportLog.CreateLog(ifcFilePath + ".log.html"); try { IFCSchemaVersion schemaVersion; m_IfcFile = CreateIFCFile(ifcFilePath, out schemaVersion); SchemaVersion = schemaVersion; } catch (Exception ex) { Log.LogError(-1, "There was an error reading the IFC file: " + ex.Message + ". Aborting import.", false); return(false); } Options = options; Document = doc; ShapeLibrary = DirectShapeLibrary.GetDirectShapeLibrary(doc); ShapeLibrary.Reset(); IFCFileReadOptions readOptions = new IFCFileReadOptions(); readOptions.FileName = ifcFilePath; readOptions.XMLConfigFileName = Path.Combine(RevitProgramPath, "EDM\\ifcXMLconfiguration.xml"); int numErrors = 0; int numWarnings = 0; try { Importer.TheCache.StatusBar.Set(String.Format(Resources.IFCReadingFile, TheFileName)); m_IfcFile.Read(readOptions, out numErrors, out numWarnings); } catch (Exception ex) { Log.LogError(-1, "There was an error reading the IFC file: " + ex.Message + ". Aborting import.", false); return(false); } if (numErrors > 0 || numWarnings > 0) { if (numErrors > 0) { if (numWarnings > 0) { Log.LogError(-1, "There were " + numErrors + " errors and " + numWarnings + " reading the IFC file. Please look at the log information at the end of this report for more information.", false); } else { Log.LogError(-1, "There were " + numErrors + " errors reading the IFC file. Please look at the log information at the end of this report for more information.", false); } } else { Log.LogWarning(-1, "There were " + numWarnings + " warnings reading the IFC file. Please look at the log information at the end of this report for more information.", false); } } m_Transaction = new Transaction(doc); switch (options.Intent) { case IFCImportIntent.Reference: InitializeOpenTransaction("Open IFC Reference File"); //If there is more than one project, we will be ignoring all but the first one. IList <IFCAnyHandle> projects = IFCImportFile.TheFile.GetInstances(IFCEntityType.IfcProject, false); if (projects.Count == 0) { Log.LogError(-1, "There were no IfcProjects found in the file. Aborting import.", false); return(false); } else { IFCProject.ProcessIFCProject(projects[0]); } break; } return(true); }
public void ImportIFC(ImporterIFC importer) { TheImporter = this; IDictionary<String, String> options = importer.GetOptions(); TheOptions = m_ImportOptions = IFCImportOptions.Create(options); // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it. try { string revitFileName = IFCImportFile.GetRevitFileName(importer.FullFileName); if (!TheOptions.ForceImport && !NeedsReload(importer.FullFileName, revitFileName)) return; // Clear the category mapping table, to force reload of options. IFCCategoryUtil.Clear(); if (TheOptions.Intent != IFCImportIntent.Reference) { IFCImportFile.Import(importer); } else { Document originalDocument = importer.Document; Document ifcDocument = null; if (TheOptions.Action == IFCImportAction.Link) { string linkedFileName = IFCImportFile.GetRevitFileName(importer.FullFileName); ifcDocument = LoadOrCreateLinkDocument(originalDocument, linkedFileName); if (ifcDocument == null) return; } else ifcDocument = originalDocument; bool useCachedRevitFile = DocumentUpToDate(ifcDocument, importer.FullFileName); // In the case where the document is already opened as a link, but it has been updated on disk, // give the user a warning and use the cached value. if (!useCachedRevitFile && ifcDocument.IsLinked) { useCachedRevitFile = true; Importer.AddDelayedLinkError(BuiltInFailures.ImportFailures.IFCCantUpdateLinkedFile); } if (!useCachedRevitFile) { m_ImportCache = IFCImportCache.Create(ifcDocument, importer.FullFileName); // Limit creating the cache to Link, but may either remove limiting or make it more restrict (reload only) later. if (TheOptions.Action == IFCImportAction.Link) TheCache.CreateExistingElementMaps(ifcDocument); // TheFile will contain the same value as the return value for this function. IFCImportFile.Create(importer.FullFileName, m_ImportOptions, ifcDocument); } if (useCachedRevitFile || IFCImportFile.TheFile != null) { if (IFCImportFile.TheFile != null) { if (IFCImportFile.TheFile.IFCProject != null) IFCObjectDefinition.CreateElement(ifcDocument, IFCImportFile.TheFile.IFCProject); IFCImportFile.TheFile.EndImport(ifcDocument, importer.FullFileName); } if (TheOptions.Action == IFCImportAction.Link) { // If we have an original Revit link file name, don't create a new RvtLinkSymbol - // we will use the existing one. bool useExistingType = (TheOptions.RevitLinkFileName != null); IFCImportFile.LinkInFile(importer.FullFileName, ifcDocument, originalDocument, useExistingType, !useCachedRevitFile); } } m_ImportCache.Reset(ifcDocument); } } catch (Exception ex) { if (IFCImportFile.TheFile != null) IFCImportFile.TheFile.Log.LogError(-1, ex.Message, false); } finally { if (IFCImportFile.TheFile != null) IFCImportFile.TheFile.Close(); } }
public void ImportIFC(ImporterIFC importer) { TheImporter = this; IDictionary <String, String> options = importer.GetOptions(); TheOptions = m_ImportOptions = IFCImportOptions.Create(options); // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it. try { string revitFileName = IFCImportFile.GetRevitFileName(importer.FullFileName); if (!TheOptions.ForceImport && !NeedsReload(importer.FullFileName, revitFileName)) { return; } // Clear the category mapping table, to force reload of options. IFCCategoryUtil.Clear(); if (TheOptions.Intent != IFCImportIntent.Reference) { IFCImportFile.Import(importer); } else { Document originalDocument = importer.Document; Document ifcDocument = null; if (TheOptions.Action == IFCImportAction.Link) { string linkedFileName = IFCImportFile.GetRevitFileName(importer.FullFileName); ifcDocument = LoadOrCreateLinkDocument(originalDocument, linkedFileName); if (ifcDocument == null) { return; } } else { ifcDocument = originalDocument; } bool useCachedRevitFile = DocumentUpToDate(ifcDocument, importer.FullFileName); // In the case where the document is already opened as a link, but it has been updated on disk, // give the user a warning and use the cached value. if (!useCachedRevitFile && ifcDocument.IsLinked) { useCachedRevitFile = true; Importer.AddDelayedLinkError(BuiltInFailures.ImportFailures.IFCCantUpdateLinkedFile); } if (!useCachedRevitFile) { m_ImportCache = IFCImportCache.Create(ifcDocument, importer.FullFileName); // Limit creating the cache to Link, but may either remove limiting or make it more restrict (reload only) later. if (TheOptions.Action == IFCImportAction.Link) { TheCache.CreateExistingElementMaps(ifcDocument); } // TheFile will contain the same value as the return value for this function. IFCImportFile.Create(importer.FullFileName, m_ImportOptions, ifcDocument); } if (useCachedRevitFile || IFCImportFile.TheFile != null) { if (IFCImportFile.TheFile != null) { if (IFCImportFile.TheFile.IFCProject != null) { IFCObjectDefinition.CreateElement(ifcDocument, IFCImportFile.TheFile.IFCProject); } IFCImportFile.TheFile.EndImport(ifcDocument, importer.FullFileName); } if (TheOptions.Action == IFCImportAction.Link) { // If we have an original Revit link file name, don't create a new RvtLinkSymbol - // we will use the existing one. bool useExistingType = (TheOptions.RevitLinkFileName != null); IFCImportFile.LinkInFile(importer.FullFileName, ifcDocument, originalDocument, useExistingType, !useCachedRevitFile); } } m_ImportCache.Reset(ifcDocument); } } catch (Exception ex) { if (IFCImportFile.TheFile != null) { IFCImportFile.TheFile.Log.LogError(-1, ex.Message, false); } } finally { if (IFCImportFile.TheFile != null) { IFCImportFile.TheFile.Close(); } } }