From 1b70c4018661e7eb3658aef8b3a6970b64ddb29d Mon Sep 17 00:00:00 2001 From: Arthur Moore Date: Tue, 8 Oct 2024 00:15:45 -0400 Subject: [PATCH 1/2] Fixed 0.5mm gap between grids. This fixes a compatibility issue when using fractional grid sizes. --- gridfinity-rebuilt-utility.scad | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gridfinity-rebuilt-utility.scad b/gridfinity-rebuilt-utility.scad index 4968542..80115cf 100644 --- a/gridfinity-rebuilt-utility.scad +++ b/gridfinity-rebuilt-utility.scad @@ -224,18 +224,21 @@ module gridfinityBase(gx, gy, length, dx, dy, hole_options=bundle_hole_options() // Final size in number of bases grid_size = [gx/dbnx, gy/dbny]; - // Per spec, there's a 0.5mm gap between each base, - // But that needs to be scaled based on everything else. - individual_base_size_mm = [dbnx, dbny] * BASE_SIZE; - base_center_distance_mm = [dbnx, dbny] * length; - gap_mm = base_center_distance_mm - individual_base_size_mm; + // Per spec, there's a 0.5mm gap between each base. + // This must be kept constant or half bins may not work correctly. + gap_mm = l_grid - BASE_SIZE; + + base_center_distance_mm = [dbnx, dbny] * length; // Per spec this should be 42. + individual_base_size_mm = [base_center_distance_mm.x - gap_mm, base_center_distance_mm.y - gap_mm]; // Final size of the base top. In mm. + // subtracting gap_mm here to remove an outer lip along the peremiter. grid_size_mm = [ - base_center_distance_mm.x * grid_size.x, - base_center_distance_mm.y * grid_size.y, - ] - gap_mm; + base_center_distance_mm.x * grid_size.x - gap_mm, + base_center_distance_mm.y * grid_size.y - gap_mm + ]; + // Top which ties all bases together if (final_cut) { translate([0, 0, h_base-TOLLERANCE]) rounded_square([grid_size_mm.x, grid_size_mm.y, h_bot], BASE_OUTSIDE_RADIUS, center=true); From adbad75eb76cd0e4d55becca78f0d45e979349e8 Mon Sep 17 00:00:00 2001 From: Arthur Moore Date: Tue, 8 Oct 2024 00:53:40 -0400 Subject: [PATCH 2/2] Always auto calculate divisions per grid If someone wants to make custom sized grid bins, they can pass in custom grid_dimensions. --- gridfinity-rebuilt-bins.scad | 18 +++++--------- gridfinity-rebuilt-lite.scad | 18 ++++++-------- gridfinity-rebuilt-utility.scad | 43 ++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/gridfinity-rebuilt-bins.scad b/gridfinity-rebuilt-bins.scad index df34491..2a7a0ab 100644 --- a/gridfinity-rebuilt-bins.scad +++ b/gridfinity-rebuilt-bins.scad @@ -78,12 +78,6 @@ style_lip = 0; //[0: Regular lip, 1:remove lip subtractively, 2: remove lip and // scoop weight percentage. 0 disables scoop, 1 is regular scoop. Any real number will scale the scoop. scoop = 1; //[0:0.1:1] -/* [Base] */ -// number of divisions per 1 unit of base along the X axis. (default 1, only use integers. 0 means automatically guess the right division) -div_base_x = 0; -// number of divisions per 1 unit of base along the Y axis. (default 1, only use integers. 0 means automatically guess the right division) -div_base_y = 0; - /* [Base Hole Options] */ // only cut magnet/screw holes at the corners of the bin to save uneccesary print time only_corners = false; @@ -118,7 +112,7 @@ gridfinityInit(gridx, gridy, height(gridz, gridz_define, style_lip, enable_zsnap cutCylinders(n_divx=cdivx, n_divy=cdivy, cylinder_diameter=cd, cylinder_height=ch, coutout_depth=c_depth, orientation=c_orientation, chamfer=c_chamfer); } } -gridfinityBase(gridx, gridy, l_grid, div_base_x, div_base_y, hole_options, only_corners=only_corners, thumbscrew=enable_thumbscrew); +gridfinityBase([gridx, gridy], hole_options=hole_options, only_corners=only_corners, thumbscrew=enable_thumbscrew); } @@ -129,7 +123,7 @@ gridfinityBase(gridx, gridy, l_grid, div_base_x, div_base_y, hole_options, only_ gridfinityInit(3, 3, height(6), 0, 42) { cutEqual(n_divx = 3, n_divy = 3, style_tab = 0, scoop_weight = 0); } -gridfinityBase(3, 3, 42, 0, 0, 1); +gridfinityBase([3, 3]); */ // Compartments can be placed anywhere (this includes non-integer positions like 1/2 or 1/3). The grid is defined as (0,0) being the bottom left corner of the bin, with each unit being 1 base long. Each cut() module is a compartment, with the first four values defining the area that should be made into a compartment (X coord, Y coord, width, and height). These values should all be positive. t is the tab style of the compartment (0:full, 1:auto, 2:left, 3:center, 4:right, 5:none). s is a toggle for the bottom scoop. @@ -146,7 +140,7 @@ gridfinityInit(3, 3, height(6), 0, 42) { cut(1.5, 0, 1.5, 5/3, 2); cut(1.5, 5/3, 1.5, 4/3, 4); } -gridfinityBase(3, 3, 42, 0, 0, 1); +gridfinityBase([3, 3]); */ // Compartments can overlap! This allows for weirdly shaped compartments, such as this "2" bin. @@ -170,7 +164,7 @@ gridfinityInit(3, 3, height(6), 0, 42) { pattern_linear(x=1, y=3, sx=42/2) cylinder(r=5, h=1000, center=true); } -gridfinityBase(3, 3, 42, 0, 0, 1); +gridfinityBase([3, 3]); */ // You can use loops as well as the bin dimensions to make different parametric functions, such as this one, which divides the box into columns, with a small 1x1 top compartment and a long vertical compartment below @@ -183,7 +177,7 @@ gridfinityInit(gx, gy, height(6), 0, 42) { cut(i,gx-1,1,1); } } -gridfinityBase(gx, gy, 42, 0, 0, 1); +gridfinityBase([gx, gy]); */ // Pyramid scheme bin @@ -195,5 +189,5 @@ gridfinityInit(gx, gy, height(6), 0, 42) { for (j = [0:i]) cut(j*gx/(i+1),gy-i-1,gx/(i+1),1,0); } -gridfinityBase(gx, gy, 42, 0, 0, 1); +gridfinityBase([gx, gy]); */ diff --git a/gridfinity-rebuilt-lite.scad b/gridfinity-rebuilt-lite.scad index da3e7df..43194af 100644 --- a/gridfinity-rebuilt-lite.scad +++ b/gridfinity-rebuilt-lite.scad @@ -16,9 +16,9 @@ $fs = 0.25; /* [General Settings] */ // number of bases along x-axis -gridx = 3; +gridx = 3; //.5 // number of bases along y-axis -gridy = 3; +gridy = 3; //.5 // bin height. See bin height information and "gridz_define" below. gridz = 6; @@ -41,10 +41,6 @@ gridz_define = 0; // [0:gridz is the height of bins in units of 7mm increments - style_tab = 1; //[0:Full,1:Auto,2:Left,3:Center,4:Right,5:None] /* [Base] */ -// number of divisions per 1 unit of base along the X axis. (default 1, only use integers. 0 means automatically guess the right division) -div_base_x = 0; -// number of divisions per 1 unit of base along the Y axis. (default 1, only use integers. 0 means automatically guess the right division) -div_base_y = 0; // thickness of bottom layer bottom_layer = 1; @@ -70,27 +66,27 @@ hole_options = bundle_hole_options(refined_holes, magnet_holes, screw_holes, cru // Input all the cutter types in here color("tomato") -gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap, l_grid, div_base_x, div_base_y, hole_options, only_corners) { +gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap, l_grid, hole_options, only_corners) { cutEqual(n_divx = divx, n_divy = divy, style_tab = style_tab, scoop_weight = 0); } // ===== CONSTRUCTION ===== // -module gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap, length, div_base_x, div_base_y, style_hole, only_corners) { +module gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap, length, style_hole, only_corners) { height_mm = height(gridz, gridz_define, style_lip, enable_zsnap); union() { difference() { union() { gridfinityInit(gridx, gridy, height_mm, 0, length, sl=style_lip) children(); - gridfinityBase(gridx, gridy, length, div_base_x, div_base_y, style_hole, only_corners=only_corners); + gridfinityBase([gridx, gridy], [length, length], hole_options=style_hole, only_corners=only_corners); } difference() { union() { intersection() { difference() { - gridfinityBase(gridx, gridy, length, div_base_x, div_base_y, style_hole, -d_wall*2, false, only_corners=only_corners); + gridfinityBase([gridx, gridy], [length, length], hole_options=style_hole, -d_wall*2, false, only_corners=only_corners); translate([-gridx*length/2,-gridy*length/2,2*h_base]) cube([gridx*length,gridy*length,1000]); } @@ -123,7 +119,7 @@ module gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap intersection() { difference() { - gridfinityBase(gridx, gridy, length, div_base_x, div_base_y, style_hole, -d_wall*2, false, only_corners=only_corners); + gridfinityBase([gridx, gridy], [length, length], hole_options=style_hole, -d_wall*2, false, only_corners=only_corners); translate([-gridx*length/2,-gridy*length/2,2*h_base]) cube([gridx*length,gridy*length,1000]); } diff --git a/gridfinity-rebuilt-utility.scad b/gridfinity-rebuilt-utility.scad index 80115cf..553fbfe 100644 --- a/gridfinity-rebuilt-utility.scad +++ b/gridfinity-rebuilt-utility.scad @@ -201,41 +201,44 @@ module cut_move(x, y, w, h) { /** *@summary Create the base of a gridfinity bin, or use it for a custom object. - * @param length X,Y size of a single Gridfinity base. + * @param grid_size Number of bases in each dimension. [x, y] + * @param grid_dimensions [length, width] of a single Gridfinity base. * @param thumbscrew Enable "gridfinity-refined" thumbscrew hole in the center of each base unit. This is a ISO Metric Profile, 15.0mm size, M15x1.5 designation. */ -module gridfinityBase(gx, gy, length, dx, dy, hole_options=bundle_hole_options(), off=0, final_cut=true, only_corners=false, thumbscrew=false) { +module gridfinityBase(grid_size, grid_dimensions=[l_grid, l_grid], hole_options=bundle_hole_options(), off=0, final_cut=true, only_corners=false, thumbscrew=false) { + assert(is_list(grid_dimensions) && len(grid_dimensions) == 2 && + grid_dimensions.x > 0 && grid_dimensions.y > 0); + assert(is_list(grid_size) && len(grid_size) == 2 && + grid_size.x > 0 && grid_size.y > 0); assert( - is_num(gx) && - is_num(gy) && - is_num(length) && - is_num(dx) && - is_num(dy) && is_bool(final_cut) && is_bool(only_corners) && is_bool(thumbscrew) ); - dbnxt = [for (i=[1:5]) if (abs(gx*i)%1 < 0.001 || abs(gx*i)%1 > 0.999) i]; - dbnyt = [for (i=[1:5]) if (abs(gy*i)%1 < 0.001 || abs(gy*i)%1 > 0.999) i]; - dbnx = 1/(dx != 0 ? round(dx) : (len(dbnxt) > 0 ? dbnxt[0] : 1)); - dbny = 1/(dy != 0 ? round(dy) : (len(dbnyt) > 0 ? dbnyt[0] : 1)); - - // Final size in number of bases - grid_size = [gx/dbnx, gy/dbny]; - // Per spec, there's a 0.5mm gap between each base. // This must be kept constant or half bins may not work correctly. gap_mm = l_grid - BASE_SIZE; - base_center_distance_mm = [dbnx, dbny] * length; // Per spec this should be 42. + // Divisions per grid + // Normal, half, or quarter grid sizes supported. + // Automatically calculated using floating point comparisons. + dbnxt = [for (i=[1,2,4]) if (abs(grid_size.x*i)%1 < 0.001 || abs(grid_size.x*i)%1 > 0.999) i]; + dbnyt = [for (i=[1,2,4]) if (abs(grid_size.y*i)%1 < 0.001 || abs(grid_size.y*i)%1 > 0.999) i]; + assert(len(dbnxt) > 0 && len(dbnyt) > 0, "Base only supports half and quarter grid spacing."); + divisions_per_grid = [dbnxt[0], dbnyt[0]]; + + // Final size in number of bases + final_grid_size = [grid_size.x * divisions_per_grid.x, grid_size.y * divisions_per_grid.y]; + + base_center_distance_mm = [grid_dimensions.x / divisions_per_grid.x, grid_dimensions.y / divisions_per_grid.y]; individual_base_size_mm = [base_center_distance_mm.x - gap_mm, base_center_distance_mm.y - gap_mm]; // Final size of the base top. In mm. // subtracting gap_mm here to remove an outer lip along the peremiter. grid_size_mm = [ - base_center_distance_mm.x * grid_size.x - gap_mm, - base_center_distance_mm.y * grid_size.y - gap_mm + base_center_distance_mm.x * final_grid_size.x - gap_mm, + base_center_distance_mm.y * final_grid_size.y - gap_mm ]; // Top which ties all bases together @@ -246,7 +249,7 @@ module gridfinityBase(gx, gy, length, dx, dy, hole_options=bundle_hole_options() if(only_corners) { difference(){ - pattern_linear(grid_size.x, grid_size.y, base_center_distance_mm.x, base_center_distance_mm.y) + pattern_linear(final_grid_size.x, final_grid_size.y, base_center_distance_mm.x, base_center_distance_mm.y) block_base(bundle_hole_options(), 0, individual_base_size_mm, thumbscrew=thumbscrew); copy_mirror([0, 1, 0]) { @@ -262,7 +265,7 @@ module gridfinityBase(gx, gy, length, dx, dy, hole_options=bundle_hole_options() } } else { - pattern_linear(grid_size.x, grid_size.y, base_center_distance_mm.x, base_center_distance_mm.y) + pattern_linear(final_grid_size.x, final_grid_size.y, base_center_distance_mm.x, base_center_distance_mm.y) block_base(hole_options, off, individual_base_size_mm, thumbscrew=thumbscrew); } }