How to filter elements connected between two mechanical equipment informed by the user?

Viewed 33

I'm having difficulty making a filter for a system consisting of pipes, accessories, pipe connections and mechanical equipment. This filter returns all elements in the view. But I just want the connected elements mentioned in the title.

FilteredElementCollector FEC_EM = new FilteredElementCollector(doc, doc.ActiveView.Id);
FEC_EM.OfClass(typeof(FamilyInstance));
FEC_EM.OfCategory(BuiltInCategory.OST_MechanicalEquipment);
foreach (FamilyInstance FI_EM in FEC_EM)
{
    Parameter EM1 = FI_EM.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
    TaskDialog.Show("EM1", "EM1: " + EM1.AsString());

    BoundingBoxXYZ bb = FI_EM.get_BoundingBox(doc.ActiveView);
    Outline outline = new Outline(bb.Min, bb.Max);
    BoundingBoxIntersectsFilter bbfilter = new BoundingBoxIntersectsFilter(outline);

    BuiltInCategory[] bics = new BuiltInCategory[] {
    BuiltInCategory.OST_PipeCurves,
    BuiltInCategory.OST_PipeFitting,
    BuiltInCategory.OST_PipeAccessory,
    };
    IList<ElementFilter> a = new List<ElementFilter>(bics.Count());
    foreach (BuiltInCategory bic in bics)
    {
        a.Add(new ElementCategoryFilter(bic));
    }
    LogicalOrFilter categoryFilter = new LogicalOrFilter(a);
    LogicalAndFilter familyInstanceFilter = new LogicalAndFilter(categoryFilter,
        new ElementClassFilter(typeof(FamilyInstance)));
    IList<ElementFilter> b = new List<ElementFilter>(6);
    b.Add(new ElementClassFilter(typeof(CableTray)));
    b.Add(new ElementClassFilter(typeof(Conduit)));
    b.Add(new ElementClassFilter(typeof(Duct)));
    b.Add(new ElementClassFilter(typeof(Pipe)));
    b.Add(familyInstanceFilter);
    LogicalOrFilter classFilter = new LogicalOrFilter(b);

    FilteredElementCollector collector = new FilteredElementCollector(doc);
    collector.WherePasses(classFilter);
    ICollection<ElementId> idsExclude = new List<ElementId>();
    idsExclude.Add(doc.ActiveView.Id); 
    collector.Excluding(idsExclude).WherePasses(bbfilter);

    int nCount = 0;
    string report = string.Empty;
    foreach (Element e in collector)
    {
        string name = e.Name;
        report += "\n\nName = " + name + " Element Id: " + e.Id.ToString();
        nCount++;
    }
    TaskDialog.Show("Caixa delimitadora + visualização + filtro de exclusão", "\nEncontrado " + nCount.ToString()
        + " elementos cuja caixa delimitadora cruza" + report.ToString());
}
1 Answers

Yes. That cannot be achieved directly using a filtered element collector. In order to determine and traverse connected MEP elements, you need to query them for their connector data. This is demonstrated by the Revit SDK MEP samples. Check them out in SamplesReadMe.htm. The most relevant one for your question is the TraverseSystem sample. The Building Coder also shares some examples of traversing MEP systems.

Related