How to avoid getting "sub element in an element" when getting all elements?

How to avoid getting "sub element in an element" when getting all elements?

tumbleweed1024
Explorer Explorer
387 Views
7 Replies
Message 1 of 8

How to avoid getting "sub element in an element" when getting all elements?

tumbleweed1024
Explorer
Explorer

Hello everyone.

 

I use the following code to get all the elements with geometry.
List<Element> mainModeElems = new List<Element>();
FilteredElementCollector collector = new FilteredElementCollector(Document);
ICollection<Element> allElements = collector.WhereElementIsNotElementType().ToElements();
Options geoOptions = new Options();
foreach (Element element in allElements)
{
    GeometryElement geomElement = element.get_Geometry(geoOptions);
    if (geomElement != null)
    {
        mainModeElems.Add(element);
    }
}​
 
 

But this will collect sub element like OST_StairsRuns, OST_RailingTopRail, OST_StairsRailingBaluster and mullions.

 

tumbleweed1024_0-1748429804619.png

tumbleweed1024_2-1748429877448.png

 

I don't need these elements, and these elements cause the ElementIntersectsElementFilter to throw an exception stating "The category of the element is not supported for element intersection filters."

 

How to filter out these sub elements? I haven't found any differences in attributes between them and the regular overall elements. Now I'm trying to use element.ArePhasesModifiable() for filtering, which seems to work, but could this cause any errors or lead to the omission of certain elements?

 

Thank you all.

 

0 Likes
388 Views
7 Replies
Replies (7)
Message 2 of 8

rcrdzmmrmnn
Advocate
Advocate

You can use a ElementMultiCategoryFilter with the inverted overload, like this:

				var catsToExclude = new ElementMulticategoryFilter(new BuiltInCategory[]{BuiltInCategory.OST_StairsRuns,BuiltInCategory.OST_RailingTopRail},true);
				var elementsWithoutAboveCategories = new FilteredElementCollector(Doc).WhereElementIsNotElementType().WherePasses(catsToExclude);
Message 3 of 8

tumbleweed1024
Explorer
Explorer
Yes, I can filter out this sub element that I know BuiltInCategory, but this is not a universal solution and I can't possibly list all the BuiltInCategories of all sub element
0 Likes
Message 4 of 8

tumbleweed1024
Explorer
Explorer
Can someone reply to me? I'd really appreciate it  : D
0 Likes
Message 5 of 8

rcrdzmmrmnn
Advocate
Advocate

For familyInstances it should be easy, using the property SuperComponent. If this property is null, it does not have a parent element.
You mentioned that you want to filter them out in order to use the ElementIntersectElement filter, and some of them throw an exception.
My best guess is, create a List<BuiltinCategory> and everytime you catch that exception you add the failed category to that list and after all elements iterate over the list,  print the listed categories and use for tweaking the code. Even better than a list is a Hashset as it won't add repeated categories. Unfortunately, this is the best I can think of.

Message 6 of 8

ctm_mka
Collaborator
Collaborator

you could go the"unprofessional" route and use a try/catch, something like this:

 try
 {
     //element intersections code
     //when it throws exceptions, it goes to catch, but you dont need to do anything about it, essentially skipping the elements you dont want.
 }
 catch { }

 

Message 7 of 8

rcrdzmmrmnn
Advocate
Advocate

Yeah, basically that's what I've said, but then, save the failed categories to improve the code in order to the future runs don't even pass the failing categories, because some categories like mullions will have A LOT of elements(and obviously, a lot of exceptions).

Message 8 of 8

tumbleweed1024
Explorer
Explorer
Well, thank you, it looks like Revit doesn't provide an API that can distinguish sub elements.
If there is a problem with the ArePhasesModifiable() method, will have to manually write a list of categories  : (
0 Likes