mirror of
https://github.com/kennetek/gridfinity-rebuilt-openscad.git
synced 2024-12-22 14:53:25 +00:00
Define the profile of the base by sweeping a polygon.
This is the same approach taken for the stacking lip and baseplate.
This commit is contained in:
parent
ea8a583507
commit
d40a3decc9
3 changed files with 137 additions and 93 deletions
|
@ -199,44 +199,56 @@ module cut_move(x, y, w, h) {
|
||||||
|
|
||||||
// ===== Modules ===== //
|
// ===== Modules ===== //
|
||||||
|
|
||||||
module profile_base() {
|
/**
|
||||||
polygon([
|
*@summary Create the base of a gridfinity bin, or use it for a custom object.
|
||||||
[0,0],
|
* @param length X,Y size of a single Gridfinity base.
|
||||||
[0,h_base],
|
*/
|
||||||
[r_base,h_base],
|
module gridfinityBase(gx, gy, length, dx, dy, hole_options=bundle_hole_options(), off=0, final_cut=true, only_corners=false) {
|
||||||
[r_base-r_c2,h_base-r_c2],
|
assert(
|
||||||
[r_base-r_c2,r_c1],
|
is_num(gx) &&
|
||||||
[r_base-r_c2-r_c1,0]
|
is_num(gy) &&
|
||||||
]);
|
is_num(length) &&
|
||||||
}
|
is_num(dx) &&
|
||||||
|
is_num(dy) &&
|
||||||
|
is_bool(final_cut) &&
|
||||||
|
is_bool(only_corners)
|
||||||
|
);
|
||||||
|
|
||||||
module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off=0, final_cut=true, only_corners=false) {
|
|
||||||
dbnxt = [for (i=[1:5]) if (abs(gx*i)%1 < 0.001 || abs(gx*i)%1 > 0.999) i];
|
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];
|
dbnyt = [for (i=[1:5]) if (abs(gy*i)%1 < 0.001 || abs(gy*i)%1 > 0.999) i];
|
||||||
dbnx = 1/(dx==0 ? len(dbnxt) > 0 ? dbnxt[0] : 1 : round(dx));
|
dbnx = 1/(dx != 0 ? round(dx) : (len(dbnxt) > 0 ? dbnxt[0] : 1));
|
||||||
dbny = 1/(dy==0 ? len(dbnyt) > 0 ? dbnyt[0] : 1 : round(dy));
|
dbny = 1/(dy != 0 ? round(dy) : (len(dbnyt) > 0 ? dbnyt[0] : 1));
|
||||||
xx = gx*l-0.5;
|
|
||||||
yy = gy*l-0.5;
|
|
||||||
|
|
||||||
if (final_cut)
|
// Final size in number of bases
|
||||||
translate([0,0,h_base])
|
grid_size = [gx/dbnx, gy/dbny];
|
||||||
rounded_rectangle(xx+0.002, yy+0.002, h_bot/1.5, r_fo1+0.001);
|
|
||||||
|
|
||||||
intersection(){
|
// Per spec, there's a 0.5mm gap between each base,
|
||||||
if (final_cut)
|
// But that needs to be scaled based on everything else.
|
||||||
translate([0,0,-1])
|
individual_base_size_mm = [dbnx, dbny] * BASE_SIZE;
|
||||||
rounded_rectangle(xx+0.005, yy+0.005, h_base+h_bot/2*10, r_fo1+0.001);
|
base_center_distance_mm = [dbnx, dbny] * length;
|
||||||
|
gap_mm = base_center_distance_mm - individual_base_size_mm;
|
||||||
|
|
||||||
|
// Final size of the base top. In mm.
|
||||||
|
grid_size_mm = [
|
||||||
|
base_center_distance_mm.x * grid_size.x,
|
||||||
|
base_center_distance_mm.y * grid_size.y,
|
||||||
|
] - gap_mm;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
if(only_corners) {
|
if(only_corners) {
|
||||||
difference(){
|
difference(){
|
||||||
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
pattern_linear(grid_size.x, grid_size.y, base_center_distance_mm.x, base_center_distance_mm.y)
|
||||||
block_base(gx, gy, l, dbnx, dbny, bundle_hole_options(), off);
|
block_base(bundle_hole_options(), 0, individual_base_size_mm);
|
||||||
|
|
||||||
copy_mirror([0, 1, 0]) {
|
copy_mirror([0, 1, 0]) {
|
||||||
copy_mirror([1, 0, 0]) {
|
copy_mirror([1, 0, 0]) {
|
||||||
translate([
|
translate([
|
||||||
(gx/2)*l_grid - d_hole_from_side,
|
grid_size_mm.x/2 - HOLE_DISTANCE_FROM_BOTTOM_EDGE - BASE_PROFILE_MAX.x,
|
||||||
(gy/2) * l_grid - d_hole_from_side,
|
grid_size_mm.y/2 - HOLE_DISTANCE_FROM_BOTTOM_EDGE - BASE_PROFILE_MAX.x,
|
||||||
0
|
0
|
||||||
])
|
])
|
||||||
block_base_hole(hole_options, off);
|
block_base_hole(hole_options, off);
|
||||||
|
@ -245,57 +257,64 @@ module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
pattern_linear(grid_size.x, grid_size.y, base_center_distance_mm.x, base_center_distance_mm.y)
|
||||||
block_base(gx, gy, l, dbnx, dbny, hole_options, off);
|
block_base(hole_options, off, individual_base_size_mm);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A single Gridfinity base. With holes (if set).
|
* @brief A single Gridfinity base. With holes (if set).
|
||||||
* @param gx
|
|
||||||
* @param gy
|
|
||||||
* @param l
|
|
||||||
* @param dbnx
|
|
||||||
* @param dbny
|
|
||||||
* @param hole_options @see block_base_hole.hole_options
|
* @param hole_options @see block_base_hole.hole_options
|
||||||
* @param off
|
* @param off
|
||||||
|
* @param size [x, y] size of a single base. Only set if deviating from the standard!
|
||||||
*/
|
*/
|
||||||
module block_base(gx, gy, l, dbnx, dbny, hole_options, off) {
|
module block_base(hole_options, off=0, size=[BASE_SIZE, BASE_SIZE]) {
|
||||||
|
assert(is_list(size) && len(size) == 2);
|
||||||
|
|
||||||
|
// How far, in the +x direction,
|
||||||
|
// the profile needs to be from it's [0, 0] point
|
||||||
|
// such that when swept by 90 degrees to produce a corner,
|
||||||
|
// the outside edge has the desired radius.
|
||||||
|
translation_x = BASE_OUTSIDE_RADIUS - BASE_PROFILE_MAX.x;
|
||||||
|
|
||||||
|
outer_diameter = [2*BASE_OUTSIDE_RADIUS, 2*BASE_OUTSIDE_RADIUS];
|
||||||
|
base_profile_size = size - outer_diameter;
|
||||||
|
base_bottom_size = base_profile_size + [2*translation_x, 2*translation_x];
|
||||||
|
assert(base_profile_size.x > 0 && base_profile_size.y > 0,
|
||||||
|
str("Minimum size of a single base must be greater than ", outer_diameter)
|
||||||
|
);
|
||||||
|
|
||||||
render(convexity = 2)
|
render(convexity = 2)
|
||||||
difference() {
|
difference() {
|
||||||
block_base_solid(dbnx, dbny, l, off);
|
|
||||||
|
|
||||||
pattern_circular(abs(l-d_hole_from_side/2)<0.001?1:4)
|
|
||||||
translate([l/2-d_hole_from_side, l/2-d_hole_from_side, 0])
|
|
||||||
block_base_hole(hole_options, off);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A gridfinity base with no holes.
|
|
||||||
* @details Used as the "base" with holes removed from it later.
|
|
||||||
* @param dbnx
|
|
||||||
* @param dbny
|
|
||||||
* @param l
|
|
||||||
* @param o
|
|
||||||
*/
|
|
||||||
module block_base_solid(dbnx, dbny, l, o) {
|
|
||||||
xx = dbnx*l-0.05;
|
|
||||||
yy = dbny*l-0.05;
|
|
||||||
oo = (o/2)*(sqrt(2)-1);
|
|
||||||
translate([0,0,h_base])
|
|
||||||
mirror([0,0,1])
|
|
||||||
union() {
|
union() {
|
||||||
hull() {
|
sweep_rounded(base_profile_size.x, base_profile_size.y)
|
||||||
rounded_rectangle(xx-2*r_c2-2*r_c1+o, yy-2*r_c2-2*r_c1+o, h_base+oo, r_fo3);
|
translate([translation_x, 0, 0])
|
||||||
rounded_rectangle(xx-2*r_c2+o, yy-2*r_c2+o, h_base-r_c1+oo, r_fo2);
|
polygon(BASE_PROFILE);
|
||||||
|
|
||||||
|
rounded_square(
|
||||||
|
[
|
||||||
|
base_bottom_size.x + TOLLERANCE,
|
||||||
|
base_bottom_size.y + TOLLERANCE,
|
||||||
|
BASE_PROFILE_MAX.y
|
||||||
|
],
|
||||||
|
translation_x,
|
||||||
|
center=true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
translate([0,0,oo])
|
|
||||||
hull() {
|
// 4 holes
|
||||||
rounded_rectangle(xx-2*r_c2+o, yy-2*r_c2+o, r_c2, r_fo2);
|
// Need this fancy code to support refined holes and non-square bases.
|
||||||
mirror([0,0,1])
|
for(a=[0:90:270]){
|
||||||
rounded_rectangle(xx+o, yy+o, h_bot/2+abs(10*o), r_fo1);
|
// i and j represent the 4 quadrants.
|
||||||
|
// The +1 is used to keep any values from being exactly 0.
|
||||||
|
j = sign(sin(a+1));
|
||||||
|
i = sign(cos(a+1));
|
||||||
|
translate([
|
||||||
|
i * (base_bottom_size.x/2 - HOLE_DISTANCE_FROM_BOTTOM_EDGE),
|
||||||
|
j * (base_bottom_size.y/2 - HOLE_DISTANCE_FROM_BOTTOM_EDGE),
|
||||||
|
0])
|
||||||
|
rotate([0, 0, a])
|
||||||
|
block_base_hole(hole_options, off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,13 +72,20 @@ else gridfinityVase(); // Generate the bin
|
||||||
|
|
||||||
// ===== CONSTRUCTION ===== //
|
// ===== CONSTRUCTION ===== //
|
||||||
|
|
||||||
|
//Deprecated Variables
|
||||||
|
r_fo2 = 3.2 / 2; // outside radii 2
|
||||||
|
r_fo3 = 1.6 / 2; // outside radii 3
|
||||||
|
r_c2 = 2.4; // upper base chamfer "radius"
|
||||||
|
d_hole = 26; // center-to-center distance between holes
|
||||||
|
//End Deprecated Variables
|
||||||
|
|
||||||
d_bottom = layer*(max(bottom_layer,1));
|
d_bottom = layer*(max(bottom_layer,1));
|
||||||
x_l = l_grid/2;
|
x_l = l_grid/2;
|
||||||
|
|
||||||
dht = (gridz_define==0)?gridz*7 : (gridz_define==1)?h_bot+gridz+h_base : gridz-(enable_lip?3.8:0);
|
dht = (gridz_define==0)?gridz*7 : (gridz_define==1)?h_bot+gridz+h_base : gridz-(enable_lip?3.8:0);
|
||||||
d_height = (enable_zsnap?((abs(dht)%7==0)?dht:dht+7-abs(dht)%7):dht)-h_base;
|
d_height = (enable_zsnap?((abs(dht)%7==0)?dht:dht+7-abs(dht)%7):dht)-h_base;
|
||||||
|
|
||||||
d_fo1 = 2*r_fo1;
|
d_fo1 = 2*+BASE_OUTSIDE_RADIUS;
|
||||||
|
|
||||||
f2c = sqrt(2)*(sqrt(2)-1); // fillet to chamfer ratio
|
f2c = sqrt(2)*(sqrt(2)-1); // fillet to chamfer ratio
|
||||||
me = ((gridx*l_grid-0.5)/n_divx)-nozzle*4-d_fo1-12.7-4;
|
me = ((gridx*l_grid-0.5)/n_divx)-nozzle*4-d_fo1-12.7-4;
|
||||||
|
@ -161,7 +168,7 @@ module gridfinityBaseVase() {
|
||||||
intersection() {
|
intersection() {
|
||||||
block_base_blank(0);
|
block_base_blank(0);
|
||||||
translate([0,0,-h_base-1])
|
translate([0,0,-h_base-1])
|
||||||
rounded_square([l_grid-0.5-0.005, l_grid-0.5-0.005, h_base*10], r_fo1+0.001, center=true);
|
rounded_square([l_grid-0.5-0.005, l_grid-0.5-0.005, h_base*10], BASE_OUTSIDE_RADIUS+0.001, center=true);
|
||||||
}
|
}
|
||||||
translate([0,0,0.01])
|
translate([0,0,0.01])
|
||||||
difference() {
|
difference() {
|
||||||
|
@ -229,7 +236,7 @@ module block_base_blank(o = 0) {
|
||||||
rounded_square(l_grid-o-0.05-2*r_c2, r_fo2, center=true);
|
rounded_square(l_grid-o-0.05-2*r_c2, r_fo2, center=true);
|
||||||
mirror([0,0,1])
|
mirror([0,0,1])
|
||||||
linear_extrude(d_bottom)
|
linear_extrude(d_bottom)
|
||||||
rounded_square(l_grid-o-0.05, r_fo1, center=true);
|
rounded_square(l_grid-o-0.05, BASE_OUTSIDE_RADIUS, center=true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,15 @@
|
||||||
|
|
||||||
// height of the base
|
|
||||||
h_base = 5;
|
|
||||||
// lower base chamfer "radius"
|
// lower base chamfer "radius"
|
||||||
r_c1 = 0.8;
|
r_c1 = 0.8;
|
||||||
// upper base chamfer "radius"
|
|
||||||
r_c2 = 2.4;
|
|
||||||
// bottom thiccness of bin
|
// bottom thiccness of bin
|
||||||
h_bot = 2.2;
|
h_bot = 2.2;
|
||||||
// outside radii 1
|
|
||||||
r_fo1 = 7.5 / 2;
|
|
||||||
// outside radii 2
|
|
||||||
r_fo2 = 3.2 / 2;
|
|
||||||
// outside radii 3
|
|
||||||
r_fo3 = 1.6 / 2;
|
|
||||||
// length of a grid unit
|
// length of a grid unit
|
||||||
l_grid = 42;
|
l_grid = 42;
|
||||||
|
|
||||||
|
|
||||||
// Outside rounded radius of bin
|
// Outside rounded radius of bin
|
||||||
// Per spec, matches radius of upper base section.
|
// Per spec, matches radius of upper base section.
|
||||||
r_base = r_fo1;
|
r_base = 7.5 / 2;
|
||||||
|
|
||||||
// Tollerance to make sure cuts don't leave a sliver behind,
|
// Tollerance to make sure cuts don't leave a sliver behind,
|
||||||
// and that items are properly connected to each other.
|
// and that items are properly connected to each other.
|
||||||
|
@ -35,11 +25,12 @@ SCREW_HOLE_RADIUS = 3 / 2;
|
||||||
MAGNET_HOLE_RADIUS = 6.5 / 2;
|
MAGNET_HOLE_RADIUS = 6.5 / 2;
|
||||||
MAGNET_HOLE_DEPTH = MAGNET_HEIGHT + (LAYER_HEIGHT * 2);
|
MAGNET_HOLE_DEPTH = MAGNET_HEIGHT + (LAYER_HEIGHT * 2);
|
||||||
|
|
||||||
// center-to-center distance between holes
|
|
||||||
d_hole = 26;
|
|
||||||
// distance of hole from side of bin
|
// distance of hole from side of bin
|
||||||
d_hole_from_side=8;
|
d_hole_from_side=8;
|
||||||
|
|
||||||
|
// Based on https://gridfinity.xyz/specification/
|
||||||
|
HOLE_DISTANCE_FROM_BOTTOM_EDGE = 4.8;
|
||||||
|
|
||||||
// Meassured diameter in Fusion360.
|
// Meassured diameter in Fusion360.
|
||||||
// Smaller than the magnet to keep it squeezed.
|
// Smaller than the magnet to keep it squeezed.
|
||||||
REFINED_HOLE_RADIUS = 5.86 / 2;
|
REFINED_HOLE_RADIUS = 5.86 / 2;
|
||||||
|
@ -62,6 +53,7 @@ CHAMFER_ANGLE = 45;
|
||||||
BASEPLATE_SCREW_COUNTERSINK_ADDITIONAL_RADIUS = 5/2;
|
BASEPLATE_SCREW_COUNTERSINK_ADDITIONAL_RADIUS = 5/2;
|
||||||
BASEPLATE_SCREW_COUNTERBORE_RADIUS = 5.5/2;
|
BASEPLATE_SCREW_COUNTERBORE_RADIUS = 5.5/2;
|
||||||
BASEPLATE_SCREW_COUNTERBORE_HEIGHT = 3;
|
BASEPLATE_SCREW_COUNTERBORE_HEIGHT = 3;
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
|
|
||||||
// top edge fillet radius
|
// top edge fillet radius
|
||||||
|
@ -109,6 +101,34 @@ stacking_lip_support_wall_height_mm = 1.2;
|
||||||
stacking_lip_support_height_mm =
|
stacking_lip_support_height_mm =
|
||||||
stacking_lip_support_wall_height_mm + d_wall2;
|
stacking_lip_support_wall_height_mm + d_wall2;
|
||||||
|
|
||||||
|
// ****************************************
|
||||||
|
// Base constants
|
||||||
|
// Based on https://gridfinity.xyz/specification/
|
||||||
|
// ****************************************
|
||||||
|
BASE_OUTSIDE_RADIUS = r_base;
|
||||||
|
|
||||||
|
BASE_PROFILE = [
|
||||||
|
[0, 0], // Innermost bottom point
|
||||||
|
[0.8, 0.8], // Up and out at a 45 degree angle
|
||||||
|
[0.8, (0.8+1.8)], // Straight up
|
||||||
|
[(0.8+2.15), (0.8+1.8+2.15)], // Up and out at a 45 degree angle
|
||||||
|
[0, (0.8+1.8+2.15)], // Go in to form a solid polygon
|
||||||
|
[0, 0] //Back to start
|
||||||
|
];
|
||||||
|
|
||||||
|
// Maximum [x,y] values/size of the base.
|
||||||
|
BASE_PROFILE_MAX = BASE_PROFILE[3];
|
||||||
|
|
||||||
|
// Each unit's base is 41.5mm x 41.5mm
|
||||||
|
// Leaving 0.5mm gap with an l_grid of 42
|
||||||
|
BASE_SIZE = 41.5;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Height of the raw base
|
||||||
|
*/
|
||||||
|
h_base = BASE_PROFILE_MAX.y;
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
// Baseplate constants
|
// Baseplate constants
|
||||||
// Based on https://gridfinity.xyz/specification/
|
// Based on https://gridfinity.xyz/specification/
|
||||||
|
@ -159,8 +179,6 @@ bp_rcut_depth = 2;
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
|
|
||||||
// Baseplate clearance offset
|
|
||||||
bp_xy_clearance = 0.5;
|
|
||||||
// radius of cutout for skeletonized baseplate
|
// radius of cutout for skeletonized baseplate
|
||||||
r_skel = 2;
|
r_skel = 2;
|
||||||
// minimum baseplate thickness (when skeletonized)
|
// minimum baseplate thickness (when skeletonized)
|
||||||
|
|
Loading…
Reference in a new issue