11
11
12
12
include < gridfinity- rebuilt- openscad/gridfinity- rebuilt- utility.scad>
13
13
14
- // ===== PARAMETERS ===== //
14
+ // [Default Value Overrides] */
15
+ // Tab size
16
+ d_tabh = 14.265 ; // [15.85: Default, 14.265: 90% -- for reduced tab angle, 12.68: 80%]
17
+ // Tab angle
18
+ a_tab = 20 ; // [36: Default, 20: Reduced]
19
+ // Outer wall thickness
20
+ d_wall = 0.95 ; // [0.95: Default, 1.2: 3 lines, 1.6: 4 lines, 2.6: Full thickness -- desk tray style]
21
+ // Divider wall thickness
22
+ d_div = 1.2 ; // [1.2: Default, 1.6: 4 lines, 2.1: 5 lines]
15
23
16
24
/* [General Settings] */
17
25
// number of bases along x-axis
18
- gridx = 3 ;
26
+ gridx = 2 ; // [1:1:8]
19
27
// number of bases along y-axis
20
- gridy = 2 ;
28
+ gridy = 2 ; // [1:1:8]
21
29
// bin height. See bin height information and "gridz_define" below.
22
- gridz = 6 ;
30
+ gridz = 3 ; // [1:0.5:20]
31
+
32
+ /* [Remix Features] */
33
+ // generate tabs on the lid to help align stacked bins
34
+ Stacking_Tabs = true ;
35
+ // Interior depth
36
+ h_cut_extra = 1.6 ; // [0: Default, 1.8: 2 bottom layers, 1.6: 3 bottom layers, 1.4: 4 bottom layers]
37
+ // Additional interior depth for single-grid pockets -- best used with h_cut_extra set to 2 bottom layers
38
+ h_cut_extra_single = 2.0 ; // [0: Default, 2.0: Most, 1.4: Some]
23
39
24
40
/* [Linear Compartments] */
25
41
// number of X Divisions (set to zero to have solid bin)
26
- divx = 0 ;
42
+ divx = 1 ;
27
43
// number of Y Divisions (set to zero to have solid bin)
28
- divy = 0 ;
44
+ divy = 1 ;
29
45
30
46
/* [Cylindrical Compartments] */
31
47
// number of cylindrical X Divisions (mutually exclusive to Linear Compartments)
@@ -60,7 +76,7 @@ scoop = 1; //[0:0.1:1]
60
76
only_corners = false ;
61
77
62
78
/* [Base] */
63
- style_hole = 4 ; // [0:no holes, 1:magnet holes only, 2: magnet and screw holes - no printable slit, 3: magnet and screw holes - printable slit, 4: Gridfinity Refined hole - no glue needed]
79
+ style_hole = 0 ; // [0:no holes, 1:magnet holes only, 2: magnet and screw holes - no printable slit, 3: magnet and screw holes - printable slit, 4: Gridfinity Refined hole - no glue needed]
64
80
// number of divisions per 1 unit of base along the X axis. (default 1, only use integers. 0 means automatically guess the right division)
65
81
div_base_x = 0 ;
66
82
// number of divisions per 1 unit of base along the Y axis. (default 1, only use integers. 0 means automatically guess the right division)
@@ -73,25 +89,259 @@ module __end_customizer_options__() { }
73
89
$ fa = $ preview ? $ fa : 2 ;
74
90
$ fs = $ preview ? $ fs : 0.4 ;
75
91
92
+ min_z = gridz;
93
+
94
+ // Functions //
95
+
96
+ function gf_height(z= gridz) = height(z, gridz_define, style_lip, enable_zsnap);
97
+
76
98
// Modules //
77
99
78
- module main() {
100
+ module gf_init_stub(gx=gridx, gy=gridy, h=-1, h0=0, l=l_grid, sl=style_lip) {
101
+ $ gxx = gx;
102
+ $ gyy = gy;
103
+ $ dh = (h == - 1 ) ? gf_height() : h;
104
+ $ dh0 = h0;
105
+ $ ll = l;
106
+ $ style_lip = sl;
107
+ children();
108
+ }
109
+
110
+ module gf_init(bin=false) {
111
+ cut_height = gf_height(min_z + 1 );
112
+ $ dh = gf_height();
113
+ gf_init_stub() {
114
+ $ cuttop = (gridz > min_z) ? min_z * 7 + 0.25 : h_base + $ dh;
115
+ $ bindepth = (gridz > min_z) ? (gridz - min_z) * 7 : 0 ;
116
+ if (bin) {
117
+ difference () {
118
+ union () {
119
+ block_bottom($ dh0 == 0 ? $ dh - 0.1 : $ dh0, $ gxx, $ gyy, $ ll);
120
+ gridfinityBase(
121
+ $ gxx, $ gyy, $ ll,
122
+ div_base_x, div_base_y,
123
+ style_hole, only_corners= only_corners
124
+ );
125
+ }
126
+ if (gridz > min_z) {
127
+ translate ([0 , 0 , - (h_base + h_bot) + cut_height])
128
+ cut(0 , 0 , gridx, gridy, 5 , s= 0 );
129
+ }
130
+ children();
131
+ }
132
+ block_wall($ gxx, $ gyy, $ ll) {
133
+ if ($ style_lip == 0 ) profile_wall();
134
+ else profile_wall2();
135
+ }
136
+ if (Stacking_Tabs && $ style_lip == 0 )
137
+ generate_tabs();
138
+ } else {
139
+ children();
140
+ }
141
+ }
142
+ }
143
+
144
+ module gf_bin() {
145
+ gf_init(bin= true )
146
+ children();
147
+ }
148
+
149
+ // Feature Modules //
150
+
151
+ // Stacking tabs by @rpedde
152
+ // https://github.com/kennetek/gridfinity-rebuilt-openscad/pull/122
153
+ module generate_tabs() {
154
+
155
+ module lip_tab(x, y) {
156
+ // Calculate rotation of lip based on which edge it is on
157
+ rot = (x == $ gxx) ? 0 : ((x == 0 ) ? 180 : ((y == $ gyy) ? 90 : 270 ));
158
+ wall_thickness = r_base- r_c2+ d_clear* 2 ;
159
+
160
+ translate (
161
+ [(x * l_grid) - ((l_grid * $ gxx / 2 )),
162
+ (y * l_grid) - ((l_grid * $ gyy / 2 )),
163
+ $ dh+ h_base]) {
164
+ rotate ([0 , 0 , rot])
165
+ translate ([- r_base- d_clear,- r_base,0 ]) {
166
+ // Extrude the wall profile in circle; same as you would at a corner of bin
167
+ // Intersection - limit it to the section where the lip would not interfere with the base
168
+ intersection () {
169
+ translate ([wall_thickness, - r_base* 1.5 , 0 ]) cube ([wall_thickness, r_base* 5 , (h_lip)* 5 ]);
170
+ translate ([0 ,0 ,-$ dh]) union () {
171
+ rotate_extrude(angle= 90 ) profile_wall();
172
+ translate ([0 , r_base* 2 , 0 ]) rotate_extrude(angle=- 90 ) profile_wall();
173
+ }
174
+ }
175
+ // Fill the gap between rotational extrusions (think of it as the gap between bins, if this was multiple bins instead of tabs)
176
+ difference () {
177
+ translate ([wall_thickness, 0 , - h_lip* 0.5 ]) cube ([(r_base- wall_thickness)- r_f1, r_base* 2 , h_lip* 1.5 ]);
178
+ cylinder (h= h_lip* 3 , r= r_base- r_f1, center= true );
179
+ translate ([0 , r_base* 2 , 0 ]) cylinder (h= h_lip* 3 , r= r_base- r_f1, center= true );
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ if ($ gxx > 1 ) {
186
+ for (xtab= [1 :$ gxx- 1 ]) {
187
+ lip_tab(xtab, 0 );
188
+ lip_tab(xtab, $ gyy);
189
+ }
190
+ }
191
+
192
+ if ($ gyy > 1 ) {
193
+ for (ytab= [1 :$ gyy- 1 ]) {
194
+ lip_tab(0 , ytab);
195
+ lip_tab($ gxx, ytab);
196
+ }
197
+ }
198
+ }
199
+
200
+ // Override block_cutter for optional deeper bins
201
+ module block_cutter(x,y,w,h,t,s) {
202
+
203
+ v_len_tab = d_tabh;
204
+ v_len_lip = d_wall2- d_wall+ 1.2 ;
205
+ v_cut_tab = d_tabh - (2 * r_f1)/tan (a_tab);
206
+ v_cut_lip = d_wall2- d_wall- d_clear;
207
+ v_ang_tab = a_tab;
208
+ v_ang_lip = 45 ;
209
+
210
+ ycutfirst = y == 0 && $ style_lip == 0 ;
211
+ ycutlast = abs (y+ h-$ gyy)< 0.001 && $ style_lip == 0 ;
212
+ xcutfirst = x == 0 && $ style_lip == 0 ;
213
+ xcutlast = abs (x+ w-$ gxx)< 0.001 && $ style_lip == 0 ;
214
+ zsmall = ($ dh+ h_base)/7 < 3 ;
215
+
216
+ ylen = h* ($ gyy* l_grid+ d_magic)/$ gyy- d_div;
217
+ xlen = w* ($ gxx* l_grid+ d_magic)/$ gxx- d_div;
79
218
80
- color ("tomato" ) {
81
- gridfinityInit(gridx, gridy, height(gridz, gridz_define, style_lip, enable_zsnap), height_internal) {
219
+ cut_extra = h_cut_extra + (
220
+ (
221
+ floor (x) == floor (x + w - 0.0001 )
222
+ && floor (y) == floor (y + h - 0.0001 )
223
+ )
224
+ ? h_cut_extra_single
225
+ : 0
226
+ );
227
+ height = $ dh + cut_extra;
228
+ extent_size = d_wall2 - d_wall - d_clear;
229
+ extent = (abs (s) > 0 && ycutfirst ? extent_size : 0 );
230
+ tab = (zsmall || t == 5 ) ? (ycutlast?v_len_lip:0 ) : v_len_tab;
231
+ ang = (zsmall || t == 5 ) ? (ycutlast?v_ang_lip:0 ) : v_ang_tab;
232
+ cut = (zsmall || t == 5 ) ? (ycutlast?v_cut_lip:0 ) : v_cut_tab;
233
+ style = (t > 1 && t < 5 ) ? t- 3 : (x == 0 ? - 1 : xcutlast ? 1 : 0 );
82
234
83
- if (divx > 0 && divy > 0 ) {
235
+ translate ([0 ,ylen/2 ,h_base + h_bot - cut_extra])
236
+ rotate ([90 ,0 ,- 90 ]) {
84
237
85
- cutEqual(n_divx = divx, n_divy = divy, style_tab = style_tab, scoop_weight = scoop);
238
+ if (! zsmall && xlen - d_tabw > 4 * r_f2 && (t != 0 && t != 5 )) {
239
+ fillet_cutter(3 ,"bisque" )
240
+ difference () {
241
+ transform_tab(style, xlen, ((xcutfirst&& style==- 1 )|| (xcutlast&& style== 1 ))?v_cut_lip:0 )
242
+ translate ([ycutlast?v_cut_lip:0 ,0 ])
243
+ profile_cutter(height- h_bot, ylen/2 , s);
86
244
87
- } else if (cdivx > 0 && cdivy > 0 ) {
245
+ if (xcutfirst)
246
+ translate ([0 ,0 ,(xlen/2 - r_f2)- v_cut_lip])
247
+ cube ([ylen,height,v_cut_lip* 2 ]);
88
248
89
- cutCylinders(n_divx= cdivx, n_divy= cdivy, cylinder_diameter= cd, cylinder_height= ch, coutout_depth= c_depth, orientation= c_orientation);
249
+ if (xcutlast)
250
+ translate ([0 ,0 ,- (xlen/2 - r_f2)- v_cut_lip])
251
+ cube ([ylen,height,v_cut_lip* 2 ]);
252
+ }
253
+ if (t != 0 && t != 5 )
254
+ fillet_cutter(2 ,"indigo" )
255
+ difference () {
256
+ transform_tab(style, xlen, ((xcutfirst&& style==- 1 )|| (xcutlast&& style== 1 ))?v_cut_lip:0 )
257
+ difference () {
258
+ intersection () {
259
+ profile_cutter(height- h_bot, ylen- extent, s);
260
+ profile_cutter_tab(height- h_bot, v_len_tab, v_ang_tab);
261
+ }
262
+ if (ycutlast) profile_cutter_tab(height- h_bot, v_len_lip, 45 );
263
+ }
264
+
265
+ if (xcutfirst)
266
+ translate ([ylen/2 ,0 ,xlen/2 ])
267
+ rotate ([0 ,90 ,0 ])
268
+ transform_main(2 * ylen)
269
+ profile_cutter_tab(height- h_bot, v_len_lip, v_ang_lip);
270
+
271
+ if (xcutlast)
272
+ translate ([ylen/2 ,0 ,- xlen/2 ])
273
+ rotate ([0 ,- 90 ,0 ])
274
+ transform_main(2 * ylen)
275
+ profile_cutter_tab(height- h_bot, v_len_lip, v_ang_lip);
90
276
}
91
277
}
92
- gridfinityBase(gridx, gridy, l_grid, div_base_x, div_base_y, style_hole, only_corners= only_corners);
278
+
279
+ fillet_cutter(1 ,"seagreen" )
280
+ translate ([0 ,0 ,xcutlast?v_cut_lip/2 :0 ])
281
+ translate ([0 ,0 ,xcutfirst?- v_cut_lip/2 :0 ])
282
+ transform_main(xlen- (xcutfirst?v_cut_lip:0 )- (xcutlast?v_cut_lip:0 ))
283
+ translate ([cut,0 ])
284
+ profile_cutter(height- h_bot, ylen- extent- cut- (! s&& ycutfirst?v_cut_lip:0 ), s);
285
+
286
+ fillet_cutter(0 ,"hotpink" )
287
+ difference () {
288
+ transform_main(xlen)
289
+ difference () {
290
+ profile_cutter(height- h_bot, ylen- extent, s);
291
+
292
+ if (! ((zsmall || t == 5 ) && ! ycutlast))
293
+ profile_cutter_tab(height- h_bot, tab, ang);
294
+
295
+ if (! (abs (s) > 0 )&& y == 0 )
296
+ translate ([ylen- extent,0 ,0 ])
297
+ mirror ([1 ,0 ,0 ])
298
+ profile_cutter_tab(height- h_bot, v_len_lip, v_ang_lip);
299
+ }
300
+
301
+ if (xcutfirst)
302
+ color ("indigo" )
303
+ translate ([ylen/2 + 0.001 ,0 ,xlen/2 + 0.001 ])
304
+ rotate ([0 ,90 ,0 ])
305
+ transform_main(2 * ylen)
306
+ profile_cutter_tab(height- h_bot, v_len_lip, v_ang_lip);
307
+
308
+ if (xcutlast)
309
+ color ("indigo" )
310
+ translate ([ylen/2 + 0.001 ,0 ,- xlen/2 + 0.001 ])
311
+ rotate ([0 ,- 90 ,0 ])
312
+ transform_main(2 * ylen)
313
+ profile_cutter_tab(height- h_bot, v_len_lip, v_ang_lip);
93
314
}
94
315
316
+ }
317
+ }
318
+
319
+ // Main Module //
320
+
321
+ module main() {
322
+ gf_init() {
323
+ color ("cornflowerblue" , 0.8 )
324
+ render (convexity= 4 )
325
+ gf_bin() {
326
+ if (divx > 0 && divy > 0 ) {
327
+ cutEqual(
328
+ n_divx= divx,
329
+ n_divy= divy,
330
+ style_tab= style_tab,
331
+ scoop_weight= scoop
332
+ );
333
+ } else if (cdivx > 0 && cdivy > 0 ) {
334
+ cutCylinders(
335
+ n_divx= cdivx,
336
+ n_divy= cdivy,
337
+ cylinder_diameter= cd,
338
+ cylinder_height= ch,
339
+ coutout_depth= c_depth,
340
+ orientation= c_orientation
341
+ );
342
+ }
343
+ }
344
+ }
95
345
}
96
346
97
347
main();
0 commit comments