merge
This commit is contained in:
Binary file not shown.
@@ -1,14 +1,17 @@
|
|||||||
{
|
{
|
||||||
"schema_version": "1.0",
|
"schema_version": "1.0",
|
||||||
"request": "生成中心距120mm、大头孔36mm、小头孔20mm、厚14mm的发动机连杆,导出STEP和STL,后续可以修改参数",
|
"request": "Modify the existing build123d connecting rod from the CAD Viewer selection: add a 2 mm wide blind slot along the selected segment on face f18, regenerate STEP, STL, and CAD Viewer mesh/topology assets.",
|
||||||
"route": {
|
"route": {
|
||||||
"selected_backend": "build123d",
|
"selected_backend": "build123d",
|
||||||
"runner_skill": "cad",
|
"runner_skill": "cad",
|
||||||
|
"project": "text-to-cad",
|
||||||
"confidence": "high",
|
"confidence": "high",
|
||||||
"fallback_order": [
|
"fallback_order": [
|
||||||
"simplecadapi",
|
"simplecadapi",
|
||||||
"cadam"
|
"cadam"
|
||||||
],
|
],
|
||||||
|
"operation": "modify",
|
||||||
|
"modification_strategy": "native_parameter_editing",
|
||||||
"decision_path": "route-decision.json"
|
"decision_path": "route-decision.json"
|
||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
@@ -26,7 +29,11 @@
|
|||||||
"role": "secondary"
|
"role": "secondary"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "connecting_rod_20260722T071141Z.png",
|
"path": ".connecting_rod.step.glb",
|
||||||
|
"role": "viewer_mesh_topology"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "connecting_rod_slot_review_20260723T100007Z.png",
|
||||||
"role": "verification_snapshot"
|
"role": "verification_snapshot"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -38,57 +45,74 @@
|
|||||||
"small_end_outer_diameter_mm": 36.0,
|
"small_end_outer_diameter_mm": 36.0,
|
||||||
"small_end_bore_diameter_mm": 20.0,
|
"small_end_bore_diameter_mm": 20.0,
|
||||||
"web_width_mm": 24.0,
|
"web_width_mm": 24.0,
|
||||||
"pocket_depth_each_side_mm": 3.0
|
"pocket_depth_each_side_mm": 3.0,
|
||||||
|
"viewer_slot_start_mm": [
|
||||||
|
-28.73179347578467,
|
||||||
|
-0.3844822039559189
|
||||||
|
],
|
||||||
|
"viewer_slot_end_mm": [
|
||||||
|
24.36043904920138,
|
||||||
|
-0.24367243243227724
|
||||||
|
],
|
||||||
|
"viewer_slot_surface_z_mm": 11.0,
|
||||||
|
"viewer_slot_width_mm": 2.0,
|
||||||
|
"viewer_slot_blind_depth_mm": 2.0,
|
||||||
|
"viewer_slot_bottom_z_mm": 9.0
|
||||||
|
},
|
||||||
|
"experience": {
|
||||||
|
"library": "../../../cad-experience-library/library.json",
|
||||||
|
"context_kind": "generalized_cad_experience_query",
|
||||||
|
"methods_applied": []
|
||||||
},
|
},
|
||||||
"assumptions": [
|
"assumptions": [
|
||||||
|
"The selected face f18 is the existing top-pocket floor at z=11 mm, so the blind slot cuts inward into the material from z=11 mm down to z=9 mm.",
|
||||||
|
"The CAD edit intent marks depth as blind but does not provide a numeric depth, so a conservative 2 mm blind depth was used.",
|
||||||
"This V1 sample demonstrates routing and editability rather than a production-rated engine component.",
|
"This V1 sample demonstrates routing and editability rather than a production-rated engine component.",
|
||||||
"Material, fatigue loads, bearing fits, lubrication, fasteners, tolerances, and split big-end construction are intentionally out of scope."
|
"Material, fatigue loads, bearing fits, lubrication, fasteners, tolerances, and split big-end construction are intentionally out of scope."
|
||||||
],
|
],
|
||||||
"validation": [
|
"validation": [
|
||||||
{
|
{
|
||||||
"check": "closed solid count",
|
"check": "STEP generation from editable source",
|
||||||
"result": 1,
|
"result": "scripts/cad step regenerated connecting_rod.step, connecting_rod.stl, and hidden CAD Viewer GLB/topology assets from connecting_rod.py.",
|
||||||
"status": "pass"
|
"status": "pass"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"check": "bounding box millimeters",
|
"check": "closed solid topology",
|
||||||
"result": [
|
|
||||||
166.0,
|
|
||||||
56.0,
|
|
||||||
14.0
|
|
||||||
],
|
|
||||||
"status": "pass"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"check": "volume cubic millimeters",
|
|
||||||
"result": 50729.813,
|
|
||||||
"status": "pass"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"check": "bore radii millimeters",
|
|
||||||
"result": [
|
|
||||||
10.0,
|
|
||||||
18.0
|
|
||||||
],
|
|
||||||
"status": "pass"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"check": "STEP topology",
|
|
||||||
"result": {
|
"result": {
|
||||||
|
"kind": "part",
|
||||||
"shape_count": 1,
|
"shape_count": 1,
|
||||||
"face_count": 18,
|
"face_count": 23,
|
||||||
"edge_count": 42,
|
"edge_count": 54,
|
||||||
"warnings": []
|
"bounds_mm": [
|
||||||
|
165.978199,
|
||||||
|
55.977382,
|
||||||
|
14.0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"status": "pass"
|
"status": "pass"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"check": "isometric snapshot review",
|
"check": "selected-face slot placement",
|
||||||
"result": "Both bores, the connected web, and the top pocket are visibly present; no disconnected body is visible.",
|
"result": "Original selected face f18 remains the top-pocket floor at z=11 mm; new slot bottom face f23 is centered at [-2.185677, -0.314077, 9.0].",
|
||||||
|
"status": "pass"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"check": "blind slot depth",
|
||||||
|
"result": "Slot side faces span z=9.0 mm to z=11.0 mm.",
|
||||||
|
"status": "pass"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"check": "slot width",
|
||||||
|
"result": "Slot end faces are cylinders with radius 1.0 mm, matching the requested 2.0 mm slot width.",
|
||||||
|
"status": "pass"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"check": "snapshot review",
|
||||||
|
"result": "Isometric snapshot shows the connecting rod, existing top pocket, and the new narrow blind slot without visible breakage or disconnected geometry.",
|
||||||
"status": "pass"
|
"status": "pass"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"viewer_links": [
|
"viewer_links": [
|
||||||
"http://127.0.0.1:4178/?dir=%2FUsers%2Fjerry%2Flinkhand%2FCadSet%2Ftext-to-cad%2Fmodels%2Fcad-router-v1&file=connecting_rod.step"
|
"http://127.0.0.1:5175/?dir=%2FUsers%2Flk%2FProjects%2FcadSet%2Ftext-to-cad%2Fmodels%2Fcad-router-v1&file=connecting_rod.step"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
"""Parametric V1 connecting-rod sample routed to the build123d backend."""
|
"""Parametric V1 connecting-rod sample routed to the build123d backend."""
|
||||||
|
|
||||||
from build123d import Align, Box, BuildPart, BuildSketch, Cylinder, Location, Locations, Mode, Plane, SlotOverall, extrude
|
from math import atan2, degrees, hypot
|
||||||
|
|
||||||
|
from build123d import (
|
||||||
|
Align,
|
||||||
|
Box,
|
||||||
|
BuildPart,
|
||||||
|
BuildSketch,
|
||||||
|
Cylinder,
|
||||||
|
Location,
|
||||||
|
Locations,
|
||||||
|
Mode,
|
||||||
|
Plane,
|
||||||
|
SlotOverall,
|
||||||
|
extrude,
|
||||||
|
fillet,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
CENTER_DISTANCE = 120.0
|
CENTER_DISTANCE = 120.0
|
||||||
@@ -16,6 +31,61 @@ POCKET_LENGTH = 72.0
|
|||||||
POCKET_WIDTH = 12.0
|
POCKET_WIDTH = 12.0
|
||||||
POCKET_DEPTH = 3.0
|
POCKET_DEPTH = 3.0
|
||||||
|
|
||||||
|
VIEWER_SLOT_START = (-28.73179347578467, -0.3844822039559189)
|
||||||
|
VIEWER_SLOT_END = (24.36043904920138, -0.24367243243227724)
|
||||||
|
VIEWER_SLOT_SURFACE_Z = THICKNESS - POCKET_DEPTH
|
||||||
|
VIEWER_SLOT_WIDTH = 2.0
|
||||||
|
VIEWER_SLOT_BLIND_DEPTH = 2.0
|
||||||
|
VIEWER_EDGE_E14_FILLET_RADIUS = 1.0
|
||||||
|
VIEWER_HOLE_CENTER = (-22.122781376227962, -9.435525387895417)
|
||||||
|
VIEWER_HOLE_DIAMETER = 6.0
|
||||||
|
VIEWER_HOLE_BLIND_DEPTH = 6.0
|
||||||
|
VIEWER_HOLE_SURFACE_Z = THICKNESS
|
||||||
|
VIEWER_HOLE_BOOLEAN_OVERTRAVEL = 0.2
|
||||||
|
|
||||||
|
VIEWER_SLOT_CENTER = (
|
||||||
|
(VIEWER_SLOT_START[0] + VIEWER_SLOT_END[0]) / 2.0,
|
||||||
|
(VIEWER_SLOT_START[1] + VIEWER_SLOT_END[1]) / 2.0,
|
||||||
|
)
|
||||||
|
VIEWER_SLOT_LENGTH = hypot(
|
||||||
|
VIEWER_SLOT_END[0] - VIEWER_SLOT_START[0],
|
||||||
|
VIEWER_SLOT_END[1] - VIEWER_SLOT_START[1],
|
||||||
|
)
|
||||||
|
VIEWER_SLOT_ROTATION = degrees(
|
||||||
|
atan2(
|
||||||
|
VIEWER_SLOT_END[1] - VIEWER_SLOT_START[1],
|
||||||
|
VIEWER_SLOT_END[0] - VIEWER_SLOT_START[0],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _viewer_edge_e14(part):
|
||||||
|
"""Select the big-end top outer edge selected in CAD Viewer as e14."""
|
||||||
|
selected_edges = []
|
||||||
|
for edge in part.edges():
|
||||||
|
try:
|
||||||
|
edge_radius = edge.radius
|
||||||
|
edge_center = edge.arc_center
|
||||||
|
edge_normal = edge.normal()
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if abs(edge_radius - BIG_END_OUTER_DIAMETER / 2.0) > 0.05:
|
||||||
|
continue
|
||||||
|
if abs(edge_center.X + CENTER_DISTANCE / 2.0) > 0.05:
|
||||||
|
continue
|
||||||
|
if abs(edge_center.Y) > 0.05:
|
||||||
|
continue
|
||||||
|
if abs(edge_center.Z - THICKNESS) > 0.05:
|
||||||
|
continue
|
||||||
|
if abs(edge_normal.Z) < 1.0 - 1e-4:
|
||||||
|
continue
|
||||||
|
selected_edges.append(edge)
|
||||||
|
|
||||||
|
if len(selected_edges) != 1:
|
||||||
|
raise RuntimeError(f"Expected one viewer-selected e14 edge, found {len(selected_edges)}")
|
||||||
|
return selected_edges
|
||||||
|
|
||||||
|
|
||||||
def gen_step():
|
def gen_step():
|
||||||
"""Return a closed, STEP-ready connecting-rod solid in millimeters."""
|
"""Return a closed, STEP-ready connecting-rod solid in millimeters."""
|
||||||
@@ -67,6 +137,32 @@ def gen_step():
|
|||||||
SlotOverall(width=POCKET_LENGTH, height=POCKET_WIDTH)
|
SlotOverall(width=POCKET_LENGTH, height=POCKET_WIDTH)
|
||||||
extrude(amount=POCKET_DEPTH, mode=Mode.SUBTRACT)
|
extrude(amount=POCKET_DEPTH, mode=Mode.SUBTRACT)
|
||||||
|
|
||||||
|
with BuildSketch(Plane.XY.offset(VIEWER_SLOT_SURFACE_Z - VIEWER_SLOT_BLIND_DEPTH)):
|
||||||
|
with Locations(Location((VIEWER_SLOT_CENTER[0], VIEWER_SLOT_CENTER[1], 0.0))):
|
||||||
|
SlotOverall(
|
||||||
|
width=VIEWER_SLOT_LENGTH,
|
||||||
|
height=VIEWER_SLOT_WIDTH,
|
||||||
|
rotation=VIEWER_SLOT_ROTATION,
|
||||||
|
)
|
||||||
|
extrude(amount=VIEWER_SLOT_BLIND_DEPTH, mode=Mode.SUBTRACT)
|
||||||
|
|
||||||
|
with Locations(
|
||||||
|
Location(
|
||||||
|
(
|
||||||
|
VIEWER_HOLE_CENTER[0],
|
||||||
|
VIEWER_HOLE_CENTER[1],
|
||||||
|
VIEWER_HOLE_SURFACE_Z - VIEWER_HOLE_BLIND_DEPTH,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
Cylinder(
|
||||||
|
radius=VIEWER_HOLE_DIAMETER / 2.0,
|
||||||
|
height=VIEWER_HOLE_BLIND_DEPTH + VIEWER_HOLE_BOOLEAN_OVERTRAVEL,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||||
|
mode=Mode.SUBTRACT,
|
||||||
|
)
|
||||||
|
|
||||||
result = rod.part
|
result = rod.part
|
||||||
|
result = fillet(_viewer_edge_e14(result), radius=VIEWER_EDGE_E14_FILLET_RADIUS)
|
||||||
result.label = "cad_router_v1_connecting_rod"
|
result.label = "cad_router_v1_connecting_rod"
|
||||||
return result
|
return result
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,21 +1,13 @@
|
|||||||
{
|
{
|
||||||
"schema_version": "1.0",
|
"schema_version": "1.0",
|
||||||
"request": "参考图片生成一个8孔圆法兰,中心孔直径20毫米,外径50毫米,厚度4毫米,螺丝孔使用M3",
|
"request": "参考图片生成一个8孔圆法兰,中心孔直径20毫米,外径50毫米,厚度4毫米,螺丝孔使用M3;根据 viewer 选中的几何位置添加2x2、直径2毫米、8毫米间距的贯穿孔阵列、一个3毫米贯穿沉头孔,以及一个10x6x1毫米矩形口袋",
|
||||||
"route": {
|
"route": {
|
||||||
"selected_backend": "build123d",
|
"selected_backend": "build123d",
|
||||||
"runner_skill": "cad",
|
"runner_skill": "cad",
|
||||||
"project": "text-to-cad",
|
"project": "text-to-cad",
|
||||||
"fallback_order": [
|
"fallback_order": ["simplecadapi", "cadam"],
|
||||||
"simplecadapi",
|
"workflow_profiles": ["requirement_refinement", "visual_repair", "source_modification"],
|
||||||
"cadam"
|
"downstream_skills": ["cad-viewer"]
|
||||||
],
|
|
||||||
"workflow_profiles": [
|
|
||||||
"requirement_refinement",
|
|
||||||
"visual_repair"
|
|
||||||
],
|
|
||||||
"downstream_skills": [
|
|
||||||
"cad-viewer"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
"path": "flange_8x_m3.py",
|
"path": "flange_8x_m3.py",
|
||||||
@@ -30,6 +22,10 @@
|
|||||||
{
|
{
|
||||||
"path": "flange_8x_m3.stl",
|
"path": "flange_8x_m3.stl",
|
||||||
"role": "secondary"
|
"role": "secondary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".flange_8x_m3.step.glb",
|
||||||
|
"role": "viewer_mesh_topology"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@@ -39,12 +35,37 @@
|
|||||||
"bolt_hole_count": 8,
|
"bolt_hole_count": 8,
|
||||||
"bolt_hole_diameter_mm": 3.4,
|
"bolt_hole_diameter_mm": 3.4,
|
||||||
"bolt_circle_diameter_mm": 40.0,
|
"bolt_circle_diameter_mm": 40.0,
|
||||||
"angular_spacing_deg": 45.0
|
"angular_spacing_deg": 45.0,
|
||||||
|
"viewer_pattern_center_mm": [8.077088362294017, 15.744119598589815],
|
||||||
|
"viewer_pattern_hole_diameter_mm": 2.0,
|
||||||
|
"viewer_pattern_rows": 2,
|
||||||
|
"viewer_pattern_columns": 2,
|
||||||
|
"viewer_pattern_pitch_x_mm": 8.0,
|
||||||
|
"viewer_pattern_pitch_y_mm": 8.0,
|
||||||
|
"viewer_pattern_depth": "through",
|
||||||
|
"viewer_pattern_hole_centers_mm": [
|
||||||
|
[4.077088362294017, 11.744119598589815],
|
||||||
|
[12.077088362294017, 11.744119598589815],
|
||||||
|
[4.077088362294017, 19.744119598589815],
|
||||||
|
[12.077088362294017, 19.744119598589815]
|
||||||
|
],
|
||||||
|
"viewer_countersink_center_mm": [-14.6034432889167, -4.110394299469192],
|
||||||
|
"viewer_countersink_hole_diameter_mm": 3.0,
|
||||||
|
"viewer_countersink_diameter_mm": 6.0,
|
||||||
|
"viewer_countersink_angle_deg": 90.0,
|
||||||
|
"viewer_countersink_depth": "through",
|
||||||
|
"viewer_pocket_center_mm": [6.197199513379157, -14.374353062530322],
|
||||||
|
"viewer_pocket_shape": "rectangle",
|
||||||
|
"viewer_pocket_width_mm": 10.0,
|
||||||
|
"viewer_pocket_height_mm": 6.0,
|
||||||
|
"viewer_pocket_depth_mm": 1.0,
|
||||||
|
"viewer_pocket_bottom_z_mm": 3.0
|
||||||
},
|
},
|
||||||
"assumptions": [
|
"assumptions": [
|
||||||
"M3螺丝孔按普通间隙通孔处理,孔径采用3.4毫米,不是M3攻丝底孔。",
|
"M3螺丝孔按普通间隙通孔处理,孔径采用3.4毫米,不是M3攻丝底孔。",
|
||||||
"未指定分度圆,采用40毫米分度圆,以保持孔到外圆约3.3毫米的最小径向边距。",
|
"未指定分度圆,采用40毫米分度圆,以保持孔到外圆约3.3毫米的最小径向边距。",
|
||||||
"参考图中的车削纹理作为外观参考,不生成削弱4毫米薄法兰的深槽。"
|
"参考图中的车削纹理作为外观参考,不生成削弱4毫米薄法兰的深槽。",
|
||||||
|
"矩形口袋按 surface_xy 对齐全局 XY,沿选中面法向进入材料,深度1毫米。"
|
||||||
],
|
],
|
||||||
"validation": [
|
"validation": [
|
||||||
{
|
{
|
||||||
@@ -54,15 +75,32 @@
|
|||||||
"step_valid": true,
|
"step_valid": true,
|
||||||
"solid_count": 1,
|
"solid_count": 1,
|
||||||
"exact_size_mm": [50.0, 50.0, 4.0],
|
"exact_size_mm": [50.0, 50.0, 4.0],
|
||||||
|
"topology_faces": 24,
|
||||||
|
"topology_edges": 62,
|
||||||
"m3_clearance_hole_count": 8,
|
"m3_clearance_hole_count": 8,
|
||||||
"m3_clearance_hole_diameter_mm": 3.4,
|
"m3_clearance_hole_diameter_mm": 3.4,
|
||||||
"bolt_circle_diameter_mm": 40.0,
|
"viewer_pattern_hole_count": 4,
|
||||||
"angular_spacing_deg": 45.0,
|
"viewer_pattern_hole_diameter_mm": 2.0,
|
||||||
"visual_review": "passed_iso_opposite_top_front"
|
"viewer_countersink_hole_diameter_mm": 3.0,
|
||||||
|
"viewer_countersink_diameter_mm": 6.0,
|
||||||
|
"viewer_countersink_angle_deg": 90.0,
|
||||||
|
"viewer_pocket_bottom_center_mm": [6.197199513379157, -14.374353062530322, 3.0],
|
||||||
|
"viewer_pocket_bottom_size_mm": [10.0, 6.0],
|
||||||
|
"viewer_pocket_depth_mm": 1.0,
|
||||||
|
"viewer_mesh_topology": ".flange_8x_m3.step.glb",
|
||||||
|
"visual_review": "passed_viewer_pocket_top"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "review/viewer_pocket_top_20260724T031341Z.png",
|
||||||
|
"status": "passed",
|
||||||
|
"checks": {
|
||||||
|
"snapshot_camera": "top",
|
||||||
|
"pocket_visible": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"viewer_links": [
|
"viewer_links": [
|
||||||
"http://127.0.0.1:4178/?dir=%2FUsers%2Fjerry%2Flinkhand%2FCadSet%2Ftext-to-cad%2Fmodels%2Fcad-router-v1%2Fflange_8x_m3&file=flange_8x_m3.step"
|
"http://127.0.0.1:5174/?dir=%2FUsers%2Flk%2FProjects%2FcadSet%2Ftext-to-cad%2Fmodels%2Fcad-router-v1%2Fflange_8x_m3&file=flange_8x_m3.step"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"""Parametric eight-hole circular flange generated with build123d."""
|
"""Parametric eight-hole circular flange generated with build123d."""
|
||||||
|
|
||||||
from math import cos, radians, sin
|
from math import cos, radians, sin, tan
|
||||||
|
|
||||||
from build123d import Align, BuildPart, Cylinder, Location, Locations, Mode
|
from build123d import Align, Box, BuildPart, Cone, Cylinder, Location, Locations, Mode
|
||||||
|
|
||||||
|
|
||||||
OUTER_DIAMETER_MM = 50.0
|
OUTER_DIAMETER_MM = 50.0
|
||||||
@@ -11,6 +11,32 @@ THICKNESS_MM = 4.0
|
|||||||
BOLT_HOLE_COUNT = 8
|
BOLT_HOLE_COUNT = 8
|
||||||
M3_CLEARANCE_DIAMETER_MM = 3.4
|
M3_CLEARANCE_DIAMETER_MM = 3.4
|
||||||
BOLT_CIRCLE_DIAMETER_MM = 40.0
|
BOLT_CIRCLE_DIAMETER_MM = 40.0
|
||||||
|
M4_THREAD_SPEC = "M4"
|
||||||
|
M4_TAP_DRILL_DIAMETER_MM = 3.3
|
||||||
|
M4_THREAD_DEPTH_MM = 6.0
|
||||||
|
M4_THREAD_HOLE_CENTER_MM = (-6.104359972902419, -13.137483558259564)
|
||||||
|
M4_THREAD_HOLE_FACE_Z_MM = THICKNESS_MM
|
||||||
|
M4_THREAD_HOLE_DIRECTION = (0.0, 0.0, -1.0)
|
||||||
|
VIEWER_PATTERN_CENTER_MM = (8.077088362294017, 15.744119598589815)
|
||||||
|
VIEWER_PATTERN_HOLE_DIAMETER_MM = 2.0
|
||||||
|
VIEWER_PATTERN_ROWS = 2
|
||||||
|
VIEWER_PATTERN_COLUMNS = 2
|
||||||
|
VIEWER_PATTERN_PITCH_X_MM = 8.0
|
||||||
|
VIEWER_PATTERN_PITCH_Y_MM = 8.0
|
||||||
|
VIEWER_PATTERN_FACE_Z_MM = THICKNESS_MM
|
||||||
|
VIEWER_PATTERN_DIRECTION = (0.0, 0.0, -1.0)
|
||||||
|
VIEWER_COUNTERSINK_CENTER_MM = (-14.6034432889167, -4.110394299469192)
|
||||||
|
VIEWER_COUNTERSINK_HOLE_DIAMETER_MM = 3.0
|
||||||
|
VIEWER_COUNTERSINK_DIAMETER_MM = 6.0
|
||||||
|
VIEWER_COUNTERSINK_ANGLE_DEG = 90.0
|
||||||
|
VIEWER_COUNTERSINK_FACE_Z_MM = THICKNESS_MM
|
||||||
|
VIEWER_COUNTERSINK_DIRECTION = (0.0, 0.0, -1.0)
|
||||||
|
VIEWER_POCKET_CENTER_MM = (6.197199513379157, -14.374353062530322)
|
||||||
|
VIEWER_POCKET_WIDTH_MM = 10.0
|
||||||
|
VIEWER_POCKET_HEIGHT_MM = 6.0
|
||||||
|
VIEWER_POCKET_DEPTH_MM = 1.0
|
||||||
|
VIEWER_POCKET_FACE_Z_MM = THICKNESS_MM
|
||||||
|
VIEWER_POCKET_DIRECTION = (0.0, 0.0, -1.0)
|
||||||
|
|
||||||
|
|
||||||
def polar_point(radius: float, angle_degrees: float) -> tuple[float, float]:
|
def polar_point(radius: float, angle_degrees: float) -> tuple[float, float]:
|
||||||
@@ -46,6 +72,65 @@ def gen_step():
|
|||||||
mode=Mode.SUBTRACT,
|
mode=Mode.SUBTRACT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
m4_x_pos, m4_y_pos = M4_THREAD_HOLE_CENTER_MM
|
||||||
|
m4_cut_depth = min(M4_THREAD_DEPTH_MM, THICKNESS_MM)
|
||||||
|
with Locations(Location((m4_x_pos, m4_y_pos, M4_THREAD_HOLE_FACE_Z_MM - m4_cut_depth))):
|
||||||
|
Cylinder(
|
||||||
|
radius=M4_TAP_DRILL_DIAMETER_MM / 2.0,
|
||||||
|
height=m4_cut_depth + 1.0,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||||
|
mode=Mode.SUBTRACT,
|
||||||
|
)
|
||||||
|
|
||||||
|
pattern_center_x, pattern_center_y = VIEWER_PATTERN_CENTER_MM
|
||||||
|
pattern_start_x = pattern_center_x - (VIEWER_PATTERN_COLUMNS - 1) * VIEWER_PATTERN_PITCH_X_MM / 2.0
|
||||||
|
pattern_start_y = pattern_center_y - (VIEWER_PATTERN_ROWS - 1) * VIEWER_PATTERN_PITCH_Y_MM / 2.0
|
||||||
|
for row_index in range(VIEWER_PATTERN_ROWS):
|
||||||
|
for column_index in range(VIEWER_PATTERN_COLUMNS):
|
||||||
|
hole_x = pattern_start_x + column_index * VIEWER_PATTERN_PITCH_X_MM
|
||||||
|
hole_y = pattern_start_y + row_index * VIEWER_PATTERN_PITCH_Y_MM
|
||||||
|
with Locations(Location((hole_x, hole_y, -1.0))):
|
||||||
|
Cylinder(
|
||||||
|
radius=VIEWER_PATTERN_HOLE_DIAMETER_MM / 2.0,
|
||||||
|
height=THICKNESS_MM + 2.0,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||||
|
mode=Mode.SUBTRACT,
|
||||||
|
)
|
||||||
|
|
||||||
|
countersink_x, countersink_y = VIEWER_COUNTERSINK_CENTER_MM
|
||||||
|
countersink_radius = VIEWER_COUNTERSINK_DIAMETER_MM / 2.0
|
||||||
|
countersink_through_radius = VIEWER_COUNTERSINK_HOLE_DIAMETER_MM / 2.0
|
||||||
|
countersink_depth = (
|
||||||
|
countersink_radius - countersink_through_radius
|
||||||
|
) / tan(radians(VIEWER_COUNTERSINK_ANGLE_DEG / 2.0))
|
||||||
|
with Locations(Location((countersink_x, countersink_y, -1.0))):
|
||||||
|
Cylinder(
|
||||||
|
radius=countersink_through_radius,
|
||||||
|
height=THICKNESS_MM + 2.0,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||||
|
mode=Mode.SUBTRACT,
|
||||||
|
)
|
||||||
|
with Locations(
|
||||||
|
Location((countersink_x, countersink_y, VIEWER_COUNTERSINK_FACE_Z_MM - countersink_depth))
|
||||||
|
):
|
||||||
|
Cone(
|
||||||
|
countersink_through_radius,
|
||||||
|
countersink_radius,
|
||||||
|
countersink_depth + 0.05,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||||
|
mode=Mode.SUBTRACT,
|
||||||
|
)
|
||||||
|
|
||||||
|
pocket_x, pocket_y = VIEWER_POCKET_CENTER_MM
|
||||||
|
with Locations(Location((pocket_x, pocket_y, VIEWER_POCKET_FACE_Z_MM - VIEWER_POCKET_DEPTH_MM))):
|
||||||
|
Box(
|
||||||
|
VIEWER_POCKET_WIDTH_MM,
|
||||||
|
VIEWER_POCKET_HEIGHT_MM,
|
||||||
|
VIEWER_POCKET_DEPTH_MM + 0.05,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.MIN),
|
||||||
|
mode=Mode.SUBTRACT,
|
||||||
|
)
|
||||||
|
|
||||||
part = flange.part
|
part = flange.part
|
||||||
part.label = "flange_8x_m3_clearance"
|
part.label = "flange_8x_m3_clearance_with_m4_tapped_hole_viewer_pattern_countersink_and_pocket"
|
||||||
return part
|
return part
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -2,11 +2,67 @@
|
|||||||
"step_valid": true,
|
"step_valid": true,
|
||||||
"solid_count": 1,
|
"solid_count": 1,
|
||||||
"exact_size_mm": [50.0, 50.0, 4.0],
|
"exact_size_mm": [50.0, 50.0, 4.0],
|
||||||
|
"topology_counts": {
|
||||||
|
"faces": 24,
|
||||||
|
"edges": 62
|
||||||
|
},
|
||||||
"outer_radius_mm": 25.0,
|
"outer_radius_mm": 25.0,
|
||||||
"inner_radius_mm": 10.0,
|
"inner_radius_mm": 10.0,
|
||||||
"m3_clearance_hole_radius_mm": 1.7,
|
"m3_clearance_hole_radius_mm": 1.7,
|
||||||
"m3_clearance_hole_count": 8,
|
"m3_clearance_hole_count": 8,
|
||||||
"bolt_circle_radius_mm": 20.0,
|
"bolt_circle_radius_mm": 20.0,
|
||||||
"angular_spacing_deg": [45.0, 45.0, 45.0, 45.0, 45.0, 45.0, 45.0, 45.0],
|
"angular_spacing_deg": [45.0, 45.0, 45.0, 45.0, 45.0, 45.0, 45.0, 45.0],
|
||||||
"visual_review": "passed_iso_opposite_top_front"
|
"viewer_edits": {
|
||||||
|
"hole_pattern": {
|
||||||
|
"operation": "add_hole_pattern",
|
||||||
|
"selection_point_model_mm": [8.077088362294017, 15.744119598589815, 4.0],
|
||||||
|
"hole_diameter_mm": 2.0,
|
||||||
|
"rows": 2,
|
||||||
|
"columns": 2,
|
||||||
|
"pitch_x_mm": 8.0,
|
||||||
|
"pitch_y_mm": 8.0,
|
||||||
|
"depth": "through",
|
||||||
|
"hole_centers_mm": [
|
||||||
|
[4.077088362294017, 11.744119598589815, 2.0],
|
||||||
|
[12.077088362294017, 11.744119598589815, 2.0],
|
||||||
|
[4.077088362294017, 19.744119598589815, 2.0],
|
||||||
|
[12.077088362294017, 19.744119598589815, 2.0]
|
||||||
|
],
|
||||||
|
"verified_hole_count": 4,
|
||||||
|
"verified_hole_diameter_mm": 2.0,
|
||||||
|
"verified_through_height_mm": 4.0,
|
||||||
|
"max_center_error_mm": 0.0
|
||||||
|
},
|
||||||
|
"countersink": {
|
||||||
|
"operation": "add_countersink",
|
||||||
|
"selection_point_model_mm": [-14.6034432889167, -4.110394299469192, 4.0],
|
||||||
|
"hole_diameter_mm": 3.0,
|
||||||
|
"countersink_diameter_mm": 6.0,
|
||||||
|
"countersink_angle_deg": 90.0,
|
||||||
|
"countersink_depth_mm": 1.5,
|
||||||
|
"depth": "through"
|
||||||
|
},
|
||||||
|
"pocket": {
|
||||||
|
"operation": "add_pocket",
|
||||||
|
"selection_point_model_mm": [6.197199513379157, -14.374353062530322, 4.0],
|
||||||
|
"shape": "rectangle",
|
||||||
|
"width_mm": 10.0,
|
||||||
|
"height_mm": 6.0,
|
||||||
|
"depth_mm": 1.0,
|
||||||
|
"bottom_z_mm": 3.0,
|
||||||
|
"verified_bottom_center_mm": [6.197199513379157, -14.374353062530322, 3.0],
|
||||||
|
"verified_bottom_size_mm": [10.0, 6.0],
|
||||||
|
"verified_bottom_face_count": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"viewer_mesh_topology": {
|
||||||
|
"path": ".flange_8x_m3.step.glb",
|
||||||
|
"regenerated": true
|
||||||
|
},
|
||||||
|
"snapshot_review": {
|
||||||
|
"status": "passed",
|
||||||
|
"path": "review/viewer_pocket_top_20260724T031341Z.png",
|
||||||
|
"camera": "top"
|
||||||
|
},
|
||||||
|
"visual_review": "passed_viewer_pocket_top"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"schema_version": "1.0",
|
"schema_version": "1.0",
|
||||||
"request": "生成一个28齿、厚度4毫米的齿轮",
|
"request": "生成一个28齿、厚度4毫米的齿轮,并在 viewer 选中的两个面点位置各添加一个2.0毫米贯穿孔;随后根据 viewer 选中的顶面点 f5 添加一个10x6x1毫米矩形口袋",
|
||||||
"route": {
|
"route": {
|
||||||
"selected_backend": "simplecadapi",
|
"selected_backend": "simplecadapi",
|
||||||
"runner_skill": "simplecadapi",
|
"runner_skill": "simplecadapi",
|
||||||
@@ -31,6 +31,10 @@
|
|||||||
{
|
{
|
||||||
"path": "gear_28t_4mm.stl",
|
"path": "gear_28t_4mm.stl",
|
||||||
"role": "secondary"
|
"role": "secondary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".gear_28t_4mm.step.glb",
|
||||||
|
"role": "viewer_mesh_topology"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@@ -41,13 +45,65 @@
|
|||||||
"bore_diameter_mm": 5.0,
|
"bore_diameter_mm": 5.0,
|
||||||
"addendum_factor": 1.0,
|
"addendum_factor": 1.0,
|
||||||
"clearance_factor": 0.25,
|
"clearance_factor": 0.25,
|
||||||
"backlash_mm": 0.0
|
"backlash_mm": 0.0,
|
||||||
|
"edit_holes": [
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": [
|
||||||
|
-2.9189440262073063,
|
||||||
|
5.47686606164935,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": [
|
||||||
|
7.5974463825483305,
|
||||||
|
-0.8433357012066764,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_hole_count": 2,
|
||||||
|
"edit_hole_axis": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"edit_pockets": [
|
||||||
|
{
|
||||||
|
"shape": "rectangle",
|
||||||
|
"width_mm": 10.0,
|
||||||
|
"height_mm": 6.0,
|
||||||
|
"depth_mm": 1.0,
|
||||||
|
"center_mm": [
|
||||||
|
-8.717129036056448,
|
||||||
|
-0.9462437095981322,
|
||||||
|
4.0
|
||||||
|
],
|
||||||
|
"direction": "face_normal",
|
||||||
|
"orientation": "surface_xy",
|
||||||
|
"selected_face": {
|
||||||
|
"reference_id": "f5",
|
||||||
|
"selector": "f5",
|
||||||
|
"face_index": 5428,
|
||||||
|
"row_index": 4,
|
||||||
|
"normal": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_pocket_count": 1
|
||||||
},
|
},
|
||||||
"assumptions": [
|
"assumptions": [
|
||||||
"未指定模数,V1采用1.0毫米。",
|
"未指定模数,V1采用1.0毫米。",
|
||||||
"未指定压力角,采用标准20度。",
|
"未指定压力角,采用标准20度。",
|
||||||
"未指定中心孔,采用5.0毫米通孔。",
|
"未指定中心孔,采用5.0毫米通孔。",
|
||||||
"未指定齿轮类型,采用直齿渐开线外齿轮。"
|
"未指定齿轮类型,采用直齿渐开线外齿轮。",
|
||||||
|
"viewer 编辑请求未指定孔径,采用2.0毫米贯穿孔作为可编辑默认值。"
|
||||||
],
|
],
|
||||||
"validation": [
|
"validation": [
|
||||||
{
|
{
|
||||||
@@ -62,12 +118,55 @@
|
|||||||
4.0
|
4.0
|
||||||
],
|
],
|
||||||
"pitch_diameter_mm": 28.0,
|
"pitch_diameter_mm": 28.0,
|
||||||
|
"edit_holes": [
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": [
|
||||||
|
-2.9189440262073063,
|
||||||
|
5.47686606164935,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": [
|
||||||
|
7.5974463825483305,
|
||||||
|
-0.8433357012066764,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_hole_count": 2,
|
||||||
|
"edit_pockets": [
|
||||||
|
{
|
||||||
|
"shape": "rectangle",
|
||||||
|
"width_mm": 10.0,
|
||||||
|
"height_mm": 6.0,
|
||||||
|
"depth_mm": 1.0,
|
||||||
|
"center_mm": [
|
||||||
|
-8.717129036056448,
|
||||||
|
-0.9462437095981322,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_pocket_count": 1,
|
||||||
|
"faces": 182,
|
||||||
|
"edges": 545,
|
||||||
"outside_diameter_mm": 30.0,
|
"outside_diameter_mm": 30.0,
|
||||||
"visual_review": "passed_iso_top_front"
|
"volume_mm3": 2167.600632,
|
||||||
|
"viewer_mesh_topology": {
|
||||||
|
"path": ".gear_28t_4mm.step.glb",
|
||||||
|
"status": "regenerated",
|
||||||
|
"face_count": 182,
|
||||||
|
"edge_count": 545,
|
||||||
|
"step_hash": "d07ba4428ce372d7dc65ea31c2c8bf636399f38e40e2bd705029789832825267"
|
||||||
|
},
|
||||||
|
"visual_review": "not_run"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"viewer_links": [
|
"viewer_links": [
|
||||||
"http://127.0.0.1:4178/?dir=%2FUsers%2Fjerry%2Flinkhand%2FCadSet%2Ftext-to-cad%2Fmodels%2Fcad-router-v1%2Fgear_28t_4mm&file=gear_28t_4mm.step"
|
"http://127.0.0.1:5174/?dir=%2FUsers%2Flk%2FProjects%2FcadSet%2Ftext-to-cad%2Fmodels%2Fcad-router-v1%2Fgear_28t_4mm&file=gear_28t_4mm.step"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,8 +1,14 @@
|
|||||||
"""Parametric 28-tooth spur gear generated with SimpleCADAPI."""
|
"""Parametric 28-tooth spur gear generated with SimpleCADAPI."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
_PROJECT_ROOT = Path(__file__).resolve().parents[4]
|
||||||
|
_SIMPLECADAPI_SRC = _PROJECT_ROOT / "SimpleCADAPI" / "src"
|
||||||
|
if str(_SIMPLECADAPI_SRC) not in sys.path:
|
||||||
|
sys.path.insert(0, str(_SIMPLECADAPI_SRC))
|
||||||
|
|
||||||
import simplecadapi as scad
|
import simplecadapi as scad
|
||||||
|
|
||||||
|
|
||||||
@@ -14,6 +20,76 @@ BORE_DIAMETER_MM = 5.0
|
|||||||
ADDENDUM_FACTOR = 1.0
|
ADDENDUM_FACTOR = 1.0
|
||||||
CLEARANCE_FACTOR = 0.25
|
CLEARANCE_FACTOR = 0.25
|
||||||
BACKLASH_MM = 0.0
|
BACKLASH_MM = 0.0
|
||||||
|
VIEWER_SELECTED_EDGE = {
|
||||||
|
"reference_id": "e344",
|
||||||
|
"row_index": 343,
|
||||||
|
"description": "top circular edge of the center bore",
|
||||||
|
}
|
||||||
|
BORE_TOP_CHAMFER_DISTANCE_MM = 3.0
|
||||||
|
EDIT_HOLE_AXIS = (0.0, 0.0, 1.0)
|
||||||
|
EDIT_HOLES = [
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": (-2.9189440262073063, 5.47686606164935, THICKNESS_MM),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": (7.5974463825483305, -0.8433357012066764, THICKNESS_MM),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
EDIT_HOLE_PATTERNS = [
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"rows": 2,
|
||||||
|
"columns": 2,
|
||||||
|
"pitch_x_mm": 8.0,
|
||||||
|
"pitch_y_mm": 8.0,
|
||||||
|
"depth": "through",
|
||||||
|
"direction": "face_normal",
|
||||||
|
"orientation": "surface_xy",
|
||||||
|
"center_mm": (0.24688766006678975, -8.367405492677905, THICKNESS_MM),
|
||||||
|
"selected_face": {
|
||||||
|
"reference_id": "f5",
|
||||||
|
"selector": "f5",
|
||||||
|
"face_index": 2785,
|
||||||
|
"row_index": 4,
|
||||||
|
"normal": (0.0, 0.0, 1.0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
EDIT_POCKETS = [
|
||||||
|
{
|
||||||
|
"shape": "rectangle",
|
||||||
|
"width_mm": 10.0,
|
||||||
|
"height_mm": 6.0,
|
||||||
|
"depth_mm": 1.0,
|
||||||
|
"center_mm": (-8.717129036056448, -0.9462437095981322, THICKNESS_MM),
|
||||||
|
"direction": "face_normal",
|
||||||
|
"orientation": "surface_xy",
|
||||||
|
"selected_face": {
|
||||||
|
"reference_id": "f5",
|
||||||
|
"selector": "f5",
|
||||||
|
"face_index": 5428,
|
||||||
|
"row_index": 4,
|
||||||
|
"normal": (0.0, 0.0, 1.0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def hole_pattern_centers(pattern):
|
||||||
|
x_center, y_center, z_center = pattern["center_mm"]
|
||||||
|
x_start = x_center - (pattern["columns"] - 1) * pattern["pitch_x_mm"] / 2.0
|
||||||
|
y_start = y_center - (pattern["rows"] - 1) * pattern["pitch_y_mm"] / 2.0
|
||||||
|
return [
|
||||||
|
(
|
||||||
|
x_start + column * pattern["pitch_x_mm"],
|
||||||
|
y_start + row * pattern["pitch_y_mm"],
|
||||||
|
z_center,
|
||||||
|
)
|
||||||
|
for row in range(pattern["rows"])
|
||||||
|
for column in range(pattern["columns"])
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def generate() -> None:
|
def generate() -> None:
|
||||||
@@ -32,14 +108,75 @@ def generate() -> None:
|
|||||||
blank_faces = scad.ql.select(items=gear_blank.get_faces()).all()
|
blank_faces = scad.ql.select(items=gear_blank.get_faces()).all()
|
||||||
print("gear_blank_faces", len(blank_faces))
|
print("gear_blank_faces", len(blank_faces))
|
||||||
|
|
||||||
|
bore_radius = BORE_DIAMETER_MM / 2.0
|
||||||
bore = scad.make_cylinder_rsolid(
|
bore = scad.make_cylinder_rsolid(
|
||||||
radius=BORE_DIAMETER_MM / 2.0,
|
radius=bore_radius,
|
||||||
height=THICKNESS_MM + 2.0,
|
height=THICKNESS_MM + 2.0,
|
||||||
bottom_face_center=(0.0, 0.0, -1.0),
|
bottom_face_center=(0.0, 0.0, -1.0),
|
||||||
axis=(0.0, 0.0, 1.0),
|
axis=(0.0, 0.0, 1.0),
|
||||||
)
|
)
|
||||||
gear = scad.cut_rsolid(gear_blank, bore, skip_non_intersecting=False)
|
bore_top_chamfer = scad.make_cone_rsolid(
|
||||||
|
bottom_radius=bore_radius,
|
||||||
|
height=BORE_TOP_CHAMFER_DISTANCE_MM,
|
||||||
|
top_radius=bore_radius + BORE_TOP_CHAMFER_DISTANCE_MM,
|
||||||
|
bottom_face_center=(
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
THICKNESS_MM - BORE_TOP_CHAMFER_DISTANCE_MM,
|
||||||
|
),
|
||||||
|
axis=(0.0, 0.0, 1.0),
|
||||||
|
)
|
||||||
|
edit_hole_cutters = [
|
||||||
|
scad.make_cylinder_rsolid(
|
||||||
|
radius=hole["diameter_mm"] / 2.0,
|
||||||
|
height=THICKNESS_MM + 2.0,
|
||||||
|
bottom_face_center=(hole["center_mm"][0], hole["center_mm"][1], -1.0),
|
||||||
|
axis=EDIT_HOLE_AXIS,
|
||||||
|
)
|
||||||
|
for hole in EDIT_HOLES
|
||||||
|
]
|
||||||
|
pattern_hole_cutters = [
|
||||||
|
scad.make_cylinder_rsolid(
|
||||||
|
radius=pattern["diameter_mm"] / 2.0,
|
||||||
|
height=THICKNESS_MM + 2.0,
|
||||||
|
bottom_face_center=(center[0], center[1], -1.0),
|
||||||
|
axis=EDIT_HOLE_AXIS,
|
||||||
|
)
|
||||||
|
for pattern in EDIT_HOLE_PATTERNS
|
||||||
|
for center in hole_pattern_centers(pattern)
|
||||||
|
]
|
||||||
|
pocket_cutters = [
|
||||||
|
scad.make_box_rsolid(
|
||||||
|
width=pocket["width_mm"],
|
||||||
|
height=pocket["height_mm"],
|
||||||
|
depth=pocket["depth_mm"] + 0.02,
|
||||||
|
bottom_face_center=(
|
||||||
|
pocket["center_mm"][0],
|
||||||
|
pocket["center_mm"][1],
|
||||||
|
THICKNESS_MM - pocket["depth_mm"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
for pocket in EDIT_POCKETS
|
||||||
|
]
|
||||||
|
print("viewer_edit_holes", len(edit_hole_cutters))
|
||||||
|
print("viewer_edit_pattern_holes", len(pattern_hole_cutters))
|
||||||
|
print("viewer_edit_pockets", len(pocket_cutters))
|
||||||
|
gear = scad.cut_rsolid(
|
||||||
|
gear_blank,
|
||||||
|
[
|
||||||
|
bore,
|
||||||
|
bore_top_chamfer,
|
||||||
|
*edit_hole_cutters,
|
||||||
|
*pattern_hole_cutters,
|
||||||
|
*pocket_cutters,
|
||||||
|
],
|
||||||
|
skip_non_intersecting=False,
|
||||||
|
)
|
||||||
gear = scad.apply_tag(shape=gear, tag="role.power_transmission.gear")
|
gear = scad.apply_tag(shape=gear, tag="role.power_transmission.gear")
|
||||||
|
gear = scad.apply_tag(shape=gear, tag="feature.viewer_edit_point_hole")
|
||||||
|
gear = scad.apply_tag(shape=gear, tag="feature.viewer_edit_hole_pattern")
|
||||||
|
gear = scad.apply_tag(shape=gear, tag="feature.viewer_edit_rectangular_pocket")
|
||||||
|
gear = scad.apply_tag(shape=gear, tag="feature.viewer_selected_edge_chamfer")
|
||||||
final_faces = scad.ql.select(items=gear.get_faces()).all()
|
final_faces = scad.ql.select(items=gear.get_faces()).all()
|
||||||
final_edges = scad.ql.select(items=gear.get_edges()).all()
|
final_edges = scad.ql.select(items=gear.get_edges()).all()
|
||||||
print("final_topology", {"faces": len(final_faces), "edges": len(final_edges)})
|
print("final_topology", {"faces": len(final_faces), "edges": len(final_edges)})
|
||||||
@@ -61,6 +198,61 @@ def generate() -> None:
|
|||||||
"root_diameter_mm": root_diameter_mm,
|
"root_diameter_mm": root_diameter_mm,
|
||||||
"thickness_mm": THICKNESS_MM,
|
"thickness_mm": THICKNESS_MM,
|
||||||
"bore_diameter_mm": BORE_DIAMETER_MM,
|
"bore_diameter_mm": BORE_DIAMETER_MM,
|
||||||
|
"viewer_selected_edge": VIEWER_SELECTED_EDGE,
|
||||||
|
"bore_top_chamfer_distance_mm": BORE_TOP_CHAMFER_DISTANCE_MM,
|
||||||
|
"bore_top_chamfer_top_diameter_mm": BORE_DIAMETER_MM
|
||||||
|
+ 2.0 * BORE_TOP_CHAMFER_DISTANCE_MM,
|
||||||
|
"edit_holes": [
|
||||||
|
{
|
||||||
|
"diameter_mm": hole["diameter_mm"],
|
||||||
|
"center_mm": list(hole["center_mm"]),
|
||||||
|
}
|
||||||
|
for hole in EDIT_HOLES
|
||||||
|
],
|
||||||
|
"edit_hole_count": len(EDIT_HOLES),
|
||||||
|
"edit_hole_axis": list(EDIT_HOLE_AXIS),
|
||||||
|
"edit_hole_patterns": [
|
||||||
|
{
|
||||||
|
"diameter_mm": pattern["diameter_mm"],
|
||||||
|
"rows": pattern["rows"],
|
||||||
|
"columns": pattern["columns"],
|
||||||
|
"pitch_x_mm": pattern["pitch_x_mm"],
|
||||||
|
"pitch_y_mm": pattern["pitch_y_mm"],
|
||||||
|
"depth": pattern["depth"],
|
||||||
|
"direction": pattern["direction"],
|
||||||
|
"orientation": pattern["orientation"],
|
||||||
|
"center_mm": list(pattern["center_mm"]),
|
||||||
|
"hole_centers_mm": [
|
||||||
|
list(center) for center in hole_pattern_centers(pattern)
|
||||||
|
],
|
||||||
|
"selected_face": {
|
||||||
|
**pattern["selected_face"],
|
||||||
|
"normal": list(pattern["selected_face"]["normal"]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for pattern in EDIT_HOLE_PATTERNS
|
||||||
|
],
|
||||||
|
"edit_hole_pattern_count": len(EDIT_HOLE_PATTERNS),
|
||||||
|
"edit_hole_pattern_hole_count": sum(
|
||||||
|
pattern["rows"] * pattern["columns"] for pattern in EDIT_HOLE_PATTERNS
|
||||||
|
),
|
||||||
|
"edit_pockets": [
|
||||||
|
{
|
||||||
|
"shape": pocket["shape"],
|
||||||
|
"width_mm": pocket["width_mm"],
|
||||||
|
"height_mm": pocket["height_mm"],
|
||||||
|
"depth_mm": pocket["depth_mm"],
|
||||||
|
"center_mm": list(pocket["center_mm"]),
|
||||||
|
"direction": pocket["direction"],
|
||||||
|
"orientation": pocket["orientation"],
|
||||||
|
"selected_face": {
|
||||||
|
**pocket["selected_face"],
|
||||||
|
"normal": list(pocket["selected_face"]["normal"]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for pocket in EDIT_POCKETS
|
||||||
|
],
|
||||||
|
"edit_pocket_count": len(EDIT_POCKETS),
|
||||||
"volume_mm3": round(gear.get_volume(), 6),
|
"volume_mm3": round(gear.get_volume(), 6),
|
||||||
"faces": len(final_faces),
|
"faces": len(final_faces),
|
||||||
"edges": len(final_edges),
|
"edges": len(final_edges),
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -5,15 +5,129 @@
|
|||||||
"root_diameter_mm": 25.5,
|
"root_diameter_mm": 25.5,
|
||||||
"thickness_mm": 4.0,
|
"thickness_mm": 4.0,
|
||||||
"bore_diameter_mm": 5.0,
|
"bore_diameter_mm": 5.0,
|
||||||
"volume_mm3": 2343.649578,
|
"viewer_selected_edge": {
|
||||||
"faces": 171,
|
"reference_id": "e344",
|
||||||
"edges": 507,
|
"row_index": 343,
|
||||||
|
"description": "top circular edge of the center bore"
|
||||||
|
},
|
||||||
|
"bore_top_chamfer_distance_mm": 3.0,
|
||||||
|
"bore_top_chamfer_top_diameter_mm": 11.0,
|
||||||
|
"edit_holes": [
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": [
|
||||||
|
-2.9189440262073063,
|
||||||
|
5.47686606164935,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"center_mm": [
|
||||||
|
7.5974463825483305,
|
||||||
|
-0.8433357012066764,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_hole_count": 2,
|
||||||
|
"edit_hole_axis": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"edit_hole_patterns": [
|
||||||
|
{
|
||||||
|
"diameter_mm": 2.0,
|
||||||
|
"rows": 2,
|
||||||
|
"columns": 2,
|
||||||
|
"pitch_x_mm": 8.0,
|
||||||
|
"pitch_y_mm": 8.0,
|
||||||
|
"depth": "through",
|
||||||
|
"direction": "face_normal",
|
||||||
|
"orientation": "surface_xy",
|
||||||
|
"center_mm": [
|
||||||
|
0.24688766006678975,
|
||||||
|
-8.367405492677905,
|
||||||
|
4.0
|
||||||
|
],
|
||||||
|
"hole_centers_mm": [
|
||||||
|
[
|
||||||
|
-3.7531123399332103,
|
||||||
|
-12.367405492677905,
|
||||||
|
4.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
4.24688766006679,
|
||||||
|
-12.367405492677905,
|
||||||
|
4.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-3.7531123399332103,
|
||||||
|
-4.367405492677905,
|
||||||
|
4.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
4.24688766006679,
|
||||||
|
-4.367405492677905,
|
||||||
|
4.0
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"selected_face": {
|
||||||
|
"reference_id": "f5",
|
||||||
|
"selector": "f5",
|
||||||
|
"face_index": 2785,
|
||||||
|
"row_index": 4,
|
||||||
|
"normal": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_hole_pattern_count": 1,
|
||||||
|
"edit_hole_pattern_hole_count": 4,
|
||||||
|
"edit_pockets": [
|
||||||
|
{
|
||||||
|
"shape": "rectangle",
|
||||||
|
"width_mm": 10.0,
|
||||||
|
"height_mm": 6.0,
|
||||||
|
"depth_mm": 1.0,
|
||||||
|
"center_mm": [
|
||||||
|
-8.717129036056448,
|
||||||
|
-0.9462437095981322,
|
||||||
|
4.0
|
||||||
|
],
|
||||||
|
"direction": "face_normal",
|
||||||
|
"orientation": "surface_xy",
|
||||||
|
"selected_face": {
|
||||||
|
"reference_id": "f5",
|
||||||
|
"selector": "f5",
|
||||||
|
"face_index": 5428,
|
||||||
|
"row_index": 4,
|
||||||
|
"normal": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edit_pocket_count": 1,
|
||||||
|
"volume_mm3": 2128.275635,
|
||||||
|
"faces": 184,
|
||||||
|
"edges": 557,
|
||||||
"tags": [
|
"tags": [
|
||||||
|
"feature.viewer_edit_hole_pattern",
|
||||||
|
"feature.viewer_edit_point_hole",
|
||||||
|
"feature.viewer_edit_rectangular_pocket",
|
||||||
|
"feature.viewer_selected_edge_chamfer",
|
||||||
"role.power_transmission.gear",
|
"role.power_transmission.gear",
|
||||||
"sketch.gear_28t_m1.id_0",
|
"sketch.gear_28t_m1.id_0",
|
||||||
"sketch_profile.arc_root_0",
|
"sketch_profile.arc_root_0",
|
||||||
"solid.boolean.cut",
|
"solid.boolean.cut",
|
||||||
"solid.extrusion"
|
"solid.extrusion"
|
||||||
],
|
],
|
||||||
"graph_nodes": 351
|
"graph_nodes": 359
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,9 @@
|
|||||||
"""Approximate long cylindrical pin with a shallow axial end recess."""
|
"""Approximate long cylindrical pin with a shallow axial end recess."""
|
||||||
|
|
||||||
|
from math import atan2, degrees, hypot, sqrt
|
||||||
|
|
||||||
|
from build123d import Box, Cylinder, Location
|
||||||
|
|
||||||
from shaft_common import cut_end_bore, export_horizontal, stepped_body
|
from shaft_common import cut_end_bore, export_horizontal, stepped_body
|
||||||
|
|
||||||
|
|
||||||
@@ -8,8 +12,115 @@ LENGTH = 120.0
|
|||||||
RECESS_DIAMETER = 6.0
|
RECESS_DIAMETER = 6.0
|
||||||
RECESS_DEPTH = 5.0
|
RECESS_DEPTH = 5.0
|
||||||
|
|
||||||
|
VIEWER_POCKET_CENTER = (50.72611906534796, 1.4055875192234604, 8.886497233823093)
|
||||||
|
VIEWER_POCKET_WIDTH = 2.0
|
||||||
|
VIEWER_POCKET_HEIGHT = 2.0
|
||||||
|
VIEWER_POCKET_DEPTH = 1.0
|
||||||
|
VIEWER_POCKET_OVERSHOOT = 0.2
|
||||||
|
|
||||||
|
CIRCULAR_POCKET_CENTER = (68.62703575804954, 0.06569140145571417, 8.989927422862593)
|
||||||
|
CIRCULAR_POCKET_NORMAL = (0.0, -0.156229, -0.987721)
|
||||||
|
CIRCULAR_POCKET_DIAMETER = 8.0
|
||||||
|
CIRCULAR_POCKET_DEPTH = 1.0
|
||||||
|
CIRCULAR_POCKET_OVERSHOOT = 0.2
|
||||||
|
|
||||||
|
COUNTERBORE_CENTER = (40.48928144002571, -7.833112445247494, 4.424155112072327)
|
||||||
|
COUNTERBORE_NORMAL = (0.000061, -0.039505, -0.999219)
|
||||||
|
COUNTERBORE_HOLE_DIAMETER = 3.0
|
||||||
|
COUNTERBORE_DIAMETER = 6.0
|
||||||
|
COUNTERBORE_DEPTH = 2.0
|
||||||
|
COUNTERBORE_FACE_SELECTOR = {
|
||||||
|
"reference_id": "f1",
|
||||||
|
"face_index": 164,
|
||||||
|
"row_index": 0,
|
||||||
|
}
|
||||||
|
COUNTERBORE_OVERSHOOT = 0.2
|
||||||
|
COUNTERBORE_THROUGH_OVERSHOOT = 2.0
|
||||||
|
|
||||||
|
|
||||||
|
def cut_viewer_rectangular_pocket(body):
|
||||||
|
x_pos, y_pos, z_pos = VIEWER_POCKET_CENTER
|
||||||
|
radial_length = hypot(y_pos, z_pos)
|
||||||
|
normal_y = y_pos / radial_length
|
||||||
|
normal_z = z_pos / radial_length
|
||||||
|
rotation_x = degrees(atan2(-normal_y, normal_z))
|
||||||
|
tool_depth = VIEWER_POCKET_DEPTH + VIEWER_POCKET_OVERSHOOT
|
||||||
|
tool_center_offset = (VIEWER_POCKET_OVERSHOOT - VIEWER_POCKET_DEPTH) / 2.0
|
||||||
|
tool_center = (
|
||||||
|
x_pos,
|
||||||
|
y_pos + normal_y * tool_center_offset,
|
||||||
|
z_pos + normal_z * tool_center_offset,
|
||||||
|
)
|
||||||
|
tool = Location(tool_center, (rotation_x, 0.0, 0.0)) * Box(
|
||||||
|
VIEWER_POCKET_WIDTH,
|
||||||
|
VIEWER_POCKET_HEIGHT,
|
||||||
|
tool_depth,
|
||||||
|
)
|
||||||
|
return body - tool
|
||||||
|
|
||||||
|
|
||||||
|
def cut_viewer_circular_pocket(body):
|
||||||
|
x_pos, y_pos, z_pos = CIRCULAR_POCKET_CENTER
|
||||||
|
normal_x, normal_y, normal_z = CIRCULAR_POCKET_NORMAL
|
||||||
|
normal_length = sqrt(normal_x**2 + normal_y**2 + normal_z**2)
|
||||||
|
normal_y /= normal_length
|
||||||
|
normal_z /= normal_length
|
||||||
|
rotation_x = degrees(atan2(-normal_y, normal_z))
|
||||||
|
tool_depth = CIRCULAR_POCKET_DEPTH + CIRCULAR_POCKET_OVERSHOOT
|
||||||
|
tool_center_offset = (CIRCULAR_POCKET_DEPTH - CIRCULAR_POCKET_OVERSHOOT) / 2.0
|
||||||
|
tool_center = (
|
||||||
|
x_pos,
|
||||||
|
y_pos + normal_y * tool_center_offset,
|
||||||
|
z_pos + normal_z * tool_center_offset,
|
||||||
|
)
|
||||||
|
tool = Location(tool_center, (rotation_x, 0.0, 0.0)) * Cylinder(
|
||||||
|
CIRCULAR_POCKET_DIAMETER / 2.0,
|
||||||
|
tool_depth,
|
||||||
|
)
|
||||||
|
return body - tool
|
||||||
|
|
||||||
|
|
||||||
|
def cut_viewer_counterbore(body):
|
||||||
|
x_pos, y_pos, z_pos = COUNTERBORE_CENTER
|
||||||
|
normal_x, normal_y, normal_z = COUNTERBORE_NORMAL
|
||||||
|
normal_length = sqrt(normal_x**2 + normal_y**2 + normal_z**2)
|
||||||
|
normal_y /= normal_length
|
||||||
|
normal_z /= normal_length
|
||||||
|
rotation_x = degrees(atan2(-normal_y, normal_z))
|
||||||
|
|
||||||
|
through_depth = OUTER_DIAMETER + 4.0
|
||||||
|
through_tool_depth = through_depth + COUNTERBORE_THROUGH_OVERSHOOT
|
||||||
|
through_center_offset = (through_depth - COUNTERBORE_THROUGH_OVERSHOOT) / 2.0
|
||||||
|
through_center = (
|
||||||
|
x_pos,
|
||||||
|
y_pos + normal_y * through_center_offset,
|
||||||
|
z_pos + normal_z * through_center_offset,
|
||||||
|
)
|
||||||
|
through_tool = Location(through_center, (rotation_x, 0.0, 0.0)) * Cylinder(
|
||||||
|
COUNTERBORE_HOLE_DIAMETER / 2.0,
|
||||||
|
through_tool_depth,
|
||||||
|
)
|
||||||
|
|
||||||
|
counterbore_tool_depth = COUNTERBORE_DEPTH + COUNTERBORE_OVERSHOOT
|
||||||
|
counterbore_center_offset = (COUNTERBORE_DEPTH - COUNTERBORE_OVERSHOOT) / 2.0
|
||||||
|
counterbore_center = (
|
||||||
|
x_pos,
|
||||||
|
y_pos + normal_y * counterbore_center_offset,
|
||||||
|
z_pos + normal_z * counterbore_center_offset,
|
||||||
|
)
|
||||||
|
counterbore_tool = Location(counterbore_center, (rotation_x, 0.0, 0.0)) * Cylinder(
|
||||||
|
COUNTERBORE_DIAMETER / 2.0,
|
||||||
|
counterbore_tool_depth,
|
||||||
|
)
|
||||||
|
return body - through_tool - counterbore_tool
|
||||||
|
|
||||||
|
|
||||||
def gen_step():
|
def gen_step():
|
||||||
body, total = stepped_body([(OUTER_DIAMETER, LENGTH)])
|
body, total = stepped_body([(OUTER_DIAMETER, LENGTH)])
|
||||||
body = cut_end_bore(body, total, RECESS_DIAMETER, RECESS_DEPTH)
|
body = cut_end_bore(body, total, RECESS_DIAMETER, RECESS_DEPTH)
|
||||||
return export_horizontal(body, "pin_004910_like")
|
result = export_horizontal(body, "pin_004910_like")
|
||||||
|
result = cut_viewer_rectangular_pocket(result)
|
||||||
|
result = cut_viewer_circular_pocket(result)
|
||||||
|
result = cut_viewer_counterbore(result)
|
||||||
|
result.label = "pin_004910_like"
|
||||||
|
return result
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -4,7 +4,9 @@ The image does not define a thread standard. Rings represent the visible
|
|||||||
thread rhythm while keeping the concept model lightweight and editable.
|
thread rhythm while keeping the concept model lightweight and editable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import BuildPart, BuildSketch, Cylinder, Mode, Plane, Pos, RegularPolygon, extrude
|
from math import atan2, degrees
|
||||||
|
|
||||||
|
from build123d import Align, Axis, BuildPart, BuildSketch, Cylinder, Mode, Plane, Pos, RegularPolygon, extrude
|
||||||
|
|
||||||
from shaft_common import add_thread_rings, cut_end_bore, export_horizontal, stepped_body
|
from shaft_common import add_thread_rings, cut_end_bore, export_horizontal, stepped_body
|
||||||
|
|
||||||
@@ -17,10 +19,36 @@ def _hex_prism(z_start, across_corners, length):
|
|||||||
return prism.part
|
return prism.part
|
||||||
|
|
||||||
|
|
||||||
|
def _radial_through_hole(body, axial_position, surface_y, surface_z, diameter, stock_diameter):
|
||||||
|
# The source is authored along +Z and export_horizontal rotates it onto +X.
|
||||||
|
source_x = -surface_z
|
||||||
|
source_y = surface_y
|
||||||
|
angle = degrees(atan2(source_y, source_x))
|
||||||
|
tool = (
|
||||||
|
Pos(0, 0, axial_position)
|
||||||
|
* Cylinder(
|
||||||
|
diameter / 2.0,
|
||||||
|
stock_diameter + 4.0,
|
||||||
|
align=(Align.CENTER, Align.CENTER, Align.CENTER),
|
||||||
|
)
|
||||||
|
.rotate(Axis.Y, 90)
|
||||||
|
.rotate(Axis.Z, angle)
|
||||||
|
)
|
||||||
|
return body - tool
|
||||||
|
|
||||||
|
|
||||||
def gen_step():
|
def gen_step():
|
||||||
# Minor thread stem, neck, roller, and short nut-supporting neck.
|
# Minor thread stem, neck, roller, and short nut-supporting neck.
|
||||||
body, total = stepped_body([(8.2, 40.0), (9.5, 7.0), (28.0, 25.0), (10.0, 4.0)])
|
body, total = stepped_body([(8.2, 40.0), (9.5, 7.0), (28.0, 25.0), (10.0, 4.0)])
|
||||||
body = add_thread_rings(body, z_start=0.5, length=38.5, major_diameter=10.0, pitch=2.0)
|
body = add_thread_rings(body, z_start=0.5, length=38.5, major_diameter=10.0, pitch=2.0)
|
||||||
|
body = _radial_through_hole(
|
||||||
|
body,
|
||||||
|
axial_position=59.77433249254057,
|
||||||
|
surface_y=0.8860768186618869,
|
||||||
|
surface_z=13.963760796195984,
|
||||||
|
diameter=4.0,
|
||||||
|
stock_diameter=28.0,
|
||||||
|
)
|
||||||
hex_body = _hex_prism(total - 0.15, across_corners=22.0, length=11.0)
|
hex_body = _hex_prism(total - 0.15, across_corners=22.0, length=11.0)
|
||||||
body = body + hex_body
|
body = body + hex_body
|
||||||
total += 10.85
|
total += 10.85
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user