Not able to add views on sheet correctly - viewport

Not able to add views on sheet correctly - viewport

Anonymous
Not applicable
3,198 Views
16 Replies
Message 1 of 17

Not able to add views on sheet correctly - viewport

Anonymous
Not applicable

Good afternoon all,

 

I'm trying to create a viewport on a sheet by adding the view on a sheet but the code doesn't seem to be working for me. Because whenever I run the code the Viewport.CanAddViewToSheet() method returns false. I'm not sure what I'm doing wrong.  Here's the code below, would appreciate any help.

 

 

        public static void MoveViewOnSheet(View view, Sheet sheet, Document doc)
        {
            var revitView = doc.GetElement(view.ElementID) as ViewPlan;
            var revitSheet = doc.GetElement(sheet.ElementID) as ViewSheet;

            // Map the view on sheet
            using (Transaction transaction = new Transaction(doc, "Mapping views on sheet"))
            {
                if (Viewport.CanAddViewToSheet(doc, revitSheet.Id, revitView.Id))
                {
                    transaction.Start();
                    Viewport.Create(doc, revitSheet.Id, revitView.Id, XYZ.Zero);
                    transaction.Commit();
                }
            }
        }

 

0 Likes
3,199 Views
16 Replies
Replies (16)
Message 2 of 17

aignatovich
Advisor
Advisor

Hi!

 

There are some strange things in your code, do you use your own wrappers for RevitAPI classes? Are you sure, that all ok on your code?

1) what is Sheet class?

2) Element has ElementId property, not ElementID, so again what is View in your case. It is not Autodesk.Revit.DB.View

And the second thing: Revit does not allow to add view to more than one sheet. If it is already added, Viewport.CanAddViewToSheet will return false

Message 3 of 17

Anonymous
Not applicable

@aignatovich thanks for replying. The view and sheet are the custom classes that I have created which have ElementID as a property and with some other properties too. 

 




And the second thing: Revit does not allow to add view to more than one sheet. If it is already added, Viewport.CanAddViewToSheet will return false

I understood your point so, my question is how can we determine on which sheet the view is added and how can we delete it. So, we could add the view to our desired sheet.

 

 

 

0 Likes
Message 4 of 17

aignatovich
Advisor
Advisor

You can use FilteredElementCollector to find all Viewports in project, and check ViewId and SheetId properties:

LookupViewports.png

Message 5 of 17

Anonymous
Not applicable

@aignatovich thank you again for replying. As the matter of fact, I tried already. But still, the solution doesn't seem to be working for me. Here's the code that I've used to find the appropriate viewpoint, delete it and then adding a view to the desired sheet. But still, I'm facing the same problem, the Viewport.CanAddViewToSheet() returns false.

Can you spot the error?

 

 

        public static void MoveViewOnSheet(View view, Sheet sheet, Document doc)
        {
            var revitView = doc.GetElement(view.ElementID) as ViewPlan;
            var revitSheet = doc.GetElement(sheet.ElementID) as ViewSheet;


            foreach (Viewport vp in (new FilteredElementCollector(doc).OfClass(typeof(Viewport))))
            {
               
                // Get those viewport which matches the viewid
                if (vp.ViewId.ToString().Contains(revitView.Id.ToString()))
                {
                    // Delete the viewport
                    using (Transaction transaction = new Transaction(doc, "Remove viewport"))
                    {
                        transaction.Start();
                        doc.Delete(vp.Id);
                        transaction.Commit();
                    }
                }
            }




            // Map the view on sheet
            using (Transaction transaction = new Transaction(doc, "Mapping views on sheet"))
            {
                if (Viewport.CanAddViewToSheet(doc, revitSheet.Id, revitView.Id))
                {
                    transaction.Start();
                    Viewport.Create(doc, revitSheet.Id, revitView.Id, XYZ.Zero);
                    transaction.Commit();
                }
            }
        }

 

0 Likes
Message 6 of 17

aignatovich
Advisor
Advisor

It seems, that it should not work at all if the view already placed due to changing the collection while enumerating.

The second problem is your element id comparison, just test vp.ViewId == revitView.Id

0 Likes
Message 7 of 17

aignatovich
Advisor
Advisor

I also tried to reproduce in simplified way what you want to achieve with Revit Python shell code. The code below recreates delete and re-creates selected viewport in XYZ.Zero position:

 

viewport = selection[0] # you should select viewport before running this code

viewId = viewport.ViewId
sheetId = viewport.SheetId

tx = Transaction(doc, "recreate viewport")
tx.Start()

doc.Delete(viewport.Id)

doc.Regenerate()

print Viewport.CanAddViewToSheet(doc, sheetId, viewId) #reports true

Viewport.Create(doc, sheetId, viewId, XYZ.Zero)

tx.Commit()

This works without problems

Message 8 of 17

Anonymous
Not applicable

@aignatovich thank you again for looking into the code. 

 

 


The second problem is your element id comparison, just test vp.ViewId == revitView.Id


I changed the code and replaced the string comparison with the vp.ViewId == revitView.Id. But still, it wasn't able to find a viewpoint that holds the reference of revitView.

 

 

 

0 Likes
Message 9 of 17

Anonymous
Not applicable

the code is simple, I'm afraid it won't work with my scenario. I need to find that viewport first which holds the reference of revitview. But when the run the code, it doesn't find the viewport with revit-view. Further when I tried to add that revitview in a new sheet, the Viewport.CanAddViewToSheet() returns false. 

I'm not able to find the error and that's bugging me so much. Can you share your opinion on how can I fix it?

0 Likes
Message 10 of 17

aignatovich
Advisor
Advisor

Try something like this:

def FindViewPlan():
	col = FilteredElementCollector(doc)
	return filter(lambda x: x.Name == "Level 1", col.OfClass(ViewPlan))[0]
	
def FindViewSheet():
	col = FilteredElementCollector(doc)
	return filter(lambda x: x.Name == "My new view", col.OfClass(ViewSheet))[0]
	
def FindViewport(viewId):
	col = FilteredElementCollector(doc)
	viewports = filter(lambda x: x.ViewId == viewId, col.OfClass(Viewport))
	if viewports.Count == 1:
		return viewports[0]
	else:
		return None
		
viewPlan = FindViewPlan()

viewport = FindViewport(viewPlan.Id)

tx = Transaction(doc, "recreate viewport")
tx.Start()

if viewport != None:
	doc.Delete(viewport.Id)
	doc.Regenerate()
	
Viewport.Create(doc, FindViewSheet().Id, viewPlan.Id, XYZ.Zero)

tx.Commit()
Message 11 of 17

Anonymous
Not applicable

@aignatovich I really appreciate your support in helping me on this. The code you've written is very good. I simulate the same in C#, when I run the code, the program doesn't able to find a viewport that holds the reference of the revit-view. 

I crossed checked the revitview (which is ViewPlan) and revitSheet (which is ViewSheet) everything seems fine. But I'm not sure if there is no such viewport with revitview reference, then why the program doesn't allow me to add revitview on a sheet. why the Viewport.CanAddViewtoSheet() returns false. 

 

Here's the updated code, I hope you'll suggest me something else that I'm missing.

 

 

        public static Viewport FindViewPort(ViewPlan viewPlan, Document doc)
        {
            var col = new FilteredElementCollector(doc);

            return col.OfClass(typeof(Viewport))
                        .Where(vp => ((Viewport)vp).ViewId == viewPlan.Id)
                          .Select(vp => (Viewport)vp)
                            .FirstOrDefault();
        }

        public static void MoveViewOnSheet(View view, Sheet sheet, Document doc)
        {
            var revitView = doc.GetElement(view.ElementID) as ViewPlan;
            var revitSheet = doc.GetElement(sheet.ElementID) as ViewSheet;

            // Find the viewPort which has the RevitViewID
            var vp = FindViewPort(revitView, doc);
            if (vp != null)
            {
                // Delete the viewport
                using (Transaction transaction = new Transaction(doc, "Remove viewport"))
                {
                    transaction.Start();
                    doc.Delete(vp.Id);
                    transaction.Commit();
                }
            }

            // Map the view on sheet
            using (Transaction transaction = new Transaction(doc, "Mapping views on sheet"))
            {
                if (Viewport.CanAddViewToSheet(doc, revitSheet.Id, revitView.Id))
                {
                    transaction.Start();
                    Viewport.Create(doc, revitSheet.Id, revitView.Id, XYZ.Zero);
                    transaction.Commit();
                }
            }
        }

 

0 Likes
Message 12 of 17

aignatovich
Advisor
Advisor

This is C# code, that do the same as Iron Python script above:

[Transaction(TransactionMode.Manual)]
public class MoveViewToSheetCommand : IExternalCommand
{
	public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
	{
		var uiapp = commandData.Application;
		var uidoc = uiapp.ActiveUIDocument;
		var doc = uidoc.Document;

		var viewPlan = FindView<ViewPlan>(doc, "Level 1");

		var viewSheet = FindView<ViewSheet>(doc, "My new view");

		using (var transaction = new Transaction(doc, "move view to sheet"))
		{
			transaction.Start();

			var viewport = FindViewPort(doc, viewPlan.Id);

			if (viewport != null)
			{
				doc.Delete(viewport.Id);

				doc.Regenerate();
			}

			if (Viewport.CanAddViewToSheet(doc, viewSheet.Id, viewPlan.Id))
				Viewport.Create(doc, viewSheet.Id, viewPlan.Id, XYZ.Zero);

			transaction.Commit();
		}

		return Result.Succeeded;
	}

	private static View FindView<T>(Document document, string name) where T: View
	{
		var collector = new FilteredElementCollector(document);

		return collector
			.OfClass(typeof (T))
			.OfType<T>()
			.FirstOrDefault(x => x.Name == name);
	}

	private static Viewport FindViewPort(Document document, ElementId viewId)
	{
		var collector = new FilteredElementCollector(document);

		return collector
			.OfClass(typeof (Viewport))
			.OfType<Viewport>()
			.FirstOrDefault(x => x.ViewId == viewId);
	}
}
Message 13 of 17

Anonymous
Not applicable

@aignatovich I feel awkward that I'm bugging you again on this. But I don't have much choice but to seek your advice. 

I ran your code, it didn't work. Please see the image below, when I run the code I was able to get the reference of viewplan and viewsheet. So, I ran further to find the viewport but the program returns null. I ran further and the Viewport.CanAddViewToSheet() returns false. I'm not sure why it returns false when the program returns no viewport associated with the viewplan in the first place. 

 

I really appreciate your support. Thank you

 

error.PNG

0 Likes
Message 14 of 17

aignatovich
Advisor
Advisor

To run the code you need to have plan view named "Level 1" and view sheet named "My new view"

var viewPlan = FindView<ViewPlan>(doc, "Level 1");
var viewSheet = FindView<ViewSheet>(doc, "My new view");

Try to run and debug your code in very simple environment, e.g. in empty project with view plan and view sheet. Try to add view to your sheet via UI, may be there is something, that prevents Revit to do this. May be your view is not added to any sheets, but cannot be added to your sheet for some reason

Message 15 of 17

aignatovich
Advisor
Advisor

It seems, that in worksharing environment, when viewsheet workset is not editable Viewport.CanAddViewToSheet reports false, but you still can add this view via Viewport.Create

Message 16 of 17

Anonymous
Not applicable

@aignatovich thank you very much for helping me out on this, I'll see why the API not allowing me to add a view on the sheet. Will share the solution, once i found it. 

0 Likes
Message 17 of 17

FlorisvdG
Advocate
Advocate

Any news on this? Having Similar Problems. Would love to hear from you.

0 Likes