+module LidEdgeProfile(){
+ polygon([ lpp10,
+ lpp11,
+ lpp12,
+ lpp13,
+ lpp13 + [10, 0],
+ lpp10 + [10, 0]
+ ]);
+ intersection(){
+ circleat(lpp12, r=lp_r12);
+ rectfromto( lpp12 + [-10, 0],
+ lpp12 + [+10, +10] );
+ }
+}
+
+module ButtonCoverProfile(){
+ intersection(){
+ polygon([ bppM, bppP, bppO, bppJ, bppL, bppK ]);
+ hull(){
+ EdgeProfile();
+ LidEdgeProfile();
+ }
+ }
+}
+
+module ButtonPlan(l, deep, cut){
+ epsilon =
+ (cut ? 0 : lid_buttoncover_gap);
+
+ delta =
+ (deep ? lid_buttoncover_overlap : 0);
+
+ C = [0,0]; // by definition
+ T = [ 0, epp4[1] ];
+ G = T + [0,10];
+
+ B0 = C + [0,-1] * button_cutout_depth;
+ B1 = B0 + [0,1] * epsilon;
+
+ r0 = 0.5 * (T[1] - B0[1]);
+ A = [ -(l + button_l_fudge)/2 + r0, 0.5 * (T[1] + B0[1]) ];
+ H = A + [0,-1] * delta;
+
+ D = A + [-2,0] * r0;
+ F = D + [0,10];
+
+ E0 = 0.5 * (D + A);
+ E1 = E0 + [1,0] * epsilon;
+
+ I0 = [ E0[0], H[1] ];
+ I1 = [ E1[0], H[1] ];
+
+ hull(){
+ for (m=[0,1]) mirror([m,0])
+ circleat(H, r0 - epsilon);
+ }
+ for (m=[0,1]) mirror([m,0]) {
+ difference(){
+ polygon([ E1,
+ I1,
+ H,
+ B1,
+ G,
+ F,
+ D
+ ]);
+ circleat(D, r0 + epsilon);
+ }
+ }
+}
+
+module CatchCatchProfile(){
+ hull(){
+ for (c=[ cppR, cppQ ])
+ circleat(c, cp_rQ);
+ }
+ hull(){
+ circleat(lpp12, lp_r12);
+ circleat(lpp12 + [5,0], lp_r12);
+ rectfromto(cppP, cppP + [5,0.1]);
+ }
+ polygon([cppJ, cppS, cppT, cppU, cppV, cppQ, cppR]);
+}
+
+module CatchCutProfile(){
+ polygon([ cppB,
+ cppA,
+ cppD,
+ cppF,
+ cppF + [0,-10],
+ cppF + [-10,-10],
+ lpp12 + [-10,0],
+ lpp12 + [10,0]
+ ]);
+}
+
+module Flip_rhs(yn=[0,1]) {
+ for ($rhsflip=yn) {
+ translate([phone_width/2, 0, 0])
+ mirror([$rhsflip,0,0])
+ translate([-phone_width/2, 0, 0])
+ children();
+ }
+}
+
+module Flip_bot(yn=[0,1]) {
+ for ($botflip=yn) {
+ translate([0, -phone_height/2, 0])
+ mirror([0, $botflip, 0])
+ translate([0, phone_height/2, 0])
+ children();
+ }
+}
+
+module AroundEdges(fill_zstart, fill_th, fill_downwards=0){
+ // sides
+ Flip_rhs(){
+ translate([0, -phone_cnr_rad, 0])
+ rotate([90,0,0])
+ linear_extrude(height = phone_height - phone_cnr_rad*2)
+ children(0);
+ }
+ // corners
+ Flip_rhs() Flip_bot() {
+ translate([+1,-1] * phone_cnr_rad)
+ intersection(){
+ rotate_extrude()
+ intersection(){
+ mirror([1,0,0])
+ translate([-1,0] * phone_cnr_rad)
+ children(0);
+ rectfromto([0,-20],[10,20]);
+ }
+ translate([-10, 0, -20] + 0.01 * [+1,-1, 0] )
+ cube([10,10,40]);
+ }
+ }
+ // top and bottom
+ Flip_bot(){
+ translate([ phone_width - phone_cnr_rad, 0,0 ])
+ rotate([90,0,-90])
+ linear_extrude(height = phone_width - phone_cnr_rad*2)
+ children(0);
+ }
+ // fill
+ translate([0,0, fill_zstart])
+ mirror([0,0, fill_downwards])
+ linear_extrude(height = fill_th)
+ rectfromto([+1,-1] * phone_cnr_rad,
+ [phone_width, -phone_height] + [-1,+1] * phone_cnr_rad);
+}
+
+module CaseAperture(pos, dia, $fn) {
+ theta = 180/$fn;
+ translate([ pos[0] + bumper[0],
+ -epp2i[0],
+ -pos[1] ])
+ rotate([-90, theta, 0])
+ cylinder(r = dia/2 / cos(theta),
+ h = 60);
+}
+
+module SideButton(y, y_ref_sign, l){
+ // y_ref_sign:
+ // +1 measured from top of actual phone to top of button
+ // -1 measured from bottom of actual phone to bottom of button
+ // 0 y is centre of button in coordinate system
+ $button_l= l;
+ eff_y = y_ref_sign > 0 ? -bumper [1] -y -l/2 :
+ y_ref_sign < 0 ? (-phone -bumper)[1] +y +l/2 :
+ y;
+ //echo(eff_y);
+ translate([0, eff_y, 0])
+ children();
+}
+
+module LidButtonishLeg(y, y_ref_sign, l=buttonishleg_default_l_is_fudge) {
+ $button_leg_only = true;
+ SideButton(y, y_ref_sign, l) children();
+}
+
+module Buttons(){
+ Flip_rhs(1) SideButton(15.580, +1, 8.9) children(); // power
+ Flip_rhs(1) SideButton(48.700, -1, 8.920) children(); // camera
+ Flip_rhs(0) SideButton(30.800, +1, 21.96) children(); // volume
+ Flip_rhs( ) LidButtonishLeg(14, -1) children();
+// Flip_rhs(0) LidButtonishLeg(20, +1, 20) children();
+}
+
+module Struts(x_start, z_min, th){
+ // if th is negative, starts at z_min and works towards -ve z
+ // and object should then be printed other way up
+ for (i= [1 : 1 : case_struts_count]) {
+ translate([0,
+ 0,
+ z_min])
+ mirror([0,0, th<0 ? 1 : 0])
+ translate([0,
+ -phone_height * i / (case_struts_count+1),
+ case_struts_solid_below])
+ linear_extrude(height= abs(th)
+ -(case_struts_solid_below+case_struts_solid_above))
+ rectfromto([ x_start, -0.5 * case_struts_width ],
+ [ phone_width - x_start, +0.5 * case_struts_width ]);
+ }
+}
+
+module OrdinaryRearAperture(rhs,bot, pos){
+ Flip_rhs(rhs) Flip_bot(bot)
+ linextr(-20, 20)
+ mirror([0,1])
+ translate(pos + bumper)
+ children();
+}
+
+module MicroUSB(){
+ Flip_bot(1){
+ rotate([90,0,0])
+ mirror([0,0,1])
+ linextr(-epp2i[0], 60)
+ translate([0.5 * phone_width, 0, 0])
+ rectfromto([-microusb_width/2, epp2i[1] + microusb_below],
+ [+microusb_width/2, epp0[1] + -microusb_above]);
+ }
+}
+
+module OrdinaryRearApertures(){
+ // rear speaker
+ OrdinaryRearAperture(1,1, rearspeaker_pos_bl)
+ rectfromto(-rearspeaker_gap,
+ rearspeaker_size + rearspeaker_gap);
+
+ // finger hole to remove phone
+ if (len(fingerpushhole_dias))
+ OrdinaryRearAperture(1,0, [ fingerpushhole_dias[0]/2 + epp2i[0],
+ phone[1]/2 ])
+ scale(fingerpushhole_dias)
+ circle(r= 0.5 );
+}
+
+module RearCameraAperture(){
+ Flip_rhs(1)
+ mirror([0, 0, 1])
+ linear_extrude(height = 20)
+ mirror([0, 1, 0])
+ translate(bumper)
+ rectfromto(camera_pos_tl, camera_pos_br);
+}
+
+module HingeLidProfile(){
+ hull(){
+ circleat(hppT, hp_r1);
+ circleat(lpp12, lp_r12);
+ polygon([lpp10,
+ lpp13 + [2,0],
+ lpp12,
+ hppT]);
+ }
+}
+
+module HingeBaseProfile(){
+ difference(){
+ hull(){
+ circleat(hppB, hp_r1);
+ circleat(hppE, hp_r1);
+ circleat(epp2o, case_th_bottom);
+ circleat(hppB + [10,0], hp_r1);
+ }
+ polygon([epp5, epp1, epp2i, epp3, bppL]);
+ }
+}
+
+module HingeLeverOuterProfile(){
+ hull(){
+ circleat(hppT, hp_r2);
+ circleat(hppB, hp_r2);
+ }
+}
+
+module HingeLeverInnerProfile(){
+ for (c = [hppT, hppB]) {
+ hull()
+ for (x=[-20,20])
+ for (y=[0, c[1] - hppM[1]])
+ translate([x,y])
+ circleat(c, hp_rn);
+ }
+}
+
+module Flip_hinge(){
+ hinge_origin = [0, -(phone_height - hppB[0]), hppB[1]];
+ translate(hinge_origin)
+ rotate([180,0,0])
+ translate(-hinge_origin)