1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
$fn = 30;
// https://gridfinity.xyz/specification/
height = 7;
width = 42;
width_tolerance = 41.5;
rounding = 3.75;
module rounding(r,angle) {
rotate(angle,[0,0,1])
translate([-r + 0.01, -r + 0.01])
difference() {
square([r,r]);
circle(r);
}
}
module rounded_square(lx, ly, r) {
difference() {
square([lx,ly],center=true);
union() {
translate([ lx/2, ly/2]) rounding(r, 0 );
translate([-lx/2, ly/2]) rounding(r, 90 );
translate([-lx/2,-ly/2]) rounding(r, 180);
translate([ lx/2,-ly/2]) rounding(r, 270);
}
}
}
module magnet_hole(h = 0) {
linear_extrude(2.5) circle(3.25);
translate([0,0,2.5]) linear_extrude(h) circle(1.5);
}
module base_solid() {
hull() {
linear_extrude(0.1)rounded_square(35.6, 35.6, 0.8);
translate([0,0,0.8]) linear_extrude(1.8) rounded_square(37.2, 37.2, 1.6);
}
translate([0,0,2.6]) hull() {
linear_extrude(0.1) rounded_square(37.2, 37.2, 1.6);
translate([0,0,2.15]) linear_extrude(0.1)rounded_square(41.5, 41.5, 3.75);
}
}
module base(magnets = false) {
l = 35.6;
o = 4.8;
difference() {
base_solid();
if (magnets) union() {
translate([ l/2 - o, l/2 - o, -0.01]) magnet_hole();
translate([-l/2 + o, l/2 - o, -0.01]) magnet_hole();
translate([ l/2 - o, -l/2 + o, -0.01]) magnet_hole();
translate([-l/2 + o, -l/2 + o, -0.01]) magnet_hole();
}
}
}
module stacking_lip_negative(ux, uy) {
x1 = (width * ux) -5.2 -0.5;
y1 = (width * uy) -5.2 -0.5;
x2 = (width * ux) -3.8 -0.5;
y2 = (width * uy) -3.8 -0.5;
x3 = (width * ux) -0.5;
y3 = (width * uy) -0.5;
// translate and scale are here to make sure the negative pokes through
// the positive block
translate([0,0,-0.001]) scale([1,1,1.001]) hull() {
linear_extrude(0.01)rounded_square(x1, y1, 0.7);
translate([0,0,0.7]) linear_extrude(1.8) rounded_square(x2, y2, 1.6);
}
translate([0,0,2.5]) hull() {
linear_extrude(0.01) rounded_square(x2, y2, 1.7);
translate([0,0,2.15]) linear_extrude(0.01)rounded_square(x3, y3, 3.75);
}
}
function coord_centered(ux) = (ux -1) * width - 0.5 * width * (ux - 1);
module stacking_lip(units_x, units_y) {
difference() {
linear_extrude(4.4)rounded_square(units_x * width -0.5, units_y * width -0.5, rounding);
stacking_lip_negative(units_x, units_y);
}
}
module cutout_slot(l, rx = 0) {
rotate([rx,-90,0]) linear_extrude(l) polygon([[0,-0.25],[0,0.25],[0.25,0]]);
}
module bottom_cutout(units_x, units_y) {
if (units_y > 1) for (i = [1:units_y - 1]) {
translate([units_x * width - width/2, i * width - width/2, 4.749]) cutout_slot(width * units_x);
}
if(units_x > 1) for (i = [1:units_x - 1]) {
translate([i * width - width/2, units_y * width - width/2, 4.749]) cutout_slot(width * units_y, rx=90);
}
}
module gridfinity(units_x, units_y, units_z, lip = true, magnets = false) {
for (ux = [0:units_x -1]) {
for (uy = [0:units_y -1]) {
translate([ux * width, uy * width,0]) base(magnets = magnets);
}
}
if (units_z > 0) {
difference() {
translate([coord_centered(units_x), coord_centered(units_y), 4.75]) {
extr = units_z * height - 4.75;
linear_extrude(extr) rounded_square(units_x * width - 0.5, units_y * width - 0.5, rounding);
}
bottom_cutout(units_x, units_y);
}
}
if (lip && units_z > 0) // Just to safeguard. h=0 is not intended to be used with lip.
translate([coord_centered(units_x), coord_centered(units_y), units_z * height])
stacking_lip(units_x, units_y);
}
|