feat: integrate SimpleCADAPI 2.0.2 CAD workflows

This commit is contained in:
Jerry
2026-08-03 11:17:05 +08:00
parent b5738e9109
commit c3a0f269b7
481 changed files with 110229 additions and 12826 deletions
@@ -9,6 +9,7 @@ import simplecadapi as scad
from simplecadapi import ql
@scad.requires_session
def apply_tags(*, shape: scad.Solid, tags: Iterable[str]) -> scad.Solid:
"""Apply semantic tags through the public functional API."""
@@ -18,12 +19,14 @@ def apply_tags(*, shape: scad.Solid, tags: Iterable[str]) -> scad.Solid:
return tagged
@scad.requires_session
def make_annulus_rsolid(
*,
outer_radius: float,
inner_radius: float,
bottom_z: float,
height: float,
tag_prefix: str,
tags: Iterable[str],
) -> scad.Solid:
"""Create a strict single-solid annular cylinder."""
@@ -33,17 +36,22 @@ def make_annulus_rsolid(
height=height,
bottom_face_center=(0.0, 0.0, bottom_z),
axis=(0.0, 0.0, 1.0),
tag_prefix=f"{tag_prefix}.outer",
result_tag=f"feature.{tag_prefix}.outer",
)
bore = scad.make_cylinder_rsolid(
radius=inner_radius,
height=height + 2.0,
bottom_face_center=(0.0, 0.0, bottom_z - 1.0),
axis=(0.0, 0.0, 1.0),
tag_prefix=f"{tag_prefix}.bore",
result_tag=f"tool.{tag_prefix}.bore",
)
annulus = scad.cut_rsolid(outer, bore, skip_non_intersecting=False)
return apply_tags(shape=annulus, tags=tags)
@scad.requires_session
def make_axis_part_rpart(
*,
part_id: str,
@@ -70,6 +78,7 @@ def make_axis_part_rpart(
return part
@scad.requires_session
def make_z_rotation_rplacement(
*,
origin: tuple[float, float, float],
@@ -94,6 +103,7 @@ def radial_centers(*, count: int, radius: float, angle_offset: float = 0.0):
yield index, angle_degrees, (radius * math.cos(angle), radius * math.sin(angle))
@scad.requires_session
def make_axial_hole_cutters_rsolids(
*,
count: int,
@@ -101,12 +111,13 @@ def make_axial_hole_cutters_rsolids(
hole_radius: float,
bottom_z: float,
height: float,
tag_prefix: str,
angle_offset: float = 0.0,
) -> list[scad.Solid]:
"""Create equally spaced axial hole cutters."""
cutters = []
for _index, _angle, center in radial_centers(
for index, _angle, center in radial_centers(
count=count,
radius=pcd / 2.0,
angle_offset=angle_offset,
@@ -117,6 +128,8 @@ def make_axial_hole_cutters_rsolids(
height=height,
bottom_face_center=(center[0], center[1], bottom_z),
axis=(0.0, 0.0, 1.0),
tag_prefix=f"{tag_prefix}.hole{index + 1}",
result_tag=f"tool.{tag_prefix}.hole{index + 1}",
)
)
return cutters
@@ -126,9 +139,13 @@ def ground_solid(*, label: str, solid: scad.Solid) -> None:
"""Print a concise QL-backed solid summary."""
faces = ql.select(items=solid.get_faces()).all()
role_faces = ql.select(items=faces).where(ql.tag(pattern="role.*")).all()
local_roles = [
tag
for tag in scad.list_tags(shape=solid, scope="local")
if tag.startswith("role.")
]
print(
f"{label}: faces={len(faces)} role_faces={len(role_faces)} "
f"{label}: faces={len(faces)} local_roles={len(local_roles)} "
f"volume={solid.get_volume():.3f} tags={','.join(scad.list_tags(shape=solid))}"
)
@@ -142,6 +159,7 @@ def ground_compound(*, label: str, compound: scad.Compound) -> None:
print(f"{label}: solids={len(solids)} faces={faces} volume={volume:.3f}")
@scad.requires_session
def connector_ref(*, component_id: str, connector_id: str) -> scad.ConnectorRef:
"""Create a component-scoped connector reference."""