37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
|
"""
|
||
|
Operations on planar geometry (usually used for laser cutting parts)
|
||
|
"""
|
||
|
import math
|
||
|
from typing import Tuple
|
||
|
import cadquery as Cq
|
||
|
|
||
|
def extrude_with_markers(
|
||
|
sketch: Cq.Sketch,
|
||
|
thickness: float,
|
||
|
tags: list[Tuple[str, Cq.Location]],
|
||
|
reverse: bool = False):
|
||
|
"""
|
||
|
Extrudes a sketch and place tags on the sketch for mating.
|
||
|
|
||
|
Each tag is of the format `(name, loc)`, where the (must be 2d) location's
|
||
|
angle is specifies in degrees counterclockwise from +X. Two marks are
|
||
|
generated for each `name`, "{name}" for the location (with normal) and
|
||
|
"{name}_dir" for the directrix specified by the angle.
|
||
|
|
||
|
This simulates a process of laser cutting and bonding (for wood and acrylic)
|
||
|
"""
|
||
|
result = (
|
||
|
Cq.Workplane('XY')
|
||
|
.placeSketch(sketch)
|
||
|
.extrude(thickness)
|
||
|
)
|
||
|
plane = result.faces("<Z" if reverse else ">Z").workplane()
|
||
|
sign = -1 if reverse else 1
|
||
|
for tag, p in tags:
|
||
|
(x, y), angle = p.to2d()
|
||
|
theta = sign * math.radians(angle)
|
||
|
direction = (math.cos(theta), math.sin(theta), 0)
|
||
|
plane.moveTo(x, sign * y).tagPlane(tag)
|
||
|
plane.moveTo(x, sign * y).tagPlane(f"{tag}_dir", direction)
|
||
|
return result
|