Cosplay/nhf/checks.py

65 lines
2.1 KiB
Python

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