|
| 1 | +{ |
| 2 | + "version": "1.1.0", |
| 3 | + "units": "mm", |
| 4 | + "meta": { |
| 5 | + "title": "Corner Idler Bracket (graph twin)", |
| 6 | + "notes": "Golden twin of main.py (graph format 1.1): the same parameters, the same derivations and the same operations in the same order. main.py stays the oracle; y4d-spec --parity compares the two at the defaults and at every preset. Constants keep main.py's names and values, and their sources are main.py's: ISO 7380-1 M5x30 (Keller & Kalmbach 157380530: SCREW_D 5, SCREW_L 30, HEAD_DK 9.5, HEAD_K 2.75), MISUMI HFS5 T-slot (SLOT_LIP_T 2, PILOT_D 4.2, PROFILE 20), MISUMI HNTAP5-5 (TNUT_L 15); HOLE_CLEAR, HEAD_CLEAR, TAB_W, POCKET_RADIAL, AXLE_WALL, HEEL_GAP, MOUNT_X1 and EDGE are main.py's labelled conventions. Clamps max(lo, min(x, hi)) and length's max are ternaries, because the expression dialect has no function calls. _cyl_y (makeCylinder along +Y) is an XZ profile_circle at (x, z) extruded by -(y1 - y0), since the XZ normal is -Y, then translated to y0. `mirrored` selects the pure YZ reflection of the body, as body.mirror(\"YZ\") does." |
| 7 | + }, |
| 8 | + "parameters": { |
| 9 | + "idler_width": {"default": 14.0}, |
| 10 | + "idler_od": {"default": 18.0}, |
| 11 | + "idler_clear": {"default": 0.5}, |
| 12 | + "idler_offset": {"default": 13.0}, |
| 13 | + "idler_drop": {"default": 24.0}, |
| 14 | + "front_arm": {"default": 5.0}, |
| 15 | + "mount_grip": {"default": 24.5}, |
| 16 | + "mount_pitch": {"default": 20.0}, |
| 17 | + "heel_reach": {"default": 18.0}, |
| 18 | + "mirrored": {"default": false} |
| 19 | + }, |
| 20 | + "derived": [ |
| 21 | + {"id": "SCREW_D", "expr": "5.0"}, |
| 22 | + {"id": "SCREW_L", "expr": "30.0"}, |
| 23 | + {"id": "HEAD_DK", "expr": "9.5"}, |
| 24 | + {"id": "HEAD_K", "expr": "2.75"}, |
| 25 | + {"id": "SLOT_LIP_T", "expr": "2.0"}, |
| 26 | + {"id": "PILOT_D", "expr": "4.2"}, |
| 27 | + {"id": "PROFILE", "expr": "20.0"}, |
| 28 | + {"id": "TNUT_L", "expr": "15.0"}, |
| 29 | + {"id": "HOLE_CLEAR", "expr": "0.25"}, |
| 30 | + {"id": "HEAD_CLEAR", "expr": "0.5"}, |
| 31 | + {"id": "TAB_W", "expr": "5.8"}, |
| 32 | + {"id": "POCKET_RADIAL", "expr": "1.0"}, |
| 33 | + {"id": "AXLE_WALL", "expr": "7.0"}, |
| 34 | + {"id": "HEEL_GAP", "expr": "0.5"}, |
| 35 | + {"id": "MOUNT_X1", "expr": "10.0"}, |
| 36 | + {"id": "EDGE", "expr": "4.75"}, |
| 37 | + {"id": "iw_cap", "expr": "idler_width < 20 ? idler_width : 20"}, |
| 38 | + {"id": "iw", "expr": "9 > iw_cap ? 9 : iw_cap"}, |
| 39 | + {"id": "od_cap", "expr": "idler_od < 24 ? idler_od : 24"}, |
| 40 | + {"id": "od", "expr": "12 > od_cap ? 12 : od_cap"}, |
| 41 | + {"id": "ic_cap", "expr": "idler_clear < 2 ? idler_clear : 2"}, |
| 42 | + {"id": "ic", "expr": "0.2 > ic_cap ? 0.2 : ic_cap"}, |
| 43 | + {"id": "fa_cap", "expr": "front_arm < 8 ? front_arm : 8"}, |
| 44 | + {"id": "fa", "expr": "3 > fa_cap ? 3 : fa_cap"}, |
| 45 | + {"id": "gap", "expr": "iw + 2 * ic"}, |
| 46 | + {"id": "rear_arm", "expr": "SCREW_L - fa - gap"}, |
| 47 | + {"id": "pocket_r", "expr": "od / 2 + POCKET_RADIAL"}, |
| 48 | + {"id": "io_cap", "expr": "idler_offset < 40 ? idler_offset : 40"}, |
| 49 | + {"id": "io", "expr": "(pocket_r + 1) > io_cap ? (pocket_r + 1) : io_cap"}, |
| 50 | + {"id": "idrop_cap", "expr": "idler_drop < 60 ? idler_drop : 60"}, |
| 51 | + {"id": "idrop", "expr": "(pocket_r + 8) > idrop_cap ? (pocket_r + 8) : idrop_cap"}, |
| 52 | + {"id": "mg_cap", "expr": "mount_grip < (SCREW_L - HEAD_K - 0.5) ? mount_grip : (SCREW_L - HEAD_K - 0.5)"}, |
| 53 | + {"id": "mg", "expr": "(SCREW_L - 8) > mg_cap ? (SCREW_L - 8) : mg_cap"}, |
| 54 | + {"id": "mp_cap", "expr": "mount_pitch < 60 ? mount_pitch : 60"}, |
| 55 | + {"id": "mp", "expr": "(TNUT_L + 1) > mp_cap ? (TNUT_L + 1) : mp_cap"}, |
| 56 | + {"id": "hr_cap", "expr": "heel_reach < PROFILE ? heel_reach : PROFILE"}, |
| 57 | + {"id": "hr", "expr": "(PROFILE / 2 + TAB_W / 2 + 2) > hr_cap ? (PROFILE / 2 + TAB_W / 2 + 2) : hr_cap"}, |
| 58 | + {"id": "DEPTH", "expr": "SCREW_L"}, |
| 59 | + {"id": "TOP", "expr": "PROFILE / 2"}, |
| 60 | + {"id": "z_axle", "expr": "-idrop"}, |
| 61 | + {"id": "z_bottom", "expr": "z_axle - AXLE_WALL"}, |
| 62 | + {"id": "x2", "expr": "MOUNT_X1 + mp"}, |
| 63 | + {"id": "length_a", "expr": "x2 + (HEAD_DK / 2 + HEAD_CLEAR) + EDGE"}, |
| 64 | + {"id": "length_b", "expr": "io + pocket_r + 4"}, |
| 65 | + {"id": "length", "expr": "length_a > length_b ? length_a : length_b"}, |
| 66 | + {"id": "heel_top", "expr": "-PROFILE / 2 - HEEL_GAP"}, |
| 67 | + {"id": "hole_d", "expr": "SCREW_D + 2 * HOLE_CLEAR"}, |
| 68 | + {"id": "cbore_d", "expr": "HEAD_DK + 2 * HEAD_CLEAR"} |
| 69 | + ], |
| 70 | + "nodes": [ |
| 71 | + {"id": "block_blank", "type": "box", "params": {"w": {"expr": "length - 0"}, "d": {"expr": "DEPTH - 0"}, "h": {"expr": "TOP - z_bottom"}}}, |
| 72 | + {"id": "block", "type": "translate", "inputs": {"shape": "block_blank"}, "params": {"x": {"expr": "(0 + length) / 2"}, "y": {"expr": "(0 + DEPTH) / 2"}, "z": {"expr": "(z_bottom + TOP) / 2"}}}, |
| 73 | + {"id": "heel_blank", "type": "box", "params": {"w": {"expr": "0.5 - -hr"}, "d": {"expr": "DEPTH - 0"}, "h": {"expr": "heel_top - z_bottom"}}}, |
| 74 | + {"id": "heel", "type": "translate", "inputs": {"shape": "heel_blank"}, "params": {"x": {"expr": "(-hr + 0.5) / 2"}, "y": {"expr": "(0 + DEPTH) / 2"}, "z": {"expr": "(z_bottom + heel_top) / 2"}}}, |
| 75 | + {"id": "body_1", "type": "union", "inputs": {"a": "block", "b": "heel"}}, |
| 76 | + {"id": "corner_tongue_blank", "type": "box", "params": {"w": {"expr": "0.5 - -SLOT_LIP_T"}, "d": {"expr": "DEPTH - 2 - 2"}, "h": {"expr": "TAB_W / 2 - (-TAB_W / 2)"}}}, |
| 77 | + {"id": "corner_tongue", "type": "translate", "inputs": {"shape": "corner_tongue_blank"}, "params": {"x": {"expr": "(-SLOT_LIP_T + 0.5) / 2"}, "y": {"expr": "(2 + (DEPTH - 2)) / 2"}, "z": {"expr": "(-TAB_W / 2 + (TAB_W / 2)) / 2"}}}, |
| 78 | + {"id": "body_2", "type": "union", "inputs": {"a": "body_1", "b": "corner_tongue"}}, |
| 79 | + {"id": "heel_tongue_blank", "type": "box", "params": {"w": {"expr": "-PROFILE / 2 + TAB_W / 2 - (-PROFILE / 2 - TAB_W / 2)"}, "d": {"expr": "0.5 - -SLOT_LIP_T"}, "h": {"expr": "heel_top - 2 - (z_bottom + 2)"}}}, |
| 80 | + {"id": "heel_tongue", "type": "translate", "inputs": {"shape": "heel_tongue_blank"}, "params": {"x": {"expr": "(-PROFILE / 2 - TAB_W / 2 + (-PROFILE / 2 + TAB_W / 2)) / 2"}, "y": {"expr": "(-SLOT_LIP_T + 0.5) / 2"}, "z": {"expr": "(z_bottom + 2 + (heel_top - 2)) / 2"}}}, |
| 81 | + {"id": "body_3", "type": "union", "inputs": {"a": "body_2", "b": "heel_tongue"}}, |
| 82 | + {"id": "mount_hole_1_outline", "type": "profile_circle", "params": {"plane": "XZ", "r": {"expr": "hole_d / 2"}}}, |
| 83 | + {"id": "mount_hole_1_blank", "type": "extrude", "inputs": {"profile": "mount_hole_1_outline"}, "params": {"height": {"expr": "-(DEPTH + 1 - -1)"}}}, |
| 84 | + {"id": "mount_hole_1_seam", "type": "rotate", "inputs": {"shape": "mount_hole_1_blank"}, "params": {"axis": "y", "angle": -90.0}}, |
| 85 | + {"id": "mount_hole_1", "type": "translate", "inputs": {"shape": "mount_hole_1_seam"}, "params": {"x": {"expr": "MOUNT_X1"}, "y": -1.0}}, |
| 86 | + {"id": "body_4", "type": "cut", "inputs": {"a": "body_3", "b": "mount_hole_1"}}, |
| 87 | + {"id": "mount_cbore_1_outline", "type": "profile_circle", "params": {"plane": "XZ", "r": {"expr": "cbore_d / 2"}}}, |
| 88 | + {"id": "mount_cbore_1_blank", "type": "extrude", "inputs": {"profile": "mount_cbore_1_outline"}, "params": {"height": {"expr": "-(DEPTH + 1 - mg)"}}}, |
| 89 | + {"id": "mount_cbore_1_seam", "type": "rotate", "inputs": {"shape": "mount_cbore_1_blank"}, "params": {"axis": "y", "angle": -90.0}}, |
| 90 | + {"id": "mount_cbore_1", "type": "translate", "inputs": {"shape": "mount_cbore_1_seam"}, "params": {"x": {"expr": "MOUNT_X1"}, "y": {"expr": "mg"}}}, |
| 91 | + {"id": "body_5", "type": "cut", "inputs": {"a": "body_4", "b": "mount_cbore_1"}}, |
| 92 | + {"id": "mount_hole_2_outline", "type": "profile_circle", "params": {"plane": "XZ", "r": {"expr": "hole_d / 2"}}}, |
| 93 | + {"id": "mount_hole_2_blank", "type": "extrude", "inputs": {"profile": "mount_hole_2_outline"}, "params": {"height": {"expr": "-(DEPTH + 1 - -1)"}}}, |
| 94 | + {"id": "mount_hole_2_seam", "type": "rotate", "inputs": {"shape": "mount_hole_2_blank"}, "params": {"axis": "y", "angle": -90.0}}, |
| 95 | + {"id": "mount_hole_2", "type": "translate", "inputs": {"shape": "mount_hole_2_seam"}, "params": {"x": {"expr": "x2"}, "y": -1.0}}, |
| 96 | + {"id": "body_6", "type": "cut", "inputs": {"a": "body_5", "b": "mount_hole_2"}}, |
| 97 | + {"id": "mount_cbore_2_outline", "type": "profile_circle", "params": {"plane": "XZ", "r": {"expr": "cbore_d / 2"}}}, |
| 98 | + {"id": "mount_cbore_2_blank", "type": "extrude", "inputs": {"profile": "mount_cbore_2_outline"}, "params": {"height": {"expr": "-(DEPTH + 1 - mg)"}}}, |
| 99 | + {"id": "mount_cbore_2_seam", "type": "rotate", "inputs": {"shape": "mount_cbore_2_blank"}, "params": {"axis": "y", "angle": -90.0}}, |
| 100 | + {"id": "mount_cbore_2", "type": "translate", "inputs": {"shape": "mount_cbore_2_seam"}, "params": {"x": {"expr": "x2"}, "y": {"expr": "mg"}}}, |
| 101 | + {"id": "body_7", "type": "cut", "inputs": {"a": "body_6", "b": "mount_cbore_2"}}, |
| 102 | + {"id": "idler_pocket_blank", "type": "box", "params": {"w": {"expr": "io + pocket_r - (io - pocket_r)"}, "d": {"expr": "rear_arm + gap - rear_arm"}, "h": {"expr": "z_axle + pocket_r - (z_bottom - 1)"}}}, |
| 103 | + {"id": "idler_pocket", "type": "translate", "inputs": {"shape": "idler_pocket_blank"}, "params": {"x": {"expr": "(io - pocket_r + (io + pocket_r)) / 2"}, "y": {"expr": "(rear_arm + (rear_arm + gap)) / 2"}, "z": {"expr": "(z_bottom - 1 + (z_axle + pocket_r)) / 2"}}}, |
| 104 | + {"id": "body_8", "type": "cut", "inputs": {"a": "body_7", "b": "idler_pocket"}}, |
| 105 | + {"id": "axle_clearance_outline", "type": "profile_circle", "params": {"plane": "XZ", "r": {"expr": "hole_d / 2"}}}, |
| 106 | + {"id": "axle_clearance_blank", "type": "extrude", "inputs": {"profile": "axle_clearance_outline"}, "params": {"height": {"expr": "-(DEPTH + 1 - (rear_arm + gap - 0.5))"}}}, |
| 107 | + {"id": "axle_clearance_seam", "type": "rotate", "inputs": {"shape": "axle_clearance_blank"}, "params": {"axis": "y", "angle": -90.0}}, |
| 108 | + {"id": "axle_clearance", "type": "translate", "inputs": {"shape": "axle_clearance_seam"}, "params": {"x": {"expr": "io"}, "y": {"expr": "rear_arm + gap - 0.5"}, "z": {"expr": "z_axle"}}}, |
| 109 | + {"id": "body_9", "type": "cut", "inputs": {"a": "body_8", "b": "axle_clearance"}}, |
| 110 | + {"id": "axle_pilot_outline", "type": "profile_circle", "params": {"plane": "XZ", "r": {"expr": "PILOT_D / 2"}}}, |
| 111 | + {"id": "axle_pilot_blank", "type": "extrude", "inputs": {"profile": "axle_pilot_outline"}, "params": {"height": {"expr": "-(rear_arm + 0.5 - -1)"}}}, |
| 112 | + {"id": "axle_pilot_seam", "type": "rotate", "inputs": {"shape": "axle_pilot_blank"}, "params": {"axis": "y", "angle": -90.0}}, |
| 113 | + {"id": "axle_pilot", "type": "translate", "inputs": {"shape": "axle_pilot_seam"}, "params": {"x": {"expr": "io"}, "y": -1.0, "z": {"expr": "z_axle"}}}, |
| 114 | + {"id": "body_10", "type": "cut", "inputs": {"a": "body_9", "b": "axle_pilot"}}, |
| 115 | + {"id": "body_mirrored", "type": "reflect", "inputs": {"shape": "body_10"}, "params": {"plane": "YZ"}}, |
| 116 | + {"id": "corner_idler", "type": "select", "inputs": {"if_true": "body_mirrored", "if_false": "body_10"}, "params": {"when": {"expr": "mirrored"}}} |
| 117 | + ], |
| 118 | + "outputs": { |
| 119 | + "corner_idler": "corner_idler" |
| 120 | + } |
| 121 | +} |
0 commit comments