/// <summary> /// Link in the new created document to parent document. /// </summary> /// <param name="baseFileName">The full path to the IFC file.</param> /// <param name="ifcDocument">The newly imported IFC file document.</param> /// <param name="originalDocument">The document to contain the IFC link.</param> /// <param name="useExistingType">True if the RevitLinkType already exists.</param> /// <param name="doSave">True if we should save the document. This should only be false if we are reusing a cached document.</param> /// <returns>The element id of the RevitLinkType for this link operation.</returns> public static ElementId LinkInFile(string baseFileName, Document ifcDocument, Document originalDocument, bool useExistingType, bool doSave) { bool saveSucceded = true; string fileName = GenerateRevitFileName(baseFileName); if (doSave) { SaveAsOptions saveAsOptions = new SaveAsOptions(); saveAsOptions.OverwriteExistingFile = true; try { ifcDocument.SaveAs(fileName, saveAsOptions); } catch (Exception ex) { // We still want to close the document to prevent having a corrupt model in memory. Importer.TheLog.LogError(-1, ex.Message, false); saveSucceded = false; } } if (!ifcDocument.IsLinked) { ifcDocument.Close(false); } ElementId revitLinkTypeId = ElementId.InvalidElementId; if (!saveSucceded) { return(revitLinkTypeId); } bool doReloadFrom = useExistingType && !Importer.TheOptions.CreateLinkInstanceOnly; if (Importer.TheOptions.RevitLinkFileName != null) { FilePath originalRevitFilePath = new FilePath(Importer.TheOptions.RevitLinkFileName); revitLinkTypeId = RevitLinkType.GetTopLevelLink(originalDocument, originalRevitFilePath); } if (!doReloadFrom) { Transaction linkTransaction = new Transaction(originalDocument); linkTransaction.Start(Resources.IFCLinkFile); try { if (revitLinkTypeId == ElementId.InvalidElementId) { RevitLinkOptions options = new RevitLinkOptions(true); RevitLinkLoadResult loadResult = RevitLinkType.CreateFromIFC(originalDocument, baseFileName, fileName, false, options); if ((loadResult != null) && (loadResult.ElementId != ElementId.InvalidElementId)) { revitLinkTypeId = loadResult.ElementId; } } if (revitLinkTypeId != ElementId.InvalidElementId) { RevitLinkInstance.Create(originalDocument, revitLinkTypeId); } Importer.PostDelayedLinkErrors(originalDocument); linkTransaction.Commit(); } catch (Exception ex) { linkTransaction.RollBack(); throw ex; } } else // reload from { // For the reload from case, we expect the transaction to have been created in the UI. if (revitLinkTypeId != ElementId.InvalidElementId) { RevitLinkType existingRevitLinkType = originalDocument.GetElement(revitLinkTypeId) as RevitLinkType; if (existingRevitLinkType != null) { existingRevitLinkType.UpdateFromIFC(originalDocument, baseFileName, fileName, false); } } } return(revitLinkTypeId); }
/// <summary> /// Link in the new created document to parent document. /// </summary> /// <param name="originalIFCFileName">The full path to the original IFC file. Same as baseLocalFileName if the IFC file is not on a server.</param> /// <param name="baseLocalFileName">The full path to the IFC file on disk.</param> /// <param name="ifcDocument">The newly imported IFC file document.</param> /// <param name="originalDocument">The document to contain the IFC link.</param> /// <param name="useExistingType">True if the RevitLinkType already exists.</param> /// <param name="doSave">True if we should save the document. This should only be false if we are reusing a cached document.</param> /// <returns>The element id of the RevitLinkType for this link operation.</returns> public static ElementId LinkInFile(string originalIFCFileName, string baseLocalFileName, Document ifcDocument, Document originalDocument, bool useExistingType, bool doSave) { bool saveSucceded = true; string fileName = GenerateRevitFileName(baseLocalFileName); if (doSave) { SaveAsOptions saveAsOptions = new SaveAsOptions(); saveAsOptions.OverwriteExistingFile = true; try { ifcDocument.SaveAs(fileName, saveAsOptions); } catch { saveSucceded = false; } if (!saveSucceded) { try { string tempPathDir = Path.GetTempPath(); string fileNameOnly = Path.GetFileName(fileName); string intermediateFileName = tempPathDir + fileNameOnly; ifcDocument.SaveAs(tempPathDir + fileNameOnly, saveAsOptions); File.Copy(intermediateFileName, fileName); Application application = ifcDocument.Application; ifcDocument.Close(false); ifcDocument = application.OpenDocumentFile(fileName); File.Delete(intermediateFileName); saveSucceded = true; } catch (Exception ex) { // We still want to close the document to prevent having a corrupt model in memory. saveSucceded = false; Importer.TheLog.LogError(-1, ex.Message, false); } } } if (!ifcDocument.IsLinked) { ifcDocument.Close(false); } ElementId revitLinkTypeId = ElementId.InvalidElementId; if (!saveSucceded) { return(revitLinkTypeId); } bool doReloadFrom = useExistingType && !Importer.TheOptions.CreateLinkInstanceOnly; if (Importer.TheOptions.RevitLinkFileName != null) { FilePath originalRevitFilePath = new FilePath(Importer.TheOptions.RevitLinkFileName); revitLinkTypeId = RevitLinkType.GetTopLevelLink(originalDocument, originalRevitFilePath); } ModelPath path = ModelPathUtils.ConvertUserVisiblePathToModelPath(originalIFCFileName); // Relative path type only works if the model isn't in the cloud. As such, we'll try again if the // routine returns an exception. ExternalResourceReference ifcResource = null; for (int ii = 0; ii < 2; ii++) { PathType pathType = (ii == 0) ? PathType.Relative : PathType.Absolute; try { ifcResource = ExternalResourceReference.CreateLocalResource(originalDocument, ExternalResourceTypes.BuiltInExternalResourceTypes.IFCLink, path, pathType); break; } catch { ifcResource = null; } } if (ifcResource == null) { Importer.TheLog.LogError(-1, "Couldn't create local IFC cached file. Aborting import.", true); } if (!doReloadFrom) { Transaction linkTransaction = new Transaction(originalDocument); linkTransaction.Start(Resources.IFCLinkFile); try { if (revitLinkTypeId == ElementId.InvalidElementId) { RevitLinkOptions options = new RevitLinkOptions(true); LinkLoadResult loadResult = RevitLinkType.CreateFromIFC(originalDocument, ifcResource, fileName, false, options); if ((loadResult != null) && (loadResult.ElementId != ElementId.InvalidElementId)) { revitLinkTypeId = loadResult.ElementId; } } if (revitLinkTypeId != ElementId.InvalidElementId) { RevitLinkInstance.Create(originalDocument, revitLinkTypeId); } Importer.PostDelayedLinkErrors(originalDocument); linkTransaction.Commit(); } catch (Exception ex) { linkTransaction.RollBack(); throw ex; } } else // reload from { // For the reload from case, we expect the transaction to have been created in the UI. if (revitLinkTypeId != ElementId.InvalidElementId) { RevitLinkType existingRevitLinkType = originalDocument.GetElement(revitLinkTypeId) as RevitLinkType; if (existingRevitLinkType != null) { existingRevitLinkType.UpdateFromIFC(originalDocument, ifcResource, fileName, false); } } } return(revitLinkTypeId); }