Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to use the ElementIntersectsElementFilter from the RevitLinkInstance?

11 REPLIES 11
Reply
Message 1 of 12
wlmsingle
3315 Views, 11 Replies

How to use the ElementIntersectsElementFilter from the RevitLinkInstance?

Dear All,

 

I need to get the MEP elements which from a linked file and intersect with some structural elements in current project.

 

I have try the ElementIntersectsElementFilter or the ElementIntersectsSolidFilter, if there is no transform between the RevitLinkInstance  and the current project. The filters are both works fine. But if the RevitLinkInstance be moved or rotated after importing, the calculation result of the filters are not correct.

 

So is that have any tricks can solve the case like that? For example,a method for pass a transform to the filter in the transaction. If no, please share a good algorithm to get the intersection result between two solid elements.

 

11 REPLIES 11
Message 2 of 12
jeremytammik
in reply to: wlmsingle

Retrieve solids from the elements of interest and use SolidUtils.CreateTransformed on them:

 

https://apidocs.co/apps/revit/2019/22592761-f39c-4f53-d33b-6c21a4fa9d2d.htm

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 12
wlmsingle
in reply to: jeremytammik

Thanks a lot! You inspire me to develop with a new solution.

 

If there is a transform from the revitlinkinstance, the key point to use the ElementIntersectsSolidFilter correctly is transform the element in current project in same coordinate with the elements in the linked file project.

 

 

            Solid solid = getSolidFromElement(elm);
            foreach (RevitLinkedInstance ins in this._linkedInstaces)
            {
                Transform transform = ins.getTransform();
                if (transform.AlmostEqual(Transform.CreateTranslation(new
                 XYZ(0, 0, 0)) == false)
                {
                    solid = SolidUtils.CreateTransformed(solid, transform.Inverse);
                }
                FilteredElementCollector elmCol = new FilteredElementCollector(ins.getLinkedDocument());
                ElementIntersectsSolidFilter filter = new ElementIntersectsSolidFilter(solid);
                List<ElementId> resultsList = elmCol.WherePasses(filter).ToElementIds().ToList();

            }

 

 

Message 4 of 12
jeremytammik
in reply to: wlmsingle

Congratulations on implementing such a very nice solution!

 

Could you please share your code for `getSolidFromElement` and `getTransform`, so we can see the complete details?

 

Thank you very much!

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 12
jeremytammik
in reply to: wlmsingle

I cleaned up your code snippet to look like this:

 

    /// <summary>
    /// Collect the element ids of all elements in the 
    /// linked documents intersecting the given element.
    /// </summary>
    /// <param name="e">Target element</param>
    /// <param name="links">Linked documents</param>
    /// <param name="ids">Return intersecting element ids</param>
    /// <returns>Number of intersecting elements found</returns>
    int GetIntersectingLinkedElementIds( 
      Element e,
      IList<RevitLinkInstance> links,
      List<ElementId> ids )
    {
      int count = ids.Count();
      Solid solid = getSolidFromElement( e );

      foreach( RevitLinkInstance i in links )
      {
        Transform transform = i.getTransform();
        if( !transform.AlmostEqual( Transform.Identity) )
        {
          solid = SolidUtils.CreateTransformed( 
            solid, transform.Inverse );
        }
        ElementIntersectsSolidFilter filter 
          = new ElementIntersectsSolidFilter( solid );

        FilteredElementCollector intersecting 
          = new FilteredElementCollector( i.getLinkedDocument() )
            .WherePasses( filter );

        ids.AddRange( intersecting.ToElementIds() );
      }
      return ids.Count - count;
    }

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 12
c_hanschen
in reply to: jeremytammik

Hello!

 

First of all @jeremytammik and @wlmsingle , thanks for sharing your code!

 

I'm trying to get it work, but my code returns no elements.

 

Here is my code in VB.net:

(I had to translate it to VB.net and need elements in return, not element id's)

 

Public Function GetIntersectingLinkedElements(MyElementCurrentDocument As Element, links As List(Of RevitLinkInstance)) As List(Of Element)

Dim IntersectingLinkedElements As New List(Of Element) 'construct empty list of elements
Dim sb As New StringBuilder() 'debug information
Dim MyListOfSolids As List(Of Solid) = GetAllSolidsOfElement(MyElementCurrentDocument) 'get all solids of the element

sb.AppendLine("Solids: " & MyListOfSolids.Count.ToString)
sb.AppendLine("Number of links: " & links.Count.ToString)

For Each MySolid As Solid In MyListOfSolids

For Each MyRevitLinkInstance As RevitLinkInstance In links

Dim MyTransform As Transform = MyRevitLinkInstance.GetTransform()

If MyTransform.AlmostEqual(Transform.Identity) = False Then MySolid = SolidUtils.CreateTransformed(MySolid, MyTransform.Inverse) 'transform my element to match the linked document

Dim filter As New ElementIntersectsSolidFilter(MySolid)
Dim intersecting As FilteredElementCollector = New FilteredElementCollector(MyRevitLinkInstance.Document).WherePasses(filter)

IntersectingLinkedElements.AddRange(intersecting.ToElements())

Next

Next

sb.AppendLine("IntersectingElements: " & IntersectingLinkedElements.Count.ToString)

MsgBox(sb.ToString())

Return IntersectingLinkedElements

End Function

 

It return 8 solids (that's correct) and 3 linkeddocuments (Also correct) but returns no elements at all.

 

what am i doing wrong? Any help would be appreciated!

 

Please take a look at the image (attachment) for easier reading of the code.

 

Many Thanks!

 

Chris

The Netherlands

Message 7 of 12
c_hanschen
in reply to: c_hanschen

Sometimes it's like rubber-ducking, after sending my post I found the problem.

 

Were the code is:

MyRevitLinkInstance.Document

It should be:

MyRevitLinkInstance.GetLinkDocument

 

Maybe some VB.net user like my post anyway 😁

 

Chris

Message 8 of 12
c_hanschen
in reply to: jeremytammik

@wlmsingle , will you share your code from  `getSolidFromElement`

 

The function seems to work, but return wrong elements (not the elements that are intersecting).

maybe it is in the way you get your solids that is different than my way.

 

Thanks.

 

Chris

The Netherlands

 

Message 9 of 12
c_hanschen
in reply to: c_hanschen

@jeremytammik and @wlmsingle 

Thanks for all the info on this topic, it really helped, works great, but;

 

I managed to get it work really well, in basic you have to follow 3 steps to use the ElementIntersectsElementFilter :

- Get the Solid

- Transform the Solid by the Transform of the Instance

- Transform the Solid again if in a link by the transform of the LinkInstance.

By Following these 3 steps you can find all kind of intersections: model-model, model-link and link-model.

 

So far, so good, the ElementIntersectsElementFilter works really simple and great.

BUT, Why is it so slow? On a medium size model with a couple of links, it takes up to more than a second to find the intersecting element(s). That does not sound like much, but when clashing a 1000 instances, it takes 15 minutes!
(In my case, 5000 should not be a problem and should not take up to an hour or more)

When you compare this to Navisworks, it finds thousands of clashes in a second!

 

So i'm really impressed by the simple use of ElementIntersectsElementFilter, but is there a quicker way to find clashes through models? 

 

Thanks again,

 

Chris Hanschen

LKSVDD architecten 

The Netherlands

 

 

 

Message 10 of 12
jeremy_tammik
in reply to: c_hanschen

The intersection filter is a slow filter. Therefore, you must expect the kind of performance you describe. However, this performance can be tremendously optimised by using quick filters first. You must never run a slow filter on hundreds of elements, let alone thousands. Use quick filters to eliminate 99% of all candidate elements, and use slow filters when only a handful remain. For instance, you can use the bounding box intersection filter first to eliminate the vast majority of elements, and then follow up on it with an intersection filter for fine-tuned handling of the last remaining few. People are using such algorithms to filter and perform interference checking with hundreds of thousands of elements.  Check out the discussion on slow and quick filters:

  

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 11 of 12
c_hanschen
in reply to: jeremy_tammik

@jeremytammik , thanks again for your reply!

 

The combination of the bounding box intersection filter and the intersection filter works great!

 

Is there an way to combine this with a 'view' filter, working on linked file(s) with a view in the main model?

off course you can start your collector with New FilteredElementCollector(Mydoc, MyViewID), but is there a way this works with a linked model (MyDoc = RevitLinkInstance) and a view in the current model?

 

Thanks again!

 

Chris Hanschen

LKSVDD architecten

The Netherlands

Message 12 of 12
jeremy_tammik
in reply to: c_hanschen

Very glad to hear that the combination works well. Yes, of course, you can combine any number of filters together very flexibly. Personally, I created some complex combinations for MEP elements, connectors, and structural elements. Check out The Building Coder topic group on filtered element collectors for those and many more examples:

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.9

   

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community