634 module construct_exterior_walls( envelop=
false )
640 : let( sf=wall_h/h_h )
641 [
for (e=h) !is_list(e) ? e * sf : [
first(e) * sf,
second(e) ] ];
643 if ( mode_scale_io ==
true )
648 pg_rectangle(wall_xy + 0*[wth, wth], vr=vr, vrm=vrm_ci, center=
true);
649 pg_rectangle(wall_xy - 2*[wth, wth], vr=vr, vrm=vrm_ci, center=
true);
657 pg_rectangle(wall_xy + 0*[wth, wth], vr=vr, vrm=vrm_ci, center=
true);
659 translate([0, 0, -10*
eps/2])
661 pg_rectangle(wall_xy - 2*[wth, wth], vr=vr, vrm=vrm_ci, center=true);
670 : let( sf = [
for (e=h) !is_list(e) ? 1 : [
for (f=
second(e)) !is_list(f) ? f :
first(f) ] ] )
675 : let( sf = [
for (e=h) !is_list(e) ? 1 : [
for (f=
second(e)) !is_list(f) ? f :
second(f) ] ] )
678 echo(
strl([
"wall: extrusion scale factors [x-min, x-max] = ", [min(sf_x), max(sf_x)]]));
679 echo(
strl([
"wall: extrusion scale factors [y-min,y- max] = ", [min(sf_y), max(sf_y)]]));
680 echo(
strl([
"wall: height (ignoring ribs) = ", wall_h]));
681 echo(
strl([
"wall: total interior height (ignoring ribs) = ", wall_h + lip_h]));
686 module construct_lips( envelop=
false )
697 sf = 2*wth / max(wall_xy) * lip_tw/100;
702 translate( [0, 0, wall_h/2] )
707 [3, 0, -1, [1 + sf, 1]],
708 [2, lip_ro, -1, [1 - sf, 1]],
709 [1, 0, +1, [1, 1 + sf]],
710 [0, lip_ro, +1, [1, 1 - sf]]
720 h1 = (ro == 0) ? [lip_h + 0 *
eps]
721 : [lip_h + 0 *
eps, hc];
723 s1 = (ro == 0) ? wall_xy - 0 * [wth, wth] * lip_bw/100
724 : (ro == 1) ? wall_xy - 2 * [wth, wth] * (1-lip_bw/100)
725 : (ro == 2) ? wall_xy - 2 * [wth, wth] * lip_bw/100
726 : wall_xy - 2 * [wth, wth] * lip_bw/100;
729 h2 = (ro == 0) ? [lip_h + 10 *
eps, hc]
730 : [lip_h + 10 *
eps];
732 s2 = (ro == 0) ? wall_xy - 2 * [wth, wth] * lip_bw/100
733 : (ro == 1) ? wall_xy - 2 * [wth, wth]
734 : (ro == 2) ? wall_xy - 2 * [wth, wth]
735 : wall_xy - 4 * [wth, wth] * lip_bw/100;
737 translate([0, 0, (wall_h + lip_h -
eps)/2 *
third(z)])
751 echo(
strl([
"lip: mode = ", lip_m]));
752 echo(
strl([
"lip: height = ", lip_h]));
753 echo(
strl([
"lip: base width percentage = ", lip_bw]));
754 echo(
strl([
"lip: top reduction percentage = ", lip_tw]));
755 echo(
strl([
"lip: inner lip alignment index = ", lip_a]));
760 module construct_lid()
763 translate([0, 0, -
eps])
765 pg_rectangle([encl_x, encl_y] + 0*[wth, wth], vr=vr, vrm=vrm_ci, center=true);
769 echo(
strl([
"lid: extrusion = ", lid]));
770 echo(
strl([
"lid: height = ", lid_h]));
775 module construct_ribs()
781 max_x =
first( wall_xy) - 2*(wth -
eps);
785 max_h = wall_h + min(2,
binary_iw2i(rib_m, 5, 2)) * lip_h;
791 rib_edx = [
for (x=[0:1/
get_fn(1)/2:1]) [2*sqrt(1-pow(x,2)), 1]];
793 rib_edy = [
for (e=rib_edx)
reverse(e)];
795 rib_sd =
defined_e_or(rib, 1, [ wth, [[wth, rib_edx]], [[wth, rib_edy]] ] );
809 crc_x = max([0, floor(max_x/rib_w * rcp_x / 100)]);
810 crc_y = max([0, floor(max_y/rib_w * rcp_y / 100)]);
811 crc_z = max([0, floor(max_h/rib_w * rcp_z / 100)]);
831 [ 0, [max_x, max_y], [cnt_x, cnt_y], [[0, 0, 0], [0, 0, 0]] ],
832 [ 1, [max_y, max_h], [cnt_y, cnt_z], [[90, 0, -90], [max_x/2, 0, max_h/2]] ],
833 [ 2, [max_x, max_h], [cnt_x, cnt_z], [[90, 0, 0], [0, max_y/2, max_h/2]] ],
834 [ 3, [max_y, max_h], [cnt_y, cnt_z], [[90, 0, 90], [-max_x/2, 0, max_h/2]] ],
835 [ 4, [max_x, max_h], [cnt_x, cnt_z], [[-90, 0, 0], [0, -max_y/2, max_h/2]] ],
858 translate([(sx/nx*(1-nx)/2) + (sx/nx * i), 0, 0])
860 square([rib_w, sy], center=true);
865 translate([0, (sy/ny*(1-ny)/2) + (sy/ny * i), 0])
867 square([sx, rib_w], center=true);
875 rib_hxd =
sum( [
for (e=rib_hx) is_list(e) ?
first(e) : e] );
876 rib_hyd =
sum( [
for (e=rib_hy) is_list(e) ?
first(e) : e] );
880 rib_rwh = wall_h + lip_h
881 - max( 0, max([rib_hxd, rib_hyd]) +
third(rib_lo) )
884 echo(
strl([
"rib: mode = ", rib_m]));
885 echo(
strl([
"rib: width = ", rib_w]));
886 echo(
strl([
"rib: extrusion x = ", rib_hx]));
887 echo(
strl([
"rib: height x = ", rib_hxd]));
888 echo(
strl([
"rib: extrusion y = ", rib_hy]));
889 echo(
strl([
"rib: height y = ", rib_hyd]));
890 echo(
strl([
"rib: coverage [x, y, z] = ", [rcp_x, rcp_y, rcp_z]]));
891 echo(
strl([
"rib: count [x, y, z] = ", [cnt_x, cnt_y, cnt_z]]));
893 echo(
strl([
"rib: global offset = ", rib_lo]));
894 echo(
strl([
"rib: remaining wall height = ", rib_rwh]));
899 module construct_interior_walls()
913 max_x =
first( wall_xy) - 2*(wth -
eps);
917 max_h = wall_h + min(2,
binary_iw2i(wall_m, 8, 2)) * lip_h;
924 (i == 1) ? [ 9, 10, 9, 10]
925 : (i == 2) ? [ 3, 4, 3, 4]
926 : (i == 3) ? [ 7, 8, 7, 8]
936 [
for (x=[0:1/
get_fn(1)/2:1]) [1,sqrt(1+
eps-pow(x,2))]],
937 [
for (x=[1:-1/
get_fn(1)/2:1/2]) [1,1-sqrt(1-pow(x,2))]],
939 [
for (x=[0:1/
get_fn(1)/2:1]) [1,sqrt(1+
eps+pow(x,2))]],
940 [
for (x=[1:-1/
get_fn(1)/2:1/2]) [1,1+sqrt(1-pow(x,2))]],
945 s_wt_rm =
select_ci( cfg_wt_rm, wt_rm_i,
true );
946 cfg_rt = [def_dw/2, s_wt_rm];
950 s_wb_rm =
select_ci( cfg_wt_rm, wb_rm_i,
true );
951 cfg_rb = [def_dw/2,
reverse(s_wb_rm)];
955 (wt_rm_i > 0 && wb_rm_i == 0) ? [max_h - def_dw/2, cfg_rt]
956 : (wt_rm_i == 0 && wb_rm_i > 0) ? [cfg_rb, max_h - def_dw/2]
957 : (wt_rm_i > 0 && wb_rm_i > 0) ? [cfg_rb, max_h - def_dw, cfg_rt]
991 type_m = is_list(inst_m) ?
998 tdef_s = (inst_t == 0) ?
1003 tdef_he = !is_list(def_he) ?
1014 tdef_vr = !is_list(def_vr) ?
1018 :
shift(def_vr, n=-1, r=
false, c=
true);
1021 tdef_vrm = !is_list(def_vrm) ?
1025 :
shift(def_vrm, n=+1, r=
false, c=
true);
1047 echo(
strl([
"wall-inst: [type, move, scale, rotation, size, he, vr, vrm] = ",
1048 [inst_t, inst_m, inst_f, inst_r, s, he, vr, vrm]]));
1054 wall_cnt = is_list(inst_l) ? len(inst_l) : 1;
1056 echo(
strl([
"wall: configuration = ", config]));
1057 echo(
strl([
"wall: mode = ", wall_m]));
1059 echo(
strl([
"wall: max [x, y, h] = ", [max_x, max_y, max_h]]));
1061 echo(
strl([
"wall: default width = ", def_dw]));
1062 echo(
strl([
"wall: default extrusion = ", def_he]));
1063 echo(
strl([
"wall: default edge rounding = ", def_vr]));
1064 echo(
strl([
"wall: default edge rounding mode = ", def_vrm]));
1066 echo(
strl([
"wall: count = ", wall_cnt]));
1068 echo(
strl([
"wall: global offset = ", wall_lo]));
1073 module construct_posts( add=
false, remove=
false )
1087 cfg_p_vr_sf = (cfg_rbst ==
true) ? [0, 1/2, 1/2, 0] : [0, 1/2, 3/2, 0];
1088 cfg_p_vrm_filet = (cfg_rbst ==
true) ? [0, 1, 1, 0] : [0, 1, 4, 0];
1089 cfg_p_vrm_bevel = (cfg_rbst ==
true) ? [0, 5, 5, 0] : [0, 5, 10, 0];
1091 cfg_f0_vr_sf = [2, 0, 1];
1092 cfg_f0_vrm_filet = [4, 0, 3];
1093 cfg_f0_vrm_bevel = [10, 0, 9];
1095 cfg_f1_vr_sf = [0, 1, 1, 0];
1096 cfg_f1_vrm_filet = [0, 4, 3, 0];
1097 cfg_f1_vrm_bevel = [0, 10, 9, 0];
1102 (i == 1) ? cfg_p_vrm_bevel
1103 : (i == 2) ? cfg_p_vrm_filet
1108 (i == 1) ? cfg_f0_vrm_bevel
1109 : (i == 2) ? cfg_f0_vrm_filet
1113 (i == 1) ? cfg_f1_vrm_bevel
1114 : (i == 2) ? cfg_f1_vrm_filet
1124 lip_h_t = ((
binary_bit_is(post_m, 8, 1) ? 1 : 0) + 1) * lip_h;
1127 cfg_p1_h = (
binary_bit_is(post_m, 7, 1) ? lip_h_t : 0) + wall_h;
1128 cfg_p2_h = (
binary_bit_is(post_m, 7, 0) ? lip_h_t : 0) + wall_h;
1133 max_x =
first( wall_xy) - 2*(wth -
eps);
1134 max_y =
second(wall_xy) - 2*(wth -
eps);
1135 max_h = wall_h + lip_h_t;
1162 def_h1_d_c = def_h0_d
1166 def_p1_d_c = def_h0_d
1170 def_h2_d_c = def_h0_d
1174 def_p2_d_c = def_h0_d
1193 def_p1_vr =
defined_e_or(def_p1, 5, cfg_p_vr_sf * wth);
1202 def_h2_vr =
defined_e_or(def_h2, 5, cfg_p_vr_sf * wth/2);
1211 def_p2_vr =
defined_e_or(def_p2, 5, cfg_p_vr_sf * wth);
1220 def_f0_vr =
defined_e_or(def_f0, 5, cfg_f0_vr_sf * wth);
1229 def_f1_vr =
defined_e_or(def_f1, 5, cfg_f1_vr_sf * wth);
1239 module construct_fins(d, h, t, f)
1244 function fin_embed(r, w) =
1250 r - sqrt( pow(r,2) - pow(w/2, 2) - pow(d/2, 2) );
1265 echo(
strl([
"post-inst-fins: [d, h, t, f] = ", [d, h, t, f]]));
1267 f_in = fin_embed(d/2, w);
1274 rotate([90, 0, da/c * i + 180])
1275 translate([-d/2 - b + f_in, 0, 0])
1286 rotate([0, 0, da/c * i + 180])
1287 translate([b/2 + d/2 - f_in, 0, 0])
1297 module construct_cylinder ( en, c, ft, f,
eps=0 )
1310 echo(
strl([
"post-inst-cylinder: [c, eps] = ", [c,
eps]]));
1312 translate([0, 0, ho -
eps/2])
1321 construct_fins(d_adj, h_adj, ft, f);
1329 post_cfm = ( add ==
true && remove == false ) ?
"add"
1330 : ( add ==
false && remove ==
true ) ?
"remove"
1331 : ( add ==
true && remove == true ) ?
"add & remove"
1334 echo(
strl([
"post: construction phase = ", post_cfm]));
1358 inst_zx = is_undef( inst_ax ) ? 0
1359 : (
binary_bit_is(inst_ax, 0, 0) ? -1 : +1 ) * (max_x + wth)/2;
1361 inst_zy = is_undef( inst_ay ) ? 0
1362 : (
binary_bit_is(inst_ay, 0, 0) ? -1 : +1 ) * (max_y + wth)/2;
1376 tdef_h1_d_c = (inst_pt == 0) ? def_h1_d_c : def_h2_d_c;
1377 tdef_h1_d = (inst_pt == 0) ? def_h1_d : def_h2_d;
1378 tdef_h1_h = (inst_pt == 0) ? def_h1_h : def_h2_h;
1379 tdef_h1_ho = (inst_pt == 0) ? def_h1_ho : def_h2_ho;
1380 tdef_h1_da = (inst_pt == 0) ? def_h1_da : def_h2_da;
1381 tdef_h1_ha = (inst_pt == 0) ? def_h1_ha : def_h2_ha;
1382 tdef_h1_vr = (inst_pt == 0) ? def_h1_vr : def_h2_vr;
1383 tdef_h1_vrm = (inst_pt == 0) ? def_h1_vrm : def_h2_vrm;
1386 tdef_p_d_c = (inst_pt == 0) ? def_p1_d_c : def_p2_d_c;
1387 tdef_p_d = (inst_pt == 0) ? def_p1_d : def_p2_d;
1388 tdef_p_h = (inst_pt == 0) ? def_p1_h : def_p2_h;
1389 tdef_p_ho = (inst_pt == 0) ? def_p1_ho : def_p2_ho;
1390 tdef_p_da = (inst_pt == 0) ? def_p1_da : def_p2_da;
1391 tdef_p_ha = (inst_pt == 0) ? def_p1_ha : def_p2_ha;
1392 tdef_p_vr = (inst_pt == 0) ? def_p1_vr : def_p2_vr;
1393 tdef_p_vrm = (inst_pt == 0) ? def_p1_vrm : def_p2_vrm;
1399 tdef_f_c = (inst_ft == 0) ? def_f0_c : def_f1_c;
1400 tdef_f_da = (inst_ft == 0) ? def_f0_da : def_f1_da;
1401 tdef_f_w = (inst_ft == 0) ? def_f0_w : def_f1_w;
1402 tdef_f_d_sf = (inst_ft == 0) ? def_f0_d_sf : def_f1_d_sf;
1403 tdef_f_h_sf = (inst_ft == 0) ? def_f0_h_sf : def_f1_h_sf;
1404 tdef_f_vr = (inst_ft == 0) ? def_f0_vr : def_f1_vr;
1405 tdef_f_vrm = (inst_ft == 0) ? def_f0_vrm : def_f1_vrm;
1412 h0_en = (remove ==
true);
1422 h0 = [h0_d, h0_h, h0_ho, h0_da, h0_ha, h0_vr, h0_vrm];
1427 tdef_h1_ims = (cfg_hp_idr ==
true) ? h0_d + tdef_h1_d_c : tdef_h1_d;
1428 tdef_p_ims = (cfg_hp_idr ==
true) ? h0_d + tdef_p_d_c : tdef_p_d;
1431 h1_en = (remove ==
true);
1441 h1 = [h1_d, h1_h, h1_ho, h1_da, h1_ha, h1_vr, h1_vrm];
1444 p_en = (add ==
true);
1454 p = [p_d, p_h, p_ho, p_da, p_ha, p_vr, p_vrm];
1464 f = [f_c, f_da, f_w, f_d_sf, f_h_sf, f_vr, f_vrm];
1471 translate([inst_zx, inst_zy, inst_zz])
1475 construct_cylinder(p_en, p, inst_ft, f);
1477 construct_cylinder(h0_en, h0,
eps=10*
eps);
1478 construct_cylinder(h1_en, h1,
eps=10*
eps);
1482 echo(
strl([
"post-inst: [type, align, move, rotation, hole0, hole1, post, fins] = ",
1483 [inst_t, inst_a, inst_m, inst_r, inst_h0, inst_h1, inst_p, inst_f]]));
1490 post_cnt = is_list(inst_l) ? len(inst_l) : 1;
1492 echo(
strl([
"post: configuration = ", config]));
1493 echo(
strl([
"post: mode = ", post_m]));
1495 echo(
strl([
"post: count = ", post_cnt]));
1500 module envelop_assembly( envelop=
false )
1502 if ( envelop ==
true )
1508 construct_exterior_walls(
true );
1509 construct_lips(
true );
1522 module assembly_add()
1526 construct_exterior_walls();
1545 envelop_assembly( mode_int_mask ==
true )
1551 envelop_assembly( mode_int_mask ==
true )
1552 construct_interior_walls();
1557 envelop_assembly( mode_int_mask ==
true )
1558 construct_posts( add=true);
1563 module assembly_remove()
1567 construct_posts( remove=
true);
1594 vrm_ci = (mode_lmt_vrm ==
false) ? vrm
1596 [
for (e=vrm)
select_ci(v=[0, 5, 1], i=e, l=
false)]
1597 :
select_ci(v=[0, 5, 1], i=vrm, l=
false);
1605 lid_hv =
is_defined(lid) ? [
for (e=lid) is_list(e) ?
first(e) : e] : [0];
1606 lid_h =
sum(lid_hv);
1609 wall_h = (mode_size_in ==
true) ? h_h - lip_h : h_h - lip_h - lid_h;
1617 encl_x = (mode_size_in ==
true) ? size_x + 2*wth - wall_ox : size_x;
1618 encl_y = (mode_size_in ==
true) ? size_y + 2*wth - wall_oy : size_y;
1619 encl_z = (mode_size_in ==
true) ? wall_h + lip_h + lid_h : h_h;
1622 wall_xy = [encl_x + wall_ox, encl_y + wall_oy];
1625 szint_x =
first (wall_xy) - 2*wth;
1626 szint_y =
second(wall_xy) - 2*wth;
1627 szint_z = wall_h + lip_h;
1631 echo(
strl([
"box: construction begin"]));
1633 echo(
strl([
"box: exterior dimensions [x, y, z] = ", [encl_x, encl_y, encl_z]]));
1634 echo(
strl([
"box: interior dimensions [x, y, z] = ", [szint_x, szint_y, szint_z]]));
1645 [0, -encl_x, -szint_x -wth*2, -szint_x, +szint_x, +szint_x +wth*2, +encl_x ]/2,
1646 [0, -encl_y, -szint_y -wth*2, -szint_y, +szint_y, +szint_y +wth*2, +encl_y ]/2,
1647 [lid_h, 0, lid_h -encl_z/2, -wall_h/2, -wall_h, -wall_h -lip_h]
1654 translate([align_x, align_y, align_z])
1663 echo(
strl([
"box: alignment [x, y, z] = ", [align_x, align_y, align_z]]));
1665 echo(
strl([
"box: construction end"]));
zero3d
<decimal-list-2> A 3d zero vector (a list with three zeros).
eps
<decimal> Epsilon, small distance to deal with overlapping shapes.
empty_lst
<list> A list with no values (the empty list).
function binary_iw2i(v, s, w)
Decode the binary bits of a bit window to an integer value.
function binary_bit_is(v, b, t=1)
Test if a binary bit position of an integer value equals a test bit.
function defined_e_or(v, i, d)
Return an element of an iterable when it exists or a default value otherwise.
function third(v)
Return the third element of an iterable value.
function shift(v, n=0, r=true, c=true)
Shift the elements of an iterable value.
function second(v)
Return the second element of an iterable value.
function first(v)
Return the first element of an iterable value.
function reverse(v)
Reverse the elements of an iterable value.
function select_ci(v, i, l=true)
Select specified element from list or return a default.
function strl(v)
Convert a list of values to a concatenated string.
function merge_s(v, r=false)
Serially merge the elements of a list.
function sum(v, i1, i2)
Compute the sum of a list of numbers.
function defined_or(v, d)
Return given value, if defined, or a secondary value, if primary is not defined.
function is_scalar(v)
Test if a value is a single non-iterable value.
function is_defined(v)
Test if a value is defined.
function polygon_regular_perimeter(n, r, a)
Compute the perimeter of an n-sided regular polygon in 2D.
function get_fn(r)
Return facets number for the given arc radius.
module project_box_rectangle(wth, h, size, vr, vrm, inset, lid, lip, rib, wall, post, align, mode=0, verb=0)
A rectangular box maker for project boxes, enclosures and housings.
module pg_triangle_sas(v, a=x_axis_ci, o, vr, vrm=1, vfn, cm=0)
A polygon triangle specified by size-angle-size with vertex rounding.
module pg_rectangle(size=1, o, vr, vrm=1, vfn, center=false)
A polygon rectangle with vertex rounding.