/// <summary> /// Links in a Revit File or files /// using a Dialog box within the active document; /// pins the instance of the Revit Link Origin-to-Origin automatically. /// Returns the name of the main file which should be used for Copy-Monitoriing etc /// </summary> /// <param name="doc">Active Document</param> public static ElementId CreateLinkRevit(this Document doc) { // Ask the user which links they would like to add to the project // Call the ShowDialog method to show the dialog box filtered to show only Revit Projects // Choose the main link to base the document on for Copy-Monitoring TaskDialog td_mainrvtlnk = TaskDialogUtil.Create("Main Revit Link", "Select the link which should be used to set up Grids and Levels for Copy Monitoring", TaskDialogIcon.TaskDialogIconNone); OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = false; ofd.Filter = "Revit Documents|*.rvt"; TaskDialog td_addtlrvtlnk = TaskDialogUtil.Create("Additional Revit Links", "Select any additional links which should be added to the project", TaskDialogIcon.TaskDialogIconNone); OpenFileDialog ofd2 = new OpenFileDialog(); ofd2.Multiselect = true; ofd2.Filter = "Revit Documents|*.rvt"; td_mainrvtlnk.Show(); DialogResult dr = ofd.ShowDialog(); //If the user clicks ok - record the name of main RVT Link if (dr == System.Windows.Forms.DialogResult.OK || dr == DialogResult.Cancel) { //Add the link selected to a list for later string lnk_cm = ofd.FileName; td_addtlrvtlnk.Show(); DialogResult dr2 = ofd2.ShowDialog(); //If the user clicks ok - continue if (dr2 == System.Windows.Forms.DialogResult.OK || dr2 == DialogResult.Cancel) { //Link in the revit files //Add the links selected to a list List <string> rvtfiles = new List <string>(); rvtfiles.Add(ofd.FileName); foreach (string x in ofd2.FileNames) { rvtfiles.Add(x); } InstanceMaker(doc, rvtfiles); } } // Gets the elementID of the link you want for copy-monitoring ElementId cm_linkid = RevitLinkType.GetTopLevelLink(doc, ModelPathUtils.ConvertUserVisiblePathToModelPath(ofd.FileName)); return(cm_linkid); }
/// <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); }