Group lists by common elements

Hello everyone.

I’m working on a script to insert families (Generic Model void) of holes at the intersection of pipes, ducts, and conduits with walls and floors.
As long as there are no intersecting groups of elements, everything is fine. I’d like to solve the problem of creating holes that include groups of closely spaced pipes (as in the example image).
I’ve reached the point where I have lists containing which pipes intersect each pipe, as shown in the image (the intersecting elements it’s not actually the diameter of the pipe, but a family representing its increased diameter).
At this point, I’d like to merge the lists containing common elements to obtain additional lists representing the groups of “nearby” pipes. I’ll use these lists to create a bounding box that will represent the final through hole.

The image above is an elevation view of a wall with interseting pipes.

I’ve already tried List.Combine, List.SetDifference, Springs.List.MergeByBoolMask, List.JoinByKey without success. Maybe I didn’t use them correctly.

Thank you all so much.
Luca

The most straightforward method in my mind requires either a recursive function or a true while loop, both of which would likely require you to use Python. You essentially need to go through each pipe and build up a list of other pipes that intersect it, joining them into a larger combined volume. Continue this process (looping over again every time you add a pipe) until there are no more intersections with your combined group, then move on to the next pipe/group.

You could also try identifying “matches” within your existing groups, which is what it sounds like you’ve been trying so far. For each current group of intersecting pipes, use List.Contains to see which other groups also contain any of the same pipes as the existing group. Collect all those subgroups and join them into a unique list. This can get very messy with list levels but it’s technically possible.

Hi Nick,

Thanks so much for your reply. I should be able to do some tests in a few days and then give you some feedback.

Tnx again
Luca

Did something similar recently regarding overlapping ElementId grouping.

Here is a simple function (rejigged a bit) that helped me.

def group_by_overlap(lists):
    groups = []
    group_order = []  # Track the original list index for each group
    
    for list_idx, lst in enumerate(lists):
        # Find which existing groups share items with this list
        matching_groups = []
        for i, group in enumerate(groups):
            if any(item in group for item in lst):
                matching_groups.append(i)
        
        if not matching_groups:
            # No matches - create new group
            groups.append(set(lst))
            group_order.append(list_idx)
        else:
            # Merge all matching groups + current list
            merged = set(lst)
            earliest_order = list_idx
            
            for i in reversed(matching_groups):  # reverse to avoid index issues
                merged.update(groups.pop(i))
                earliest_order = min(earliest_order, group_order.pop(i))
            
            groups.append(merged)
            group_order.append(earliest_order)
    
    # Sort groups by their original appearance order
    sorted_groups = sorted(zip(group_order, groups), key=lambda x: x[0])
    return [list(group) for _, group in sorted_groups]

lists = IN[0]
OUT = group_by_overlap(lists)

Hi Ewan.

Thank you so much for your reply and for the codes, because I think I also used your code to create a BoundingBox for multiple elements belonging to a list.
But now that I’ve added more Pipes to complicate the test model, I don’t understand why 400198 intersects 400199? (The yellow cylinders are generic models that the script inserts by increasing the overall radius of the Pipe, including any insulation).

I think the Lacing is ok!?

Tnx again.

Luca

Hi @Luca79 maybe group by distance from spring could help

Hi @sovitek

thanks for the tip. I hadn’t discovered that node yet.

For now, though, if possible, I’d like to try continuing the script while still using elements…if possible :thinking:

1 Like

OK, guess spring have a node for group element by distance as well…not sure if it could fit your workflow, but you could give it a try

Hi @sovitek

I had installed a version of Spring without that node. Now I updated and found the node. I’ll test it as soon as I can.

tnx
Luca