Add first crack files
This commit is contained in:
parent
c581a35abf
commit
054811a55c
BIN
MicroscopeLenseHolder.FCStd
Normal file
BIN
MicroscopeLenseHolder.FCStd
Normal file
Binary file not shown.
BIN
Parametric_Gridfinity-Bin.fcstd
Normal file
BIN
Parametric_Gridfinity-Bin.fcstd
Normal file
Binary file not shown.
85
gridfinity-constants.scad
Normal file
85
gridfinity-constants.scad
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
// height of the base
|
||||
h_base = 5;
|
||||
// outside rounded radius of bin
|
||||
r_base = 4;
|
||||
// lower base chamfer "radius"
|
||||
r_c1 = 0.8;
|
||||
// upper base chamfer "radius"
|
||||
r_c2 = 2.4;
|
||||
// bottom thiccness of bin
|
||||
h_bot = 2.2;
|
||||
// outside radii 1
|
||||
r_fo1 = 8.5;
|
||||
// outside radii 2
|
||||
r_fo2 = 3.2;
|
||||
// outside radii 3
|
||||
r_fo3 = 1.6;
|
||||
|
||||
// screw hole radius
|
||||
r_hole1 = 1.5;
|
||||
// magnet hole radius
|
||||
r_hole2 = 3.25;
|
||||
// center-to-center distance between holes
|
||||
d_hole = 26;
|
||||
// magnet hole depth
|
||||
h_hole = 2.4;
|
||||
// slit depth (printer layer height)
|
||||
h_slit = 0.2;
|
||||
|
||||
// top edge fillet radius
|
||||
r_f1 = 0.6;
|
||||
// internal fillet radius
|
||||
r_f2 = 2.8;
|
||||
|
||||
// width of divider between compartments
|
||||
d_div = 1.2;
|
||||
// minimum wall thickness
|
||||
d_wall = 0.95;
|
||||
// tolerance fit factor
|
||||
d_clear = 0.25;
|
||||
|
||||
// height of tab (yaxis, measured from inner wall)
|
||||
d_tabh = 15.85;
|
||||
// maximum width of tab
|
||||
d_tabw = 42;
|
||||
// angle of tab
|
||||
a_tab = 36;
|
||||
|
||||
d_wall2 = r_base-r_c1-d_clear*sqrt(2);
|
||||
d_magic = -2*d_clear-2*d_wall+d_div;
|
||||
|
||||
// Baseplate constants
|
||||
|
||||
// Baseplate bottom part height (part added with weigthed=true)
|
||||
bp_h_bot = 6.4;
|
||||
|
||||
// Baseplate bottom cutout rectangle size
|
||||
bp_cut_size = 21.4;
|
||||
|
||||
// Baseplate bottom cutout rectangle depth
|
||||
bp_cut_depth = 4;
|
||||
|
||||
// Baseplate bottom cutout rounded thingy width
|
||||
bp_rcut_width = 8.5;
|
||||
|
||||
// Baseplate bottom cutout rounded thingy left
|
||||
bp_rcut_length = 4.25;
|
||||
|
||||
// Baseplate bottom cutout rounded thingy depth
|
||||
bp_rcut_depth = 2;
|
||||
|
||||
// countersink diameter for baseplate
|
||||
d_cs = 2.5;
|
||||
|
||||
// radius of cutout for skeletonized baseplate
|
||||
r_skel = 2;
|
||||
|
||||
// baseplate counterbore radius
|
||||
r_cb = 2.75;
|
||||
|
||||
// baseplate counterbore depth
|
||||
h_cb = 3;
|
||||
|
||||
// minimum baseplate thickness (when skeletonized)
|
||||
h_skel = 1;
|
147
gridfinity-rebuilt-baseplate.scad
Normal file
147
gridfinity-rebuilt-baseplate.scad
Normal file
@ -0,0 +1,147 @@
|
||||
include <gridfinity-rebuilt-utility.scad>
|
||||
|
||||
// ===== INFORMATION ===== //
|
||||
/*
|
||||
IMPORTANT: rendering will be better for analyzing the model if fast-csg is enabled. As of writing, this feature is only available in the development builds and not the official release of OpenSCAD, but it makes rendering only take a couple seconds, even for comically large bins. Enable it in Edit > Preferences > Features > fast-csg
|
||||
|
||||
https://github.com/kennetek/gridfinity-rebuilt-openscad
|
||||
|
||||
*/
|
||||
|
||||
// ===== PARAMETERS ===== //
|
||||
|
||||
/* [Setup Parameters] */
|
||||
$fa = 8;
|
||||
$fs = 0.25;
|
||||
|
||||
/* [General Settings] */
|
||||
// number of bases along x-axis
|
||||
gridx = 4;
|
||||
// number of bases along y-axis
|
||||
gridy = 4;
|
||||
// base unit
|
||||
length = 42;
|
||||
|
||||
/* [Fit to Drawer] */
|
||||
// minimum length of baseplate along x (leave zero to ignore, will automatically fill area if gridx is zero)
|
||||
distancex = 0;
|
||||
// minimum length of baseplate along y (leave zero to ignore, will automatically fill area if gridy is zero)
|
||||
distancey = 0;
|
||||
|
||||
/* [Styles] */
|
||||
|
||||
// baseplate styles
|
||||
style_plate = 2; // [0: thin, 1:weighted, 2:skeletonized]
|
||||
|
||||
// enable magnet hole
|
||||
enable_magnet = true;
|
||||
|
||||
// hole styles
|
||||
style_hole = 2; // [0:none, 1:contersink, 2:counterbore]
|
||||
|
||||
|
||||
// ===== IMPLEMENTATION ===== //
|
||||
|
||||
color("tomato")
|
||||
gridfinityBaseplate(gridx, gridy, length, distancex, distancey, style_plate, enable_magnet, style_hole);
|
||||
|
||||
|
||||
|
||||
// ===== CONSTRUCTION ===== //
|
||||
|
||||
module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, sm, sh) {
|
||||
|
||||
assert(gridx > 0 || dx > 0, "Must have positive x grid amount!");
|
||||
assert(gridy > 0 || dy > 0, "Must have positive y grid amount!");
|
||||
gx = gridx == 0 ? floor(dix/length) : gridx;
|
||||
gy = gridy == 0 ? floor(diy/length) : gridy;
|
||||
dx = max(gx*length-0.5, dix);
|
||||
dy = max(gy*length-0.5, diy);
|
||||
off = (sp==0?0:sp==1?bp_h_bot:h_skel+(sm?h_hole:0)+(sh==0?0:sh==1?d_cs:h_cb));
|
||||
|
||||
difference() {
|
||||
translate([0,0,h_base])
|
||||
mirror([0,0,1])
|
||||
rounded_rectangle(dx, dy, h_base+off, r_base);
|
||||
|
||||
gridfinityBase(gx, gy, length, 1, 1, 0, 0.5, false);
|
||||
|
||||
translate([0,0,h_base-0.6])
|
||||
rounded_rectangle(dx*2, dy*2, h_base*2, r_base);
|
||||
|
||||
pattern_linear(gx, gy, length) {
|
||||
if (sm) block_base_hole(1);
|
||||
|
||||
if (sp == 1)
|
||||
translate([0,0,-off])
|
||||
cutter_weight();
|
||||
else if (sp == 2)
|
||||
linear_extrude(10*(h_base+off), center = true)
|
||||
profile_skeleton();
|
||||
|
||||
translate([0,0,-off]) {
|
||||
if (sh == 1) cutter_countersink();
|
||||
else if (sh == 2) cutter_counterbore();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module cutter_weight() {
|
||||
union() {
|
||||
linear_extrude(bp_cut_depth*2,center=true)
|
||||
square(bp_cut_size, center=true);
|
||||
pattern_circular(4)
|
||||
translate([0,10,0])
|
||||
linear_extrude(bp_rcut_depth*2,center=true)
|
||||
union() {
|
||||
square([bp_rcut_width, bp_rcut_length], center=true);
|
||||
translate([0,bp_rcut_length/2,0])
|
||||
circle(d=bp_rcut_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module cutter_countersink() {
|
||||
pattern_circular(4)
|
||||
translate([d_hole/2, d_hole/2, 0]) {
|
||||
cylinder(r = r_hole1+d_clear, h = 100*h_base, center = true);
|
||||
|
||||
translate([0,0,d_cs])
|
||||
mirror([0,0,1])
|
||||
hull() {
|
||||
cylinder(h = d_cs+10, r=r_hole1+d_clear);
|
||||
translate([0,0,d_cs])
|
||||
cylinder(h=d_cs+10, r=r_hole1+d_clear+d_cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module cutter_counterbore() {
|
||||
pattern_circular(4)
|
||||
translate([d_hole/2,d_hole/2,0]) {
|
||||
cylinder(h=100*h_base, r=r_hole1+d_clear, center=true);
|
||||
difference() {
|
||||
cylinder(h = 2*(h_cb+0.2), r=r_cb, center=true);
|
||||
copy_mirror([0,1,0])
|
||||
translate([-1.5*r_cb,r_hole1+d_clear+0.1,h_cb-h_slit])
|
||||
cube([r_cb*3,r_cb*3, 10]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module profile_skeleton() {
|
||||
l = length-2*r_c2-2*r_c1;
|
||||
minkowski() {
|
||||
difference() {
|
||||
square([l-2*r_skel+2*d_clear,l-2*r_skel+2*d_clear], center = true);
|
||||
pattern_circular(4)
|
||||
translate([d_hole/2,d_hole/2,0])
|
||||
minkowski() {
|
||||
square([l,l]);
|
||||
circle(r_hole2+r_skel+2);
|
||||
}
|
||||
}
|
||||
circle(r_skel);
|
||||
}
|
||||
}
|
158
gridfinity-rebuilt-bins.scad
Normal file
158
gridfinity-rebuilt-bins.scad
Normal file
@ -0,0 +1,158 @@
|
||||
include <gridfinity-rebuilt-utility.scad>
|
||||
|
||||
// ===== INFORMATION ===== //
|
||||
/*
|
||||
IMPORTANT: rendering will be better for analyzing the model if fast-csg is enabled. As of writing, this feature is only available in the development builds and not the official release of OpenSCAD, but it makes rendering only take a couple seconds, even for comically large bins. Enable it in Edit > Preferences > Features > fast-csg
|
||||
the magnet holes can have an extra cut in them to make it easier to print without supports
|
||||
tabs will automatically be disabled when gridz is less than 3, as the tabs take up too much space
|
||||
base functions can be found in "gridfinity-rebuilt-utility.scad"
|
||||
examples at end of file
|
||||
|
||||
BIN HEIGHT
|
||||
the original gridfinity bins had the overall height defined by 7mm increments
|
||||
a bin would be 7*u millimeters tall
|
||||
the lip at the top of the bin (3.8mm) added onto this height
|
||||
The stock bins have unit heights of 2, 3, and 6:
|
||||
Z unit 2 -> 7*2 + 3.8 -> 17.8mm
|
||||
Z unit 3 -> 7*3 + 3.8 -> 24.8mm
|
||||
Z unit 6 -> 7*6 + 3.8 -> 45.8mm
|
||||
|
||||
https://github.com/kennetek/gridfinity-rebuilt-openscad
|
||||
|
||||
*/
|
||||
|
||||
// ===== PARAMETERS ===== //
|
||||
|
||||
/* [Setup Parameters] */
|
||||
$fa = 8;
|
||||
$fs = 0.25;
|
||||
|
||||
/* [General Settings] */
|
||||
// number of bases along x-axis
|
||||
gridx = 2;
|
||||
// number of bases along y-axis
|
||||
gridy = 3;
|
||||
// bin height. See bin height information and "gridz_define" below.
|
||||
gridz = 42;
|
||||
// base unit
|
||||
length = 42;
|
||||
|
||||
/* [Compartments] */
|
||||
// number of X Divisions
|
||||
divx = 1;
|
||||
// number of y Divisions
|
||||
divy = 1;
|
||||
|
||||
/* [Toggles] */
|
||||
// internal fillet for easy part removal
|
||||
enable_scoop = true;
|
||||
// snap gridz height to nearest 7mm increment
|
||||
enable_zsnap = false;
|
||||
// enable upper lip for stacking other bins
|
||||
enable_lip = true;
|
||||
|
||||
/* [Other] */
|
||||
// determine what the variable "gridz" applies to based on your use case
|
||||
gridz_define = 2; // [0:gridz is the height of bins in units of 7mm increments - Zack's method,1:gridz is the internal height in millimeters, 2:gridz is the overall external height of the bin in millimeters]
|
||||
// the type of tabs
|
||||
style_tab = 1; //[0:Full,1:Auto,2:Left,3:Center,4:Right,5:None]
|
||||
|
||||
// overrides internal block height of bin (for solid containers). Leave zero for default height. Units: mm
|
||||
height_internal = 0;
|
||||
|
||||
/* [Base] */
|
||||
style_hole = 3; // [0:no holes, 1:magnet holes only, 2: magnet and screw holes - no printable slit, 3: magnet and screw holes - printable slit]
|
||||
// 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;
|
||||
|
||||
|
||||
|
||||
// ===== IMPLEMENTATION ===== //
|
||||
|
||||
color("tomato") {
|
||||
gridfinityInit(gridx, gridy, height(gridz, gridz_define, enable_lip, enable_zsnap), height_internal, length) {
|
||||
|
||||
cutEqual(n_divx = divx, n_divy = divy, style_tab = style_tab, enable_scoop = enable_scoop);
|
||||
}
|
||||
gridfinityBase(gridx, gridy, length, div_base_x, div_base_y, style_hole);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ===== EXAMPLES ===== //
|
||||
|
||||
// 3x3 even spaced grid
|
||||
/*
|
||||
gridfinityInit(3, 3, height(6), 0, 42) {
|
||||
cutEqual(n_divx = 3, n_divy = 3, style_tab = 0, enable_scoop = true);
|
||||
}
|
||||
gridfinityBase(3, 3, 42, 0, 0, 1);
|
||||
*/
|
||||
|
||||
// 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.
|
||||
/*
|
||||
gridfinityInit(3, 3, height(6), 0, 42) {
|
||||
cut(x=0, y=0, w=1.5, h=0.5, t=5, s=false);
|
||||
cut(0, 0.5, 1.5, 0.5, 5, false);
|
||||
cut(0, 1, 1.5, 0.5, 5, false);
|
||||
|
||||
cut(0,1.5,0.5,1.5,5,false);
|
||||
cut(0.5,1.5,0.5,1.5,5,false);
|
||||
cut(1,1.5,0.5,1.5,5,false);
|
||||
|
||||
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);
|
||||
*/
|
||||
|
||||
// Compartments can overlap! This allows for weirdly shaped compartments, such as this "2" bin.
|
||||
/*
|
||||
gridfinityInit(3, 3, height(6), 0, 42) {
|
||||
cut(0,2,2,1,5,false);
|
||||
cut(1,0,1,3,5);
|
||||
cut(1,0,2,1,5);
|
||||
cut(0,0,1,2);
|
||||
cut(2,1,1,2);
|
||||
}
|
||||
gridfinityBase(3, 3, 42, 0, 0, 1);
|
||||
*/
|
||||
|
||||
// Areas without a compartment are solid material, where you can put your own cutout shapes. using the cut_move() function, you can select an area, and any child shapes will be moved from the origin to the center of that area, and subtracted from the block. For example, a pattern of three cylinderical holes.
|
||||
/*
|
||||
gridfinityInit(3, 3, height(6), 0, 42) {
|
||||
cut(x=0, y=0, w=2, h=3);
|
||||
cut(x=0, y=0, w=3, h=1, t=5);
|
||||
cut_move(x=2, y=1, w=1, h=2)
|
||||
pattern_linear(x=1, y=3, sx=42/2)
|
||||
cylinder(r=5, h=1000, center=true);
|
||||
}
|
||||
gridfinityBase(3, 3, 42, 0, 0, 1);
|
||||
*/
|
||||
|
||||
// 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
|
||||
/*
|
||||
gx = 3;
|
||||
gy = 3;
|
||||
gridfinityInit(gx, gy, height(6), 0, 42) {
|
||||
for(i=[0:gx-1]) {
|
||||
cut(i,0,1,gx-1);
|
||||
cut(i,gx-1,1,1);
|
||||
}
|
||||
}
|
||||
gridfinityBase(gx, gy, 42, 0, 0, 1);
|
||||
*/
|
||||
|
||||
// Pyramid scheme bin
|
||||
/*
|
||||
gx = 4.5;
|
||||
gy = 4;
|
||||
gridfinityInit(gx, gy, height(6), 0, 42) {
|
||||
for (i = [0:gx-1])
|
||||
for (j = [0:i])
|
||||
cut(j*gx/(i+1),gy-i-1,gx/(i+1),1,0);
|
||||
}
|
||||
gridfinityBase(gx, gy, 42, 0, 0, 1);
|
||||
*/
|
93
gridfinity-rebuilt-lite.scad
Normal file
93
gridfinity-rebuilt-lite.scad
Normal file
@ -0,0 +1,93 @@
|
||||
include <gridfinity-rebuilt-utility.scad>
|
||||
|
||||
// ===== INFORMATION ===== //
|
||||
/*
|
||||
IMPORTANT: rendering will be better for analyzing the model if fast-csg is enabled. As of writing, this feature is only available in the development builds and not the official release of OpenSCAD, but it makes rendering only take a couple seconds, even for comically large bins. Enable it in Edit > Preferences > Features > fast-csg
|
||||
|
||||
https://github.com/kennetek/gridfinity-rebuilt-openscad
|
||||
|
||||
*/
|
||||
|
||||
// ===== PARAMETERS ===== //
|
||||
|
||||
/* [Setup Parameters] */
|
||||
$fa = 8;
|
||||
$fs = 0.25;
|
||||
|
||||
/* [General Settings] */
|
||||
// number of bases along x-axis
|
||||
gridx = 3;
|
||||
// number of bases along y-axis
|
||||
gridy = 3;
|
||||
// bin height. See bin height information and "gridz_define" below.
|
||||
gridz = 6;
|
||||
// base unit
|
||||
length = 42;
|
||||
|
||||
/* [Compartments] */
|
||||
// number of X Divisions
|
||||
divx = 2;
|
||||
// number of y Divisions
|
||||
divy = 2;
|
||||
|
||||
/* [Toggles] */
|
||||
// snap gridz height to nearest 7mm increment
|
||||
enable_zsnap = false;
|
||||
// enable upper lip for stacking other bins
|
||||
enable_lip = true;
|
||||
|
||||
/* [Other] */
|
||||
// determine what the variable "gridz" applies to based on your use case
|
||||
gridz_define = 0; // [0:gridz is the height of bins in units of 7mm increments - Zack's method,1:gridz is the internal height in millimeters, 2:gridz is the overall external height of the bin in millimeters]
|
||||
// the type of tabs
|
||||
style_tab = 1; //[0:Full,1:Auto,2:Left,3:Center,4:Right,5:None]
|
||||
|
||||
/* [Base] */
|
||||
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]
|
||||
// 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;
|
||||
|
||||
|
||||
// ===== IMPLEMENTATION ===== //
|
||||
|
||||
// Input all the cutter types in here
|
||||
color("tomato")
|
||||
gridfinityLite(gridx, gridy, gridz, gridz_define, enable_lip, enable_zsnap, length, div_base_x, div_base_y, style_hole) {
|
||||
cutEqual(n_divx = divx, n_divy = divy, style_tab = style_tab, enable_scoop = false);
|
||||
}
|
||||
|
||||
// ===== CONSTRUCTION ===== //
|
||||
|
||||
|
||||
module gridfinityLite(gridx, gridy, gridz, gridz_define, enable_lip, enable_zsnap, length, div_base_x, div_base_y, style_hole) {
|
||||
difference() {
|
||||
union() {
|
||||
gridfinityInit(gridx, gridy, height(gridz, gridz_define, enable_lip, enable_zsnap), 0, length)
|
||||
children();
|
||||
gridfinityBase(gridx, gridy, length, div_base_x, div_base_y, style_hole);
|
||||
}
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
intersection() {
|
||||
difference() {
|
||||
gridfinityBase(gridx, gridy, length, div_base_x, div_base_y, style_hole, -d_wall*2, false);
|
||||
translate([-gridx*length/2,-gridy*length/2,2*h_base])
|
||||
cube([gridx*length,gridy*length,1000]);
|
||||
}
|
||||
translate([0,0,-1])
|
||||
rounded_rectangle(gridx*length-0.5005-d_wall*2, gridy*length-0.5005-d_wall*2, 1000, r_f2);
|
||||
}
|
||||
translate([0,0,h_base+d_clear])
|
||||
rounded_rectangle(gridx*length-0.5005-d_wall*2, gridy*length-0.5005-d_wall*2, h_base, r_f2);
|
||||
}
|
||||
|
||||
translate([0,0,-4*h_base])
|
||||
gridfinityInit(gridx, gridy, height(20,0), 0, length)
|
||||
children();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
444
gridfinity-rebuilt-utility.scad
Normal file
444
gridfinity-rebuilt-utility.scad
Normal file
@ -0,0 +1,444 @@
|
||||
// UTILITY FILE, DO NOT EDIT
|
||||
// EDIT OTHER FILES IN REPO FOR RESULTS
|
||||
|
||||
include <gridfinity-constants.scad>
|
||||
|
||||
// ===== User Modules ===== //
|
||||
|
||||
// functions to convert gridz values to mm values
|
||||
function hf (z, d, l) = (d==0)?z*7:(d==1)?h_bot+z+h_base:z-(l?3.8:0);
|
||||
function height (z,d=0,l=true,s=true) = (s?((abs(hf(z,d,l))%7==0)?hf(z,d,l):hf(z,d,l)+7-abs(hf(z,d,l))%7):hf(z,d,l))-h_base;
|
||||
|
||||
// Creates equally divided cutters for the bin
|
||||
//
|
||||
// n_divx: number of x compartments (ideally, coprime w/ gridx)
|
||||
// n_divy: number of y compartments (ideally, coprime w/ gridy)
|
||||
// set n_div values to 0 for a solid bin
|
||||
// style_tab: tab style for all compartments. see cut()
|
||||
// enable_scoop: scoop toggle for all compartments. see cut()
|
||||
module cutEqual(n_divx=1, n_divy=1, style_tab=1, enable_scoop=true) {
|
||||
for (i = [1:n_divx])
|
||||
for (j = [1:n_divy])
|
||||
cut((i-1)*$gxx/n_divx,(j-1)*$gyy/n_divy, $gxx/n_divx, $gyy/n_divy, style_tab, enable_scoop);
|
||||
}
|
||||
|
||||
// initialize gridfinity
|
||||
module gridfinityInit(gx, gy, h, h0 = 0, l) {
|
||||
$gxx = gx;
|
||||
$gyy = gy;
|
||||
$dh = h;
|
||||
$dh0 = h0;
|
||||
color("tomato") {
|
||||
difference() {
|
||||
color("firebrick")
|
||||
block_bottom(h0==0?$dh-0.1:h0, gx, gy, l);
|
||||
children();
|
||||
}
|
||||
color("royalblue")
|
||||
block_wall(gx, gy, l) {
|
||||
if (enable_lip) profile_wall();
|
||||
else profile_wall2();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Function to include in the custom() module to individually slice bins
|
||||
// Will try to clamp values to fit inside the provided base size
|
||||
//
|
||||
// x: start coord. x=1 is the left side of the bin.
|
||||
// y: start coord. y=1 is the bottom side of the bin.
|
||||
// w: width of compartment, in # of bases covered
|
||||
// h: height of compartment, in # of basese covered
|
||||
// t: tab style of this specific compartment.
|
||||
// alignment only matters if the compartment size is larger than d_tabw
|
||||
// 0:full, 1:auto, 2:left, 3:center, 4:right, 5:none
|
||||
// Automatic alignment will use left tabs for bins on the left edge, right tabs for bins on the right edge, and center tabs everywhere else.
|
||||
// s: toggle the rounded back corner that allows for easy removal
|
||||
module cut(x=0, y=0, w=1, h=1, t=1, s=true) {
|
||||
translate([0,0,-$dh-h_base])
|
||||
cut_move(x,y,w,h)
|
||||
block_cutter(clp(x,0,$gxx), clp(y,0,$gyy), clp(w,0,$gxx-x), clp(h,0,$gyy-y), t, s);
|
||||
}
|
||||
|
||||
// Translates an object from the origin point to the center of the requested compartment block, can be used to add custom cuts in the bin
|
||||
// See cut() module for parameter descriptions
|
||||
module cut_move(x, y, w, h) {
|
||||
translate([0,0,$dh0==0?$dh+h_base:$dh0+h_base])
|
||||
cut_move_unsafe(clp(x,0,$gxx), clp(y,0,$gyy), clp(w,0,$gxx-x), clp(h,0,$gyy-y))
|
||||
children();
|
||||
}
|
||||
|
||||
// ===== Modules ===== //
|
||||
|
||||
module profile_base() {
|
||||
polygon([
|
||||
[0,0],
|
||||
[0,h_base],
|
||||
[r_base,h_base],
|
||||
[r_base-r_c2,h_base-r_c2],
|
||||
[r_base-r_c2,r_c1],
|
||||
[r_base-r_c2-r_c1,0]
|
||||
]);
|
||||
}
|
||||
|
||||
module gridfinityBase(gx, gy, l, dx, dy, style_hole, off=0, final_cut=true) {
|
||||
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 ? len(dbnxt) > 0 ? dbnxt[0] : 1 : round(dx));
|
||||
dbny = 1/(dy==0 ? len(dbnyt) > 0 ? dbnyt[0] : 1 : round(dy));
|
||||
xx = gx*l-0.5;
|
||||
yy = gy*l-0.5;
|
||||
|
||||
if (final_cut)
|
||||
translate([0,0,h_base])
|
||||
rounded_rectangle(xx+0.002, yy+0.002, h_bot/1.5, r_fo1/2+0.001);
|
||||
|
||||
intersection(){
|
||||
if (final_cut)
|
||||
translate([0,0,-1])
|
||||
rounded_rectangle(xx+0.005, yy+0.005, h_base+h_bot/2*10, r_fo1/2+0.001);
|
||||
|
||||
render()
|
||||
difference() {
|
||||
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
||||
block_base_solid(dbnx, dbny, l, off);
|
||||
|
||||
if (style_hole > 0)
|
||||
pattern_linear(gx, gy, l)
|
||||
block_base_hole(style_hole, off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
hull() {
|
||||
rounded_rectangle(xx-2*r_c2-2*r_c1+o, yy-2*r_c2-2*r_c1+o, h_base+oo, r_fo3/2);
|
||||
rounded_rectangle(xx-2*r_c2+o, yy-2*r_c2+o, h_base-r_c1+oo, r_fo2/2);
|
||||
}
|
||||
translate([0,0,oo])
|
||||
hull() {
|
||||
rounded_rectangle(xx-2*r_c2+o, yy-2*r_c2+o, r_c2, r_fo2/2);
|
||||
mirror([0,0,1])
|
||||
rounded_rectangle(xx+o, yy+o, h_bot/2+abs(10*o), r_fo1/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module block_base_hole(style_hole, o=0) {
|
||||
r1 = r_hole1-o/2;
|
||||
r2 = r_hole2-o/2;
|
||||
pattern_circular(abs(d_hole)<0.001?1:4)
|
||||
translate([d_hole/2, d_hole/2, 0])
|
||||
union() {
|
||||
difference() {
|
||||
cylinder(h = 2*(h_hole-o+(style_hole==3?h_slit:0)), r=r2, center=true);
|
||||
|
||||
if (style_hole==3)
|
||||
copy_mirror([0,1,0])
|
||||
translate([-1.5*r2,r1+0.1,h_hole-o])
|
||||
cube([r2*3,r2*3, 10]);
|
||||
}
|
||||
if (style_hole > 1)
|
||||
cylinder(h = 2*h_base-o, r = r1, center=true);
|
||||
}
|
||||
}
|
||||
|
||||
module profile_wall_sub_sub() {
|
||||
polygon([
|
||||
[0,0],
|
||||
[d_wall/2,0],
|
||||
[d_wall/2,$dh-1.2-d_wall2+d_wall/2],
|
||||
[d_wall2-d_clear,$dh-1.2],
|
||||
[d_wall2-d_clear,$dh+h_base],
|
||||
[0,$dh+h_base]
|
||||
]);
|
||||
}
|
||||
|
||||
module profile_wall_sub() {
|
||||
difference() {
|
||||
profile_wall_sub_sub();
|
||||
color("red")
|
||||
offset(delta = d_clear)
|
||||
translate([r_base-d_clear,$dh,0])
|
||||
mirror([1,0,0])
|
||||
profile_base();
|
||||
square([d_wall,0]);
|
||||
}
|
||||
}
|
||||
|
||||
module profile_wall() {
|
||||
translate([r_base,0,0])
|
||||
mirror([1,0,0])
|
||||
difference() {
|
||||
profile_wall_sub();
|
||||
difference() {
|
||||
translate([0, $dh+h_base-d_clear*sqrt(2), 0])
|
||||
circle(r_base/2);
|
||||
offset(r = r_f1)
|
||||
offset(delta = -r_f1)
|
||||
profile_wall_sub();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lipless profile
|
||||
module profile_wall2() {
|
||||
translate([r_base,0,0])
|
||||
mirror([1,0,0])
|
||||
square([d_wall,$dh]);
|
||||
}
|
||||
|
||||
module block_wall(gx, gy, l) {
|
||||
translate([0,0,h_base])
|
||||
sweep_rounded(gx*l-2*r_base-0.5-0.001, gy*l-2*r_base-0.5-0.001)
|
||||
children();
|
||||
}
|
||||
|
||||
module block_bottom( h = 2.2, gx, gy, l ) {
|
||||
translate([0,0,h_base+0.1])
|
||||
rounded_rectangle(gx*l-0.5-d_wall/4, gy*l-0.5-d_wall/4, h, r_base+0.01);
|
||||
}
|
||||
|
||||
module cut_move_unsafe(x, y, w, h) {
|
||||
xx = ($gxx*length+d_magic);
|
||||
yy = ($gyy*length+d_magic);
|
||||
translate([(x)*xx/$gxx,(y)*yy/$gyy,0])
|
||||
translate([(-xx+d_div)/2,(-yy+d_div)/2,0])
|
||||
translate([(w*xx/$gxx-d_div)/2,(h*yy/$gyy-d_div)/2,0])
|
||||
children();
|
||||
}
|
||||
|
||||
module block_cutter(x,y,w,h,t,s) {
|
||||
|
||||
v_len_tab = d_tabh;
|
||||
v_len_lip = d_wall2-d_wall+1.2;
|
||||
v_cut_tab = d_tabh - (2*r_f1)/tan(a_tab);
|
||||
v_cut_lip = d_wall2-d_wall-d_clear;
|
||||
v_ang_tab = a_tab;
|
||||
v_ang_lip = 45;
|
||||
|
||||
ycutfirst = y == 0 && enable_lip;
|
||||
ycutlast = abs(y+h-$gyy)<0.001 && enable_lip;
|
||||
xcutfirst = x == 0 && enable_lip;
|
||||
xcutlast = abs(x+w-$gxx)<0.001 && enable_lip;
|
||||
zsmall = ($dh+h_base)/7 < 3;
|
||||
|
||||
ylen = h*($gyy*length+d_magic)/$gyy-d_div;
|
||||
xlen = w*($gxx*length+d_magic)/$gxx-d_div;
|
||||
|
||||
height = $dh;
|
||||
extent = (s && ycutfirst ? d_wall2-d_wall-d_clear : 0);
|
||||
tab = (zsmall || t == 5) ? (ycutlast?v_len_lip:0) : v_len_tab;
|
||||
ang = (zsmall || t == 5) ? (ycutlast?v_ang_lip:0) : v_ang_tab;
|
||||
cut = (zsmall || t == 5) ? (ycutlast?v_cut_lip:0) : v_cut_tab;
|
||||
style = (t > 1 && t < 5) ? t-3 : (x == 0 ? -1 : xcutlast ? 1 : 0);
|
||||
|
||||
translate([0,ylen/2,h_base+h_bot])
|
||||
rotate([90,0,-90]) {
|
||||
|
||||
if (!zsmall && xlen - d_tabw > 4*r_f2 && t != 0) {
|
||||
fillet_cutter(3,"bisque")
|
||||
difference() {
|
||||
transform_tab(style, xlen, ((xcutfirst&&style==-1)||(xcutlast&&style==1))?v_cut_lip:0)
|
||||
translate([ycutlast?v_cut_lip:0,0])
|
||||
profile_cutter(height-h_bot, ylen/2, s);
|
||||
|
||||
if (xcutfirst)
|
||||
translate([0,0,(xlen/2-r_f2)-v_cut_lip])
|
||||
cube([ylen,height,v_cut_lip*2]);
|
||||
|
||||
if (xcutlast)
|
||||
translate([0,0,-(xlen/2-r_f2)-v_cut_lip])
|
||||
cube([ylen,height,v_cut_lip*2]);
|
||||
}
|
||||
if (t != 0 && t != 5)
|
||||
fillet_cutter(2,"indigo")
|
||||
difference() {
|
||||
transform_tab(style, xlen, ((xcutfirst&&style==-1)||(xcutlast&&style==1))?v_cut_lip:0)
|
||||
difference() {
|
||||
intersection() {
|
||||
profile_cutter(height-h_bot, ylen-extent, s);
|
||||
profile_cutter_tab(height-h_bot, v_len_tab, v_ang_tab);
|
||||
}
|
||||
if (ycutlast) profile_cutter_tab(height-h_bot, v_len_lip, 45);
|
||||
}
|
||||
|
||||
if (xcutfirst)
|
||||
translate([ylen/2,0,xlen/2])
|
||||
rotate([0,90,0])
|
||||
transform_main(2*ylen)
|
||||
profile_cutter_tab(height-h_bot, v_len_lip, v_ang_lip);
|
||||
|
||||
if (xcutlast)
|
||||
translate([ylen/2,0,-xlen/2])
|
||||
rotate([0,-90,0])
|
||||
transform_main(2*ylen)
|
||||
profile_cutter_tab(height-h_bot, v_len_lip, v_ang_lip);
|
||||
}
|
||||
}
|
||||
|
||||
fillet_cutter(1,"seagreen")
|
||||
translate([0,0,xcutlast?v_cut_lip/2:0])
|
||||
translate([0,0,xcutfirst?-v_cut_lip/2:0])
|
||||
transform_main(xlen-(xcutfirst?v_cut_lip:0)-(xcutlast?v_cut_lip:0))
|
||||
translate([cut,0])
|
||||
profile_cutter(height-h_bot, ylen-extent-cut-(!s&&ycutfirst?v_cut_lip:0), s);
|
||||
|
||||
fillet_cutter(0,"hotpink")
|
||||
difference() {
|
||||
transform_main(xlen)
|
||||
difference() {
|
||||
profile_cutter(height-h_bot, ylen-extent, s);
|
||||
|
||||
if (!((zsmall || t == 5) && !ycutlast))
|
||||
profile_cutter_tab(height-h_bot, tab, ang);
|
||||
|
||||
if (!s && y == 0)
|
||||
translate([ylen-extent,0,0])
|
||||
mirror([1,0,0])
|
||||
profile_cutter_tab(height-h_bot, v_len_lip, v_ang_lip);
|
||||
}
|
||||
|
||||
if (xcutfirst)
|
||||
color("indigo")
|
||||
translate([ylen/2+0.001,0,xlen/2+0.001])
|
||||
rotate([0,90,0])
|
||||
transform_main(2*ylen)
|
||||
profile_cutter_tab(height-h_bot, v_len_lip, v_ang_lip);
|
||||
|
||||
if (xcutlast)
|
||||
color("indigo")
|
||||
translate([ylen/2+0.001,0,-xlen/2+0.001])
|
||||
rotate([0,-90,0])
|
||||
transform_main(2*ylen)
|
||||
profile_cutter_tab(height-h_bot, v_len_lip, v_ang_lip);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module transform_main(xlen) {
|
||||
translate([0,0,-(xlen-2*r_f2)/2])
|
||||
linear_extrude(xlen-2*r_f2)
|
||||
children();
|
||||
}
|
||||
|
||||
module transform_tab(type, xlen, cut) {
|
||||
mirror([0,0,type==1?1:0])
|
||||
copy_mirror([0,0,-(abs(type)-1)])
|
||||
translate([0,0,-(xlen)/2])
|
||||
translate([0,0,r_f2])
|
||||
linear_extrude((xlen-d_tabw-abs(cut))/(1-(abs(type)-1))-2*r_f2)
|
||||
children();
|
||||
}
|
||||
|
||||
module fillet_cutter(t = 0, c = "goldenrod") {
|
||||
color(c)
|
||||
minkowski() {
|
||||
children();
|
||||
sphere(r = r_f2-t/1000);
|
||||
}
|
||||
}
|
||||
|
||||
module profile_cutter(h, l, s) {
|
||||
scoop = s ? (length*(($dh-2)/7+1)/12-r_f2) : 0;
|
||||
translate([r_f2,r_f2])
|
||||
hull() {
|
||||
if (l-scoop-2*r_f2 > 0)
|
||||
square(0.1);
|
||||
if (scoop < h) {
|
||||
translate([l-2*r_f2,h-r_f2/2])
|
||||
mirror([1,1])
|
||||
square(0.1);
|
||||
|
||||
translate([0,h-r_f2/2])
|
||||
mirror([0,1])
|
||||
square(0.1);
|
||||
}
|
||||
difference() {
|
||||
translate([l-scoop-2*r_f2, scoop])
|
||||
if (scoop != 0) {
|
||||
intersection() {
|
||||
circle(scoop);
|
||||
mirror([0,1]) square(2*scoop);
|
||||
}
|
||||
} else mirror([1,0]) square(0.1);
|
||||
translate([l-scoop-2*r_f2,-1])
|
||||
square([-(l-scoop-2*r_f2),2*h]);
|
||||
|
||||
translate([0,h])
|
||||
square([2*l,scoop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module profile_cutter_tab(h, tab, ang) {
|
||||
if (tab > 0)
|
||||
color("blue")
|
||||
offset(delta = r_f2)
|
||||
polygon([[0,h],[tab,h],[0,h-tab*tan(ang)]]);
|
||||
|
||||
}
|
||||
|
||||
// ==== Utilities =====
|
||||
|
||||
function clp(x,a,b) = min(max(x,a),b);
|
||||
|
||||
module rounded_rectangle(length, width, height, rad) {
|
||||
linear_extrude(height)
|
||||
offset(rad)
|
||||
offset(-rad)
|
||||
square([length,width], center = true);
|
||||
}
|
||||
|
||||
module rounded_square(length, height, rad) {
|
||||
rounded_rectangle(length, length, height, rad);
|
||||
}
|
||||
|
||||
module copy_mirror(vec=[0,1,0]) {
|
||||
children();
|
||||
if (vec != [0,0,0])
|
||||
mirror(vec)
|
||||
children();
|
||||
}
|
||||
|
||||
module pattern_linear(x = 1, y = 1, sx = 0, sy = 0) {
|
||||
yy = sy <= 0 ? sx : sy;
|
||||
translate([-(x-1)*sx/2,-(y-1)*yy/2,0])
|
||||
for (i = [1:ceil(x)])
|
||||
for (j = [1:ceil(y)])
|
||||
translate([(i-1)*sx,(j-1)*yy,0])
|
||||
children();
|
||||
}
|
||||
|
||||
module pattern_circular(n=2) {
|
||||
for (i = [1:n])
|
||||
rotate(i*360/n)
|
||||
children();
|
||||
}
|
||||
|
||||
module sweep_rounded(w=10, h=10) {
|
||||
union() pattern_circular(2) {
|
||||
copy_mirror([1,0,0])
|
||||
translate([w/2,h/2,0])
|
||||
rotate_extrude(angle = 90, convexity = 4)
|
||||
children();
|
||||
|
||||
translate([w/2,0,0])
|
||||
rotate([90,0,0])
|
||||
linear_extrude(height = h, center = true)
|
||||
children();
|
||||
|
||||
rotate([0,0,90])
|
||||
translate([h/2,0,0])
|
||||
rotate([90,0,0])
|
||||
linear_extrude(height = w, center = true)
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user