I asked ChatGPT to select all objects intersected by other objects

Script asks for geometry in Set A and Set B.
Then selects the geometry in Set A intersected by the geometry in Set B.

This time I had to debug the script a few times.
Tested on 2000 geometries, for meshes, curves, surfaces, polysurfaces.

# -*- coding: utf-8 -*-
import Rhino
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs
import scriptcontext as sc

def to_brep_from_id(obj_id):
    """
    Try to turn any supported object into a Brep.
    - Brep / polysurface / surface / extrusion: via rs.coercebrep
    - Mesh: via Brep.CreateFromMesh
    Returns a Brep or None.
    """
    if not obj_id:
        return None

    geo = rs.coercegeometry(obj_id)
    if geo is None:
        return None

    # Mesh → Brep
    if isinstance(geo, rg.Mesh):
        brep = rg.Brep.CreateFromMesh(geo, True)
        return brep

    # Brep / Surface / Extrusion etc.
    brep = rs.coercebrep(obj_id)
    return brep


def objects_clash(id_a, id_b, tol):
    """
    True geometric clash test between two objects.
    Uses BrepBrep intersection only.
    No bounding box filtering involved.
    """
    brep_a = to_brep_from_id(id_a)
    brep_b = to_brep_from_id(id_b)

    # If we can't convert either to a Brep, skip
    if brep_a is None or brep_b is None:
        return False

    # Real clash: BrepBrep intersection
    rc, curves, points = rg.Intersect.Intersection.BrepBrep(brep_a, brep_b, tol)
    if not rc:
        return False

    has_curves = curves is not None and len(curves) > 0
    has_points = points is not None and len(points) > 0

    return has_curves or has_points


def main():
    tol = sc.doc.ModelAbsoluteTolerance

    # First set: GeoA (can be preselected)
    geo_a_ids = rs.GetObjects(
        "Select GeoA (objects that will be filtered by clash)",
        preselect=True,
        select=False
    )
    if not geo_a_ids:
        print("No GeoA objects selected.")
        return

    # Second set: GeoB (clashing objects)
    geo_b_ids = rs.GetObjects(
        "Select GeoB (objects that may clash with GeoA)",
        preselect=False,
        select=False
    )
    if not geo_b_ids:
        print("No GeoB objects selected.")
        return

    clashing_ids = []
    count_a = len(geo_a_ids)
    count_b = len(geo_b_ids)

    for i, id_a in enumerate(geo_a_ids):
        # Optional: progress feedback for large sets:
        # print("Testing {}/{} from GeoA...".format(i+1, count_a))

        for id_b in geo_b_ids:
            if objects_clash(id_a, id_b, tol):
                clashing_ids.append(id_a)
                break  # already found a clash, no need to test more GeoB

    rs.UnselectAllObjects()

    if clashing_ids:
        rs.SelectObjects(clashing_ids)
        print("Found {} clashing object(s) in GeoA (out of {} GeoA, {} GeoB).".format(
            len(clashing_ids), count_a, count_b))
        print("They are now selected.")
    else:
        print("No clashes found between GeoA and GeoB.")


if __name__ == "__main__":
    main()