change viewport type via API

change viewport type via API

MuirEng
Collaborator Collaborator
1,850 Views
12 Replies
Message 1 of 13

change viewport type via API

MuirEng
Collaborator
Collaborator

Hello, I am trying to write a utility that capable of changing viewport type from one custom type to another. The basic idea is to track down specific views that are drawn NTS and set them to a type that does not display the scale. 


In order to understand what parameters I am dealing with I wrote a simple dynamo script to pull out all the parameters of a viewport and after some experimentation I discovered that manipulating Viewport Type ID works. 

So now I can set the viewport type but I'm doing it by stuffing in the type ID, which is a cryptic value (1809505) and I really should be referencing the name of the custom type (in my case "Title, No Scale, Line") to make this code robust and modifyable. 

Can anyone give me a hint here about how to do this, or even basic information about the object used for custom types (which so far I haven't identified in the API reference) will be helpful. 

thank you. 

thanks. 


Brian Muir, P.Eng, Muir Engineering
0 Likes
1,851 Views
12 Replies
Replies (12)
Message 2 of 13

jeremy_tammik
Alumni
Alumni

Would this give you what you need?

   

FilteredElementCollector
  + WhereElementIsElementType
  + OfClass view type
  + Where name == "Title, No Scale, Line"

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 13

MuirEng
Collaborator
Collaborator

thanks, I'll see what I can do with this when I can come back to it. 
in Dyanamo I can't find a category "View Type". When I isolate the element that appears to correlate to this view type and run it through element.type I get a null. I run the element through element.parameters and I clearly this is the view type but the Family Name reads: Viewport. This is all a bit confusing. I believe there is an object class View Type and these are assigned to Viewports, is that right? 

 

Brian Muir, P.Eng, Muir Engineering
0 Likes
Message 4 of 13

MuirEng
Collaborator
Collaborator

Still stuck...
this code: 

var viewTypes = new FilteredElementCollector(doc)
.WhereElementIsElementType()
.OfClass(typeof(View))
.Cast<View>();

// Diagnostic: List all view types
StringBuilder viewTypeNames = new StringBuilder("Available View Types:\n");
foreach (var viewType in viewTypes)
{
viewTypeNames.AppendLine(viewType.Name);
}
TaskDialog.Show("View Types Diagnostic", viewTypeNames.ToString());

 

returns nothing.

The API documentation discusses view types but not this correlation between the view and the view title which seems to be defined in the property Type ID

Further guidance appreciated!

 

 

Brian Muir, P.Eng, Muir Engineering
0 Likes
Message 5 of 13

naveen.kumar.t
Autodesk Support
Autodesk Support

Hi @MuirEng ,

 

Could you kindly review the attached screenshot?

If your goal is to collect the viewport types mentioned in the screenshot, please use the code provided below.

 

IEnumerable<ElementType> ViewportTypes = new FilteredElementCollector(doc).OfClass(typeof(ElementType)).Cast<ElementType>().Where(q => q.FamilyName == "Viewport");

Autodesk.Revit.DB.Reference viewportRef = uidoc.Selection.PickObject(ObjectType.Element, "Select a ViewPort");
Viewport viewport = doc.GetElement(viewportRef) as Viewport;
if (viewport != null)
{
    using (Transaction transaction = new Transaction(doc, "Change Viewport Type"))
    {
        transaction.Start();
        viewport.ChangeTypeId(ViewportTypes.First().Id);
        transaction.Commit();
    }
}

 

If this is not the case, please clarify the issue you're facing with the screenshot so I can assist you further.


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 6 of 13

MuirEng
Collaborator
Collaborator

Hi Naveen, did you look at the opening post on this conversation?
As explained, my basic goal is that I want to change the view title assigned to a view, but now we are into specific diagnostics where I'm trying to understand what objects and properties are involved in this.

I know that viewport Type ID is a key, and that this represents an element but I'm having trouble pulling this element out from the view type name, in my case "Title, Scale, No Line" 


Brian Muir, P.Eng, Muir Engineering
0 Likes
Message 7 of 13

naveen.kumar.t
Autodesk Support
Autodesk Support

Hi @MuirEng ,

 

I’m having difficulty understanding what you're trying to achieve.
Could you please explain the issue with a screenshot or a short video?


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 8 of 13

MuirEng
Collaborator
Collaborator

Sorry, I think my original post is reasonable clear.

I've retreated to providing our users with a tool that will warn our users if a drafting report has a view title assigned with a scale and for now given up on the idea of changing the view title programmatically, so I've moved on to other things. Thanks for trying to help. 

Brian Muir, P.Eng, Muir Engineering
0 Likes
Message 9 of 13

BriCircuitBIM
Explorer
Explorer

Hi Brian,

Your initial post and follow-up responses highlight a common challenge in Revit API programming: understanding the relationship between viewports, view types, and title types. Let me clarify this for you and provide actionable advice based on your goal.


Clarifying Viewport, View Type, and Title Type

  1. Viewport Type:

    • Each viewport placed on a sheet is an instance of a Viewport system family.
    • Viewports have a type ID, which refers to the viewport type (e.g., "Title, No Scale, Line"). These types define how the title is displayed, including parameters like line visibility and scale display.
  2. View Type:

    • The view type (ViewType.FloorPlan, ViewType.Legend, etc.) is a property of the view associated with the viewport. It describes the kind of view (floor plan, legend, section, etc.) but is unrelated to the viewport's title or appearance.
  3. Title Type:

    • The title type (referenced via the viewport's ELEM_TYPE_PARAM) is what controls the viewport's title behavior and visual style. This is the parameter you're trying to modify programmatically.

Addressing Your Goal

If your goal is to change the viewport type based on the view title name (e.g., "Title, No Scale, Line"), here's how you can proceed:

1. Retrieve Viewport Types Programmatically

The key is to work with ElementType objects within the OST_ViewportLabel category, which represents viewport title types:

// Retrieve all viewport types (family symbols) in the project
FilteredElementCollector collector = new FilteredElementCollector(doc)
    .OfClass(typeof(FamilySymbol))
    .OfCategory(BuiltInCategory.OST_ViewportLabel);

string targetViewportTypeName = "Title, No Scale, Line";
FamilySymbol targetViewportType = collector
    .Cast<FamilySymbol>()
    .FirstOrDefault(fs => fs.Name.Equals(targetViewportTypeName, StringComparison.OrdinalIgnoreCase));

if (targetViewportType == null)
{
    TaskDialog.Show("Error", "The specified viewport type was not found.");
    return;
}

2. Update Viewport Types

Once you've identified the desired viewport type, you can update specific viewports programmatically using the Viewport.ChangeTypeId() method:

FilteredElementCollector viewportCollector = new FilteredElementCollector(doc)
    .OfClass(typeof(Viewport));

using (Transaction trans = new Transaction(doc, "Change Viewport Types"))
{
    try
    {
        trans.Start();

        foreach (Viewport viewport in viewportCollector.Cast<Viewport>())
        {
            Autodesk.Revit.DB.View view = doc.GetElement(viewport.ViewId) as Autodesk.Revit.DB.View;

            // Example: Update only viewports associated with Drafting Views
            if (view != null && view.ViewType == ViewType.DraftingView)
            {
                viewport.ChangeTypeId(targetViewportType.Id);
            }
        }

        trans.Commit();
    }
    catch (Exception ex)
    {
        trans.RollBack();
        TaskDialog.Show("Error", $"An error occurred: {ex.Message}");
    }
}

Key Insights for the API Limitations Why Your Diagnostic Code Returns Nothing

Your initial code attempts to retrieve viewport types by filtering with .OfClass(typeof(View)). However:

  • Viewport types are ElementType objects under the OST_ViewportLabel category.
  • Using OfClass(typeof(View)) will not return these types since it filters for views, not viewport types.

Correct Diagnostic Code

Here's a diagnostic script to list all available viewport types by name:

FilteredElementCollector collector = new FilteredElementCollector(doc)
    .OfClass(typeof(FamilySymbol))
    .OfCategory(BuiltInCategory.OST_ViewportLabel);

StringBuilder viewportTypeNames = new StringBuilder("Available Viewport Types:\n");
foreach (FamilySymbol type in collector.Cast<FamilySymbol>())
{
    viewportTypeNames.AppendLine(type.Name);
}

TaskDialog.Show("Viewport Types", viewportTypeNames.ToString());

Dynamo Users

For users working in Dynamo:

  • Viewport Types are stored as FamilySymbol elements within the OST_ViewportLabel category.
  • Use a combination of FamilySymbol.Name and Viewport.ChangeTypeId (if scripting with Python/DesignScript) to identify and update viewport types programmatically.

Practical Considerations

  1. Revit API Version:

    • Ensure compatibility between your code and the Revit version you're using. Revit 2024 introduced enhanced sub-element handling for viewports, but these changes are not available in earlier versions.
  2. Scale Display:

    • If you're filtering by scale (e.g., "NTS"), retrieve the Scale parameter of the associated view and use it to identify relevant viewports.
  3. Error Handling:

    • Always validate the ViewId, TypeId, and compatibility of the viewport type before applying changes.

Summary of Steps

  1. Retrieve Viewport Types:

    • Use FilteredElementCollector to find all viewport types in the OST_ViewportLabel category.
  2. Filter by Target Name:

    • Identify the desired viewport type by its name (e.g., "Title, No Scale, Line").
  3. Update Viewport Types:

    • Use Viewport.ChangeTypeId() to apply the target type to specific viewports.
  4. Diagnostic Code:

    • Use the provided diagnostic code to list available viewport types and verify your settings.

Additional Insights from My Experience

Sometimes, my NLU (Natural Language Understanding) system doesn't interpret things perfectly, so please feel free to let me know if any part of this explanation is unclear or inaccurate. This response stems from my own challenges when attempting to programmatically change legend viewport titles in Revit.

After spending two days meticulously experimenting, I concluded that it is not possible to change a legend viewport type unless that type already exists in the project. The breakthrough came when I shifted my focus to identifying viewport types that were already present in the project. By filtering and listing these existing types, I was able to determine which one to use as the replacement.

For anyone facing similar struggles, I highly recommend starting with a diagnostic approach: gather all available viewport types using the FilteredElementCollector and confirm their names match your desired title type. This ensures you're working within the constraints of your project's current configuration.

Message 10 of 13

Moustafa_K
Collaborator
Collaborator

Fetching Viewport Types is a bit tricky, I recall I have written an article about purging them (deleting the un-used ones). In general, the process of identifying elements like Viewport Types without a defined class in Revit is challenging. ViewportType is categorized as an ElementType, which is too broad to be helpful. An alternative approach is to indirectly identify purgeable Viewport Types by targeting parameters. Since ViewportType is a system family, all instances must have the "Show Extension Line" parameter (BuiltInParameter.VIEWPORT_ATTR_SHOW_EXTENSION_LINE). This Boolean parameter (0 or 1) can be used in a filter rule. By applying  ParameterFilterRuleFactory.CreateGreaterOrEqualRule with a value of 0, all types possessing this parameter can be identified.

 

you can try this code to change the viewportType, you can read more about this code in this article

 

 

 

// create filterRule to be used in collection
var rule = ParameterFilterRuleFactory.CreateGreaterOrEqualRule(
    new ElementId(BuiltInParameter.VIEWPORT_ATTR_SHOW_EXTENSION_LINE),
    0
);
// define which type name you are looking for
var nameRule = ParameterFilterRuleFactory.CreateEqualsRule(
    new ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME),
   "Titre sans ligne"
);

// get all elements that comply to this rule
var viewPortTypes = new FilteredElementCollector(doc)
    .WhereElementIsElementType()
    .OfCategory(BuiltInCategory.INVALID)
    .WherePasses(new ElementParameterFilter(rule))
    .WherePasses(new ElementParameterFilter(nameRule))
    .ToElementIds();

// should be only one result
var viewPortTypeId = viewPortTypes.FirstOrDefault();
if (viewPortTypeId != null)
{
    var vp = ... ; // the viewport you need to change
    Trans.Start();
    vp.ChangeTypeId(viewPortTypeId);
    Trans.Commit();
}

 

 

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes
Message 11 of 13

Sean_Page
Collaborator
Collaborator

I have done this several ways in the past, but the way you get them is so clean I am going to change to that method everywhere!

 


@BriCircuitBIM wrote:

1. Retrieve Viewport Types Programmatically

The key is to work with ElementType objects within the OST_ViewportLabel category, which represents viewport title types:

// Retrieve all viewport types (family symbols) in the project
FilteredElementCollector collector = new FilteredElementCollector(doc)
    .OfClass(typeof(FamilySymbol))
    .OfCategory(BuiltInCategory.OST_ViewportLabel);

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 12 of 13

BIMologist_
Collaborator
Collaborator

For future reference, you may want to take a look at pyRevit's "Wipe Unpurgable Viewport Types.pushbutton" which might provide you some guidance

 

 

https://github.com/pyrevitlabs/pyRevit/blob/1491f86fb8d4b020cbbe592e3ca9d0a01d0c7ba3/extensions/pyRe...

 

 

 

BIMologist
- Nauman Mysorewala
Did you find this post
helpful? Feel free to like this post.
Did your question get successfully answered? Then click
on the ACCEPT SOLUTION button.


EESignature

0 Likes
Message 13 of 13

Sean_Page
Collaborator
Collaborator

I think those are two different things, but I have tried for quite some time to remove the "Viewport" text reference from this collector, but still the only way I am aware of, but I use it with a Filter.

 

internal static IList<ElementType> ViewportTypes(Document doc)
{
    FilterRule rule = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId((long)BuiltInParameter.SYMBOL_FAMILY_NAME_PARAM), "Viewport");
    ElementParameterFilter filter = new ElementParameterFilter(rule);
    FilteredElementCollector fec = new FilteredElementCollector(doc).OfClass(typeof(ElementType)).WherePasses(filter);
    return fec.Cast<ElementType>().ToList();
}

 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect