Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

Filter Visible Elements From Linked Revit Model

Mohamed_Arshad
Advisor

Filter Visible Elements From Linked Revit Model

Mohamed_Arshad
Advisor
Advisor

Hello Everyone,
     Using FilterElementCollector(), I can able to filter out completed elements from Linked Revit Model, Bypassing Linked Model Document to the FilterElementCollector(LinkedModelDocument)


Output Needed:
   If  I hide any element from the Linked Model Using (Tab Key), Then I'm applying the filter, The filter needs to get only the visible elements of Linked Models.

Approaches I Tried

01. By using FilterElementCollector(Document, ViewId), I tried to filter active view Elements in the linked model document
but it throws a null argument error

02.By using FilterElementCollector(Document). I filter the complete elements and using IsHidden(view) method, I try to ensure the element 
was hidden, But it throws a null argument error


Is there any way to solve this problem? Kindly Help me to solve this problem.

 

@naveen.kumar.t @jeremy_tammik @jeremytammik @RPTHOMAS108 @ricaun @moturi.magati.george 

Thanks & Regards,
Mohamed Arshad K
0 Likes
Reply
Accepted solutions (1)
2,655 Views
16 Replies
Replies (16)

jeremy_tammik
Autodesk
Autodesk

You could try to run the filtered element collector directly in the linked document.

  

using IsHidden(view) method ... it throws a null argument error

  

That may be caused by the view being in a different document.

   

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

RPTHOMAS108
Mentor
Mentor

On Revit 2024 you have the new overload on the filtered element collector:
FilteredElementCollector(Document hostDocument, ElementId viewId, ElementId linkId)

 

Prior to 2024 getting visibility of elements in link per view is non-existent I believe. You can approximate with some element filters transferred into the link document but they will not pick up if the element has been hidden in view in the document that hosts the link. 

 

One idea would be to transfer the view itself to the link document (transformed to correct position for link instance) and use the FilteredElementCollector on it there. I've not tried that myself but see no obvious reasons why it would not work. You will not get the elements from the host document that way but those can be added separately.

 

Even in 2024 I believe there is still no way of individually hiding a linked element in view or finding out if a single linked element is visible in view or not. There is the new RevitLinkGraphicsSettings but that relates to the global link visibility settings per view (used with View.Get/SetLinkOverrides).

 

 

 

Mohamed_Arshad
Advisor
Advisor

@jeremy_tammik 
Thanks for reply 
As you mentioned I run the filtered Element Collector Directly in the linked Document,
Still, the IsHidden() method not working

 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {

            Application revitApp = commandData.Application.Application;
            Document revitDoc = commandData.Application.ActiveUIDocument.Document;

            DocumentSet docSet = revitApp.Documents;

            Document linkedDoc = null;

            //Getting Linked Model from the Project
            foreach(Document doc in docSet)
            {
                if(doc!=revitDoc)
                {
                    linkedDoc = doc;
                }
            }
            
            //Filtering
            List<Element> likedDocElements = 
                new FilteredElementCollector(linkedDoc)
                .OfCategory(BuiltInCategory.OST_Walls)
                .ToElements()
                .ToList();

            //Itteration to Check Whether Element is Visisible or Nor
            foreach(var e in likedDocElements)
            {
                if(e.IsHidden(revitDoc.ActiveView))
                {
                    TaskDialog.Show("Info", e.Name);
                }
            }

            return Result.Succeeded;

        }

 

 

Thanks & Regards,
Mohamed Arshad K
0 Likes

Mohamed_Arshad
Advisor
Advisor

HI @RPTHOMAS108 
As you mentioned, I will conclude this as not possible to get visible elements from Linked Document
@jeremy_tammik  Can you please add this conversion in your building coder blog, So that everyone can make use of it

Thank you so much for both superheroes 🙂

Thanks & Regards,
Mohamed Arshad K
0 Likes

RPTHOMAS108
Mentor
Mentor

Not directly but you can try transferring the view itself to the link document and test it there with FilteredElementCollector. Essentially my logic is that if there is a view looking upon the same scene in the link document then the collector run there will return the elements. The only issue I can see is that the items from the link hidden in view could likely be visible (since they have a different reference when not linked).

0 Likes

Mohamed_Arshad
Advisor
Advisor

@RPTHOMAS108 
Can you please tell me how to transfer the view to LinkedModel?
Like you telling me to Pass LinkedDocument Active View to FilterElementCollector(LinkedDocument, LinkedDocument.ActiveView.Id)?
Can you please elaborately explain this to me..

Thanks & Regards,
Mohamed Arshad K
0 Likes

RPTHOMAS108
Mentor
Mentor

The view itself is a model element (not a view specific element) so you would use one of the CopyElements overloads from ElementTransformUtils that doesn't relate to copying between views i.e.:

 

public static ICollection<ElementId> CopyElements(
	Document sourceDocument,
	ICollection<ElementId> elementsToCopy,
	Document destinationDocument,
	Transform transform,
	CopyPasteOptions options
)

 

There was a discussion recently regarding transforms with this API for your purpose I would try: RevitLinkInstance.GetTransform.Inverse

 

i.e. in simple terms if the link instance is 10m east from model origin and the section view is at the side of it also 10m east from model origin. Then you want to deduct the 10m when the section view is copied into the linked document otherwise the section will end up 10m east of the origin within the link. If you are copying elements in the other direction (not your case) from the link document to the host then you want to add the 10m. For that case you would have just used the transform not the inverse of it.

 

I think perhaps as I mentioned above the limitation of this method will relate to how the view identifies what elements in the link have been manually hidden in view by the user. I'm assuming the references stored for that will be as related to how those hidden elements were identified in the host document that the view was copied from (so may be lost).

0 Likes

Mohamed_Arshad
Advisor
Advisor

@RPTHOMAS108 

Yes, I will implement the above-mentioned method.

Steps to be Followed 
01. Copy element from Linked Document to Host Document
02. We get a List of elements from the CopyElementMethod
03. By using FilteredElementCollector(hostdocument, activeView.Id) I try to get the visible Elements.

the above-mentioned steps are correct?

Thanks & Regards,
Mohamed Arshad K
0 Likes

RPTHOMAS108
Mentor
Mentor

No copy a view to the linked document and run the FilteredElementCollector within the linked document.

 

You could do it the other way around but I assume it will take longer to process copying multiple elements rather than one single view but you get the idea (there is a saying related to Mount Safa isn't there). That is what this common API process reminds me of: you either copy the elements to the host document to see them in the view or copy the view to the linked document to see the elements there. The latter would be my preference.

0 Likes

Mohamed_Arshad
Advisor
Advisor

@RPTHOMAS108 
I followed your instructions and implemented the below code. I got a Transaction Exception.
The view is not copied from one document to another.

  public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {

            Application revitApp = commandData.Application.Application;
            Document revitDoc = commandData.Application.ActiveUIDocument.Document;

            DocumentSet docSet = revitApp.Documents;

            Document linkedDoc = null;

            //Getting Linked Model from the Project
            foreach (Document doc in docSet)
            {
                if (doc != revitDoc)
                {
                    linkedDoc = doc;
                }
            }

            List<ElementId> viewIds = new List<ElementId>()
            {
                revitDoc.ActiveView.Id
            };

            using (Transaction copyView = new Transaction(revitDoc, "Copy"))
            {
                copyView.Start();

                ElementTransformUtils.CopyElements(revitDoc, viewIds, linkedDoc, Transform.Identity, new CopyPasteOptions());

                copyView.Commit();
            }


            ElementClassFilter classFilter = new ElementClassFilter(typeof(Wall));

            //Filtering
            List<ElementId> linkedElementIds =
                new FilteredElementCollector(linkedDoc,linkedDoc.ActiveView.Id)
               .WherePasses(classFilter)
                .OfCategory(BuiltInCategory.OST_Walls)
                .ToElementIds()
                .ToList();


            return Result.Succeeded;

        }


Error Image:

arshad99_0-1681387481527.jpeg

 



Thanks & Regards,
Mohamed Arshad K
0 Likes

RPTHOMAS108
Mentor
Mentor

Transaction should be related to the document you are modifying i.e. you are effectively adding a view (new element) to the destination document so that is what the transaction should be related to.

 

This kind of highlights another issue in that you would have to unload the link in order to modify the linked document i.e. open the linked document even to temporarily modify it. The reason you have to unload links to open them is because they already exist in a ReadOnly state in the document set (whilst link is loaded).

 

Nothing stopping you from copying the linked document to a temporary location with new name to open it, that is probably the easiest workaround.

 

Alternatively use:

RevitLinkType.Unload

Application.OpenDocumentFile

 

View copy and filter activity here

 

Document.Close(false)

RevitLinkType.Reload

 

0 Likes

Mohamed_Arshad
Advisor
Advisor

We can't be able to give LinkedDocument to Transaction, Instead of that you're saying to unload the Revit Type Link.
Open the Linked Document with new name. If I open the Revit Link again the DocumentSet become editable?

 

Thanks & Regards,
Mohamed Arshad K

RPTHOMAS108
Mentor
Mentor

1) If you open it in the background then you can start a transaction in it but you need to unload it from the documents it is linked in or Revit will prompt the user to do so and you don't want that.

 

2) Alternatively

If you copy the linked document with a new name to a temporary location then you can open that and Revit will not see it as the same document as the link (so will not prompt user to unload the link). Use a GUID for the temporary file name.

 

Since this is just an information gathering exercise you can close and discard the temporary file after doing the element in view filtering.

 

Option two seems easier since same link may be loaded into multiple open documents in the UI 

 

The downside of either of these approaches is the time it takes to open the document and handling the dialogues that appear during loading but that is a different subject.

 

 

0 Likes

Mohamed_Arshad
Advisor
Advisor

Sorry for the more Question, Final question was
I'm hiding an element in Host Document, But you're saying that do filtering in Newly opened document.
Are my hidden elements will reflect in the open document?

My Scenario was By using the Tab key I hide particular elements from Linked Model, Now I need to filter only the visible elements from Linked Model. But Upcoming conversation I'm not getting it. Can you explain what steps should I need follow to achieve these?  Sorry for the misunderstanding

Thanks & Regards,
Mohamed Arshad K
0 Likes

RPTHOMAS108
Mentor
Mentor
Accepted solution

I don't know for sure but I said previous that likely wouldn't be reflected since the linked elements will have a different reference in the host project (which the view is using to identify if it is hidden). The only benefit here is you get elements within the same crop. You could probably achieve similar to the limited solution I suggest here by using a bounding box filter but you would have to re-orientate the elements to have the same relation to the outline since the bounding box filters have their input boxes (Outline class) always parallel with the model coordinate system.

0 Likes

Mohamed_Arshad
Advisor
Advisor

Yeah, I agree with this, Thank you so much for your patience. I learned quite a things from you.

Thanks & Regards,
Mohamed Arshad K
0 Likes