LLMs are unable to select views (sections, elevations, callouts) from current/active view

LLMs are unable to select views (sections, elevations, callouts) from current/active view

DanielKP2Z9V
Advocate Advocate
286 Views
4 Replies
Message 1 of 5

LLMs are unable to select views (sections, elevations, callouts) from current/active view

DanielKP2Z9V
Advocate
Advocate

I'm probably going to solve it in an hour or so, but I've spent the past hour unable to prompt LLMs to select all active views in this command, so I thought it might be worth sharing for your own amusement. It seems to roughly come down to this:

 

                    var viewsInActiveView = new FilteredElementCollector(doc, activeView.Id)
                        .OfClass(typeof(View))
                        .Cast<View>()
                        .Where(v => !v.IsTemplate)
                        .Select(v => v.Id)
                        .ToList();

 


this returns  Count=0. I trust that you can see an issue right away, but I can't right now.

This works though, but selects all elements in the view, while I'm trying to get only views:

 

        List<ElementId> ElementsNotInGroups = new FilteredElementCollector(doc, currentView.Id)
            .WhereElementIsNotElementType()
            .Where(e => e.GroupId == ElementId.InvalidElementId)
            .Where(e => !(e is View)) // Exclude views
            .Where(x => x.Category != null) // Exclude ExtentElem
            .Where(e => !(e.Category?.Id.IntegerValue == (int)BuiltInCategory.OST_Cameras)) // Exclude cameras
            .Select(e => e.Id)
            .ToList();

 

LLMs I'm working with are chatgpt, claude, gemini and deepseek

0 Likes
287 Views
4 Replies
Replies (4)
Message 2 of 5

DanielKP2Z9V
Advocate
Advocate

I wouldn't posit this as a proper solution, but it does work and isn't too slow. If someone knows how to do it in a single step (directly in he FilteredElementCollector) please oblige

 

 

 

// collect all the elements in current view
        List<ElementId> ElementsNotInGroups = new FilteredElementCollector(doc, currentView.Id)
            .WhereElementIsNotElementType()
            .Where(e => e.GroupId == ElementId.InvalidElementId)
            .Where(x => x.Category != null) // Exclude ExtentElem
            .Where(e => !(e.Category?.Id.IntegerValue == (int)BuiltInCategory.OST_Cameras)) // Exclude cameras
            .Select(e => e.Id)
            .ToList();


// iterate through all the elements
foreach (ElementId id in ElementsNotInGroups)
{
    Element element = doc.GetElement(id);
    if (element != null && element.Category != null)
    {
        // Check if the element is in the Views category.
        if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Viewers)
        {
                viewIds.Add(id);
        }
    }
}

 

 

my thoughts every time this happens:

DanielKP2Z9V_0-1739734691354.png

 

 

0 Likes
Message 3 of 5

DanielKP2Z9V
Advocate
Advocate

what was strange though is that not a single LLM could figure it out (or please prove me wrong), it doesn't look like a difficult or poorly documented part of the api, so it took me by surprise

also fact that Category.GetCategory(doc, id) returns null when BuiltInCategory.OST_Viewers is passed is just plain e̷͖̬͖̰̥̍͋̽͂v̵̯̮͍̀̇̂͂̔ĭ̶̛͓̖͙̐̚̕l̵̗̦̈́̆͝

0 Likes
Message 4 of 5

Sleepingfish_Kuo
Advocate
Advocate

OST_Viewers in other view is not type of view, and not OST_Views, but just elements.

You can check that in Revit lookup.

 

new FilteredElementCollector(doc, activeView.Id)
                        .OfCategory(BuiltInCategory.OST_Viewers)

Try this.

0 Likes
Message 5 of 5

rhanzlick
Advocate
Advocate

Firstly, I applaud your use of the C#/.Net API and use of LINQ. However, I would caution and even discourage you from using an LLM for RevitAPI - ALMOST ALWAYS. Always be wary using LLMs in any programming exercise, not only will their hallucinations very often lead you down bad paths, but can land you in a situation similar to your current one (where you've allowed it to lead you in an awfully backwards and unhelpful direction for - hours?). For example, and in fairness, this may not be trivial, but Groups do not apply to Viewports or Views in any context AFAIK (just to verify - when I tried to create a group with a Viewport via the standard UI, Revit threw a Failure warning). So your above solution filtering for elements who are not grouped is not applicable to your query at all. Please, save yourself the headache and always first explore your project with the look-up tool followed by checking the docs. Now with that out of the way...

 

The combined fact that Revit API is niche W.R.T. the broad internet to begin with AND its official documentation is very often lacking, unhelpful, or even counter-productive means that even RAG or custom fine-tuned models will from first principles likely always give bad results; moreover leaving broad foundation models a hopeless cause for a very long time. Now with that out of the way....

 

If I understand correctly what you're looking for, the very basics of Revit, the API, and a snoop of your active sheet will tell you:

 

1. Views appear on sheets via Viewports. Viewports have a ViewId property that references the view they are displaying:

https://www.revitapidocs.com/2024/71bf8e09-95f2-595f-ff19-7726800f0069.htm

 

2. Your header question is almost verbatim described in the description of the ViewSection class' documentation:

https://www.revitapidocs.com/2024/fcc75682-bd99-a97d-5a4d-0f8eb9e92ab5.htm

 

So using the above 1 and 2, something like this should get you what you want (or at least very close):

 

new FilteredElementCollector(rvtDocument, sheet.Id)

    // From [1]

    .OfClass(typeof(Viewport))

    .OfType<Viewport>()

    .Select(vp => rvtDocument(vp.ViewId))

    .Cast<View>()

    // From [2]

    .Where(v => v is ViewSection)

    .ToList();