code wiki / (root) / nx_underridge_cleaner.nx

nx_underridge_cleaner.nx source

↩ module page · 140 lines · 7978 B

1// nx_underridge_cleaner.nx -- the UNDER-RIDGE toilet-bowl cleaner head, GENERATED OUT OF 2// THE TEAM as a sovereign N-primitive CSG scene (nx_csg_scene) -> watertight NxMesh -> 3// nx_stl_write_mesh -> slicer -> G-code. No 3rd-party CAD anywhere in the path. 4// 5// Design (a FLAT paddle = prints with zero supports; the strong, never-break geometry): 6// * rounded head plate (every glaze-facing edge filleted = never-break NB2) 7// * a recessed POCKET that holds a glaze-SAFE scour/melamine pad -- the pad stands proud 8// of the printed lip, so the ONLY thing that ever touches the porcelain is the soft pad 9// (never-break NB1: the tool cannot scratch the glaze) 10// * two strap slots to clamp the pad (zip-tie / rubber band) 11// * a neck for reach + two MOUNT HOLES to HOOK ONTO a handle ("hookable on") 12// * power vs the black biofilm = pad pressure under the rim + reach, not hard abrasion 13// 14// Axis-aligned v1 (SDF has no rotation yet -> the candy-cane hook tilt is a later rung; 15// the flat paddle is the strongest, most printable starting geometry). All dims Q14-mm 16// (1mm = 16384). The never-break gate reads these same numbers. license_tier: ORIGINAL 17import "nx_syscalls.nx" 18import "nx_mesh.nx" 19import "nx_sdf.nx" 20import "nx_csg_scene.nx" 21import "nx_stl_write.nx" 22 23const UC_MM: i64 = 16384 24 25// Build the cleaner as a 7-primitive scene. drop_slot lets the never-break / liar-kill 26// tests displace strap-slot A far away to prove the field depends on real parameters. 27func nx_uc_build(drop_slot: i64) -> *NxCsgScene { 28 let M: i64 = 16384 29 let s: *NxCsgScene = nx_csg_scene_new(12) 30 31 // p0 SEED: head plate 75 x 36 x 6 mm, 2mm rounded edges (overall half - r feeds the box). 32 nx_csg_scene_add(s, nx_sdf_make4(NX_SDF_ROUNDBOX, 0, 0, 3*M, 33 (75*M)/2 - 2*M, (36*M)/2 - 2*M, 3*M - 2*M, 2*M), NX_CSG_UNION, 0) 34 35 // p1 DIFF: pad pocket -- 68 x 30 mm, 3mm deep into the top face (centre z=6mm, floor z=3mm). 36 nx_csg_scene_add(s, nx_sdf_make4(NX_SDF_ROUNDBOX, 0, 0, 6*M, 37 (68*M)/2 - 1*M, (30*M)/2 - 1*M, 3*M - 1*M, 1*M), NX_CSG_DIFF, 0) 38 39 // p2 DIFF: strap slot A (4mm wide, through the plate) at x=-22.5mm. drop_slot moves it out. 40 var slotA_x: i64 = 0 - (45*M)/2 41 if drop_slot == 1 { slotA_x = 200*M } 42 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_BOX, slotA_x, 0, 3*M, 2*M, 10*M, 5*M), NX_CSG_DIFF, 0) 43 44 // p3 DIFF: strap slot B at x=+22.5mm. 45 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_BOX, (45*M)/2, 0, 3*M, 2*M, 10*M, 5*M), NX_CSG_DIFF, 0) 46 47 // p4 UNION: neck bar extends -X from the heel (overlaps the head ~4mm for a solid weld). 48 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_BOX, 0 - 58*M, 0, 3*M, 24*M + 8192, 8*M, 3*M), NX_CSG_UNION, 0) 49 50 // p5,p6 DIFF: two mount holes (5mm dia) through the neck -> HOOK ONTO / bolt onto a handle. 51 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_CYL, 0 - 70*M, 0, 3*M, 2*M + 8192, 6*M, 0), NX_CSG_DIFF, 0) 52 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_CYL, 0 - 60*M, 0, 3*M, 2*M + 8192, 6*M, 0), NX_CSG_DIFF, 0) 53 54 return s 55} 56 57// extraction bounds (mm*M) that tightly bound the part + 2-3mm padding. 58func nx_uc_lox() -> i64 { return 0 - 85*16384 } 59func nx_uc_loy() -> i64 { return 0 - 20*16384 } 60func nx_uc_loz() -> i64 { return 0 - 2*16384 } 61func nx_uc_hix() -> i64 { return 40*16384 } 62func nx_uc_hiy() -> i64 { return 20*16384 } 63func nx_uc_hiz() -> i64 { return 9*16384 } 64 65// generate the part mesh at grid resolution `res`. 66func nx_uc_mesh(res: i64) -> *NxMesh { 67 let s: *NxCsgScene = nx_uc_build(0) 68 return nx_csg_extract_scene(s, nx_uc_lox(), nx_uc_loy(), nx_uc_loz(), 69 nx_uc_hix(), nx_uc_hiy(), nx_uc_hiz(), res) 70} 71 72// ===== HOOK variant (candy-cane tilt) ===================================== 73// Tilts the head + pocket + slots UP about the HEEL (where the head meets the neck), 74// keeping the neck + mount holes low -> the working face angles up UNDER the rim while 75// the handle stays clear of the bowl. Uses the nx_csg_scene Y-rotation about the heel 76// pivot. SAME never-break parameters as the flat paddle (neck cross-section unchanged, 77// pad stack unchanged), so nx_underridge_nevergate stays valid. 78const UC_HOOK_ANG: i64 = 43 // ~15 deg up (1024*15/360) 79func nx_uc_heel_x() -> i64 { return 0 - (75*16384)/2 } // -37.5mm = head heel (neck weld) 80func nx_uc_heel_z() -> i64 { return 3*16384 } // mid-plate pivot height 81 82func nx_uc_build_hook(drop_slot: i64) -> *NxCsgScene { 83 let MM: i64 = 16384 84 let px: i64 = nx_uc_heel_x() 85 let pz: i64 = nx_uc_heel_z() 86 let s: *NxCsgScene = nx_csg_scene_new(12) 87 // p0 head plate (tilted up about the heel) 88 nx_csg_scene_add_rot(s, nx_sdf_make4(NX_SDF_ROUNDBOX, 0,0,3*MM, (75*MM)/2-2*MM,(36*MM)/2-2*MM,3*MM-2*MM,2*MM), 89 NX_CSG_UNION, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 90 // p1 pad pocket (tilted with the head) 91 nx_csg_scene_add_rot(s, nx_sdf_make4(NX_SDF_ROUNDBOX, 0,0,6*MM, (68*MM)/2-1*MM,(30*MM)/2-1*MM,3*MM-1*MM,1*MM), 92 NX_CSG_DIFF, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 93 // p2,p3 strap slots (tilted with the head); drop_slot moves slot A out for liar-kill 94 var slotA_x: i64 = 0 - (45*MM)/2 95 if drop_slot == 1 { slotA_x = 200*MM } 96 nx_csg_scene_add_rot(s, nx_sdf_make(NX_SDF_BOX, slotA_x,0,3*MM, 2*MM,10*MM,5*MM), 97 NX_CSG_DIFF, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 98 nx_csg_scene_add_rot(s, nx_sdf_make(NX_SDF_BOX, (45*MM)/2,0,3*MM, 2*MM,10*MM,5*MM), 99 NX_CSG_DIFF, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 100 // p4 neck bar -- axis-aligned (stays low = the candy-cane handle) 101 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_BOX, 0-58*MM,0,3*MM, 24*MM+8192,8*MM,3*MM), NX_CSG_UNION, 0) 102 // p5,p6 mount holes -- axis-aligned 103 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_CYL, 0-70*MM,0,3*MM, 2*MM+8192,6*MM,0), NX_CSG_DIFF, 0) 104 nx_csg_scene_add(s, nx_sdf_make(NX_SDF_CYL, 0-60*MM,0,3*MM, 2*MM+8192,6*MM,0), NX_CSG_DIFF, 0) 105 return s 106} 107 108// hook mesh; wider +Z extraction box because the tilted toe lifts well above the flat 6mm. 109func nx_uc_mesh_hook(res: i64) -> *NxMesh { 110 let s: *NxCsgScene = nx_uc_build_hook(0) 111 return nx_csg_extract_scene(s, nx_uc_lox(), nx_uc_loy(), nx_uc_loz(), 112 nx_uc_hix(), nx_uc_hiy(), 30*16384, res) 113} 114 115// ===== HOOK + GEL DELIVERY ================================================ 116// The "really powerful vs black biofilm" rung: 3 feed holes (3mm) through the pocket floor, 117// rotated WITH the head. Inject a glaze-safe descaling gel behind the pad -> it wicks through 118// to the rim and DWELLS while you scrub = chemistry power, not hard abrasion. Holes are kept 119// off the strap slots (x=+/-12mm vs slots at +/-22.5mm). Never-break is unaffected: plate 120// perforations don't change the sacrificial neck (NB4) or the pad-proud rule (NB1). 121func nx_uc_build_hook_gel(drop_slot: i64) -> *NxCsgScene { 122 let MM: i64 = 16384 123 let px: i64 = nx_uc_heel_x() 124 let pz: i64 = nx_uc_heel_z() 125 let s: *NxCsgScene = nx_uc_build_hook(drop_slot) // reuse the 7-feature hook... 126 // ...then add 3 gel feed holes (rotated with the head about the heel) 127 nx_csg_scene_add_rot(s, nx_sdf_make(NX_SDF_CYL, 0-12*MM, 0, 3*MM, 2*MM+8192, 6*MM, 0), 128 NX_CSG_DIFF, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 129 nx_csg_scene_add_rot(s, nx_sdf_make(NX_SDF_CYL, 0, 0, 3*MM, 2*MM+8192, 6*MM, 0), 130 NX_CSG_DIFF, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 131 nx_csg_scene_add_rot(s, nx_sdf_make(NX_SDF_CYL, 12*MM, 0, 3*MM, 2*MM+8192, 6*MM, 0), 132 NX_CSG_DIFF, 0, NX_ROT_Y, UC_HOOK_ANG, px, 0, pz) 133 return s 134} 135 136func nx_uc_mesh_hook_gel(res: i64) -> *NxMesh { 137 let s: *NxCsgScene = nx_uc_build_hook_gel(0) 138 return nx_csg_extract_scene(s, nx_uc_lox(), nx_uc_loy(), nx_uc_loz(), 139 nx_uc_hix(), nx_uc_hiy(), 30*16384, res) 140}