@@ -20,10 +20,8 @@ MODEL_HARNESS_SLIDER_BACK=107; | |||
MODEL_HARNESS_BUTTONS=108; | |||
// Platform | |||
MODEL_STRAP_PLATFORM_BASE=210; | |||
MODEL_STRAP_PLATFORM_RIB=211; | |||
MODEL_STRAP_PLATFORM_RIB_BRACE=212; | |||
MODEL_STRAP_SECONDARY=213; | |||
MODEL_PLATFORM_HARNESS=201; | |||
MODEL_PLATFORM_STRAP=202; | |||
// Strap | |||
MODEL_LINKS=301; | |||
@@ -7,6 +7,10 @@ use <BOSL/shapes.scad> | |||
use <BOSL/masks.scad> | |||
use <BOSL/sliders.scad> | |||
use <specs_phone.scad> | |||
use <specs_harness.scad> | |||
use <specs_platform.scad> | |||
// DEBUG: | |||
//validation = 1; | |||
XRAY_POSITIVE=1; | |||
@@ -14,7 +18,6 @@ XRAY_BACKPLANE=2; | |||
XRAY_BOTTOM=3; | |||
//xray = 2; | |||
function get_phone_size() = [161.2, 77.2, 10]; | |||
function use_slideout_backplane() = is_model_strict(MODEL_HARNESS_BOTTOM_PIP) || is_model_strict(MODEL_HARNESS_LEFT) || is_model_strict(MODEL_HARNESS_RIGHT); | |||
backplane_pip_slideout=10; | |||
@@ -398,7 +401,7 @@ module phone_harness() { | |||
} | |||
module model() { | |||
phone_harness(); | |||
up(get_platform_size().z + get_harness_size().z/2) phone_harness(); | |||
} | |||
if (!is_undef(validation)) { | |||
@@ -3,4 +3,4 @@ include <export.scad> | |||
include <harness.scad> | |||
include <platform.scad> | |||
include <strap.scad> | |||
//include <strap.scad> |
@@ -1,3 +1,5 @@ | |||
include <export.scad> | |||
// dependency: https://github.com/revarbat/BOSL | |||
include <BOSL/constants.scad> | |||
use <BOSL/transforms.scad> | |||
@@ -5,13 +7,17 @@ use <BOSL/shapes.scad> | |||
use <BOSL/masks.scad> | |||
use <BOSL/sliders.scad> | |||
use <specs_platform.scad> | |||
use <specs_strap.scad> | |||
use <strap_common.scad> | |||
// DEBUG: | |||
//validation = 1; | |||
//xray = 1; | |||
function get_phone_size() = [160, 76.7, 10]; | |||
module arm() { | |||
// PROP >> | |||
module prop_arm() { | |||
$fn=$preview ? 10 : 30; | |||
arm_size=[200, 55, 40]; | |||
color("gray") | |||
@@ -20,104 +26,45 @@ down(arm_size.z/2) { | |||
left(arm_size.x*0.6) scale([1, 1, 0.8]) yrot(90) cylinder(d1=arm_size.y*1.4, d2=arm_size.y*0.95, h=arm_size.x/2); | |||
} | |||
} | |||
module model_prop_arm() { | |||
if (is_not_export()) down(3) prop_arm(); | |||
} | |||
// <<< | |||
module strap_platform() { | |||
base_size=[40, 70, 2]; | |||
rib_thickness=5; | |||
rib_height=20; | |||
rib_pos=[base_size.x/2 - rib_thickness, 0, -1.3]; | |||
brace_size=[base_size.x, 3.6, 4.8]; | |||
brace_pos=[0, base_size.y/2 - 4, -1.3]; | |||
module platform_base() { | |||
cutout_size=[(base_size.x-rib_thickness*2 - 2*(base_size.x/2-rib_pos.x)), (base_size.y - 5), 2*base_size.z]; | |||
difference() { | |||
down(base_size.z/2) cuboid(base_size, fillet=2, edges=EDGES_Z_ALL); | |||
down(base_size.z/2) cuboid(cutout_size, fillet=2, edges=EDGES_Z_ALL); | |||
model_rib_left(socket=true); | |||
model_rib_right(socket=true); | |||
} | |||
} | |||
// Blocks: | |||
module platform(base) { | |||
size=get_platform_size(); | |||
top=!base; | |||
up(top?size.z:0) | |||
color(top?"Olive":"YellowGreen") | |||
cube(size, center=true); | |||
module platform_rib(socket=false) { | |||
rib_size=[rib_thickness, base_size.y - 2, rib_height]; | |||
difference() { | |||
union() { | |||
difference() { | |||
down(rib_size.z/2) scale(socket ? 1.01 : 1) sparse_strut(h=rib_size.z, l=rib_size.y, thick=rib_size.x, strut=1.2, maxang=40, max_bridge=4); | |||
arm(); | |||
} | |||
difference() { | |||
intersection() { | |||
down(rib_size.z/2) cube(rib_size, center=true); | |||
scale(1.07) arm(); | |||
} | |||
down(2) scale(1.0) arm(); | |||
} | |||
module strap_connectors() { | |||
down(size.z/2) { | |||
for (i=[0:3]) { | |||
left((i%2*(-2)+1) * (size.x/2 - get_link_segment_size().y/2)) | |||
fwd((round(i/2)%2*(-2)+1) * size.y/2) | |||
down(get_link_segment_size().z/2) | |||
zrot(90 + (round(i/2)%2*180)) link_connector_pin(); | |||
} | |||
fwd(brace_pos.y) platform_rib_brace(socket=true); | |||
back(brace_pos.y) platform_rib_brace(socket=true); | |||
} | |||
} | |||
module platform_rib_brace(socket=false) { | |||
down(rib_height - 1.2 - brace_size.z/2) scale(socket ? 1.02 : 1) cuboid(brace_size, fillet=1, edges=EDGES_X_ALL); | |||
} | |||
module model_rib_left(socket=false) { | |||
left(rib_pos.x) up(rib_pos.z) platform_rib(socket=socket); | |||
} | |||
module model_rib_right(socket=false) { | |||
right(rib_pos.x) up(rib_pos.z) platform_rib(socket=socket); | |||
} | |||
module model_brace_front() { | |||
fwd(brace_pos.y) up(brace_pos.z) platform_rib_brace(); | |||
} | |||
module model_brace_back() { | |||
back(brace_pos.y) up(brace_pos.z) platform_rib_brace(); | |||
} | |||
if (is_model(MODEL_STRAP_PLATFORM_BASE)) platform_base(); | |||
if (is_model(MODEL_STRAP_PLATFORM_RIB)) model_rib_left(); | |||
if (is_model(MODEL_STRAP_PLATFORM_RIB_BRACE)) model_brace_front(); | |||
if (is_not_export()) { | |||
model_rib_right(); | |||
model_brace_back(); | |||
if (base) { | |||
strap_connectors(); | |||
} | |||
} | |||
module strap_secondary() { | |||
size=[40, 15, 10]; | |||
size_base=[size.x, size.y]; | |||
size_top=[size.x * 0.9, size.y * 0.4]; | |||
cutout_size=[size.x - 10, size.y*10, size.z - 4]; | |||
module anchor() { | |||
difference() { | |||
xrot(180) rounded_prismoid(size1=size_base, size2=size_top, h=size.z, r=5); | |||
down(size.z/2) cube(cutout_size, center=true); | |||
} | |||
} | |||
anchor_pos=[60, 30, 0]; | |||
module anchor_front() { | |||
left(anchor_pos.x) fwd(anchor_pos.y) anchor(); | |||
} | |||
module anchor_back() { | |||
left(anchor_pos.x) back(anchor_pos.y) anchor(); | |||
} | |||
if (is_model(MODEL_STRAP_SECONDARY)) anchor_front(); | |||
if (is_not_export()) anchor_back(); | |||
// Models: | |||
module model_platform_harness() { | |||
platform(base=false); | |||
} | |||
module model_strap_platform() { | |||
strap_platform(); | |||
} | |||
module model_strap_secondary() { | |||
strap_secondary(); | |||
} | |||
module model_arm() { | |||
if (is_not_export()) down(3) arm(); | |||
module model_platform_strap() { | |||
platform(base=true); | |||
} | |||
model_strap_platform(); | |||
model_strap_secondary(); | |||
model_arm(); | |||
// Export: | |||
if (is_model(MODEL_PLATFORM_HARNESS)) model_platform_harness(); | |||
if (is_model(MODEL_PLATFORM_STRAP)) model_platform_strap(); | |||
if (is_model(MODEL_DEMO)) model_prop_arm(); |
@@ -0,0 +1,9 @@ | |||
use <specs_phone.scad> | |||
// TODO | |||
function get_harness_size() = [ | |||
get_phone_size().x + 10, | |||
get_phone_size().y + 10, | |||
get_phone_size().z + 10, | |||
]; | |||
@@ -0,0 +1,2 @@ | |||
function get_phone_size() = [161.2, 77.2, 10]; | |||
@@ -0,0 +1,8 @@ | |||
use <specs_phone.scad> | |||
function get_platform_size() = [ | |||
get_phone_size().x - 5, | |||
get_phone_size().y - 5, | |||
5 | |||
]; | |||
@@ -0,0 +1,11 @@ | |||
function get_link_segment_size() = [15, 30, 5]; | |||
function get_link_pin_diameter() = 2; | |||
function get_link_socket_slack() = [1, 4, 1]; | |||
function get_link_joiner_arm_size() = [get_link_segment_size().x - 2, 3, get_link_segment_size().z]; | |||
function get_link_socket_size() = [get_link_segment_size().z, | |||
get_link_segment_size().y - get_link_joiner_arm_size().y*2, | |||
get_link_segment_size().z]; | |||
function get_link_clip_size() = [get_link_pin_diameter()*5, get_link_segment_size().y - 5, get_link_segment_size().z]; | |||
function get_link_socket_roundgap() = 2; | |||
@@ -2,93 +2,26 @@ links_count=3; // [1..20] | |||
include_terminal=true; // [true,false] | |||
include <export.scad> | |||
//validation=1; | |||
VALIDATE_INTERSECTION=1; | |||
//xray=1; | |||
use <BOSL/transforms.scad> | |||
use <BOSL/shapes.scad> | |||
include <BOSL/constants.scad> | |||
function get_link_segment_size() = [15, 30, 5]; | |||
function get_link_pin_diameter() = 2; | |||
function get_link_socket_slack() = [1, 4, 1]; | |||
function get_link_joiner_arm_size() = [get_link_segment_size().x - 2, 3, segment_size.z]; | |||
function get_link_socket_size() = [get_link_segment_size().z, | |||
get_link_segment_size().y - get_link_joiner_arm_size().y*2, | |||
get_link_segment_size().z]; | |||
use <strap_common.scad> | |||
function get_link_clip_size() = [get_link_pin_diameter()*5, get_link_segment_size().y - 5, get_link_segment_size().z]; | |||
function get_link_socket_roundgap() = 2; | |||
echo("==============================="); | |||
echo(str("Strap length: ", (links_count * get_link_segment_size().x), " mm")); | |||
echo("==============================="); | |||
if (is_model_strict(MODEL_LINKS)) { | |||
echo("==============================="); | |||
echo(str("Strap length: ", (links_count * get_link_segment_size().x), " mm")); | |||
echo("==============================="); | |||
} | |||
assert(get_link_segment_size().x >= 10, "Link segment is too short."); | |||
assert(get_link_segment_size().z >= (get_link_pin_diameter() + get_link_socket_slack().z + 1), "Link segment is too thin."); | |||
module pin() { | |||
segment_size=get_link_segment_size(); | |||
h=segment_size.y; | |||
d=get_link_pin_diameter(); | |||
back(h/2) xrot(90) cylinder(h=h, d=d, $fn=$preview ? 10 : 30); | |||
} | |||
module pin_socket_area() { | |||
segment_size=get_link_segment_size(); | |||
h=segment_size.y-get_link_socket_slack().y; | |||
d=segment_size.z; | |||
back(h/2) xrot(90) cylinder(h=h, d=d, $fn=$preview ? 10 : 30); | |||
} | |||
module pin_socket() { | |||
difference() { | |||
pin_socket_area(); | |||
scaleup = [ | |||
((get_link_pin_diameter() + get_link_socket_slack().x) / get_link_pin_diameter()), | |||
((get_link_pin_diameter() + get_link_socket_slack().y) / get_link_pin_diameter()), | |||
((get_link_pin_diameter() + get_link_socket_slack().z) / get_link_pin_diameter()) | |||
]; | |||
scale(scaleup) pin(); | |||
} | |||
} | |||
module arm() { | |||
arm_size=get_link_joiner_arm_size(); | |||
fwd(segment_size.y/2 + arm_size.y/2 - 1) right(arm_size.x/2 - 1) cuboid(arm_size, fillet=1, edges=EDGES_FRONT + EDGES_Y_ALL); | |||
} | |||
module armFront() { | |||
arm(); | |||
} | |||
module armBack() { | |||
scale([1, -1, 1]) arm(); | |||
} | |||
module armJoiner() { | |||
gap=get_link_socket_roundgap(); | |||
arm_size=get_link_joiner_arm_size(); | |||
joiner_size=[arm_size.x-get_link_socket_size().x, segment_size.y, segment_size.z]; | |||
right(joiner_size.x/2 + get_link_socket_size().x/2 + gap) cuboid(joiner_size, fillet=1, edges=EDGES_Z_ALL + EDGES_BOTTOM); | |||
} | |||
module link_arms() { | |||
armFront(); | |||
armBack(); | |||
armJoiner(); | |||
} | |||
module link_connector_pin() { | |||
pin(); | |||
link_arms(); | |||
} | |||
module link_connector_socket() { | |||
pin_socket(); | |||
} | |||
module link(terminal=false) { | |||
$fn=$preview?4:20; | |||
module link_joiner() { | |||
gap=get_link_socket_roundgap(); | |||
segment_size=get_link_segment_size(); | |||
arm_size=get_link_joiner_arm_size(); | |||
module pin_to_socket_joiner() { | |||
@@ -106,14 +39,22 @@ module link(terminal=false) { | |||
link_connector_pin(); | |||
if (terminal) { | |||
right(segment_size.x + 2) zrot(180) link_connector_pin(); | |||
right(get_link_segment_size().x + 2) zrot(180) link_connector_pin(); | |||
} else { | |||
link_joiner(); | |||
right(segment_size.x) link_connector_socket(); | |||
right(get_link_segment_size().x) link_connector_socket(); | |||
} | |||
} | |||
module link_chain(links_count, include_terminal=true) { | |||
for (i = [0:links_count-1]) { | |||
terminal=(i==links_count-1) && include_terminal; | |||
right(i*get_link_segment_size().x) link(terminal=terminal); | |||
} | |||
} | |||
module clip() { | |||
$fn=$preview?4:20; | |||
socket_size=get_link_socket_size(); | |||
clip_size=get_link_clip_size(); | |||
pin_diam=get_link_pin_diameter(); | |||
@@ -153,25 +94,29 @@ module clip() { | |||
} | |||
} | |||
right(clip_size.x/2) | |||
if (is_model(MODEL_CLIP_A)) { | |||
difference() { | |||
model(); | |||
cover(); | |||
} | |||
joiner(groove=false); | |||
} else if (is_model(MODEL_CLIP_B)) { | |||
difference() { | |||
intersection() { | |||
left(socket_size.x/2) | |||
{ | |||
if (is_model(MODEL_CLIP_A)) { | |||
difference() { | |||
model(); | |||
cover(); | |||
} | |||
joiner(groove=true); | |||
joiner(groove=false); | |||
} | |||
if (is_model(MODEL_CLIP_B)) { | |||
difference() { | |||
intersection() { | |||
model(); | |||
cover(); | |||
} | |||
joiner(groove=true); | |||
} | |||
} | |||
} | |||
} | |||
module clip_ratcheting(ratchet_length=28) { | |||
$fn=$preview?4:20; | |||
socket_size=get_link_socket_size(); | |||
clip_size=get_link_clip_size(); | |||
pin_diam=get_link_pin_diameter(); | |||
@@ -179,22 +124,12 @@ module clip_ratcheting(ratchet_length=28) { | |||
size=[clip_size.x+socket_size.x, clip_size.y, clip_size.z]; | |||
slot_size=[clip_size.x+slot_slack.x + 0.2, size.y+1, pin_diam+slot_slack.z]; | |||
entry_size=[slot_size.x-5, clip_size.y+1, clip_size.z]; | |||
//right(clip_size.x/2) | |||
module hook() { | |||
intersection() { | |||
difference() { | |||
cuboid(size, fillet=1); | |||
cuboid(slot_size, fillet=1); | |||
up(entry_size.z/2) cube(entry_size, center=true); | |||
} | |||
translate([0, -50, -50]) cube([100, 100, 100]); | |||
} | |||
} | |||
connector_size=[25, 0, 0]; | |||
module hookRight() { | |||
right(12.5) zrot(180) link_connector_pin(); | |||
right(connector_size.x/2) zrot(180) link_connector_pin(); | |||
} | |||
module hookLeft() { | |||
left(12.5) link_connector_pin(); | |||
left(connector_size.x/2) link_connector_pin(); | |||
} | |||
wall=2; | |||
tooth_size=[4, 3, 3]; | |||
@@ -292,52 +227,44 @@ module clip_ratcheting(ratchet_length=28) { | |||
railBack(); | |||
} | |||
left(2) if (is_model(MODEL_CLIP_RATCHETING_A) || is_model(MODEL_CLIP_RATCHETING)) { | |||
left(ratchet_length + wall + 1) { | |||
hookLeft(); | |||
left(0.1) { | |||
ratchetLeft(); | |||
slideRailLeft(); | |||
right(size.x + connector_size.x - 2) { | |||
left(2) | |||
if (is_model(MODEL_CLIP_RATCHETING_A) || is_model(MODEL_CLIP_RATCHETING)) { | |||
left(ratchet_length + wall + 1) { | |||
hookLeft(); | |||
left(0.1) { | |||
ratchetLeft(); | |||
slideRailLeft(); | |||
} | |||
} | |||
} | |||
} | |||
if (is_model(MODEL_CLIP_RATCHETING_B) || is_model(MODEL_CLIP_RATCHETING)) { | |||
ratchetRight(); | |||
hookRight(); | |||
slideRailRight(); | |||
right(is_model(MODEL_DEMO) ? ratchet_length + 5 : 0) | |||
if (is_model(MODEL_CLIP_RATCHETING_B) || is_model(MODEL_CLIP_RATCHETING)) { | |||
ratchetRight(); | |||
hookRight(); | |||
slideRailRight(); | |||
} | |||
} | |||
} | |||
// Export / Demo / Validation: | |||
segment_size=get_link_segment_size(); | |||
if (!is_undef(validation)) { | |||
if (validation==VALIDATE_INTERSECTION) { | |||
intersection() { | |||
right(0*segment_size.x) link(); | |||
right(1*segment_size.x) link(); | |||
} | |||
intersection() { | |||
right(1*segment_size.x) link(); | |||
right(2*segment_size.x) link(); | |||
// === Export === | |||
if (is_model(MODEL_DEMO)) { | |||
translate([-20, -40, -10]) zrot(-90) { | |||
link_chain(links_count, include_terminal=include_terminal); | |||
right(links_count * get_link_segment_size().x + get_link_clip_size().x) { | |||
clip(); | |||
right(get_link_clip_size().x) clip_ratcheting(); | |||
} | |||
} | |||
} else { | |||
intersection () { | |||
if (!is_undef(xray)) { | |||
down(50) cube([100, 100, 100], center=true); | |||
} | |||
union() { | |||
if (is_model(MODEL_CLIP_A) || is_model(MODEL_CLIP_B)) { | |||
left(get_link_clip_size().x) clip(); | |||
} | |||
if (is_model(MODEL_CLIP_RATCHETING) || is_model(MODEL_CLIP_RATCHETING_A) || is_model(MODEL_CLIP_RATCHETING_B)) { | |||
left(get_link_clip_size().x * 2 + 3) clip_ratcheting(); | |||
} | |||
if (is_model(MODEL_LINKS)) for (i = [0:links_count-1]) { | |||
terminal=(i==links_count-1) && include_terminal; | |||
right(i*segment_size.x) link(terminal=terminal); | |||
} | |||
} | |||
if (is_model(MODEL_CLIP_A) || is_model(MODEL_CLIP_B)) { | |||
left(get_link_clip_size().x) clip(); | |||
} | |||
if (is_model(MODEL_CLIP_RATCHETING) || is_model(MODEL_CLIP_RATCHETING_A) || is_model(MODEL_CLIP_RATCHETING_B)) { | |||
left(get_link_clip_size().x * 2 + 3) clip_ratcheting(); | |||
} | |||
if (is_model(MODEL_LINKS)) for (i = [0:links_count-1]) { | |||
terminal=(i==links_count-1) && include_terminal; | |||
right(i*get_link_segment_size().x) link(terminal=terminal); | |||
} | |||
} | |||
@@ -0,0 +1,65 @@ | |||
include <export.scad> | |||
use <BOSL/transforms.scad> | |||
use <BOSL/shapes.scad> | |||
include <BOSL/constants.scad> | |||
use <specs_strap.scad> | |||
module pin() { | |||
segment_size=get_link_segment_size(); | |||
h=segment_size.y; | |||
d=get_link_pin_diameter(); | |||
back(h/2) xrot(90) cylinder(h=h, d=d, $fn=$preview ? 10 : 30); | |||
} | |||
module pin_socket_area() { | |||
segment_size=get_link_segment_size(); | |||
h=segment_size.y-get_link_socket_slack().y; | |||
d=segment_size.z; | |||
back(h/2) xrot(90) cylinder(h=h, d=d, $fn=$preview ? 10 : 30); | |||
} | |||
module pin_socket() { | |||
difference() { | |||
pin_socket_area(); | |||
scaleup = [ | |||
((get_link_pin_diameter() + get_link_socket_slack().x) / get_link_pin_diameter()), | |||
((get_link_pin_diameter() + get_link_socket_slack().y) / get_link_pin_diameter()), | |||
((get_link_pin_diameter() + get_link_socket_slack().z) / get_link_pin_diameter()) | |||
]; | |||
scale(scaleup) pin(); | |||
} | |||
} | |||
module arm() { | |||
segment_size=get_link_segment_size(); | |||
arm_size=get_link_joiner_arm_size(); | |||
fwd(segment_size.y/2 + arm_size.y/2 - 1) right(arm_size.x/2 - 1) cuboid(arm_size, fillet=1, edges=EDGES_FRONT + EDGES_Y_ALL); | |||
} | |||
module armFront() { | |||
arm(); | |||
} | |||
module armBack() { | |||
scale([1, -1, 1]) arm(); | |||
} | |||
module armJoiner() { | |||
gap=get_link_socket_roundgap(); | |||
arm_size=get_link_joiner_arm_size(); | |||
segment_size=get_link_segment_size(); | |||
joiner_size=[arm_size.x-get_link_socket_size().x, segment_size.y, segment_size.z]; | |||
right(joiner_size.x/2 + get_link_socket_size().x/2 + gap) cuboid(joiner_size, fillet=1, edges=EDGES_Z_ALL + EDGES_BOTTOM); | |||
} | |||
module link_arms() { | |||
armFront(); | |||
armBack(); | |||
armJoiner(); | |||
} | |||
module link_connector_pin() { | |||
pin(); | |||
link_arms(); | |||
} | |||
module link_connector_socket() { | |||
pin_socket(); | |||
} | |||