// Threads for acorn model // Copyright (c) 2017 Clinton Ebadi use // http://www.thingiverse.com/thing:1686322 AUTO_CALCULATE = -1; acorn_parts = [ "body", "cap", "gasket" ]; internal_thread_tolerance = 0.3; external_thread_tolerance = 0.2; thread_angle = 50; function contains (x, lst) = len([ for (i = lst) if (x == i) i]) > 0; // dome module from https://github.com/Sembiance/common/blob/master/openscad/dome.scad, Public Domain module dome(d=5, h=2, hollow=false, wallWidth=0.5) { sphereRadius = (pow(h, 2) + pow((d/2), 2) ) / (2*h); translate([0, 0, (sphereRadius-h)*-1]) { difference() { sphere(sphereRadius); translate([0, 0, -h]) cube([2*sphereRadius, 2*sphereRadius, 2*sphereRadius], center=true); if(hollow) sphere(sphereRadius-wallWidth); } } } module acorn (thread_pitch = 3.0, thread_size = 2.5, thread_height = 3.5, thread_tooth_height = AUTO_CALCULATE, inner_d = 24.5, base_height = AUTO_CALCULATE, wall_thickness = AUTO_CALCULATE, outer_d = AUTO_CALCULATE, dome_h = AUTO_CALCULATE, keychain = true) { // derived settings wall_thickness = (wall_thickness == AUTO_CALCULATE) ? thread_size : wall_thickness; outer_d = (outer_d == AUTO_CALCULATE) ? inner_d + wall_thickness*2 : outer_d; thread_tooth_height = (thread_tooth_height == AUTO_CALCULATE) ? ((thread_pitch - 0.4 > 0) ? thread_pitch - 0.4 : thread_pitch) : thread_tooth_height; base_height = (base_height == AUTO_CALCULATE) ? inner_d : base_height; echo ("outer_d = ", outer_d); module acorn_thread (outer_d = outer_d, internal = false, ring = true) { if (internal) { outer_ring_d = outer_d+max(thread_size, wall_thickness)+1; echo ("outer ring = ", outer_ring_d); ScrewHole (outer_diam=outer_d, height = thread_height, pitch = thread_pitch, tooth_height = thread_tooth_height, tooth_angle = thread_angle, tolerance=internal_thread_tolerance) { if (ring) cylinder (d = outer_ring_d, h = thread_height); } } if (!internal) { difference () { ScrewThread (outer_diam=outer_d, height = thread_height, pitch = thread_pitch, tooth_height = thread_tooth_height, tooth_angle = thread_angle, tolerance=external_thread_tolerance); cylinder (d = outer_d-wall_thickness-thread_size-0.01, h = thread_height * 4, center=true); } } } module nut_body (h = base_height, d = outer_d, nub = false) { translate ([0 ,0, h]) { intersection () { union () { resize ([d, d, h*2]) sphere (d=h*2); if (nub) { translate ([0, d/2-wall_thickness/2, -thread_height]) sphere (d=wall_thickness*2, $fs = 0.1); } } translate ([0 ,0, -h/2]) cube ([d*2, d*2, h], center=true); } } } module nut () { difference () { nut_body (); translate ([0, 0, wall_thickness + 0.01]) nut_body (d=outer_d-wall_thickness*2, nub=false); } translate ([0, 0, base_height-0.1]) acorn_thread (outer_d = outer_d); } module cap_keychain_holes (hole_d=3, spacing=12) { h=100; translate ([-spacing/2, 0, 0]) cylinder (d=hole_d, h=h, $fs=0.1); translate ([spacing/2, 0, 0]) cylinder (d=hole_d, h=h, $fs=0.1); } module cap (model="3D/RaleighAcorn_Filled_simple.stl", native_d = 168) { scale_f = outer_d / native_d; //168; echo ("scale_f = ", scale_f); difference () { scale ([scale_f, scale_f, scale_f]) { difference () { union () { translate ([0, 0, -1]) import (model); echo ("h = ", thread_height/scale_f); } // todo: only makes sense for RaleighAcorn, fix in original model... translate ([0, 0, -0.51]) cube ([200, 200, 1], center=true); } } if (keychain) cap_keychain_holes (); // hollow the cap out (make parametric later, this is pretty ugly now, but calc seems to be ok for RaleighAcorn) diam_to_height_ratio = 3.2; dome_h = (dome_h == AUTO_CALCULATE) ? outer_d / diam_to_height_ratio - thread_height : dome_h; echo ("dome_h = ", dome_h); difference () { translate ([0, 0, thread_height-0.01]) dome (d=outer_d, h=dome_h); } translate ([0, 0, -0.01]) acorn_thread (internal = true, ring = false); } } module gasket (gasket_height=0.9) { cylinder (d = outer_d, h = gasket_height, center=true); } module nuts () { if (contains ("body", acorn_parts)) translate ([outer_d+10, 0, 0,]) nut (); if (contains ("cap", acorn_parts)) cap (native_d=167);//model="3D/RaleighAcorn_ExaggeratedCap_Decimated.stl", native_d = 178); if (contains ("gasket", acorn_parts)) translate ([-(outer_d+10), 0, 0,]) gasket (); } nuts (); } //$fs = 1; //$fa = 1; acorn_parts = [ "cap"]; //acorn (); huge_acorn (); module huge_acorn () { acorn (inner_d=100, base_height=80, thread_size=4, thread_pitch=4, thread_height=8, keychain=false); }