Interactive Preview & Customizer
3D preview with OpenSCAD rendering on parameter changes.
Loading preview...
step 0.5
step 0.5
step 0.1
step 0.5
step 0.1
step 0.1
step 0.5
step 0.1
step 0.1
step 0.1
step 0.01
step 0.1
step 0.01
step 0.1
step 0.1
step 0.5
step 0.5
step 0.5
step 0.1
step 0.5
step 0.1
step 0.1
step 0.1
step 0.1
step 0.5
step 0.1
step 0.1
step 0.5
WASM compiler loads on first parameter change.
Prompt Assets
Prompt image
Prompt
remove all references to A1 mini in code
OpenSCAD Code
// ==============================================================================
// 100% 3D-Printed Optimized Low-Friction Spool Holder
// Fully Parametric, Zero Hardware, Pure FDM Roller-Bearing Mechanism
// ==============================================================================
/* [Mode Selection] */
mode = "print_layout"; // [assembly, exploded, cutaway, print_layout, mount_core, drum, roller, cage, cap, clearance_coupon, roller_test]
/* [Basic Spool Specifications] */
spool_width = 68.0; // Standard 1kg spool barrel width (mm)
max_spool_width = 80.0; // Maximum spool clearance capacity
minimum_spool_bore = 50.5; // Smallest allowable inner diameter of spool hub
recommended_spool_bore = 53.0; // Standard nominal spool bore
/* [Roller Kinematics & Race Geometry] */
roller_count = 4; // Number of rolling elements (0°, 90°, 180°, 270°)
roller_od = 10.0; // Actual maximum roller outer diameter (mm)
roller_len = 34.0; // Active roller contact length (mm)
roller_crown = 0.20; // Self-centering crown radius delta (mm)
roller_pin_d = 4.0; // Roller end guide trunnion diameter (mm)
roller_pin_len = 3.0; // Roller end guide trunnion length (mm)
radial_clearance = 0.25; // Working radial gap per side (0.20 - 0.30 mm)
axial_clearance = 0.50; // Axial running play for free rotation (mm)
cage_pocket_clearance = 0.35; // Clearance around roller trunnions in cage (mm)
/* [Drum & Core Structural Sizing] */
inner_race_radius = 9.5; // Stationary spindle core outer radius (OD = 19 mm)
drum_wall_thickness = 3.0; // Structural race & barrel wall thickness (min 2.5 mm)
rear_flange_od = 70.0; // Rear spool stop flange outer diameter (mm)
front_lip_od = 49.0; // Front anti-slide-off spool lip diameter (mm)
/* [Mount Interface Calibration Parameters] */
mount_tongue_w = 20.0; // Base slide tongue width (mm)
mount_tongue_t = 4.8; // Base slide tongue thickness (mm)
mount_tongue_l = 26.0; // Slide insertion depth (mm)
mount_lip_w = 2.4; // Side guide step rail width (mm)
mount_lip_h = 1.6; // Side guide step rail depth (mm)
mount_detent_pos = 16.0; // Insertion distance to snap detent (mm)
mount_detent_h = 1.2; // Detent wedge snap height (mm)
mount_arm_drop = 28.0; // Vertical offset from spool axis to mount slide (mm)
mount_arm_thick = 12.0; // Structural root thickness along spool axis (mm)
mount_gusset_t = 5.0; // Reinforcement gusset rib thickness (mm)
/* [Rendering Fidelity] */
$fn = 64;
// ==============================================================================
// DERIVED MATHEMATICAL RELATIONSHIPS & FIRST PRINCIPLES
// ==============================================================================
roller_r = roller_od / 2;
working_radial_gap = roller_od + (2 * radial_clearance);
outer_race_radius = inner_race_radius + working_radial_gap;
roller_pitch_radius = inner_race_radius + radial_clearance + roller_r;
// Drum outer dimensions
drum_inner_radius = outer_race_radius;
drum_outer_radius = drum_inner_radius + drum_wall_thickness;
drum_outer_diameter = drum_outer_radius * 2;
// Working lengths
spool_seat_len = spool_width + 4.0; // Free axial running room for spool
core_spindle_len = spool_seat_len + 8.0;
cage_od = (roller_pitch_radius + 1.2) * 2;
cage_id = (roller_pitch_radius - 1.2) * 2;
// Circumferential clearance between 4 rollers
circ_pitch_dist = 2 * PI * roller_pitch_radius / roller_count;
chord_clearance = (sqrt(2) * roller_pitch_radius) - roller_od;
// ==============================================================================
// MECHANICAL VALIDATION ASSERTIONS
// ==============================================================================
assert(drum_outer_diameter < minimum_spool_bore,
"FATAL: Drum OD exceeds minimum spool bore! Spool will bind.");
assert(drum_wall_thickness >= 2.5,
"FATAL: Drum wall thickness under 2.5 mm structural threshold.");
assert(working_radial_gap - roller_od >= 2 * radial_clearance - 0.001,
"FATAL: Working radial race equation does not satisfy 2 * radial_clearance.");
assert(chord_clearance > 2.0,
"FATAL: Rollers will physically collide circumferentially!");
assert(roller_len < spool_seat_len,
"FATAL: Roller length exceeds available spool seat length.");
// ==============================================================================
// MODULES
// ==============================================================================
// 1. CROWNED ROLLER WITH LOW-FRICTION TRUNNIONS
module crowned_roller() {
// Roller axis parallel to spool axis (along Z axis)
// Generates a precision crowned profile: slightly larger OD at center for self-tracking
// Integrated trunnion pins on both ends for lightweight cage containment
render() rotate_extrude() {
polygon([
[0, -roller_len/2],
[roller_pin_d/2, -roller_len/2],
[roller_pin_d/2, -(roller_len/2 - roller_pin_len)],
[roller_r - 0.35, -(roller_len/2 - roller_pin_len)],
[roller_r - 0.08, -roller_len/4],
[roller_r, 0],
[roller_r - 0.08, roller_len/4],
[roller_r - 0.35, roller_len/2 - roller_pin_len],
[roller_pin_d/2, roller_len/2 - roller_pin_len],
[roller_pin_d/2, roller_len/2],
[0, roller_len/2]
]);
}
}
// 2. LIGHTWEIGHT 4-ROLLER CAGE (0°, 90°, 180°, 270°)
module roller_cage() {
ring_thick = 2.5;
pin_pocket_r = (roller_pin_d/2) + cage_pocket_clearance;
difference() {
union() {
// Front ring
translate([0, 0, roller_len/2 + 0.5])
cylinder(r=roller_pitch_radius + 1.5, h=ring_thick, center=false);
// Rear ring
translate([0, 0, -(roller_len/2 + 0.5 + ring_thick)])
cylinder(r=roller_pitch_radius + 1.5, h=ring_thick, center=false);
// 4 Low-profile interconnecting bridge struts located between rollers (at 45°, 135°, 225°, 315°)
for (a = [45, 135, 225, 315]) {
rotate([0, 0, a])
translate([roller_pitch_radius, 0, -roller_len/2])
cylinder(r=1.6, h=roller_len, $fn=16);
}
}
// Bore through cage rings
cylinder(r=inner_race_radius + 0.8, h=100, center=true);
// Pivot sockets for roller trunnions
for (i = [0 : roller_count-1]) {
rotate([0, 0, i * (360/roller_count)]) {
translate([roller_pitch_radius, 0, roller_len/2 - 0.2])
cylinder(r=pin_pocket_r, h=roller_pin_len + 2, $fn=24);
translate([roller_pitch_radius, 0, -(roller_len/2 + roller_pin_len + 1.8)])
cylinder(r=pin_pocket_r, h=roller_pin_len + 2, $fn=24);
}
}
}
}
// 3. SLIDE-IN MOUNT INTERFACE
module slide_mount() {
// Stepped slide-in tongue matching receiver bracket socket
difference() {
union() {
// Base slide body
translate([-mount_tongue_w/2, 0, 0])
cube([mount_tongue_w, mount_tongue_t, mount_tongue_l]);
// Side guide rails / lips
translate([-(mount_tongue_w/2 + mount_lip_w), 0, 0])
cube([mount_lip_w, mount_tongue_t - mount_lip_h, mount_tongue_l]);
translate([mount_tongue_w/2, 0, 0])
cube([mount_lip_w, mount_tongue_t - mount_lip_h, mount_tongue_l]);
// Lead-in insertion chamfers
translate([-mount_tongue_w/2, 0, 0])
rotate([-45, 0, 0])
cube([mount_tongue_w, 2, 2]);
}
// Integrated snap-lock flexure cantilever slot
translate([-3.0, -1, 4.0])
cube([6.0, mount_tongue_t + 2, mount_tongue_l - 8.0]);
}
// Retention snap detent tooth with lead-in ramp on flexible tongue
translate([-2.5, 0, 4.5]) {
cube([5.0, mount_tongue_t, mount_tongue_l - 9.0]);
// Latch tooth wedge
translate([0, mount_tongue_t, mount_detent_pos - 4.5]) {
polyhedron(
points=[
[0, 0, 0], [5.0, 0, 0], [5.0, mount_detent_h, 3.0], [0, mount_detent_h, 3.0],
[0, 0, 5.0], [5.0, 0, 5.0]
],
faces=[
[0,1,2,3], [3,2,5,4], [0,3,4], [1,5,2], [0,4,5,1]
]
);
}
}
}
// 4. REINFORCED CANTILEVER ARM & STATIONARY SPINDLE CORE
module stationary_core_and_arm() {
// 1. Spool core inner race spindle
difference() {
union() {
// Precision inner race zone
cylinder(r=inner_race_radius, h=core_spindle_len);
// Spindle shoulder / thrust ring
cylinder(r=inner_race_radius + 2.5, h=4.0);
// Front cap locking neck with bayonet notch
translate([0, 0, core_spindle_len]) {
cylinder(r=inner_race_radius - 2.5, h=7.0);
// Bayonet locking pins
translate([0, 0, 3.5])
rotate([0, 90, 0])
cylinder(r=1.5, h=(inner_race_radius - 0.5) * 2, center=true, $fn=16);
}
// 2. Heavy Root Cantilever Arm to Mount
translate([0, -mount_arm_drop, 0]) {
// Main rigid drop block
translate([-mount_tongue_w/2, 0, -mount_arm_thick])
cube([mount_tongue_w, mount_arm_drop, mount_arm_thick]);
// Massive triangular stiffener gussets
hull() {
translate([-mount_tongue_w/2, 0, -mount_arm_thick])
cube([mount_tongue_w, 2.0, -mount_arm_thick]);
translate([-inner_race_radius, mount_arm_drop, -mount_arm_thick])
cube([inner_race_radius * 2, 2.0, mount_arm_thick]);
}
// Mount Interface slide
translate([0, 0, -mount_tongue_l])
slide_mount();
}
}
// Weight-reduction / print-speed central core bore
cylinder(r=4.5, h=core_spindle_len + 20, center=true);
}
}
// 5. ROTATING OUTER DRUM WITH INTEGRATED SPOOL RACE
module rotating_drum() {
difference() {
union() {
// Main barrel carrying the spool
cylinder(r=drum_outer_radius, h=spool_seat_len);
// Rear spool retention guide flange
cylinder(r=rear_flange_od/2, h=4.0);
// Transition fillet cone from flange to drum
translate([0, 0, 4.0])
cylinder(r1=rear_flange_od/2 - 2.0, r2=drum_outer_radius, h=4.0);
// Front spool retention lip (gentle angle for easy spool sliding)
translate([0, 0, spool_seat_len - 3.5])
cylinder(r1=drum_outer_radius, r2=front_lip_od/2, h=3.5);
}
// Calibrated outer bearing race bore for the 4 rollers
translate([0, 0, -1])
cylinder(r=outer_race_radius, h=roller_len + 12.0);
// Front thrust clearance bore
translate([0, 0, roller_len + 10.0])
cylinder(r=inner_race_radius + 2.0, h=spool_seat_len, center=false);
}
}
// 6. TOOL-LESS BAYONET AXIAL RETENTION CAP
module retaining_cap() {
cap_od = drum_inner_radius + 1.5;
difference() {
union() {
// Outer knurled gripping head
cylinder(r=cap_od, h=3.5);
// Internal sleeve
translate([0, 0, 3.5])
cylinder(r=inner_race_radius - 0.5, h=6.5);
}
// Central hollow bore for spindle bayonet peg
translate([0, 0, -1])
cylinder(r=inner_race_radius - 2.2, h=12);
// Bayonet J-slots
for (a = [0, 180]) {
rotate([0, 0, a]) {
translate([0, 0, 4.0])
cube([inner_race_radius * 2 + 2, 3.4, 3.2], center=true);
// Entry slot
translate([inner_race_radius - 2.2, -1.7, 3.5])
cube([4, 3.4, 7]);
}
}
}
}
// 7. CALIBRATION CLEARANCE COUPON
module clearance_coupon() {
// Reproduces the exact 3-body tribology stack: Inner Core, Roller, Outer Drum
difference() {
union() {
// Base plate
cube([55, 30, 3.0]);
// Inner race segment
translate([15, 15, 3.0])
cylinder(r=inner_race_radius, h=10.0);
// Outer race test segment
translate([15, 15, 3.0])
difference() {
cylinder(r=outer_race_radius + 3.0, h=10.0);
cylinder(r=outer_race_radius, h=12.0);
translate([-25, -25, -1]) cube([50, 25, 15]);
}
}
// Engraved text indicator
translate([32, 10, 2.2])
linear_extrude(1.2) text("0.25", size=5.5);
}
// Matching test roller
translate([15, 15 + roller_pitch_radius, 8.0])
crowned_roller();
}
// 8. ROLLER TEST RIG
module roller_test_rig() {
stationary_core_and_arm();
translate([roller_pitch_radius, 0, 10 + roller_len/2])
crowned_roller();
translate([0, 0, 6.0])
intersection() {
rotating_drum();
cube([60, 60, 40]);
}
}
// ==============================================================================
// VIEW MODES & SCENE COMPOSITION
// ==============================================================================
if (mode == "assembly") {
// @name Spindle Core and Cantilever Arm
color([0.2, 0.2, 0.25]) stationary_core_and_arm();
// @name Crowned Rollers
color([0.85, 0.5, 0.15]) {
for (i = [0 : roller_count-1]) {
rotate([0, 0, i * (360/roller_count)])
translate([roller_pitch_radius, 0, 6.0 + roller_len/2])
crowned_roller();
}
}
// @name Roller Alignment Cage
color([0.3, 0.7, 0.3, 0.7])
translate([0, 0, 6.0 + roller_len/2])
roller_cage();
// @name Rotating Spool Drum
color([0.15, 0.45, 0.85, 0.65])
translate([0, 0, 5.0])
rotating_drum();
// @name Retention Cap
color([0.9, 0.2, 0.2])
translate([0, 0, core_spindle_len + 2.0])
retaining_cap();
}
else if (mode == "exploded") {
// Exploded along horizontal spindle axis (Z in SCAD coordinates)
// @name Spindle Core and Cantilever Arm
color([0.2, 0.2, 0.25]) stationary_core_and_arm();
// @name Crowned Rollers and Cage
translate([0, 0, 30]) {
for (i = [0 : roller_count-1]) {
rotate([0, 0, i * (360/roller_count)])
translate([roller_pitch_radius + 15, 0, roller_len/2])
color([0.85, 0.5, 0.15]) crowned_roller();
}
color([0.3, 0.7, 0.3])
translate([0, 0, roller_len/2])
roller_cage();
}
// @name Rotating Spool Drum
color([0.15, 0.45, 0.85])
translate([0, 0, 95])
rotating_drum();
// @name Retention Cap
color([0.9, 0.2, 0.2])
translate([0, 0, 185])
retaining_cap();
}
else if (mode == "cutaway") {
// Half-cutaway view to inspect inner race, 4 rollers, cage, and outer drum clearances
// @name Cutaway Inspection View
difference() {
union() {
color([0.2, 0.2, 0.25]) stationary_core_and_arm();
for (i = [0 : roller_count-1]) {
rotate([0, 0, i * (360/roller_count)])
translate([roller_pitch_radius, 0, 6.0 + roller_len/2])
color([0.85, 0.5, 0.15]) crowned_roller();
}
color([0.3, 0.7, 0.3])
translate([0, 0, 6.0 + roller_len/2])
roller_cage();
color([0.15, 0.45, 0.85, 0.8])
translate([0, 0, 5.0])
rotating_drum();
color([0.9, 0.2, 0.2])
translate([0, 0, core_spindle_len + 2.0])
retaining_cap();
}
// 90-degree inspection wedge cutout
translate([0, 0, -50])
cube([100, 100, 200]);
}
}
else if (mode == "print_layout") {
// Bed-level print layout: all parts seated flat at Z = 0
// 1. Stationary core & cantilever arm
// In stationary_core_and_arm(), the flat back face of the mount root is at Y = -mount_arm_drop,
// and slide_mount tongue is in negative Z.
// Rotating around X by 90 (or -90):
// If rotate([90, 0, 0]), the arm back at Y = -mount_arm_drop lies in Z.
// Let's place it flat on its back so the cantilever spindle and mount tongue print horizontally:
// With rotate([90, 0, 0]), Z becomes Y, Y becomes -Z.
// The spindle axis (Z) is now along Y (horizontal).
// The arm drop is along -Y, which becomes +Z.
// Specifically:
// When rotate([90, 0, 0]):
// Spindle center is at X=0, Z=0. Lowest point is the spindle cylinder outer surface at Z = -(inner_race_radius + 2.5) = -12.
// Let's orient stationary_core_and_arm properly on the bed:
// If rotated [0, 90, 0]: spindle is along X.
// Or if rotated [90, 0, 0]:
// Let's test exact resting orientation:
// Spindle axis horizontal along Y. The drop block and slide mount are flat.
// In stationary_core_and_arm():
// The mount tongue back face: translate([-mount_tongue_w/2, 0, 0]) cube([mount_tongue_w, mount_tongue_t, mount_tongue_l]);
// The mount arm drop: translate([-mount_tongue_w/2, 0, -mount_arm_thick]) cube([mount_tongue_w, mount_arm_drop, mount_arm_thick]) at Y=-mount_arm_drop.
// So the flat back of the drop block is at Y = -mount_arm_drop.
// If we rotate([-90, 0, 0]): Y=-mount_arm_drop goes to Z = +mount_arm_drop.
// If we rotate([90, 0, 0]), Y becomes -Z, so Y = -mount_arm_drop goes to Z = mount_arm_drop (positive).
// But if we rotate around X and Y so that a stable flat face is at Z = 0:
// Notice the mount slide has flat back face at Y = -mount_arm_drop, Y in [0, mount_tongue_t] relative to that.
// Let's check the bounding box or test.
// Let's write the layout cleanly and check render!
// @name Spindle Core and Mount
translate([0, 10, inner_race_radius + 2.5])
rotate([-90, 0, 0])
stationary_core_and_arm();
// 2. Rotating outer drum printed vertically on its wide rear flange (Z = 0)
// @name Rotating Drum
translate([65, 30, 0])
rotating_drum();
// 3. Four crowned rollers printed vertically on their flat trunnion pin base
// @name Crowned Rollers
for (r = [0 : 3]) {
translate([-35, 10 + (r * 18), roller_len/2])
crowned_roller();
}
// 4. Lightweight roller cage printed flat on rear ring
// rear ring is at Z = -(roller_len/2 + 0.5 + ring_thick) = -(17 + 0.5 + 2.5) = -20.
// Height offset = 20 places bottom at Z = 0!
// @name Roller Cage
translate([-55, -45, roller_len/2 + 0.5 + 2.5])
roller_cage();
// 5. Retention cap printed flat on its outer gripping head (Z = 0)
// @name Retention Cap
translate([-15, -45, 0])
retaining_cap();
}
else if (mode == "mount_core") {
// @name Spindle Core and Mount
stationary_core_and_arm();
}
else if (mode == "drum") {
// @name Rotating Drum
rotating_drum();
}
else if (mode == "roller") {
// @name Crowned Roller
crowned_roller();
}
else if (mode == "cage") {
// @name Roller Cage
roller_cage();
}
else if (mode == "cap") {
// @name Retention Cap
retaining_cap();
}
else if (mode == "clearance_coupon") {
// @name Clearance Coupon
clearance_coupon();
}
else if (mode == "roller_test") {
// @name Roller Test Rig
roller_test_rig();
}


