aboutsummaryrefslogtreecommitdiff
path: root/gridfinity.scad
blob: bd9924e80feaa20574dff6fc2a2f923db0e57a8e (plain)
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
$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 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) {
		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);
		}
	}
	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);
}