refactor: Use 2d location in extrusion argument

This commit is contained in:
Leni Aniva 2024-07-17 19:28:56 -07:00
parent 014784be34
commit 6d72749c9b
Signed by: aniva
GPG Key ID: 4D9B1C8D10EA4C50
3 changed files with 72 additions and 68 deletions

36
nhf/parts/planar.py Normal file
View File

@ -0,0 +1,36 @@
"""
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

View File

@ -12,6 +12,7 @@ from nhf.build import Model, TargetKind, target, assembly, submodel
from nhf.parts.box import box_with_centre_holes, MountingBox, Hole
from nhf.parts.joints import HirthJoint
from nhf.touhou.houjuu_nue.joints import ShoulderJoint, ElbowJoint, DiskJoint
from nhf.parts.planar import extrude_with_markers
import nhf.utils
@dataclass(kw_only=True)
@ -300,13 +301,13 @@ class WingProfile(Model):
c, s = math.cos(-theta), math.sin(-theta)
tags = [
# transforms [axle_dist, -sw/2] about the centre (tip_x, tip_y - sw/2)
("shoulder", (
("shoulder", Cq.Location.from2d(
self.shoulder_tip_x + axle_dist * c + (-sw/2) * s,
self.shoulder_tip_y - sw / 2 - axle_dist * s + (-sw/2) * c),
self.shoulder_joint.angle_neutral),
("base", (base_dx, base_dy), 90),
self.shoulder_tip_y - sw / 2 - axle_dist * s + (-sw/2) * c,
self.shoulder_joint.angle_neutral)),
("base", Cq.Location.from2d(base_dx, base_dy, 90)),
]
result = nhf.utils.extrude_with_markers(
result = extrude_with_markers(
self.profile_s0(),
self.panel_thickness,
tags,
@ -453,21 +454,21 @@ class WingProfile(Model):
shoulder_h = self.shoulder_joint.child_height
h = (self.shoulder_joint.height - shoulder_h) / 2
tags_shoulder = [
("shoulder_bot", (0, h), 90),
("shoulder_top", (0, h + shoulder_h), 270),
("shoulder_bot", Cq.Location.from2d(0, h, 90)),
("shoulder_top", Cq.Location.from2d(0, h + shoulder_h, 270)),
]
h = self.elbow_height / 2
tags_elbow = [
("elbow_bot",
self.elbow_to_abs(-self.elbow_joint.parent_arm_radius, h - self.elbow_h2),
self.elbow_angle + 0),
("elbow_top",
self.elbow_to_abs(-self.elbow_joint.parent_arm_radius, h + self.elbow_h2),
self.elbow_angle + 0),
("elbow_bot", Cq.Location.from2d(
*self.elbow_to_abs(-self.elbow_joint.parent_arm_radius, h - self.elbow_h2),
self.elbow_angle + 0)),
("elbow_top", Cq.Location.from2d(
*self.elbow_to_abs(-self.elbow_joint.parent_arm_radius, h + self.elbow_h2),
self.elbow_angle + 0)),
]
profile = self.profile_s1()
tags = tags_shoulder + tags_elbow
return nhf.utils.extrude_with_markers(
return extrude_with_markers(
profile, self.panel_thickness, tags, reverse=front)
@submodel(name="spacer-s1-shoulder")
def spacer_s1_shoulder(self) -> MountingBox:
@ -526,25 +527,25 @@ class WingProfile(Model):
def surface_s2(self, front: bool = True) -> Cq.Workplane:
h = self.elbow_height / 2
tags_elbow = [
("elbow_bot",
self.elbow_to_abs(self.elbow_joint.child_arm_radius, h - self.elbow_h2),
self.elbow_angle + 180),
("elbow_top",
self.elbow_to_abs(self.elbow_joint.child_arm_radius, h + self.elbow_h2),
self.elbow_angle + 180),
("elbow_bot", Cq.Location.from2d(
*self.elbow_to_abs(self.elbow_joint.child_arm_radius, h - self.elbow_h2),
self.elbow_angle + 180)),
("elbow_top", Cq.Location.from2d(
*self.elbow_to_abs(self.elbow_joint.child_arm_radius, h + self.elbow_h2),
self.elbow_angle + 180)),
]
h = self.wrist_height / 2
tags_wrist = [
("wrist_bot",
self.wrist_to_abs(-self.wrist_joint.parent_arm_radius, h - self.wrist_h2),
self.wrist_angle),
("wrist_top",
self.wrist_to_abs(-self.wrist_joint.parent_arm_radius, h + self.wrist_h2),
self.wrist_angle),
("wrist_bot", Cq.Location.from2d(
*self.wrist_to_abs(-self.wrist_joint.parent_arm_radius, h - self.wrist_h2),
self.wrist_angle)),
("wrist_top", Cq.Location.from2d(
*self.wrist_to_abs(-self.wrist_joint.parent_arm_radius, h + self.wrist_h2),
self.wrist_angle)),
]
profile = self.profile_s2()
tags = tags_elbow + tags_wrist
return nhf.utils.extrude_with_markers(profile, self.panel_thickness, tags, reverse=front)
return extrude_with_markers(profile, self.panel_thickness, tags, reverse=front)
@submodel(name="spacer-s2-elbow")
def spacer_s2_elbow(self) -> MountingBox:
return self.spacer_of_joint(
@ -596,15 +597,15 @@ class WingProfile(Model):
front: bool = True) -> Cq.Workplane:
h = self.wrist_height / 2
tags = [
("wrist_bot",
self.wrist_to_abs(self.wrist_joint.child_arm_radius, h - self.wrist_h2),
self.wrist_angle + 180),
("wrist_top",
self.wrist_to_abs(self.wrist_joint.child_arm_radius, h + self.wrist_h2),
self.wrist_angle + 180),
("wrist_bot", Cq.Location.from2d(
*self.wrist_to_abs(self.wrist_joint.child_arm_radius, h - self.wrist_h2),
self.wrist_angle + 180)),
("wrist_top", Cq.Location.from2d(
*self.wrist_to_abs(self.wrist_joint.child_arm_radius, h + self.wrist_h2),
self.wrist_angle + 180)),
]
profile = self.profile_s3()
return nhf.utils.extrude_with_markers(profile, self.panel_thickness, tags, reverse=front)
return extrude_with_markers(profile, self.panel_thickness, tags, reverse=front)
@submodel(name="spacer-s3-wrist")
def spacer_s3_wrist(self) -> MountingBox:
return self.spacer_of_joint(

View File

@ -1,9 +1,5 @@
"""
Marking utilities for `Cq.Workplane`
Adds the functions to `Cq.Workplane`:
1. `tagPoint`
2. `tagPlane`
Utility functions for cadquery objects
"""
import math
import functools
@ -170,32 +166,3 @@ def get_abs_location(self: Cq.Assembly,
return loc
Cq.Assembly.get_abs_location = get_abs_location
def extrude_with_markers(sketch: Cq.Sketch,
thickness: float,
tags: list[Tuple[str, Tuple[float, float], float]],
reverse: bool = False):
"""
Extrudes a sketch and place tags on the sketch for mating.
Each tag is of the format `(name, (x, y), angle)`, where the 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, (px, py), angle in tags:
theta = sign * math.radians(angle)
direction = (math.cos(theta), math.sin(theta), 0)
plane.moveTo(px, sign * py).tagPlane(tag)
plane.moveTo(px, sign * py).tagPlane(f"{tag}_dir", direction)
return result