import cadquery as Cq def binary_intersection(a: Cq.Assembly) -> Cq.Shape: objs = [s.toCompound() for _, s in a.traverse() if isinstance(s, Cq.Assembly)] obj1, obj2 = objs[:2] return obj1.intersect(obj2) def visualize_intersection(assembly: Cq.Assembly, tol: float=1e-6) -> Cq.Shape: """ Given an assembly, test the pairwise intersection volume of its components. Return the pairs whose intersection volume exceeds `tol`. """ m = {name: (i, shape.moved(loc)) for i, (shape, name, loc, _) in enumerate(assembly)} for name, (i1, sh1) in m.items(): for name2, (i2, sh2) in m.items(): if name == name2: assert i1 == i2 continue if i2 <= i1: # Remove the upper diagonal continue head = name.split('/', 2)[1] head2 = name2.split('/', 2)[1] if head == head2: # Do not test into subassemblies continue isect = sh1.intersect(sh2) vol = isect.Volume() if vol > tol: return isect return None def pairwise_intersection(assembly: Cq.Assembly, tol: float=1e-6) -> list[(str, str, float)]: """ Given an assembly, test the pairwise intersection volume of its components. Return the pairs whose intersection volume exceeds `tol`. """ m = {name: (i, shape.moved(loc)) for i, (shape, name, loc, _) in enumerate(assembly)} result = [] for name, (i1, sh1) in m.items(): for name2, (i2, sh2) in m.items(): if name == name2: assert i1 == i2 continue if i2 <= i1: # Remove the upper diagonal continue head = name.split('/', 2)[1] head2 = name2.split('/', 2)[1] if head == head2: # Do not test into subassemblies continue vol = sh1.intersect(sh2).Volume() if vol > tol: result.append((name, name2, vol)) return result