Can anyone tell me why view port variable always comes back null? The parameters of Viewport.Create are not null.

Can anyone tell me why view port variable always comes back null? The parameters of Viewport.Create are not null.

ed_sa
Enthusiast Enthusiast
2,420 Views
37 Replies
Message 1 of 38

Can anyone tell me why view port variable always comes back null? The parameters of Viewport.Create are not null.

ed_sa
Enthusiast
Enthusiast

using Autodesk.Navisworks.Api;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Document = Autodesk.Revit.DB.Document;
using Transaction = Autodesk.Revit.DB.Transaction;
using View = Autodesk.Revit.DB.View;

namespace RevitAPI_JBA_Development_2022
{
[Transaction(TransactionMode.Manual)]
public class GetDraftViewToSheetElementTransformUtils : IExternalCommand
{
public UIApplication uiApp;
public UIDocument uiDoc;
public Document doc;
public Document externalDoc;
public List<ViewDrafting> draftingViewsFromExternalDoc;
public List<Autodesk.Revit.DB.ViewSheet> sheets;
public ICollection<ElementId> copiedViewElementIds;
SelectDraftingViewForm viewForm;


public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiApp = commandData.Application;
UIDocument uiDoc = uiApp.ActiveUIDocument;
Autodesk.Revit.DB.Document doc = uiDoc.Document;

using (Autodesk.Revit.DB.Transaction docTransaction = new Transaction(doc, "Process Drafting Views"))
{
try
{
docTransaction.Start();
string selectedFilePath = BrowseForFile();
if (selectedFilePath == null)
{
TaskDialog.Show("Message", "Error: File not selected");
return Result.Cancelled;
}

externalDoc = uiApp.Application.OpenDocumentFile(selectedFilePath);
//TaskDialog.Show("Print", $"{externalDoc}");
if (externalDoc == null)
{
TaskDialog.Show("Error", $"Failed to open the external document: {selectedFilePath}");
return Result.Failed;
}

draftingViewsFromExternalDoc = GetDraftingViews(externalDoc);
sheets = GetSheets(doc);

if (draftingViewsFromExternalDoc == null || draftingViewsFromExternalDoc.Count == 0)
{
TaskDialog.Show("Message", "No drafting views found in the external document.");
externalDoc.Close(true);
return Result.Cancelled;
}

// Display a form to select the drafting view
viewForm = new SelectDraftingViewForm(draftingViewsFromExternalDoc, sheets);
if (viewForm.ShowDialog() != DialogResult.OK)
{
externalDoc.Close(false);
return Result.Cancelled;
}

ViewDrafting selectedDraftingView = viewForm.SelectedDraftingView;
//TaskDialog.Show("Print", $"{uiApp}-{doc}-{externalDoc}-{draftingViewsFromExternalDoc}-{viewForm}");
//TaskDialog.Show("Print", $"{externalDoc}");
//TaskDialog.Show("Print", $"{draftingViewsFromExternalDoc}");
if (uiApp != null && doc != null && externalDoc != null && draftingViewsFromExternalDoc != null && viewForm != null && selectedDraftingView != null)
{
try
{
if (uiApp != null && doc != null && externalDoc != null && draftingViewsFromExternalDoc != null && viewForm != null)
{
// Place the selected drafting view onto a new sheet in the current document
ViewSheet selectedSheetImport = PlaceDraftingViewOnSheet(doc, selectedDraftingView);
//TaskDialog.Show("Print", $"{newSheet}");
// Close the external document
//externalDoc.Close(false);

// Update existing elements with imported items if they have the same name
//TaskDialog.Show("Print", "Print TaskDialog number one");
UpdateExistingElements(doc, externalDoc);
//TaskDialog.Show("Print", "Print TaskDialog number two");
docTransaction.Commit();
return Result.Succeeded;
}
else
{
TaskDialog.Show("Error", "One ofthe items is null!");
return Result.Failed;
}
}
catch (Exception ex)
{
if (docTransaction.GetStatus() == TransactionStatus.Started)
{
docTransaction.RollBack();
}
TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
return Result.Failed;
}
}
else
{
TaskDialog.Show("Print", "this is for print");
return Result.Failed;
}
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"Failed to place drafting view on sheet: {ex.Message}");
return Result.Failed;
}
}
}
public GetDraftViewToSheetElementTransformUtils()
{
// Initialize uiApp and uiDoc to null
uiApp = null;
uiDoc = null;
// Initialize other variables
doc = this.doc;
externalDoc = null;
draftingViewsFromExternalDoc = new List<ViewDrafting>();
copiedViewElementIds = new List<ElementId>();
SelectDraftingViewForm viewForm;


}

private string BrowseForFile()
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Revit Files (*.rvt)|*.rvt|All files(*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;

if (openFileDialog.ShowDialog() == DialogResult.OK)
{
return openFileDialog.FileName;
}
else
{
return null;
}
}
}

private List<ViewDrafting> GetDraftingViews(Autodesk.Revit.DB.Document document)
{
return new FilteredElementCollector(document)
.OfClass(typeof(ViewDrafting))
.Cast<ViewDrafting>()
.ToList();
}

public List<ViewSheet> GetSheets(Document doc)
{
return new FilteredElementCollector(doc)
.OfClass(typeof(ViewSheet))
.Cast<ViewSheet>()
.ToList();
}

//Version 1
//private ViewSheet PlaceDraftingViewOnSheet(Document currentDoc, ViewDrafting draftingView)
//{
// if (currentDoc == null || draftingView == null)
// {
// TaskDialog.Show("Error", "Document or DraftingView is null");
// return null;
// }
// try
// {
// // Retrieve the selected sheet from the combo box
// string selectedSheetName = viewForm.sheetComboBox.SelectedItem as string;
// if (string.IsNullOrEmpty(selectedSheetName))
// {
// TaskDialog.Show("Error", "No sheet selected");
// return null;
// }

// // Retrieve the selected sheet from the list of sheets
// ViewSheet selectedSheet = sheets.FirstOrDefault(sheet => sheet.Name == selectedSheetName);
// if (selectedSheet == null)
// {
// TaskDialog.Show("Error", $"Selected sheet '{selectedSheetName}' not found");
// return null;
// }

// // Copy the drafting view to the selected sheet
// ElementId copiedViewElementId = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { draftingView.Id }, currentDoc, null, null).First();
// if (copiedViewElementId == null || copiedViewElementId == ElementId.InvalidElementId)
// {
// TaskDialog.Show("Error", "Failed to copy the drafting view to the sheet");
// return null;
// }

// copiedViewElementIds.Add(copiedViewElementId);

// Element copiedElement = currentDoc.GetElement(copiedViewElementId);
// if (copiedElement is ViewDrafting copiedView)
// {
// // Create a new viewport for the drafting view
// Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, copiedView.Id, XYZ.Zero);
// if (viewport == null)
// {
// TaskDialog.Show("Error", "Failed to create viewport for the drafting view");
// return null;
// }
// }

// return selectedSheet;
// }
// catch (Exception ex)
// {
// TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
// return null;
// }
//}

//Version 2
//private ViewSheet PlaceDraftingViewOnSheet(Document currentDoc, ViewDrafting draftingView)
//{
// if (currentDoc == null || draftingView == null)
// {
// TaskDialog.Show("Error", "Document or DraftingView is null");
// return null;
// }
// try
// {
// // Create a new sheet
// //ViewSheet newSheet = ViewSheet.Create(currentDoc, ElementId.InvalidElementId);
// // Retrieve the list of sheets from the current document
// List<ViewSheet> sheets = new FilteredElementCollector(currentDoc)
// .OfClass(typeof(ViewSheet))
// .Cast<ViewSheet>()
// .ToList();

// if (sheets == null)
// {
// TaskDialog.Show("Error", "Failed to create a new sheet");
// return null;
// }
// //TaskDialog.Show("Print", $"new Sheet{newSheet}");
// // Copy the drafting view to the new sheet
// ElementId copiedViewElementId = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { draftingView.Id }, currentDoc, null, null).First();
// //TaskDialog.Show("Print", $"copied View element Id{copiedViewElementId}");
// if (copiedViewElementId == null || copiedViewElementId == ElementId.InvalidElementId)
// {
// TaskDialog.Show("Error", "Failed to copy the drafting view to the new sheet");
// return null;
// }

// copiedViewElementIds.Add(copiedViewElementId);
// Element copiedElement = currentDoc.GetElement(copiedViewElementId);
// //TaskDialog.Show("Print", $"copied Element{copiedElement}");

// if (copiedElement is ViewDrafting copiedView)
// {
// //TaskDialog.Show("Print", $"{copiedView}-{currentDoc}-{newSheet}much before");

// //TaskDialog.Show("Print", $"{copiedView}-{currentDoc}-{newSheet} Before that");
// try
// {
// //TaskDialog.Show("Print", $"{copiedView}-{currentDoc}-{newSheet} Before it");
// if (copiedView != null && currentDoc != null && newSheet != null)
// {
// Viewport viewport = Viewport.Create(currentDoc, newSheet.Id, copiedView.Id, XYZ.Zero);
// if (viewport == null)
// {
// TaskDialog.Show("Error", "Failed to create viewport for the drafting view");
// return null;
// }
// //TaskDialog.Show("Print", $"{copiedView}-{currentDoc}-{newSheet} Afterwards");
// }
// else
// {
// TaskDialog.Show("Error", "One of the items is null");
// }
// }
// catch (Exception ex)
// {
// TaskDialog.Show("Error", $"{ex.Message}");
// }
// }
// return sheets;

// }
// catch (Exception ex)
// {
// TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
// return null;
// }

//}

//Version 3
private ViewSheet PlaceDraftingViewOnSheet(Document currentDoc, ViewDrafting draftingView)
{
if (currentDoc == null || draftingView == null)
{
TaskDialog.Show("Error", "Document or DraftingView is null");
return null;
}

try
{
// Retrieve the selected sheet from the combo box
string selectedSheetName = viewForm.sheetComboBox.SelectedItem as string;
if (string.IsNullOrEmpty(selectedSheetName))
{
TaskDialog.Show("Error", "No sheet selected");
return null;
}

// Retrieve the selected sheet from the list of sheets
ViewSheet selectedSheet = sheets.FirstOrDefault(sheet => sheet.Name == selectedSheetName);
if (selectedSheet == null)
{
TaskDialog.Show("Error", $"Selected sheet '{selectedSheetName}' not found");
return null;
}

// Copy the drafting view to the selected sheet
ElementId copiedViewElementId = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { draftingView.Id }, currentDoc, null, null).FirstOrDefault();
if (copiedViewElementId == null || copiedViewElementId == ElementId.InvalidElementId)
{
TaskDialog.Show("Error", "Failed to copy the drafting view to the sheet");
return null;
}

copiedViewElementIds.Add(copiedViewElementId);

// Get the copied drafting view element
Element copiedElement = currentDoc.GetElement(copiedViewElementId);
if (copiedElement is ViewDrafting copiedView)
{
// Create a new viewport for the drafting view
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, copiedView.Id, XYZ.Zero);
if (viewport == null)
{
TaskDialog.Show("Error", "Failed to create viewport for the drafting view");
return null;
}

return selectedSheet;
}
else
{
TaskDialog.Show("Error", "Copied element is not a drafting view");
return null;
}
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
return null;
}
}

 

private void UpdateExistingElements(Document currentDoc, Document externalDoc)
{
// List to store names of imported elements from the external document
List<string> importedElementNames = new List<string>();

// Retrieve names of imported elements from external document
foreach (var elementId in copiedViewElementIds)
{
Element importedElement = externalDoc.GetElement(elementId);
if (importedElement != null)
{
string elementName = importedElement.Name;
if (!string.IsNullOrEmpty(elementName))
{
importedElementNames.Add(elementName);
}
}
}

try
{
// Iterate over copied view element IDs
foreach (var importedElementId in copiedViewElementIds)
{
// Retrieve imported element from current document
Element importedElement = currentDoc.GetElement(importedElementId);
if (importedElement != null)
{
string importedElementName = importedElement.Name;
if (!string.IsNullOrEmpty(importedElementName))
{
// Check if imported element name exists in the current document
if (importedElementNames.Contains(importedElementName))
{
// Find existing element with the same name
var existingElement = new FilteredElementCollector(currentDoc)
.WhereElementIsNotElementType()
.FirstOrDefault(e => e.Name == importedElementName);

if (existingElement != null)
{
// Delete existing element
currentDoc.Delete(existingElement.Id);
// Copy imported element to replace existing element
ElementTransformUtils.CopyElement(currentDoc, importedElementId, null);
}
}
else
{
// Check if imported element is a FamilySymbol
FamilySymbol familySymbol = importedElement as FamilySymbol;
if (familySymbol != null)
{
// Duplicate and activate the FamilySymbol
FamilySymbol newSymbol = familySymbol.Duplicate(importedElementName) as FamilySymbol;
newSymbol.Activate();
}
else
{
// Check if imported element is an ElementType
ElementType elementType = importedElement as ElementType;
if (elementType != null)
{
// Duplicate the ElementType
ElementType newType = elementType.Duplicate(importedElementName) as ElementType;
}
}
}
}
}
}
}
catch (Exception ex)
{
// Handle any exceptions that occur during the process
TaskDialog.Show("Error", $"{ex.Message}");
}
}
}
}


//public class SelectDraftingViewForm : System.Windows.Forms.Form
//{
// private System.Windows.Forms.ComboBox comboBox1;
// private Button okButton;
// private Button cancelButton;
// public ViewDrafting SelectedDraftingView { get; private set; }
// public List<ViewDrafting> draftingViewsFromExternalDoc;
// public SelectDraftingViewForm(List<ViewDrafting> draftingViewsFromExternalDoc)
// {
// try
// {
// InitializeComponent();
// this.draftingViewsFromExternalDoc = draftingViewsFromExternalDoc;
// foreach (var draftingView in draftingViewsFromExternalDoc)
// {
// comboBox1.Items.Add(draftingView.Name);
// }
// }
// catch (Exception ex)
// {
// TaskDialog.Show("Error", $"{ex.Message}");
// }

// }

// private void InitializeComponent()
// {
// this.comboBox1 = new System.Windows.Forms.ComboBox();
// this.okButton = new System.Windows.Forms.Button();
// this.cancelButton = new System.Windows.Forms.Button();

// // ComboBox
// this.comboBox1.FormattingEnabled = true;
// this.comboBox1.Location = new System.Drawing.Point(12, 12);
// this.comboBox1.Name = "comboBox1";
// this.comboBox1.Size = new System.Drawing.Size(200, 21);
// this.comboBox1.TabIndex = 0;

// // Ok Button
// this.okButton.Location = new System.Drawing.Point(12, 50);
// this.okButton.Name = "okButton";
// this.okButton.Size = new System.Drawing.Size(75, 23);
// this.okButton.TabIndex = 1;
// this.okButton.Text = "OK";
// this.okButton.UseVisualStyleBackColor = true;
// this.okButton.Click += new System.EventHandler(this.OkButton_Click);

// // Cancel Button
// this.cancelButton.Location = new System.Drawing.Point(137, 50);
// this.cancelButton.Name = "cancelButton";
// this.cancelButton.Size = new System.Drawing.Size(75, 23);
// this.cancelButton.TabIndex = 2;
// this.cancelButton.Text = "Cancel";
// this.cancelButton.UseVisualStyleBackColor = true;
// this.cancelButton.Click += new System.EventHandler(this.CancelButton_Click);

// // Form
// this.ClientSize = new System.Drawing.Size(224, 85);
// this.Controls.Add(this.cancelButton);
// this.Controls.Add(this.okButton);
// this.Controls.Add(this.comboBox1);
// this.Name = "SelectDraftingViewForm";
// this.Text = "Select Drafting View";
// }

 

// private void OkButton_Click(object sender, EventArgs e)
// {
// try
// {
// string selectedDraftingViewName = comboBox1.SelectedItem as string;
// if (!string.IsNullOrEmpty(selectedDraftingViewName) && draftingViewsFromExternalDoc != null)
// {
// SelectedDraftingView = draftingViewsFromExternalDoc
// .FirstOrDefault(view => view.Name == selectedDraftingViewName);
// }
// DialogResult = DialogResult.OK;
// Close();
// }
// catch (Exception ex)
// {
// TaskDialog.Show("Error", $"{ex.Message}");
// }
// }

// private void CancelButton_Click(object sender, EventArgs e)
// {
// DialogResult = DialogResult.Cancel;
// Close();
// }
//}
public class SelectDraftingViewForm : System.Windows.Forms.Form
{
public System.Windows.Forms.ComboBox draftingViewComboBox;
public System.Windows.Forms.ComboBox sheetComboBox;
public Button okButton;
public Button cancelButton;
public ViewDrafting SelectedDraftingView { get; private set; }
public ViewSheet SelectedSheet { get; private set; }
public List<ViewDrafting> importDraftingViewsFromExternalDoc;
public List<ViewSheet> sheets;


public SelectDraftingViewForm(List<ViewDrafting> draftingViewsFromExternalDoc, List<ViewSheet> sheets)
{
try
{
this.importDraftingViewsFromExternalDoc = draftingViewsFromExternalDoc;
this.sheets = sheets;
InitializeComponent();

if (importDraftingViewsFromExternalDoc != null)
{
foreach (var draftingView in importDraftingViewsFromExternalDoc)
{
draftingViewComboBox.Items.Add(draftingView.Name);
}
}

if(sheets!= null)
{
foreach (var sheet in sheets)
{
sheetComboBox.Items.Add(sheet.Name);
}
}
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"{ex.Message}");
}

}

private void InitializeComponent()
{
this.draftingViewComboBox = new System.Windows.Forms.ComboBox();
this.sheetComboBox = new System.Windows.Forms.ComboBox();
this.okButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();

// Drafting View ComboBox
this.draftingViewComboBox.FormattingEnabled = true;
this.draftingViewComboBox.Location = new System.Drawing.Point(12, 12);
this.draftingViewComboBox.Name = "draftingViewComboBox";
this.draftingViewComboBox.Size = new System.Drawing.Size(200, 21);
this.draftingViewComboBox.TabIndex = 0;

// Sheet ComboBox
this.sheetComboBox.FormattingEnabled = true;
this.sheetComboBox.Location = new System.Drawing.Point(12, 40);
this.sheetComboBox.Name = "sheetComboBox";
this.sheetComboBox.Size = new System.Drawing.Size(200, 21);
this.sheetComboBox.TabIndex = 1;

// Ok Button
this.okButton.Location = new System.Drawing.Point(12, 80);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 2;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.OkButton_Click);

// Cancel Button
this.cancelButton.Location = new System.Drawing.Point(137, 80);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 3;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.CancelButton_Click);

// Form
this.ClientSize = new System.Drawing.Size(224, 120);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.okButton);
this.Controls.Add(this.sheetComboBox);
this.Controls.Add(this.draftingViewComboBox);
this.Name = "SelectDraftingViewForm";
this.Text = "Select Drafting View";
}

private void OkButton_Click(object sender, EventArgs e)
{
try
{
string selectedDraftingViewName = draftingViewComboBox.SelectedItem as string;
string selectedSheetName = sheetComboBox.SelectedItem as string;

if (!string.IsNullOrEmpty(selectedDraftingViewName) && !string.IsNullOrEmpty(selectedSheetName))
{
SelectedDraftingView = importDraftingViewsFromExternalDoc
.FirstOrDefault(view => view.Name == selectedDraftingViewName);

SelectedSheet = sheets.FirstOrDefault(sheet => sheet.Name == selectedSheetName);
}

DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"{ex.Message}");
}
}

private void CancelButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}

 

 

0 Likes
2,421 Views
37 Replies
Replies (37)
Message 2 of 38

TripleM-Dev.net
Advisor
Advisor

Hi,

 

I've only looked at the line with "Viewport.Create", it says something about a drafting view.

Are you creating a Viewport of a drafting view?

 

A drafting views needs to contain some geometry, a empty drafting view can't be placed on a sheet.

 

- Michel

 

ps. Use Insert/Edit Code sample button to share code.

Message 3 of 38

ed_sa
Enthusiast
Enthusiast

very nice. I will check on the geometry aspect. Would that have anything to do with XYZ.Zero, is recalculating the xyz a necessity?

0 Likes
Message 4 of 38

ed_sa
Enthusiast
Enthusiast

By the way, they all contained geometry. would a geometry check/match of length and width matter at this point?

0 Likes
Message 5 of 38

TripleM-Dev.net
Advisor
Advisor

The actual draftview needs to have geometry to be placed on a sheet.

Test it in the Revit UI manually, it will give a message that a empty draftview can't be placed.

 

There needs to be a detailline, text or another annotation element on the draftview in order to place it on a sheet.

 

- Michel

0 Likes
Message 6 of 38

TripleM-Dev.net
Advisor
Advisor

What do you mean "They all contained Geometry", the draftviews?

 

Check if the draftview has any elements with FilteredElementCollector and as viewargument the draftview, if it has it's should be good to be placed on a sheet.

0 Likes
Message 7 of 38

ed_sa
Enthusiast
Enthusiast

I mean they all have elements. they're not blank. All you have to do is look at the draft view, I suppose I could run filteredlementcollector, but I assume that would show me the same in numbers.

0 Likes
Message 8 of 38

TripleM-Dev.net
Advisor
Advisor

Are you placing a draftview from one model onto a sheet in another model?

0 Likes
Message 9 of 38

ed_sa
Enthusiast
Enthusiast

exactly right? I open the file browser as it is prompted that collects all draftviews, converts to string puts them on combobox, then does the same for sheets in current document. then I choose which draft view to import along with which sheet to input it to. I calculate the sheet and draft view size to see if they fit, I then input the draft view in the center of the sheet using viewport.create and elementtransformutils.movelement. the latter to make sure the center of the draft view is the same as center of sheet. Then I get this error saying that elementToMove doesn't exist.  Im just now adding a null check for draft view right before the elementTransformUtils.MoveElement in " ElementTransformUtils.MoveElement(currentDoc, draftingView.Id, sheetCenter - CalculateDesiredPositionInView(draftingView));"  Being the case the draft views come from outside , should it make any difference in this? Thank you for very good question. 

0 Likes
Message 10 of 38

ed_sa
Enthusiast
Enthusiast

exactly right I meant. no question mark.

0 Likes
Message 11 of 38

TripleM-Dev.net
Advisor
Advisor

That's not possible, the view for the viewport has to be in the same document as the sheet.

 

As general rule if it's not possible in the Revit UI manually, then it's also not possible in the API.

0 Likes
Message 12 of 38

ed_sa
Enthusiast
Enthusiast

I have to disagree with that last part. First insert from file in the insert tab, does just that, second, adjusting object styles settings collectively is not possible in the UI but it's possible programmatically, I can attest. I think it is possible also based on what you're saying therefore..

0 Likes
Message 13 of 38

TripleM-Dev.net
Advisor
Advisor

Ok, we're getting there. The code you posted is hard to make out due to the large commented sections.

 

You're copying the draftview from one model to another, that's possible.

Next you get the ElementId of the newly created draftview to place on sheet.

All these steps separately are ok, but I don't think they can be combined in one transaction (or the issue is the way the original document is opened)

 

Do all the seperate tasks work (split the code), I think the copying of the draftview and the creation of the viewport need their own transaction. Give them both their own transaction and place those in a Transaction group.

 

0 Likes
Message 14 of 38

ed_sa
Enthusiast
Enthusiast

sounds interesting. Why do you think that would solve the problem?

0 Likes
Message 15 of 38

ed_sa
Enthusiast
Enthusiast

here is my revised code: 

using Autodesk.Navisworks.Api;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Document = Autodesk.Revit.DB.Document;
using Transaction = Autodesk.Revit.DB.Transaction;
using View = Autodesk.Revit.DB.View;

namespace RevitAPI_JBA_Development_2022
{
[Transaction(TransactionMode.Manual)]
public class GetDraftViewToSheetElementTransformUtils : IExternalCommand
{
public UIApplication uiApp;
public UIDocument uiDoc;
public Document doc;
public Document externalDoc;
public List<ViewDrafting> draftingViewsFromExternalDoc;
public List<Autodesk.Revit.DB.ViewSheet> sheets;
public ICollection<ElementId> copiedViewElementIds;
SelectDraftingViewForm viewForm;


public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIApplication uiApp = commandData.Application;
UIDocument uiDoc = uiApp.ActiveUIDocument;
Autodesk.Revit.DB.Document doc = uiDoc.Document;

using (Autodesk.Revit.DB.Transaction docTransaction = new Transaction(doc, "Process Drafting Views"))
{
try
{
docTransaction.Start();
string selectedFilePath = BrowseForFile();
if (selectedFilePath == null)
{
TaskDialog.Show("Message", "Error: File not selected");
return Result.Cancelled;
}
doc.Regenerate();

externalDoc = uiApp.Application.OpenDocumentFile(selectedFilePath);
//TaskDialog.Show("Print", $"{externalDoc}");
if (externalDoc == null)
{
TaskDialog.Show("Error", $"Failed to open the external document: {selectedFilePath}");
return Result.Failed;
}
doc.Regenerate();

draftingViewsFromExternalDoc = GetDraftingViews(externalDoc);
sheets = GetSheets(doc);

if (draftingViewsFromExternalDoc == null || draftingViewsFromExternalDoc.Count == 0)
{
TaskDialog.Show("Message", "No drafting views found in the external document.");
//externalDoc.Close(false);
return Result.Cancelled;
}

// Display a form to select the drafting view
viewForm = new SelectDraftingViewForm(draftingViewsFromExternalDoc, sheets);
if (viewForm.ShowDialog() != DialogResult.OK)
{
externalDoc.Close(false);
return Result.Cancelled;
}

ViewDrafting selectedDraftingView = viewForm.SelectedDraftingView;
//TaskDialog.Show("Print", $"{uiApp}-{doc}-{externalDoc}-{draftingViewsFromExternalDoc}-{viewForm}");
//TaskDialog.Show("Print", $"{externalDoc}");
//TaskDialog.Show("Print", $"{draftingViewsFromExternalDoc}");
if (uiApp != null && doc != null && externalDoc != null && draftingViewsFromExternalDoc != null && viewForm != null && selectedDraftingView != null)
{
try
{
if (uiApp != null && doc != null && externalDoc != null && draftingViewsFromExternalDoc != null && viewForm != null)
{
// Place the selected drafting view onto a new sheet in the current document
ViewSheet selectedSheetImport = PlaceDraftingViewOnSheet(doc, selectedDraftingView, viewForm, sheets);
//TaskDialog.Show("Print", $"{newSheet}");
// Close the external document
//externalDoc.Close(false);
doc.Regenerate();
// Update existing elements with imported items if they have the same name
//TaskDialog.Show("Print", "Print TaskDialog number one");
UpdateExistingElements(doc, externalDoc);
//TaskDialog.Show("Print", "Print TaskDialog number two");
docTransaction.Commit();
return Result.Succeeded;
}
else
{
TaskDialog.Show("Error", "One ofthe items is null!");
return Result.Failed;
}
}
catch (Exception ex)
{
if (docTransaction.GetStatus() == TransactionStatus.Started)
{
docTransaction.RollBack();
}
TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
return Result.Failed;
}
}
else
{
TaskDialog.Show("Print", "this is for print");
return Result.Failed;
}
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"Failed to place drafting view on sheet: {ex.Message}");
return Result.Failed;
}
}
}
public GetDraftViewToSheetElementTransformUtils()
{
// Initialize uiApp and uiDoc to null
uiApp = null;
uiDoc = null;
// Initialize other variables
//doc = this.doc;
externalDoc = null;
draftingViewsFromExternalDoc = new List<ViewDrafting>();
copiedViewElementIds = new List<ElementId>();
SelectDraftingViewForm viewForm;


}

private string BrowseForFile()
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Revit Files (*.rvt)|*.rvt|All files(*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;

if (openFileDialog.ShowDialog() == DialogResult.OK)
{
return openFileDialog.FileName;
}
else
{
return null;
}
}
}

private List<ViewDrafting> GetDraftingViews(Autodesk.Revit.DB.Document document)
{
return new FilteredElementCollector(document)
.OfClass(typeof(ViewDrafting))
.Cast<ViewDrafting>()
.ToList();
}

public List<ViewSheet> GetSheets(Document doc)
{
return new FilteredElementCollector(doc)
.OfClass(typeof(ViewSheet))
.Cast<ViewSheet>()
.ToList();
}

//Version 3
//private ViewSheet PlaceDraftingViewOnSheet(Document currentDoc, ViewDrafting draftingView)
//{
// if (currentDoc == null || draftingView == null)
// {
// TaskDialog.Show("Error", "Document or DraftingView is null");
// return null;
// }

// try
// {
// // Retrieve the selected sheet from the combo box
// string selectedSheetName = viewForm.sheetComboBox.SelectedItem as string;
// if (string.IsNullOrEmpty(selectedSheetName))
// {
// TaskDialog.Show("Error", "No sheet selected");
// return null;
// }

// // Retrieve the selected sheet from the list of sheets
// ViewSheet selectedSheet = sheets.FirstOrDefault(sheet => sheet.Name == selectedSheetName);
// if (selectedSheet == null)
// {
// TaskDialog.Show("Error", $"Selected sheet '{selectedSheetName}' not found");
// return null;
// }

// // Validate the sheet and drafting view dimensions
// if (!ValidateSheetAndDraftingView(selectedSheet, draftingView))
// {
// return null; // Validation failed
// }

// ElementId copiedViewElementId = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { draftingView.Id }, currentDoc, null, null).FirstOrDefault();
// if (copiedViewElementId == null || copiedViewElementId == ElementId.InvalidElementId)
// {
// TaskDialog.Show("Error", "Failed to copy the drafting view to the sheet");
// return null;
// }

// copiedViewElementIds.Add(copiedViewElementId);

// // Get the copied drafting view element
// Element copiedElement = currentDoc.GetElement(copiedViewElementId);
// if (copiedElement is ViewDrafting copiedView && draftingView != null)
// {
// // Calculate the center point of the sheet
// XYZ sheetCenter = CalculateSheetCenter(selectedSheet);

// // Place the drafting view at the center of the sheet
// ElementTransformUtils.MoveElement(currentDoc, draftingView.Id, sheetCenter - CalculateDesiredPositionInView(draftingView));

// currentDoc.Regenerate();//Ensure model updates before creating viewport
// // Create a new viewport for the drafting view
// Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, copiedView.Id, sheetCenter);
// if (viewport == null)
// {
// TaskDialog.Show("Error", "Failed to create viewport for the drafting view");
// return null;
// }

// return selectedSheet;
// }
// else
// {
// TaskDialog.Show("Error", "Copied element is not a drafting view");
// return null;
// }
// }
// catch (Exception ex)
// {
// TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
// return null;
// }
//}

//Version 4
private ViewSheet PlaceDraftingViewOnSheet(Document currentDoc, ViewDrafting draftingView, SelectDraftingViewForm viewForm, List<ViewSheet> sheets)
{
// Check if the required parameters are null
if (currentDoc == null || draftingView == null || viewForm == null || sheets == null)
{
TaskDialog.Show("Error", "One or more required parameters is null");
return null;
}

try
{
// Retrieve the selected sheet name from the combo box
string selectedSheetName = viewForm.sheetComboBox.SelectedItem as string;
if (string.IsNullOrEmpty(selectedSheetName))
{
TaskDialog.Show("Error", "No sheet selected");
return null;
}

// Retrieve the selected sheet from the list of sheets
ViewSheet selectedSheet = sheets.FirstOrDefault(sheet => sheet.Name == selectedSheetName);
if (selectedSheet == null)
{
TaskDialog.Show("Error", $"Selected sheet '{selectedSheetName}' not found");
return null;
}

// Validate the sheet and drafting view dimensions
if (!ValidateSheetAndDraftingView(selectedSheet, draftingView))
{
return null; // Validation failed
}

// Copy the drafting view to the current document
ElementId copiedViewElementId = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { draftingView.Id }, currentDoc, null, null).FirstOrDefault();
if (copiedViewElementId == null || copiedViewElementId == ElementId.InvalidElementId)
{
TaskDialog.Show("Error", "Failed to copy the drafting view to the sheet");
return null;
}

// Store the copied view element ID for later use
copiedViewElementIds.Add(copiedViewElementId);

// Get the copied drafting view element
Element copiedElement = currentDoc.GetElement(copiedViewElementId);
if (copiedElement is ViewDrafting copiedView)
{
if(copiedView != null)
{
// Calculate the center point of the sheet
XYZ sheetCenter = CalculateSheetCenter(selectedSheet);

// Calculate the desired position of the drafting view within the sheet
XYZ desiredPositionInView = CalculateDesiredPositionInView(draftingView);

// Move the drafting view to the calculated position within the sheet
ElementTransformUtils.MoveElement(currentDoc, copiedView.Id, sheetCenter - desiredPositionInView);

currentDoc.Regenerate(); // Ensure model updates before creating viewport

// Create a new viewport for the drafting view
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, copiedView.Id, sheetCenter);
if (viewport == null)
{
TaskDialog.Show("Error", "Failed to create viewport for the drafting view !");
return null;
}

// Return the selected sheet
return selectedSheet;
}
else
{
TaskDialog.Show("Error", "One of the items is null");
return null;
}

}
else
{
TaskDialog.Show("Error", "Copied element is not a drafting view");
return null;
}
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
return null;
}
}


private XYZ CalculateDesiredPositionInView(ViewDrafting draftingView)
{
// Example: Calculate the center point of the drafting view
BoundingBoxUV outline = draftingView.Outline;
UV minPoint = outline.Min;
UV maxPoint = outline.Max;
XYZ viewCenter = new XYZ((minPoint.U + maxPoint.U) / 2, (minPoint.V + maxPoint.V) / 2, 0);
return viewCenter;
}

private XYZ CalculateSheetCenter(ViewSheet sheet)
{
// Retrieve the outline of the sheet
BoundingBoxUV outline = sheet.Outline;

// Calculate the center point of the sheet
UV minPoint = outline.Min;
UV maxPoint = outline.Max;
XYZ sheetCenter = new XYZ((minPoint.U + maxPoint.U) / 2, (minPoint.V + maxPoint.V) / 2, 0);

return sheetCenter;
}

private double GetSheetWidth(ViewSheet sheet)
{
// Retrieve the width of the sheet from its BoundingBox
BoundingBoxUV boundingBox = sheet.Outline;
return boundingBox.Max.U - boundingBox.Min.U;
}

private double GetSheetLength(ViewSheet sheet)
{
// Retrieve the length of the sheet from its BoundingBox
BoundingBoxUV boundingBox = sheet.Outline;
return boundingBox.Max.V - boundingBox.Min.V;
}

private double GetDraftingViewWidth(ViewDrafting draftingView)
{
// Retrieve the width of the drafting view from its BoundingBox
BoundingBoxUV boundingBox = draftingView.Outline;
return boundingBox.Max.U - boundingBox.Min.U;
}

private double GetDraftingViewLength(ViewDrafting draftingView)
{
// Retrieve the length of the drafting view from its BoundingBox
BoundingBoxUV boundingBox = draftingView.Outline;
return boundingBox.Max.V - boundingBox.Min.V;
}

private bool ValidateSheetAndDraftingView(ViewSheet sheet, ViewDrafting draftingView)
{
// Retrieve dimensions of the sheet and drafting view
double sheetWidth = GetSheetWidth(sheet);
double sheetLength = GetSheetLength(sheet);
double draftingViewWidth = GetDraftingViewWidth(draftingView);
double draftingViewLength = GetDraftingViewLength(draftingView);

// Check if the drafting view fits within the sheet boundaries
if (draftingViewWidth <= sheetWidth && draftingViewLength <= sheetLength)
{
return true; // Validation successful
}
else
{
TaskDialog.Show("Validation Error", "Drafting view dimensions exceed sheet boundaries.");
return false; // Validation failed
}
}

private void UpdateExistingElements(Document currentDoc, Document externalDoc)
{
// List to store names of imported elements from the external document
List<string> importedElementNames = new List<string>();

// Retrieve names of imported elements from external document
foreach (var elementId in copiedViewElementIds)
{
Element importedElement = externalDoc.GetElement(elementId);
if (importedElement != null)
{
string elementName = importedElement.Name;
if (!string.IsNullOrEmpty(elementName))
{
importedElementNames.Add(elementName);
}
}
}

try
{
// Iterate over copied view element IDs
foreach (var importedElementId in copiedViewElementIds)
{
// Retrieve imported element from current document
Element importedElement = currentDoc.GetElement(importedElementId);
if (importedElement != null)
{
string importedElementName = importedElement.Name;
if (!string.IsNullOrEmpty(importedElementName))
{
// Check if imported element name exists in the current document
if (importedElementNames.Contains(importedElementName))
{
// Find existing element with the same name
var existingElement = new FilteredElementCollector(currentDoc)
.WhereElementIsNotElementType()
.FirstOrDefault(e => e.Name == importedElementName);

if (existingElement != null)
{
// Delete existing element
currentDoc.Delete(existingElement.Id);
// Copy imported element to replace existing element
ElementTransformUtils.CopyElement(currentDoc, importedElementId, null);
}
}
else
{
// Check if imported element is a FamilySymbol
FamilySymbol familySymbol = importedElement as FamilySymbol;
if (familySymbol != null)
{
// Duplicate and activate the FamilySymbol
FamilySymbol newSymbol = familySymbol.Duplicate(importedElementName) as FamilySymbol;
newSymbol.Activate();
}
else
{
// Check if imported element is an ElementType
ElementType elementType = importedElement as ElementType;
if (elementType != null)
{
// Duplicate the ElementType
ElementType newType = elementType.Duplicate(importedElementName) as ElementType;
}
}
}
}
}
}
}
catch (Exception ex)
{
// Handle any exceptions that occur during the process
TaskDialog.Show("Error", $"{ex.Message}");
}
}
}
}

public class SelectDraftingViewForm : System.Windows.Forms.Form
{
public System.Windows.Forms.ComboBox draftingViewComboBox;
public System.Windows.Forms.ComboBox sheetComboBox;
public Button okButton;
public Button cancelButton;
public ViewDrafting SelectedDraftingView { get; private set; }
public ViewSheet SelectedSheet { get; private set; }
public List<ViewDrafting> importDraftingViewsFromExternalDoc;
public List<ViewSheet> sheets;


public SelectDraftingViewForm(List<ViewDrafting> draftingViewsFromExternalDoc, List<ViewSheet> sheets)
{
try
{
this.importDraftingViewsFromExternalDoc = draftingViewsFromExternalDoc;
this.sheets = sheets;
InitializeComponent();

if (importDraftingViewsFromExternalDoc != null)
{
foreach (var draftingView in importDraftingViewsFromExternalDoc)
{
draftingViewComboBox.Items.Add(draftingView.Name);
}
}

if(sheets!= null)
{
foreach (var sheet in sheets)
{
sheetComboBox.Items.Add(sheet.Name);
}
}
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"{ex.Message}");
}

}

private void InitializeComponent()
{
this.draftingViewComboBox = new System.Windows.Forms.ComboBox();
this.sheetComboBox = new System.Windows.Forms.ComboBox();
this.okButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();

// Drafting View ComboBox
this.draftingViewComboBox.FormattingEnabled = true;
this.draftingViewComboBox.Location = new System.Drawing.Point(12, 12);
this.draftingViewComboBox.Name = "draftingViewComboBox";
this.draftingViewComboBox.Size = new System.Drawing.Size(200, 21);
this.draftingViewComboBox.TabIndex = 0;

// Sheet ComboBox
this.sheetComboBox.FormattingEnabled = true;
this.sheetComboBox.Location = new System.Drawing.Point(12, 40);
this.sheetComboBox.Name = "sheetComboBox";
this.sheetComboBox.Size = new System.Drawing.Size(200, 21);
this.sheetComboBox.TabIndex = 1;

// Ok Button
this.okButton.Location = new System.Drawing.Point(12, 80);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 2;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.OkButton_Click);

// Cancel Button
this.cancelButton.Location = new System.Drawing.Point(137, 80);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 3;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.CancelButton_Click);

// Form
this.ClientSize = new System.Drawing.Size(224, 120);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.okButton);
this.Controls.Add(this.sheetComboBox);
this.Controls.Add(this.draftingViewComboBox);
this.Name = "SelectDraftingViewForm";
this.Text = "Select Drafting View";
}

private void OkButton_Click(object sender, EventArgs e)
{
try
{
string selectedDraftingViewName = draftingViewComboBox.SelectedItem as string;
string selectedSheetName = sheetComboBox.SelectedItem as string;

if (!string.IsNullOrEmpty(selectedDraftingViewName) && !string.IsNullOrEmpty(selectedSheetName))
{
SelectedDraftingView = importDraftingViewsFromExternalDoc
.FirstOrDefault(view => view.Name == selectedDraftingViewName);

SelectedSheet = sheets.FirstOrDefault(sheet => sheet.Name == selectedSheetName);
}

DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"{ex.Message}");
}
}

private void CancelButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}

 

 

0 Likes
Message 16 of 38

ed_sa
Enthusiast
Enthusiast

nevermind, disregard that. just the comment section remove it my bad. I can't delete it.

0 Likes
Message 17 of 38

TripleM-Dev.net
Advisor
Advisor

For some tasks Revit needs to refresh the database, and that's only possible after a transaction.

Transactiongroup is not needed, but makes the handling as one function (undo for user) else the addin will create 2 steps, one for each transaction.

 

I don't know if this solves it.

Does the CopyElements itself work, does the Draftview show up in the document?

0 Likes
Message 18 of 38

ed_sa
Enthusiast
Enthusiast

for database regeneration I have doc.Regenerate() I hope thats working. it seems to . for copyElements it does work, because the copiedViewElementId variable is not null when debugging. Please run this code on your side, it's applicable, see if you get the error, just copy paste shouldn't be an issue. 

0 Likes
Message 19 of 38

ed_sa
Enthusiast
Enthusiast

this is where I get the error: // Create a new viewport for the drafting view
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, copiedView.Id, sheetCenter);
if (viewport == null)
{
TaskDialog.Show("Error", "Failed to create viewport for the drafting view !");
return null;
} viewport comes back null. It might be a revit api permissions thing. the draftview is imported just fine, and all argument for Viewport.Create are not null, place a breakpoint there and tell me what you get. I think two transactions within the execute method might solve the issue. 

0 Likes
Message 20 of 38

TripleM-Dev.net
Advisor
Advisor

Hi,

 

The copiedViewElementIds variable is never initialized, I changed into a List and initialized it.

Futher I also then get the error on the Creation of viewport, the Draftview exists in the model but is empty, it didn't copy it's content.

 

It's possible the view itself only gets copied and not it's content.

The error of the Viewport would then be because it's empty.

 

Maybe You also need to copy the content over from the other model?

0 Likes