def min_dist(
    scene: Scene,
    a: str | list[str] | None,
    b: str | list[str] | None = None,
    a_tags: set = None,
    b_tags: set = None,
    bvh_cache: dict = None,
):
    """
    Computes one-to-one, many-to-one, one-to-many or many-to-many distance

    In all cases, returns the minimum distance between any object in a and b
    """
    # we get fcl error otherwise
    if len(a) == 1 and len(b) == 1 and a[0] == b[0]:
        return DistanceResult(dist=0, names=[a[0], b[0]], data=None)
    a, b, a_tags, b_tags = preprocess_collision_query_cases(a, b, a_tags, b_tags)
    col = iu.col_from_subset(scene, a, a_tags, bvh_cache)

    if b is None and len(a) == 1:
        dist, data = 1e9, None
    elif b is None:
        lazydebug(logger, lambda: f"min_dist_internal({a=}, {b=})")
        dist, data = col.min_distance_internal(return_data=True)
    elif isinstance(b, str):
        T, g = scene.graph[b]
        geom = scene.geometry[g]
        if b_tags is not None and len(b_tags) > 0:
            obj = iu.blender_objs_from_names(b)[0]
            mask = tagging.tagged_face_mask(obj, b_tags)
            if not mask.any():
                lazydebug(logger, lambda: f"{b=} had {mask.sum()=} for {b_tags=}")
            geom = geom.submesh(np.where(mask), append=True)
            assert len(geom.faces) == mask.sum()

        lazydebug(logger, lambda: f"min_dist_single({a=}, {b=})")
        dist, data = col.min_distance_single(geom, transform=T, return_data=True)

        if "__external" in data.names:
            data.names.remove("__external")
            data.names.add(b)
            data._points[b] = data._points["__external"]
            data._points.pop("__external")
            logging.debug(f"WARNING: swapped __external for {b} to make {data.names}")
    elif isinstance(b, (list, set)):
        logger.debug(f"min_dist_other({a=}, {b=})")
        col2 = iu.col_from_subset(scene, b, b_tags, bvh_cache)
        dist, data = col.min_distance_other(col2, return_data=True)
    else:
        raise ValueError(f"Unhandled case {a=} {b=}")

    if data is not None:
        assert "__external" not in data.names

    return DistanceResult(
        dist=dist, names=list(data.names) if data is not None else None, data=data
    )

    Computes one-to-one, many-to-one, one-to-many or many-to-many distance

    In all cases, returns the minimum distance between any object in a and b
    
infinigen/core/constraints/evaluator/node_impl/trimesh_geometry.py