Identify GeometryObject in family instance NOT within a nested family instance

Identify GeometryObject in family instance NOT within a nested family instance

keearjun
Participant Participant
439 Views
5 Replies
Message 1 of 6

Identify GeometryObject in family instance NOT within a nested family instance

keearjun
Participant
Participant

Hi all,

 

I am attempting to write a plugin that can parse an instance for a nested family that contains both GeometryObjects as well as family instances nested within the top-level family instance. I've attached an example project that includes a single instance for the "test-table" family that I created. You will notice that the "test-table" family definition contains four instances to "test-leg", which represent the legs of the table, as well as two extrusions, one for the table surface and one for the cylinder sitting on top of the table.

 

I would like to be able to pull the nested families (i.e. the four instances for "test-leg", pointed to by red arrows in attached picture) as well as any geometry information that is not within the nested family (i.e. the table top and the cylinder, pointed to by blue arrows in attached picture). I have seen examples online to pull the nested families, but I haven't been able to find anything for just getting geometry objects NOT inside the nested family instances (using something like "familyInstance.get_Geometry(options)" and iterating over those results will include the geometry objects from everything, including within the nested family instances).

 

Below is the code I'm working with, which will write output lines for the four "test-leg" instances only. Thanks!

 

 

 

List<string> logs = new List<string>();
List<FamilyInstance> tables = new FilteredElementCollector(document)
    .OfCategory(BuiltInCategory.OST_GenericModel)
    .WhereElementIsNotElementType()
    .OfType<FamilyInstance>()
    .Where(instance => instance.Symbol.FamilyName.Contains("test-table"))
    .Where(Instance => Instance.Name.Contains("test-table"))
    .ToList();

logs.Add($"Number of tables found: {tables.Count}");

int tableCount = 0;
foreach (FamilyInstance table in tables)
{
    logs.Add($"Examining table #{++tableCount}");
    Family family = table.Symbol.Family;
    Document familyDoc = document.EditFamily(family);
    if (familyDoc == null || !familyDoc.IsFamilyDocument)
    {
        logs.Add("No family doc found!");
    }

    // TODO: Unclear on how to get GeometryObjects from familyDoc without also getting those within nested family instances
    List<FamilyInstance> familyInstances = new FilteredElementCollector(familyDoc)
        .OfCategory(BuiltInCategory.OST_GenericModel)
        .WhereElementIsNotElementType()
        .OfType<FamilyInstance>()
        .ToList();
    foreach (FamilyInstance familyInstance in familyInstances)
    {
        logs.Add($"Nested family instance found: type={familyInstance.GetType()}, name={familyInstance.Name}");
    }
}

File.WriteAllLines("/path/to/log.txt", logs.ToArray());

 

 

The above will output the below:

 

 

Number of tables found: 1
Examining table #1
Nested family instance found: type=Autodesk.Revit.DB.FamilyInstance, name=test-leg
Nested family instance found: type=Autodesk.Revit.DB.FamilyInstance, name=test-leg
Nested family instance found: type=Autodesk.Revit.DB.FamilyInstance, name=test-leg
Nested family instance found: type=Autodesk.Revit.DB.FamilyInstance, name=test-leg

 

 

0 Likes
440 Views
5 Replies
Replies (5)
Message 2 of 6

RPTHOMAS108
Mentor
Mentor

So if the nested components are not set to shared they get lumped into the single set of geometry as solids and you will not be able to distinguish unless you use subcategories within the family. Without subcategories you will only be able to identify by the form of the solids i.e. what face types they contain etc.

 

If the nested components are shared then they exist in the project as elements in their own right and so the geometry can be separately identified.

 

The geometry methods exposed to the API are based around what Revit uses to display and make object selectable in view, so nesting is irrelevant at the point Revit needs to know that (for non-shared families).

0 Likes
Message 3 of 6

keearjun
Participant
Participant

I see, thanks for the response! So it sounds like finding a general solution for distinguishing family instances from other geometries in a family document isn't really possible then. I guess I'll just need to keep that in mind, and perhaps try to get our clients to follow standards in their Revit design to use shared components and/or subcategories.

0 Likes
Message 4 of 6

RPTHOMAS108
Mentor
Mentor

Yes, the only other thing you can do is edit the family in the project (Document.EditFamily) and identify nested instances that way.

0 Likes
Message 5 of 6

keearjun
Participant
Participant

Gotcha, i believe that's what I did in the code sample I linked in my original post, via which i was indeed able to identify the nested family instance of the "table-leg" family. Is there something else I could do additionally to pull the pure geometry stuff that aren't in a nested "table-leg" family instance while editing the family document? As far as I can tell, geometry isn't an "element", so can't be filtered for via the FilteredElementCollector, so I'm guessing no.

0 Likes
Message 6 of 6

RPTHOMAS108
Mentor
Mentor

No solid objects in family that aren't nested family instances could be Forms (which are elements that have geometry).

0 Likes