2022-11-17 19:58:46 +00:00
// ===== INFORMATION ===== //
/*
2024-10-15 19:48:03 +00:00
IMPORTANT : rendering will be better in development builds and not the official release of OpenSCAD , but it makes rendering only take a couple seconds , even for comically large bins .
2022-11-17 19:58:46 +00:00
https : //github.com/kennetek/gridfinity-rebuilt-openscad
* /
2024-10-17 07:01:38 +00:00
include < src/core/standard.scad >
use < src/core/gridfinity-rebuilt-utility.scad >
use < src/helpers/generic-helpers.scad >
2022-11-17 19:58:46 +00:00
// ===== PARAMETERS ===== //
2022-10-03 00:35:03 +00:00
2022-09-18 23:29:27 +00:00
/* [Special Variables] */
$fa = 8 ;
$fs = 0.25 ;
2022-10-02 06:10:19 +00:00
/* [Bin or Base] */
2024-04-30 02:54:25 +00:00
type = 1 ; // [0:bin, 1:base]
2022-10-02 06:10:19 +00:00
2022-09-18 23:29:27 +00:00
/* [Printer Settings] */
2023-02-06 06:24:41 +00:00
// extrusion width (walls will be twice this size)
2023-09-22 06:11:23 +00:00
nozzle = 0.6 ;
2022-09-18 23:29:27 +00:00
// slicer layer size
layer = 0.35 ;
2023-09-22 06:11:23 +00:00
// number of base layers on build plate
2022-09-18 23:29:27 +00:00
bottom_layer = 3 ;
/* [General Settings] */
2023-09-22 06:11:23 +00:00
// number of bases along x-axis
2022-11-18 01:26:43 +00:00
gridx = 1 ;
2023-09-22 06:11:23 +00:00
// number of bases along y-axis
2022-11-18 01:26:43 +00:00
gridy = 1 ;
2023-09-22 06:11:23 +00:00
// bin height. See bin height information and "gridz_define" below.
2023-05-31 15:46:30 +00:00
gridz = 6 ;
2022-09-18 23:29:27 +00:00
// number of compartments along x-axis
2022-11-18 01:26:43 +00:00
n_divx = 2 ;
2022-09-18 23:29:27 +00:00
/* [Toggles] */
// toggle holes on the base for magnet
2023-09-22 06:11:23 +00:00
enable_holes = true ;
2022-09-18 23:29:27 +00:00
// round up the bin height to match the closest 7mm unit
2023-09-22 06:11:23 +00:00
enable_zsnap = false ;
2022-09-18 23:29:27 +00:00
// toggle the lip on the top of the bin that allows stacking
2023-09-22 06:11:23 +00:00
enable_lip = true ;
2022-09-18 23:29:27 +00:00
// chamfer inside bin for easy part removal
enable_scoop_chamfer = true ;
// funnel-like features on the back of tabs for fingers to grab
2023-09-22 06:11:23 +00:00
enable_funnel = true ;
2022-09-18 23:29:27 +00:00
// front inset (added for strength when there is a scoop)
2023-09-22 06:11:23 +00:00
enable_inset = true ;
2022-09-18 23:29:27 +00:00
// "pinches" the top lip of the bin, for added strength
2023-09-22 06:11:23 +00:00
enable_pinch = true ;
2022-09-18 23:29:27 +00:00
/* [Styles] */
// 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]
// how tabs are implemented
2022-09-19 00:07:08 +00:00
style_tab = 0 ; // [0:continuous, 1:broken, 2:auto, 3:right, 4:center, 5:left, 6:none]
2022-09-18 23:29:27 +00:00
// where to put X cutouts for attaching bases
2023-02-06 06:16:23 +00:00
// selecting none will also disable crosses on bases
2022-09-19 00:07:08 +00:00
style_base = 0 ; // [0:all, 1:corners, 2:edges, 3:auto, 4:none]
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// tab angle
2023-09-22 06:11:23 +00:00
a_tab = 40 ;
2022-09-18 23:29:27 +00:00
2022-11-17 19:58:46 +00:00
// ===== IMPLEMENTATION ===== //
2022-09-18 23:29:27 +00:00
2022-11-17 19:58:46 +00:00
color ( "tomato" )
if ( type ! = 0 ) gridfinityBaseVase ( ) ; // Generate a single base
2023-09-22 06:11:23 +00:00
else gridfinityVase ( ) ; // Generate the bin
2022-09-18 23:29:27 +00:00
2022-11-17 19:58:46 +00:00
// ===== CONSTRUCTION ===== //
2022-09-18 23:29:27 +00:00
2024-08-29 19:31:13 +00:00
//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
2023-02-06 06:16:23 +00:00
d_bottom = layer * ( max ( bottom_layer , 1 ) ) ;
2023-09-22 06:11:23 +00:00
x_l = l_grid / 2 ;
2022-10-03 00:35:03 +00:00
dht = ( gridz_define = = 0 ) ? gridz * 7 : ( gridz_define = = 1 ) ? h_bot + gridz + h_base : gridz - ( enable_lip ? 3.8 : 0 ) ;
2023-09-22 06:11:23 +00:00
d_height = ( enable_zsnap ? ( ( abs ( dht ) % 7 = = 0 ) ? dht : dht + 7 - abs ( dht ) % 7 ) : dht ) - h_base ;
2022-09-18 23:29:27 +00:00
2024-08-29 19:31:13 +00:00
d_fo1 = 2 * + BASE_OUTSIDE_RADIUS ;
2024-02-16 21:01:40 +00:00
2022-09-18 23:29:27 +00:00
f2c = sqrt ( 2 ) * ( sqrt ( 2 ) - 1 ) ; // fillet to chamfer ratio
2024-02-16 21:01:40 +00:00
me = ( ( gridx * l_grid - 0.5 ) / n_divx ) - nozzle * 4 - d_fo1 - 12.7 - 4 ;
2022-10-03 00:35:03 +00:00
m = min ( d_tabw / 1.8 + max ( 0 , me ) , d_tabw / 1.25 ) ;
2023-05-31 15:46:30 +00:00
d_ramp = f2c * ( l_grid * ( ( d_height - 2 ) / 7 + 1 ) / 12 - r_f2 ) + d_wall2 ;
2024-02-16 21:01:40 +00:00
d_edge = ( ( gridx * l_grid - 0.5 ) / n_divx - d_tabw - d_fo1 ) / 2 ;
2023-09-22 06:11:23 +00:00
n_st = gridz < = 3 ? 6 : d_edge < 2 && style_tab ! = 0 && style_tab ! = 6 ? 1 : style_tab = = 1 && n_divx < = 1 ? 0 : style_tab ;
2022-09-18 23:29:27 +00:00
2023-09-22 06:11:23 +00:00
n_x = ( n_st = = 0 ? 1 : n_divx ) ;
2023-05-31 15:46:30 +00:00
spacing = ( gridx * l_grid - 0.5 ) / ( n_divx ) ;
2022-09-18 23:29:27 +00:00
shift = n_st = = 3 ? - 1 : n_st = = 5 ? 1 : 0 ;
shiftauto = function ( a , b ) n_st ! = 2 ? 0 : a = = 1 ? - 1 : a = = b ? 1 : 0 ;
2023-09-22 06:11:23 +00:00
xAll = function ( a , b ) true ;
2022-09-18 23:29:27 +00:00
xCorner = function ( a , b ) ( a = = 1 || a = = gridx ) && ( b = = 1 || b = = gridy ) ;
xEdge = function ( a , b ) ( a = = 1 ) || ( a = = gridx ) || ( b = = 1 ) || ( b = = gridy ) ;
2023-09-22 06:11:23 +00:00
xAuto = function ( a , b ) xCorner ( a , b ) || ( a % 2 = = 1 && b % 2 = = 1 ) ;
2022-09-18 23:29:27 +00:00
xNone = function ( a , b ) false ;
xFunc = [ xAll , xCorner , xEdge , xAuto , xNone ] ;
module gridfinityVase ( ) {
2023-09-22 06:11:23 +00:00
$ dh = d_height ;
2022-09-18 23:29:27 +00:00
difference ( ) {
union ( ) {
difference ( ) {
block_vase_base ( ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
if ( n_st ! = 6 )
transform_style ( )
2024-02-16 21:01:40 +00:00
transform_vtab_base ( ( n_st < 2 ? gridx * l_grid / n_x - 0.5 - d_fo1 : d_tabw ) - nozzle * 4 )
2022-09-18 23:29:27 +00:00
block_tab_base ( - nozzle * sqrt ( 2 ) ) ;
}
if ( enable_scoop_chamfer )
intersection ( ) {
block_vase ( ) ;
2023-05-31 15:46:30 +00:00
translate ( [ 0 , gridy * l_grid / 2 - 0.25 - d_wall2 / 2 , d_height / 2 + 0.1 ] )
cube ( [ gridx * l_grid , d_wall2 , d_height - 0.2 ] , center = true ) ;
2022-09-18 23:29:27 +00:00
}
2023-02-14 23:20:16 +00:00
if ( enable_funnel && gridz > 3 )
2024-02-16 21:01:40 +00:00
pattern_linear ( ( n_st = = 0 ? n_divx > 1 ? n_divx : gridx : 1 ) , 1 , ( gridx * l_grid - d_fo1 ) / ( n_st = = 0 ? n_divx > 1 ? n_divx : gridx : 1 ) )
2022-09-18 23:29:27 +00:00
transform_funnel ( )
block_funnel_outside ( ) ;
if ( n_divx > 1 )
2023-05-31 15:46:30 +00:00
pattern_linear ( n_divx - 1 , 1 , ( gridx * l_grid - 0.5 ) / ( n_divx ) )
2022-09-18 23:29:27 +00:00
block_divider ( ) ;
2023-09-22 06:11:23 +00:00
if ( n_divx < 1 )
2024-02-16 21:01:40 +00:00
pattern_linear ( n_st = = 0 ? n_divx > 1 ? n_divx - 1 : gridx - 1 : 1 , 1 , ( gridx * l_grid - d_fo1 ) / ( ( n_divx > 1 ? n_divx : gridx ) ) )
2022-09-18 23:29:27 +00:00
block_tabsupport ( ) ;
}
2023-09-22 06:11:23 +00:00
2023-02-14 23:20:16 +00:00
if ( enable_funnel && gridz > 3 )
2024-02-16 21:01:40 +00:00
pattern_linear ( ( n_st = = 0 ? n_divx > 1 ? n_divx : gridx : 1 ) , 1 , ( gridx * l_grid - d_fo1 ) / ( n_st = = 0 ? n_divx > 1 ? n_divx : gridx : 1 ) )
2022-09-18 23:29:27 +00:00
transform_funnel ( )
block_funnel_inside ( ) ;
if ( ! enable_lip )
translate ( [ 0 , 0 , 1.5 * d_height ] )
2023-05-31 15:46:30 +00:00
cube ( [ gridx * l_grid , gridy * l_grid , d_height ] , center = true ) ;
2022-09-18 23:29:27 +00:00
block_x ( ) ;
block_inset ( ) ;
if ( enable_pinch )
2024-04-30 02:48:08 +00:00
block_pinch ( d_height ) ;
2023-09-22 06:11:23 +00:00
2023-02-06 06:16:23 +00:00
if ( bottom_layer < = 0 )
translate ( [ 0 , 0 , - 50 + layer + 0.01 ] )
2023-05-31 15:46:30 +00:00
cube ( [ gridx * l_grid * 10 , gridy * l_grid * 10 , 100 ] , center = true ) ;
2022-09-18 23:29:27 +00:00
}
}
module gridfinityBaseVase ( ) {
difference ( ) {
union ( ) {
difference ( ) {
intersection ( ) {
block_base_blank ( 0 ) ;
translate ( [ 0 , 0 , - h_base - 1 ] )
2024-08-29 19:31:13 +00:00
rounded_square ( [ l_grid - 0.5 - 0.005 , l_grid - 0.5 - 0.005 , h_base * 10 ] , BASE_OUTSIDE_RADIUS + 0.001 , center = true ) ;
2022-09-18 23:29:27 +00:00
}
translate ( [ 0 , 0 , 0.01 ] )
difference ( ) {
block_base_blank ( nozzle * 4 ) ;
translate ( [ 0 , 0 , - h_base ] )
2023-05-31 15:46:30 +00:00
cube ( [ l_grid * 2 , l_grid * 2 , d_bottom * 2 ] , center = true ) ;
2022-09-18 23:29:27 +00:00
}
// magic slice
rotate ( [ 0 , 0 , 90 ] )
2022-10-03 00:35:03 +00:00
translate ( [ 0 , 0 , - h_base + d_bottom + 0.01 ] )
2023-05-31 15:46:30 +00:00
cube ( [ 0.001 , l_grid * gridx , d_height + d_bottom * 2 ] ) ;
2023-02-06 06:16:23 +00:00
2022-09-18 23:29:27 +00:00
}
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
pattern_circular ( 4 )
intersection ( ) {
rotate ( [ 0 , 0 , 45 ] )
2022-10-03 00:35:03 +00:00
translate ( [ - nozzle , 3 , - h_base + d_bottom + 0.01 ] )
2023-05-31 15:46:30 +00:00
cube ( [ nozzle * 2 , l_grid * gridx , d_height + d_bottom * 2 ] ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
block_base_blank ( nozzle * 4 - 0.1 ) ;
}
if ( enable_holes )
pattern_circular ( 4 )
block_magnet_blank ( nozzle ) ;
}
if ( enable_holes )
pattern_circular ( 4 )
block_magnet_blank ( 0 , false ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
translate ( [ 0 , 0 , h_base / 2 ] )
2023-05-31 15:46:30 +00:00
cube ( [ l_grid * 2 , l_grid * 2 , h_base ] , center = true ) ;
2022-09-18 23:29:27 +00:00
}
2023-09-22 06:11:23 +00:00
2023-02-06 06:16:23 +00:00
if ( style_base ! = 4 )
2022-10-03 00:35:03 +00:00
linear_extrude ( d_bottom )
2022-09-18 23:29:27 +00:00
profile_x ( 0.1 ) ;
}
module block_magnet_blank ( o = 0 , half = true ) {
2024-04-30 02:54:25 +00:00
magnet_radius = MAGNET_HOLE_RADIUS + o ;
2022-09-18 23:29:27 +00:00
translate ( [ d_hole / 2 , d_hole / 2 , - h_base + 0.1 ] )
difference ( ) {
hull ( ) {
2024-04-30 02:54:25 +00:00
cylinder ( r = magnet_radius , h = MAGNET_HOLE_DEPTH * 2 , center = true ) ;
cylinder ( r = magnet_radius - ( h_base + 0.1 - MAGNET_HOLE_DEPTH ) , h = ( h_base + 0.1 ) * 2 , center = true ) ;
2022-09-18 23:29:27 +00:00
}
if ( half )
mirror ( [ 0 , 0 , 1 ] )
2024-04-30 02:54:25 +00:00
cylinder ( r = magnet_radius * 2 , h = ( h_base + 0.1 ) * 4 ) ;
2022-09-18 23:29:27 +00:00
}
}
module block_base_blank ( o = 0 ) {
mirror ( [ 0 , 0 , 1 ] ) {
hull ( ) {
2024-05-02 04:26:54 +00:00
linear_extrude ( h_base )
2024-05-02 04:46:41 +00:00
rounded_square ( l_grid - o - 0.05 - 2 * r_c2 - 2 * r_c1 , r_fo3 , center = true ) ;
2024-05-02 04:26:54 +00:00
linear_extrude ( h_base - r_c1 )
2024-05-02 04:46:41 +00:00
rounded_square ( l_grid - o - 0.05 - 2 * r_c2 , r_fo2 , center = true ) ;
2022-09-18 23:29:27 +00:00
}
hull ( ) {
2024-05-02 04:26:54 +00:00
linear_extrude ( r_c2 )
2024-05-02 04:46:41 +00:00
rounded_square ( l_grid - o - 0.05 - 2 * r_c2 , r_fo2 , center = true ) ;
2022-09-18 23:29:27 +00:00
mirror ( [ 0 , 0 , 1 ] )
2024-05-02 04:26:54 +00:00
linear_extrude ( d_bottom )
2024-08-29 19:31:13 +00:00
rounded_square ( l_grid - o - 0.05 , BASE_OUTSIDE_RADIUS , center = true ) ;
2022-09-18 23:29:27 +00:00
}
}
}
2024-04-30 02:48:08 +00:00
module block_pinch ( height_mm ) {
assert ( is_num ( height_mm ) ) ;
2023-09-22 06:11:23 +00:00
2024-04-30 02:48:08 +00:00
translate ( [ 0 , 0 , - h_base ] )
block_wall ( gridx , gridy , l_grid ) {
2022-09-18 23:29:27 +00:00
translate ( [ d_wall2 - nozzle * 2 - d_clear * 2 , 0 , 0 ] )
2024-04-30 02:48:08 +00:00
profile_wall ( height_mm ) ;
2022-09-18 23:29:27 +00:00
}
}
module block_tabsupport ( ) {
intersection ( ) {
translate ( [ 0 , 0 , 0.1 ] )
block_vase ( d_height * 4 ) ;
2023-09-22 06:11:23 +00:00
2023-05-31 15:46:30 +00:00
cube ( [ nozzle * 2 , gridy * l_grid , d_height * 3 ] , center = true ) ;
2023-09-22 06:11:23 +00:00
2023-05-31 15:46:30 +00:00
transform_vtab_base ( gridx * l_grid * 2 )
2022-09-18 23:29:27 +00:00
block_tab_base ( - nozzle * sqrt ( 2 ) ) ;
}
}
module block_divider ( ) {
difference ( ) {
intersection ( ) {
translate ( [ 0 , 0 , 0.1 ] )
block_vase ( ) ;
2023-05-31 15:46:30 +00:00
cube ( [ nozzle * 2 , gridy * l_grid , d_height * 2 ] , center = true ) ;
2022-09-18 23:29:27 +00:00
}
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
if ( n_st = = 0 ) block_tab ( 0.1 ) ;
else block_divider_edgecut ( ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// cut divider clearance on negative Y side
2023-05-31 15:46:30 +00:00
translate ( [ - gridx * l_grid / 2 , - ( gridy * l_grid / 2 - 0.25 ) , 0 ] )
cube ( [ gridx * l_grid , nozzle * 2 + 0.1 , d_height * 2 ] ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// cut divider clearance on positive Y side
mirror ( [ 0 , 1 , 0 ] )
if ( enable_scoop_chamfer )
2023-05-31 15:46:30 +00:00
translate ( [ - gridx * l_grid / 2 , - ( gridy * l_grid / 2 - 0.25 ) , 0 ] )
cube ( [ gridx * l_grid , d_wall2 + 0.1 , d_height * 2 ] ) ;
2022-09-18 23:29:27 +00:00
else block_divider_edgecut ( ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// cut divider to have clearance with scoop
if ( enable_scoop_chamfer )
2023-09-22 06:11:23 +00:00
transform_scoop ( )
2022-09-18 23:29:27 +00:00
offset ( delta = 0.1 )
polygon ( [
[ 0 , 0 ] ,
[ d_ramp , d_ramp ] ,
[ d_ramp , d_ramp + nozzle / sqrt ( 2 ) ] ,
[ - nozzle / sqrt ( 2 ) , 0 ]
] ) ;
}
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// divider slices
difference ( ) {
2022-10-03 00:35:03 +00:00
for ( i = [ 0 : ( d_height - d_bottom ) / ( layer ) ] ) {
2023-09-22 06:11:23 +00:00
2022-10-03 00:35:03 +00:00
if ( 2 * i * layer < d_height - layer / 2 - d_bottom - 0.1 )
2022-09-18 23:29:27 +00:00
mirror ( [ 0 , 1 , 0 ] )
2023-05-31 15:46:30 +00:00
translate ( [ 0 , ( gridy * l_grid / 2 - 0.25 - nozzle ) / 2 , layer / 2 + d_bottom + 2 * i * layer ] )
cube ( [ nozzle * 2 - 0.01 , gridy * l_grid / 2 - 0.25 - nozzle , layer ] , center = true ) ;
2022-09-18 23:29:27 +00:00
2022-10-03 00:35:03 +00:00
if ( ( 2 * i + 1 ) * layer < d_height - layer / 2 - d_bottom - 0.1 )
2023-05-31 15:46:30 +00:00
translate ( [ 0 , ( gridy * l_grid / 2 - 0.25 - nozzle ) / 2 , layer / 2 + d_bottom + ( 2 * i + 1 ) * layer ] )
cube ( [ nozzle * 2 - 0.01 , gridy * l_grid / 2 - 0.25 - nozzle , layer ] , center = true ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
}
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// divider slices cut to tabs
if ( n_st = = 0 )
transform_style ( )
2024-02-16 21:01:40 +00:00
transform_vtab_base ( ( n_st < 2 ? gridx * l_grid / n_x - 0.5 - d_fo1 : d_tabw ) - nozzle * 4 )
2022-09-18 23:29:27 +00:00
block_tab_base ( - nozzle * sqrt ( 2 ) ) ;
}
}
module block_divider_edgecut ( ) {
2023-05-31 15:46:30 +00:00
translate ( [ - 50 , - gridy * l_grid / 2 + 0.25 , 0 ] )
2022-09-18 23:29:27 +00:00
rotate ( [ 90 , 0 , 90 ] )
linear_extrude ( 100 )
offset ( delta = 0.1 )
2024-04-30 02:48:08 +00:00
mirror ( [ 1 , 0 , 0 ] )
translate ( [ - r_base , 0 , 0 ] )
profile_wall ( $ dh ) ;
2022-09-18 23:29:27 +00:00
}
module transform_funnel ( ) {
2023-02-14 23:20:16 +00:00
if ( me > 6 && enable_funnel && gridz > 3 && n_st ! = 6 )
2022-09-18 23:29:27 +00:00
transform_style ( )
render ( )
children ( ) ;
}
module block_funnel_inside ( ) {
intersection ( ) {
block_tabscoop ( m - nozzle * 3 * sqrt ( 2 ) , 0.003 , nozzle * 2 , 0.01 ) ;
block_tab ( 0.1 ) ;
}
}
module block_funnel_outside ( ) {
intersection ( ) {
difference ( ) {
block_tabscoop ( m , 0 , 0 , 0 ) ;
block_tabscoop ( m - nozzle * 4 * sqrt ( 2 ) , 0.003 , nozzle * 2 , - 1 ) ;
}
block_tab ( - nozzle * sqrt ( 2 ) / 2 ) ;
}
}
module block_vase_base ( ) {
difference ( ) {
// base
translate ( [ 0 , 0 , - h_base ] ) {
translate ( [ 0 , 0 , - 0.1 ] )
2023-09-22 06:11:23 +00:00
color ( "firebrick" )
2023-05-31 15:46:30 +00:00
block_bottom ( d_bottom , gridx , gridy , l_grid ) ;
2023-09-22 06:11:23 +00:00
color ( "royalblue" )
2023-05-31 15:46:30 +00:00
block_wall ( gridx , gridy , l_grid ) {
2024-04-30 02:48:08 +00:00
if ( enable_lip ) profile_wall ( $ dh ) ;
else profile_wall2 ( $ dh ) ;
2023-09-22 06:11:23 +00:00
}
2022-09-18 23:29:27 +00:00
}
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// magic slice
rotate ( [ 0 , 0 , 90 ] )
mirror ( [ 0 , 1 , 0 ] )
2022-10-03 00:35:03 +00:00
translate ( [ 0 , 0 , d_bottom + 0.001 ] )
2023-05-31 15:46:30 +00:00
cube ( [ 0.001 , l_grid * gridx , d_height + d_bottom * 2 ] ) ;
2022-09-18 23:29:27 +00:00
}
// scoop piece
2023-09-22 06:11:23 +00:00
if ( enable_scoop_chamfer )
transform_scoop ( )
2022-09-18 23:29:27 +00:00
polygon ( [
[ 0 , 0 ] ,
[ d_ramp , d_ramp ] ,
[ d_ramp , d_ramp + 0.6 / sqrt ( 2 ) ] ,
[ - 0.6 / sqrt ( 2 ) , 0 ]
] ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
// outside tab cutter
if ( n_st ! = 6 )
translate ( [ - ( n_x - 1 ) * spacing / 2 , 0 , 0 ] )
for ( i = [ 1 : n_x ] )
2023-09-22 06:11:23 +00:00
translate ( [ ( i - 1 ) * spacing , 0 , 0 ] )
2022-09-18 23:29:27 +00:00
translate ( [ shiftauto ( i , n_x ) * d_edge + shift * d_edge , 0 , 0 ] )
intersection ( ) {
block_vase ( ) ;
2024-02-16 21:01:40 +00:00
transform_vtab_base ( n_st < 2 ? gridx * l_grid / n_x - 0.5 - d_fo1 : d_tabw )
2022-09-18 23:29:27 +00:00
profile_tab ( ) ;
}
}
module block_inset ( ) {
2023-05-31 15:46:30 +00:00
ixx = ( gridx * l_grid - 0.5 ) / 2 ;
2024-05-07 03:09:57 +00:00
iyy = d_height / 2.1 ;
2022-09-18 23:29:27 +00:00
izz = sqrt ( ixx ^ 2 + iyy ^ 2 ) * tan ( 40 ) ;
if ( enable_scoop_chamfer && enable_inset )
difference ( ) {
intersection ( ) {
rotate ( [ 0 , 90 , 0 ] )
2023-02-06 06:16:23 +00:00
translate ( [ - iyy , 0 , 0 ] )
2023-05-31 15:46:30 +00:00
block_inset_sub ( iyy , gridx * l_grid , 45 ) ;
2022-09-18 23:29:27 +00:00
rotate ( [ 0 , 90 , 0 ] )
2023-02-06 06:16:23 +00:00
translate ( [ - iyy , 0 , 0 ] )
2022-09-18 23:29:27 +00:00
rotate ( [ 0 , 90 , 0 ] )
block_inset_sub ( ixx , d_height * 2 , 45 ) ;
}
mirror ( [ 0 , 1 , 0 ] )
2023-05-31 15:46:30 +00:00
translate ( [ - gridx * l_grid / 2 , - ( gridy * l_grid - 0.5 ) / 2 + d_wall2 - 2 * nozzle , 0 ] )
cube ( [ gridx * l_grid , izz , d_height * 2 ] ) ;
2022-09-18 23:29:27 +00:00
}
}
2023-09-22 06:11:23 +00:00
module block_inset_sub ( x , y , ang ) {
2024-02-16 21:01:40 +00:00
translate ( [ 0 , ( gridy * l_grid - 0.5 ) / 2 + r_fo1 , 0 ] )
2022-09-18 23:29:27 +00:00
mirror ( [ 0 , 1 , 0 ] )
linear_extrude ( y , center = true )
polygon ( [ [ - x , 0 ] , [ x , 0 ] , [ 0 , x * tan ( ang ) ] ] ) ;
}
module transform_style ( ) {
translate ( [ - ( n_x - 1 ) * spacing / 2 , 0 , 0 ] )
for ( i = [ 1 : n_x ] )
translate ( [ ( i - 1 ) * spacing , 0 , 0 ] )
translate ( [ shiftauto ( i , n_x ) * d_edge + shift * d_edge , 0 , 0 ] )
children ( ) ;
}
module block_flushscoop ( ) {
2023-05-31 15:46:30 +00:00
translate ( [ 0 , gridy * l_grid / 2 - d_wall2 - nozzle / 2 - 1 , d_height / 2 ] )
2022-09-18 23:29:27 +00:00
linear_extrude ( d_height )
union ( ) {
copy_mirror ( [ 1 , 0 , 0 ] )
2024-02-16 21:01:40 +00:00
polygon ( [ [ 0 , 0 ] , [ gridx * l_grid / 2 - r_fo1 , 0 ] , [ gridx * l_grid / 2 - r_fo1 , 1 ] , [ gridx * l_grid / 2 - r_fo1 - r_c1 * 5 , d_wall2 - nozzle * 2 + 1 ] , [ 0 , d_wall2 - nozzle * 2 + 1 ] ] ) ;
2022-09-18 23:29:27 +00:00
}
2023-09-22 06:11:23 +00:00
transform_scoop ( )
2022-09-18 23:29:27 +00:00
polygon ( [ [ 0 , 0 ] , [ d_ramp , 0 ] , [ d_ramp , d_ramp ] ] ) ;
}
module profile_tab ( ) {
union ( ) {
copy_mirror ( [ 0 , 1 , 0 ] )
polygon ( [ [ 0 , 0 ] , [ d_tabh * cos ( a_tab ) , 0 ] , [ d_tabh * cos ( a_tab ) , d_tabh * sin ( a_tab ) ] ] ) ;
}
}
module profile_tabscoop ( m ) {
polyhedron ( [ [ m / 2 , 0 , 0 ] , [ 0 , - m , 0 ] , [ - m / 2 , 0 , 0 ] , [ 0 , 0 , m ] ] , [ [ 0 , 2 , 1 ] , [ 1 , 2 , 3 ] , [ 0 , 1 , 3 ] , [ 0 , 3 , 2 ] ] ) ;
}
module block_tabscoop ( a = m , b = 0 , c = 0 , d = - 1 ) {
2023-05-31 15:46:30 +00:00
translate ( [ 0 , d_tabh * cos ( a_tab ) - l_grid * gridy / 2 + 0.25 + b , 0 ] )
2022-09-18 23:29:27 +00:00
difference ( ) {
2023-02-06 06:16:23 +00:00
translate ( [ 0 , 0 , - d_tabh * sin ( a_tab ) * 2 + d_height + 2.1 ] )
2022-09-18 23:29:27 +00:00
profile_tabscoop ( a ) ;
2023-09-22 06:11:23 +00:00
2023-05-31 15:46:30 +00:00
translate ( [ - gridx * l_grid / 2 , - m , - m ] )
cube ( [ gridx * l_grid , m - d_tabh * cos ( a_tab ) + 0.005 + c , d_height * 20 ] ) ;
2023-09-22 06:11:23 +00:00
2022-09-18 23:29:27 +00:00
if ( d >= 0 )
2023-02-06 06:16:23 +00:00
translate ( [ 0 , 0 , - d_tabh * sin ( a_tab ) + d_height + m / 2 + d + 2.1 ] )
2023-05-31 15:46:30 +00:00
cube ( [ gridx * l_grid , gridy * l_grid , m ] , center = true ) ;
2022-09-18 23:29:27 +00:00
}
}
module transform_vtab ( a = 0 , b = 1 ) {
2024-02-16 21:01:40 +00:00
transform_vtab_base ( gridx * l_grid / b - 0.5 - d_fo1 + a )
2022-09-18 23:29:27 +00:00
children ( ) ;
}
module transform_vtab_base ( a ) {
2023-05-31 15:46:30 +00:00
translate ( [ 0 , d_tabh * cos ( a_tab ) - l_grid * gridy / 2 + 0.25 , - d_tabh * sin ( a_tab ) + d_height + 2.1 ] )
2022-09-18 23:29:27 +00:00
rotate ( [ 90 , 0 , 270 ] )
linear_extrude ( a , center = true )
children ( ) ;
}
module block_tab ( del , b = 1 ) {
transform_vtab ( - nozzle * 4 , b )
block_tab_base ( del ) ;
}
module block_tab_base ( del ) {
offset ( delta = del )
union ( ) {
profile_tab ( ) ;
translate ( [ d_tabh * cos ( a_tab ) , - d_tabh * sin ( a_tab ) , 0 ] )
2023-05-31 15:46:30 +00:00
square ( [ l_grid , d_tabh * sin ( a_tab ) * 2 ] ) ;
2022-09-18 23:29:27 +00:00
}
}
module transform_scoop ( ) {
intersection ( ) {
block_vase ( ) ;
2023-05-31 15:46:30 +00:00
translate ( [ 0 , gridy * l_grid / 2 - d_ramp , layer * max ( bottom_layer * 1 ) ] )
2022-09-18 23:29:27 +00:00
rotate ( [ 90 , 0 , 90 ] )
2023-05-31 15:46:30 +00:00
linear_extrude ( 2 * l_grid * gridx , center = true )
2022-09-18 23:29:27 +00:00
children ( ) ;
}
}
module block_vase ( h = d_height * 2 ) {
translate ( [ 0 , 0 , - 0.1 ] )
2024-05-02 04:46:41 +00:00
rounded_square ( [ gridx * l_grid - 0.5 - nozzle , gridy * l_grid - 0.5 - nozzle , h ] , r_base + 0.01 - nozzle / 2 , center = true ) ;
2022-09-18 23:29:27 +00:00
}
module profile_x ( x_f = 3 ) {
difference ( ) {
square ( [ x_l , x_l ] , center = true ) ;
pattern_circular ( 4 )
translate ( [ 0 , nozzle * sqrt ( 2 ) , 0 ] )
rotate ( [ 0 , 0 , 45 ] )
translate ( [ x_f , x_f , 0 ] )
minkowski ( ) {
square ( [ x_l , x_l ] ) ;
circle ( x_f ) ;
}
}
}
module block_x ( ) {
2023-05-31 15:46:30 +00:00
translate ( [ - ( gridx - 1 ) * l_grid / 2 , - ( gridy - 1 ) * l_grid / 2 , 0 ] )
2022-09-18 23:29:27 +00:00
for ( i = [ 1 : gridx ] )
for ( j = [ 1 : gridy ] )
if ( xFunc [ style_base ] ( i , j ) )
2023-05-31 15:46:30 +00:00
translate ( [ ( i - 1 ) * l_grid , ( j - 1 ) * l_grid , 0 ] )
2022-09-18 23:29:27 +00:00
block_x_sub ( ) ;
}
module block_x_sub ( ) {
2022-10-03 00:35:03 +00:00
linear_extrude ( d_bottom * 2 + 0.01 , center = true )
2022-09-18 23:29:27 +00:00
offset ( 0.05 )
profile_x ( ) ;
}