Sorry its Friday and my brain is an hour behind the rest of the world. Please see below which works.
//FORMWORK ONLY FOUNDATIONS
if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_StructuralFoundation)
{
if (elem is FamilyInstance famInst)
{
Options opts = new Options();
GeometryElement geoElem = elem.get_Geometry(opts);
GeometryElement originalGeometry = famInst.GetOriginalGeometry(opts);
FamilyInstance familyInstance = elem as FamilyInstance;
Transform t = familyInstance.GetTransform();
GeometryElement originalGeometryTransformed = originalGeometry.GetTransformed(t);
//for family elements that are cut/joined
if (famInst.HasModifiedGeometry())
{
foreach (GeometryObject geoObj in originalGeometryTransformed)
{
Solid solid = geoObj as Solid;
if (solid != null && 0 < solid.Faces.Size)
{
foundationSolids.Add(solid);
////TEST DIRECT SHAPE TO SEE IF ITS PICKING UP SOLIDS
//DirectShape ds1 = null;
//ds1 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
//ds1.ApplicationId = "Application id";
//ds1.ApplicationDataId = "Geometry object id";
//ds1.Name = "FOUNDATION";
//ds1.SetShape(new GeometryObject[] { solid });
}
}
}
//for non-modified geometry
else
{
foreach (GeometryObject geoObj in geoElem)
{
GeometryInstance geoInst = geoObj as GeometryInstance;
if (null != geoInst)
{
GeometryElement instGeoElem = geoInst.GetInstanceGeometry();
if (instGeoElem != null)
{
foreach (GeometryObject o in instGeoElem)
{
Solid solid = o as Solid;
foundationSolids.Add(solid);
}
}
}
}
}
}
// Combine touching solids into a single solid using a for loop
for (int i = 0; i < foundationSolids.Count; i++)
{
Solid currentSolid = foundationSolids[i];
if (currentSolid != null && currentSolid.Faces.Size > 0)
{
for (int j = i + 1; j < foundationSolids.Count; j++)
{
Solid solidToCheck = foundationSolids[j];
if (solidToCheck != null && solidToCheck.Faces.Size > 0 && AreSolidsTouching(currentSolid, solidToCheck))
{
// Join the solids
currentSolid = BooleanOperationsUtils.ExecuteBooleanOperation(currentSolid, solidToCheck, BooleanOperationsType.Union);
foundationSolids.RemoveAt(j);
j--; // Adjust the index after removal
}
}
// Add the joined or single solid to the joinedFndSolids list
joinedFndSolids.Add(currentSolid);
}
}
// Process the joined solids
foreach (Solid s in joinedFndSolids)
{
foreach (Face f in s.Faces)
{
double norm = f.ComputeNormal(new UV(0.5, 0.5)).Z;
if (norm == 0)
{
foundationFaces.Add(f);
}
}
}
}
}