kumiki.csg.symmetry¶
Flat import path
kumiki/__init__.py re-exports everything on this page via from kumiki import *, so every name below is also available directly as kumiki.DEFAULT_TOLERANCE -- you do not need to import from the submodule path shown in the heading above.
kumiki.csg.symmetry
¶
Find which cut timbers are the same piece: identical, rotated, or mirrored (a reflection).
For frame authors who want to solve or draw a piece once for all its copies. It reports matches and what differs between them (labels, reference features, tags); what to do with them is the caller's choice.
Two timbers are compared in their own local frames (x width, y height, z length):
- Their CSG trees must have the same shape (node types and children, in order).
- Each of 16 symmetries (flips of the three axes, and swapping width with height) is tried by walking both trees in step, mapping the second's primitives through it. Directions, sizes, radii and profile shapes must agree; positions give equations linear in one unknown shift, solved at the end.
- A symmetry fits when every equation holds. Determinant +1 is a rotation, -1 a reflection.
Trees are compared, not solids, so a match is never claimed falsely, but two pieces built differently may match under fewer symmetries than their shapes would (e.g. peg-hole cutters running from opposite faces).
SymmetryKind
¶
Symmetry
dataclass
¶
Symmetry(matrix: ndarray, shift: ndarray, kind: SymmetryKind, description: str)
A map from one piece onto another in their local frames: point p of the second is at matrix @ p + shift on the first.
TimberMatch
dataclass
¶
TimberMatch(cut: CutTimber, kind: SymmetryKind, symmetries: Tuple[Symmetry, ...], differences: Tuple[str, ...])
A timber matching its group's representative.
kind is IDENTICAL if the identity fits, else ROTATION if any rotation does, else REFLECTION (a
handed piece). symmetries lists all that fit. differences are what the geometry doesn't settle
(labels, reference features, tags); they never prevent a match.
SymmetricTimberGroup
dataclass
¶
SymmetricTimberGroup(representative: CutTimber, matches: Tuple[TimberMatch, ...])
One distinct piece: the first timber found of it, and every timber that matches it.
csg_symmetries
¶
csg_symmetries(a: CutCSG, b: CutCSG, tolerance: float = DEFAULT_TOLERANCE) -> List[Symmetry]
Return every Symmetry mapping tree b onto tree a (each in its own local frame): identity first, then rotations, then reflections.
Source code in kumiki/csg/symmetry.py
timber_symmetries
¶
timber_symmetries(a: CutTimber, b: CutTimber, tolerance: float = DEFAULT_TOLERANCE) -> List[Symmetry]
Return every Symmetry mapping cut timber b onto a. With a twice, the piece's own symmetries.
Source code in kumiki/csg/symmetry.py
match_timbers
¶
match_timbers(cut_timbers: Sequence[CutTimber], tolerance: float = DEFAULT_TOLERANCE) -> List[SymmetricTimberGroup]
Return the distinct pieces among cut_timbers, in the order first met.
Each timber joins the first group whose representative it matches (timber_symmetries), else starts its own. Only timbers with the same tree shape are compared.