#RTCEUR Wish 4 – Find Native and RVT Link Penetrating Elements

This sample shows how the BoundingBoxIntersectsFilter can be used to find elements that penetrate ceilings in the model.

The host file contains 2 ceilings, 2 columns, and a RVT link that contains 3 Generic Model elements. There are also 3 shaft openings in the ceiling so that there is no interference between the ceilings and the elements going through them.

This API code analyzes the bounding box of each ceiling and finds all elements in all files (including the current RVT and links) whose bounding box intersects the ceiling’s bounding box. The results are shown in a dialog and written to a parameter of the ceiling category.

public void FindPenetrations()
{
    Document hostDoc = this.ActiveUIDocument.Document;
    string data = "";

    LogicalOrFilter columnGenericModelfilter = new LogicalOrFilter(new ElementCategoryFilter(BuiltInCategory.OST_Columns), new ElementCategoryFilter(BuiltInCategory.OST_GenericModel));

    using (Transaction t = new Transaction(hostDoc, "Find Penetrations"))
    {
        t.Start();

        foreach (Ceiling ceiling in new FilteredElementCollector(hostDoc).OfClass(typeof(Ceiling)))
        {
            data += "--- Ceiling - " + ceiling.Name + " (id = " + ceiling.Id + ") ---\n";

            // define an Outline based on the Bounding Box of this ceiling
            Outline outline = new Outline(ceiling.get_BoundingBox(null).Min, ceiling.get_BoundingBox(null).Max);

            string paramData = "";

            // search for penetrations in all open documents which will include RVT Links and native geoemtry in this RVT
            foreach (Document doc in this.Application.Documents)
            {
                // find elements that pass the Column/Generic Model filter and whose Bounding Box intersects the outline of this Ceiling
                foreach (Element e in new FilteredElementCollector(doc).WherePasses(columnGenericModelfilter).WherePasses(new BoundingBoxIntersectsFilter(outline)))
                 {
                    data += e.Category.Name + " - " + e.Name + " - " + Path.GetFileName(e.Document.PathName) + " - " + e.Id.IntegerValue + "\n";
                    paramData += e.Name + " - " + Path.GetFileName(e.Document.PathName) + " - " + e.Id.IntegerValue + "\n";
                 }
            }

            ceiling.get_Parameter("Penetrating Elements").Set(paramData);
            data += "\n";
        }
        t.Commit();    
    }
    TaskDialog.Show("Intersections",data);
}

Find a Room’s Ceiling Height

Revit can compute some great info about Rooms – area, perimeter, and volume. But out-of-the-box Revit can’t tell you the height of the ceiling above a room. Fortunately the API lets us find this info. Pulling together some things that have been covered in previous posts, here is the code and a screenshot.

public void RoomCeilingHeight()
{
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uidoc = new UIDocument(doc);

    // Prompt user to select a room
    Room room = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Room;

    // Get the location point of the room.
    // If you want to check other points for a room with non-uniform ceiling height
    // use Room.IsPointInRoom to make sure the points are in the room
    LocationPoint roomPoint = room.Location as LocationPoint;

    // The 3 inputs for ReferenceIntersector are:
    // A filter specifying that only ceilings will be reported
    // A FindReferenceTarget option indicating what types of objects to report
    // A 3d view (see http://wp.me/p2X0gy-2p for more info on how this works)
    ReferenceIntersector intersector = new ReferenceIntersector(
        new ElementCategoryFilter(BuiltInCategory.OST_Ceilings),
        FindReferenceTarget.All,
        (from v in new FilteredElementCollector(doc).OfClass(typeof(View3D)).Cast<View3D>() where v.IsTemplate == false && v.IsPerspective == false select v).First());

    // FindNearest finds the first item hit by the ray
    // XYZ.BasisZ shoots the ray "up"
    ReferenceWithContext rwC = intersector.FindNearest(roomPoint.Point, XYZ.BasisZ);

    // Report the data to the user. This information could also be used to set a "Ceiling Height" instance parameter
    if (rwC == null)
        TaskDialog.Show("Height", "no ceiling found");
    else
        TaskDialog.Show("Height",rwC.Proximity.ToString());
}
roomCeilingHeight