From 046ed3067cb0be4264301b4fac4c8304e01f4106 Mon Sep 17 00:00:00 2001 From: Stephen Kent Date: Thu, 21 Sep 2023 23:11:23 -0700 Subject: [PATCH] Add whitespace fixes generated by pre-commit --- .gitignore | 2 +- LICENSE | 2 +- README.md | 8 +- docs/baseplates.md | 8 +- docs/bins.md | 38 +++---- docs/constants.md | 14 +-- docs/index.md | 12 +-- docs/lite.md | 18 ++-- docs/vase.md | 34 +++---- gridfinity-rebuilt-baseplate.scad | 46 ++++----- gridfinity-rebuilt-bins.scad | 30 +++--- gridfinity-rebuilt-lite.scad | 14 +-- gridfinity-rebuilt-utility.scad | 161 +++++++++++++++--------------- gridfinity-spiral-vase.scad | 112 ++++++++++----------- standard.scad | 54 +++++----- 15 files changed, 276 insertions(+), 277 deletions(-) diff --git a/.gitignore b/.gitignore index 3d77328..a3b8146 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ gridfinity-rebuilt-bins.json stl/ batch/ site/ -*.json \ No newline at end of file +*.json diff --git a/LICENSE b/LICENSE index 176d560..f290803 100644 --- a/LICENSE +++ b/LICENSE @@ -27,7 +27,7 @@ MIT License Copyright (c) 2023 Zachary Freedman and Voidstar Lab LLC -Permission is hereby granted, free of charge, to any person obtaining a copy +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell diff --git a/README.md b/README.md index 1165b22..b8fbfc7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Gridfinity Rebuilt in OpenSCAD +# Gridfinity Rebuilt in OpenSCAD [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -A ground-up port (with a few extra features) of the stock [gridfinity](https://www.youtube.com/watch?v=ra_9zU-mnl8) bins in OpenSCAD. Open to feedback, because I could not feasibly test all combinations of bins. I tried my best to exactly match the original gridfinity dimensions, but some of the geometry is slightly incorrect (mainly fillets). However, I think they are negligible differences, and will not appear in the printed model. +A ground-up port (with a few extra features) of the stock [gridfinity](https://www.youtube.com/watch?v=ra_9zU-mnl8) bins in OpenSCAD. Open to feedback, because I could not feasibly test all combinations of bins. I tried my best to exactly match the original gridfinity dimensions, but some of the geometry is slightly incorrect (mainly fillets). However, I think they are negligible differences, and will not appear in the printed model. Full documentation can be found at the project's [website](https://kennetek.github.io/gridfinity-rebuilt-openscad/). @@ -35,7 +35,7 @@ The printable holes allow your slicer to bridge the gap inside the countersunk m []() ## Recommendations -For best results, use a version of OpenSCAD with the fast-csg feature. As of writing, this feature is only implemented in the [development snapshots](https://openscad.org/downloads.html). To enable the feature, go to Edit > Preferences > Features > fast-csg. On my computer, this sped up rendering from 10 minutes down to a couple of seconds, even for comically large bins. +For best results, use a version of OpenSCAD with the fast-csg feature. As of writing, this feature is only implemented in the [development snapshots](https://openscad.org/downloads.html). To enable the feature, go to Edit > Preferences > Features > fast-csg. On my computer, this sped up rendering from 10 minutes down to a couple of seconds, even for comically large bins. ## Enjoy! @@ -43,7 +43,7 @@ For best results, use a version of OpenSCAD with the fast-csg feature. As of wri [Gridfinity](https://www.youtube.com/watch?v=ra_9zU-mnl8) by [Zack Freedman](https://www.youtube.com/c/ZackFreedman/about) -This work is licensed under the same license as Gridfinity, being a +This work is licensed under the same license as Gridfinity, being a [MIT License](https://opensource.org/licenses/MIT). [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) diff --git a/docs/baseplates.md b/docs/baseplates.md index dd81b0b..f788a30 100644 --- a/docs/baseplates.md +++ b/docs/baseplates.md @@ -15,7 +15,7 @@ distancex | { n>0 \| n∈R } | minimum length of baseplate along x
alternati distancey | { n>0 \| n∈R } | minimum length of baseplate along y
alternatively, how large is the drawer along y
(leave zero to ignore) fitx | { -1<=n<=1 \| n∈R } | alignment factor for extra space along x axis fity | { -1<=n<=1 \| n∈R } | alignment factor for extra space along y axis -style_plate | { 0, 1, 2 } | the style of baseplate
• (0) thin (minimum material, only outline)
• (1) weighted (thick with space for tire iron)
• (2) skeletonized (thick, center hollowed) +style_plate | { 0, 1, 2 } | the style of baseplate
• (0) thin (minimum material, only outline)
• (1) weighted (thick with space for tire iron)
• (2) skeletonized (thick, center hollowed) enable_magnet | boolean | toggle hole for magnet on top style_hole | { 0, 1, 2 } | the style of holes underneath the baseplate, if applicable
• (0) none
• (1) countersink
• (2) counterbore @@ -23,7 +23,7 @@ style_hole | { 0, 1, 2 } | the style of holes underneath the baseplate, if appli ### gridfinityBaseplate -Generates a baseplate to use with gridfinity bins. +Generates a baseplate to use with gridfinity bins. ** `gridfinityBaseplate(gridx, gridy, length, distancex, distancey, style_plate, enable_magnet, style_hole)` ** @@ -36,6 +36,6 @@ distancex | { n>0 \| n∈R } | minimum length of baseplate along x
alternati distancey | { n>0 \| n∈R } | minimum length of baseplate along y
alternatively, how large is the drawer along y
(leave zero to ignore) fitx | { -1<=n<=1 \| n∈R } | alignment factor for extra space along x axis fity | { -1<=n<=1 \| n∈R } | alignment factor for extra space along y axis -style_plate | { 0, 1, 2 } | the style of baseplate
• (0) thin (minimum material, only outline)
• (1) weighted (thick with space for tire iron)
• (2) skeletonized (thick, center hollowed) +style_plate | { 0, 1, 2 } | the style of baseplate
• (0) thin (minimum material, only outline)
• (1) weighted (thick with space for tire iron)
• (2) skeletonized (thick, center hollowed) enable_magnet | boolean | toggle hole for magnet on top -style_hole | { 0, 1, 2 } | the style of holes underneath the baseplate, if applicable
• (0) none
• (1) countersink
• (2) counterbore \ No newline at end of file +style_hole | { 0, 1, 2 } | the style of holes underneath the baseplate, if applicable
• (0) none
• (1) countersink
• (2) counterbore diff --git a/docs/bins.md b/docs/bins.md index eca02a1..f75ae73 100644 --- a/docs/bins.md +++ b/docs/bins.md @@ -1,6 +1,6 @@ # gridfinity-rebuilt-bins -Generates stock bins, with a great number of variations. +Generates stock bins, with a great number of variations. ![Bin](images/custom_dimension.gif) @@ -8,13 +8,13 @@ Generates stock bins, with a great number of variations. Parameter | Range | Description --- | ----- | --- -gridx | { n>0 \| n∈R } | number of bases along the x-axis -gridy | { n>0 \| n∈R } | number of bases along the y-axis -gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. +gridx | { n>0 \| n∈R } | number of bases along the x-axis +gridy | { n>0 \| n∈R } | number of bases along the y-axis +gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. length | { n>0 \| n∈R } | length of one unit of the base.
default: 42 (The Answer to the Ultimate Question of Life,
the Universe, and Everything.) divx | { n>0 \| n∈Z } | number of compartments along X divy | { n>0 \| n∈Z } | number of compartments along Y -scoop | n>0 \| n∈R | controls the fillet on the bottom of the compartment for easy
item removal. 0 is disabled, 1 is full, any other real number will
scale from full. +scoop | n>0 \| n∈R | controls the fillet on the bottom of the compartment for easy
item removal. 0 is disabled, 1 is full, any other real number will
scale from full. enable_zsnap | boolean | automatically snap the bin size to the nearest 7mm increment.
default: true style_lip | {0, 1, 2} | if you are not stacking the bin, you can disable the top lip
to save space.
• (0) Regular lip
• (1) Subtract lip to save space
• (2) Disable lip while retaining height gridz_define | { n>0 \| n∈R } | determine what the variable "gridz" applies to based on
your use case. default: 0.
• (0) gridz is the height in # of 7mm increments (Zack)
• (1) gridz is the internal height in millimeters
• (2) gridz is the overall external height of the bin in millimeters @@ -32,14 +32,14 @@ div_base_y | { n>=0 \| n∈Z } | number of divisions per 1 unit of base along th ### gridfinityInit -Initializes the top part of the bin (walls and solid section). All bins have to use this module, and have the compartments cut out from it. +Initializes the top part of the bin (walls and solid section). All bins have to use this module, and have the compartments cut out from it. ** `gridfinityInit (gridx, gridy, height, height_internal, length)` ** Parameter | Range | Description --- | ----- | --- -gridx | { n>0 \| n∈R } | number of bases along the x-axis -gridy | { n>0 \| n∈R } | number of bases along the y-axis +gridx | { n>0 \| n∈R } | number of bases along the x-axis +gridy | { n>0 \| n∈R } | number of bases along the y-axis height | { n>0 \| n∈R } | height of the bin, in millimeters (but not exactly).
See the `height()` function for more info. height_internal | { n>0 \| n∈R } | height of the internal block.
Can be lower than bin height to save filament on custom bins.
default of 0 means use the calculated height. length | { n>0 \| n∈R } | length of one unit of the base.
default: 42 (The Answer to the Ultimate Question of Life,
the Universe, and Everything.) @@ -55,13 +55,13 @@ gridfinityInit(3, 3, height(6), 0, 42) { ### height -Calculates the proper height for bins. - +Calculates the proper height for bins. + ** `height (gridz, gridz_define, style_lip, enable_zsnap)` ** Parameter | Range | Description --- | ----- | --- -gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. +gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. gridz_define | { n>0 \| n∈R } | determine what the variable "gridz" applies to based on
your use case. default: 0.
• (0) gridz is the height in # of 7mm increments (Zack)
• (1) gridz is the internal height in millimeters
• (2) gridz is the overall external height of the bin in millimeters style_lip | {0, 1, 2} | if you are not stacking the bin, you can disable the top lip
to save space.
• (0) Regular lip
• (1) Subtract lip to save space
• (2) Disable lip while retaining height enable_zsnap | boolean | automatically snap the bin size to the nearest 7mm increment.
default: true @@ -71,12 +71,12 @@ enable_zsnap | boolean | automatically snap the bin size to the nearest 7mm incr height(6); // Example: height for a bin that can fit (at maximum) a 30mm high object inside -height(30, 1, 0, false); +height(30, 1, 0, false); ``` --- -### gridfinityBase +### gridfinityBase Generates the bases for bins. Has various different hole styles, and can be subdivided. @@ -84,8 +84,8 @@ Generates the bases for bins. Has various different hole styles, and can be subd Parameter | Range | Description --- | ----- | --- -gridx | { n>0 \| n∈R } | number of bases along the x-axis -gridy | { n>0 \| n∈R } | number of bases along the y-axis +gridx | { n>0 \| n∈R } | number of bases along the x-axis +gridy | { n>0 \| n∈R } | number of bases along the y-axis length | { n>0 \| n∈R } | length of one unit of the base. default: 42 div_base_x | { n>=0 \| n∈Z } | number of divisions per 1 unit of base along the X axis.
(default 1, only use integers. 0 means automatically guess the division) div_base_y | { n>=0 \| n∈Z } | number of divisions per 1 unit of base along the Y axis.
(default 1, only use integers. 0 means automatically guess the division) @@ -100,7 +100,7 @@ gridfinityBase(3, 3, 42, 0, 0, 1); ### cutEqual -Generates the "traditional" bin cutters. It is a utility function that creates evenly distributed compartments. +Generates the "traditional" bin cutters. It is a utility function that creates evenly distributed compartments. ** `cutEqual (n_divx, n_divy, style_tab, scoop_weight)` ** @@ -137,8 +137,8 @@ s | n>0 \| n∈R | controls the fillet on the bottom of the compartment for easy ``` // Example: -// this cuts two compartments that are both 1 wide and 2 high. -// One is on the bottom left, and the other is at the top right. +// this cuts two compartments that are both 1 wide and 2 high. +// One is on the bottom left, and the other is at the top right. gridfinityInit(3, 3, height(6), 0, 42) { cut(0, 0, 1, 2, 0, 1); cut(2, 1, 1, 2, 0, 1); @@ -169,4 +169,4 @@ gridfinityInit(3, 3, height(6), 0, 42) { cylinder(r=5, h=100, center=true); } } -``` \ No newline at end of file +``` diff --git a/docs/constants.md b/docs/constants.md index 7df2420..3c69989 100644 --- a/docs/constants.md +++ b/docs/constants.md @@ -1,6 +1,6 @@ # gridfinity-rebuilt-constants -This file contains dimensions that are critical to the constructiuon of the other models, but are not values that often need to be changed. Thus, they were outsourced to this file such that the rest of the files would retain parity. All values here have the same range, this is positive real numbers. Some can be zero, but that may result in strange or invalid geometry, +This file contains dimensions that are critical to the constructiuon of the other models, but are not values that often need to be changed. Thus, they were outsourced to this file such that the rest of the files would retain parity. All values here have the same range, this is positive real numbers. Some can be zero, but that may result in strange or invalid geometry, Parameter | Description --- | ------ @@ -19,12 +19,12 @@ h_hole| magnet hole depth h_slit| slit depth (printer layer height) r_f1| top edge fillet radius r_f2 | internal fillet radius -d_div | width of divider between compartments +d_div | width of divider between compartments d_wall| minimum wall thickness -d_clear| tolerance fit factor -d_tabh| height of tab (yaxis, measured from inner wall) -d_tabw| maximum width of tab -a_tab| angle of tab +d_clear| tolerance fit factor +d_tabh| height of tab (yaxis, measured from inner wall) +d_tabw| maximum width of tab +a_tab| angle of tab bp_h_bot| Baseplate bottom part height (part added with weigthed=true) bp_cut_size| Baseplate bottom cutout rectangle size bp_cut_depth| Baseplate bottom cutout rectangle depth @@ -35,4 +35,4 @@ d_cs | countersink diameter for baseplate r_skel| radius of cutout for skeletonized baseplate r_cb| baseplate counterbore radius h_cb| baseplate counterbore depth -h_skel | minimum baseplate thickness (when skeletonized) \ No newline at end of file +h_skel | minimum baseplate thickness (when skeletonized) diff --git a/docs/index.md b/docs/index.md index 04f729f..4df6b60 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,14 +1,14 @@ ## Introduction -Gridfinity rebuilt aims to remake the brilliant Gridfinity project from [Zack Freedman](https://www.youtube.com/c/ZackFreedman/about) in a more robust and open-source way than the original Fusion 360 files. Many major CAD suites struggle with making parametric models constructed from linear patterns, due to changing fillet edges and seams. Thus, a pure mathematical approach using OpenSCAD can allow a single solution for all possible bin variants. +Gridfinity rebuilt aims to remake the brilliant Gridfinity project from [Zack Freedman](https://www.youtube.com/c/ZackFreedman/about) in a more robust and open-source way than the original Fusion 360 files. Many major CAD suites struggle with making parametric models constructed from linear patterns, due to changing fillet edges and seams. Thus, a pure mathematical approach using OpenSCAD can allow a single solution for all possible bin variants. -The project has expanded into more eccentric models that use modules from the original generator. This wiki aims to document these modules in great detail. +The project has expanded into more eccentric models that use modules from the original generator. This wiki aims to document these modules in great detail. -Models are generated subtractively. First, the solid bin and bases are constructed, and then the compartments and holes are removed. This allows for internal fillets that nearly match the originals. However, they are not exactly perfect. There are some fillets that are too small and too difficult to be worth implementing, as most printers do not have a high enough resolution for it to matter. +Models are generated subtractively. First, the solid bin and bases are constructed, and then the compartments and holes are removed. This allows for internal fillets that nearly match the originals. However, they are not exactly perfect. There are some fillets that are too small and too difficult to be worth implementing, as most printers do not have a high enough resolution for it to matter. ## Getting Started -For best results, use a version of OpenSCAD with the fast-csg feature. As of writing, this feature is only implemented in the [development snapshots](https://openscad.org/downloads.html). To enable the feature, go to Edit > Preferences > Features > fast-csg. This can speed up rendering from 10 minutes down to a couple of seconds, even for comically large bins. It is not a requirement to use development versions of OpenSCAD. +For best results, use a version of OpenSCAD with the fast-csg feature. As of writing, this feature is only implemented in the [development snapshots](https://openscad.org/downloads.html). To enable the feature, go to Edit > Preferences > Features > fast-csg. This can speed up rendering from 10 minutes down to a couple of seconds, even for comically large bins. It is not a requirement to use development versions of OpenSCAD. -Most files will come ready-to-run, so parameters can be changed using OpenSCAD's built-in customizer window, and the bins will automatically generate. However, all modules are packed up nicely, so any module can be imported into other files or have more custom modifications beyond tweaking the parameters. +Most files will come ready-to-run, so parameters can be changed using OpenSCAD's built-in customizer window, and the bins will automatically generate. However, all modules are packed up nicely, so any module can be imported into other files or have more custom modifications beyond tweaking the parameters. ## Script Structure * Information (Imports / Script Details) @@ -17,6 +17,6 @@ Most files will come ready-to-run, so parameters can be changed using OpenSCAD's * Construction (Script-Specific Modules and Constants) * Examples -The two files which do not follow these conventions are `gridfinity-rebuilt-utility` and `gridfinity-rebuilt-constants`. These files are not meant to be exposed to the user, except for special requirements that the normal parameters cannot handle. Their respective wiki pages go into more depth. +The two files which do not follow these conventions are `gridfinity-rebuilt-utility` and `gridfinity-rebuilt-constants`. These files are not meant to be exposed to the user, except for special requirements that the normal parameters cannot handle. Their respective wiki pages go into more depth. **NOTE: This documentation is a work in progress, just like the rest of the repository, so parts may still be under construction.** diff --git a/docs/lite.md b/docs/lite.md index 7269ce1..c59aa1f 100644 --- a/docs/lite.md +++ b/docs/lite.md @@ -1,6 +1,6 @@ # gridfinity-rebuilt-lite -Generates stock bins, but with a twist: the bases are hollow. This is unable to be implemented directly into `gridfinity-rebuilt-bins` due to its surprisingly complex construction. It couldn't be a toggle without causing the structure of the script to fundamentally change (and become more complex) so it was moved to a separate file. Notably, there are some parameters missing, as they are incompatible with the lite variation. Additionally, the complex geometry means rendering is fairly slow, and currently causes many CSG errors. +Generates stock bins, but with a twist: the bases are hollow. This is unable to be implemented directly into `gridfinity-rebuilt-bins` due to its surprisingly complex construction. It couldn't be a toggle without causing the structure of the script to fundamentally change (and become more complex) so it was moved to a separate file. Notably, there are some parameters missing, as they are incompatible with the lite variation. Additionally, the complex geometry means rendering is fairly slow, and currently causes many CSG errors. ![Bin](images/lite.gif) @@ -8,9 +8,9 @@ Generates stock bins, but with a twist: the bases are hollow. This is unable to Parameter | Range | Description --- | ----- | --- -gridx | { n>0 \| n∈R } | number of bases along the x-axis -gridy | { n>0 \| n∈R } | number of bases along the y-axis -gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. +gridx | { n>0 \| n∈R } | number of bases along the x-axis +gridy | { n>0 \| n∈R } | number of bases along the y-axis +gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. length | { n>0 \| n∈R } | length of one unit of the base.
default: 42 (The Answer to the Ultimate Question of Life,
the Universe, and Everything.) divx | { n>0 \| n∈Z } | number of compartments along X divy | { n>0 \| n∈Z } | number of compartments along Y @@ -30,15 +30,15 @@ div_base_y | { n>=0 \| n∈Z } | number of divisions per 1 unit of base along th ### gridfinityLite -Wrapper function that calls [`gridfinityInit`](bins.md#gridfinityInit) and [`gridfinityBase`](bins.md#gridfinityBase) functions (hence the sheer quantity of parameters). Like [`gridfinityInit`](bins.md#gridfinityInit), it uses its children as cutters for the compartments. +Wrapper function that calls [`gridfinityInit`](bins.md#gridfinityInit) and [`gridfinityBase`](bins.md#gridfinityBase) functions (hence the sheer quantity of parameters). Like [`gridfinityInit`](bins.md#gridfinityInit), it uses its children as cutters for the compartments. **`gridfinityLite(gridx, gridy, gridz, gridz_define, enable_lip, enable_zsnap, length, div_base_x, div_base_y, style_hole)`** Parameter | Range | Description --- | ----- | --- -gridx | { n>0 \| n∈R } | number of bases along the x-axis -gridy | { n>0 \| n∈R } | number of bases along the y-axis -gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. +gridx | { n>0 \| n∈R } | number of bases along the x-axis +gridy | { n>0 \| n∈R } | number of bases along the y-axis +gridz | { n>0 \| n∈R } | bin height. See bin height information and "gridz_define" below. gridz_define | { n>0 \| n∈R } | determine what the variable "gridz" applies to based on
your use case. default: 0.
• (0) gridz is the height in # of 7mm increments (Zack)
• (1) gridz is the internal height in millimeters
• (2) gridz is the overall external height of the bin in millimeters style_lip | {0, 1, 2} | if you are not stacking the bin, you can disable the top lip
to save space.
• (0) Regular lip
• (1) Subtract lip to save space
• (2) Disable lip while retaining height enable_zsnap | boolean | automatically snap the bin size to the nearest 7mm increment.
default: true @@ -52,4 +52,4 @@ style_hole | { 0, 1, 2, 3 } | the style of holes in the bases
• (0) N gridfinityLite(gridx=3, gridy=3, gridz=6, gridz_define=0, enable_lip=true, enable_zsnap=false, length=42, div_base_x=0, div_base_y=0, style_hole=1) { cutEqual(n_divx=2, n_divy=2, style_tab=1, enable_scoop = false); } -``` \ No newline at end of file +``` diff --git a/docs/vase.md b/docs/vase.md index f10e677..80ba0a5 100644 --- a/docs/vase.md +++ b/docs/vase.md @@ -1,7 +1,7 @@ # gridfinity-spiral-vase Some assembly required! -Adaptation of Gridfinity bins to work with spiral vase mode, as to save filament and print time. A big drawback of using vase mode for Gridfinity bins was that they would be very flimsy, and would lack the features that make Gridfinity such a good organizational tool. The goal of this implementation was to maintain the design philosophy while working under the constraints of vase mode. +Adaptation of Gridfinity bins to work with spiral vase mode, as to save filament and print time. A big drawback of using vase mode for Gridfinity bins was that they would be very flimsy, and would lack the features that make Gridfinity such a good organizational tool. The goal of this implementation was to maintain the design philosophy while working under the constraints of vase mode. ![Bin](images/vase_dividers.gif) ![Bin](images/vase_base.gif) @@ -9,19 +9,19 @@ Adaptation of Gridfinity bins to work with spiral vase mode, as to save filament ## Instructions Normal Gridfinity is impossible to convert to vase mode due to the geometry of the bases, meaning most existing vase mode Gridfinity models are limited to 1x1 bins. How this script gets around the impossible is to use two separate pieces. **The bin and bases must be printed separately, and then glued together to form the final bin.** While this is slightly more work, there is an added bonus to this method, as for larger bins you may not need every single grid slot to have a base, you only really need them on the corners, or the edges, with some in the middle for support. Using less bases saves filament and print time. -All parameters are global. The customizer has descriptions for all parameters. It is **essential** that the section *Printer Settings* matches your preferred slicer's settings, otherwise the model will not slice correctly. Additionally, you have to turn on the spiral vase parameter in your slicer. If you do not know what vase mode is, [this](https://www.youtube.com/watch?v=HZSFoFYpBaA) is a helpful video. +All parameters are global. The customizer has descriptions for all parameters. It is **essential** that the section *Printer Settings* matches your preferred slicer's settings, otherwise the model will not slice correctly. Additionally, you have to turn on the spiral vase parameter in your slicer. If you do not know what vase mode is, [this](https://www.youtube.com/watch?v=HZSFoFYpBaA) is a helpful video. 1. Change the *Printer Settings* parameters to match your slicer and printer settings. -2. Run the `gridfinityVaseBase()` module. This will generate a single spiral-capable base. Export as an STL file. You will need to print multiple of these, so it recommended to fill a base plate with them using the "complete individual objects" option (or equivilant) in your slicer. You only need to do this step initially, and then each time your printer settings change afterwards. -3. Change the bin parameters and run `gridfinityVase()` module to generate the main bin. -4. Glue bases to the bottom of the bin. I recommend superglue on the corners and the top of the magnet holes. +2. Run the `gridfinityVaseBase()` module. This will generate a single spiral-capable base. Export as an STL file. You will need to print multiple of these, so it recommended to fill a base plate with them using the "complete individual objects" option (or equivilant) in your slicer. You only need to do this step initially, and then each time your printer settings change afterwards. +3. Change the bin parameters and run `gridfinityVase()` module to generate the main bin. +4. Glue bases to the bottom of the bin. I recommend superglue on the corners and the top of the magnet holes. How your sliced files should look (cross section shown for 1x1 bin): ![Bin](images/slicer_bin.png) ![Bin](images/slicer_base.png) -Example sliced files can be found on the [Printables](https://www.printables.com/model/284371-spiral-vase-gridfinity-in-openscad) page. +Example sliced files can be found on the [Printables](https://www.printables.com/model/284371-spiral-vase-gridfinity-in-openscad) page. ## Statistics Given how it has become a bit of a [challenge](https://www.printables.com/model/265271-gridfinity-lite-economical-plain-storage-bins) to reduce the weight and print time for these bins, here is a comparison for a large bin: @@ -32,7 +32,7 @@ Plain 4x2x6 Bin | 114.66g | 3h58m Vase 4x2x6 Bin with 8 Bases | 68.31g | 2h27m Vase 4x2x6 Bin with 4 Bases (only corners) | 56.43g | 1h59m -Clearly, vase mode is very quick and quite lightweight. However, this fundamentally means the bins will be weaker, so keep that in mind. +Clearly, vase mode is very quick and quite lightweight. However, this fundamentally means the bins will be weaker, so keep that in mind. ## Script Parameters @@ -42,9 +42,9 @@ type | { 0 , 1 } | generate the bin (0) or base (1) nozzle | { n>0 \| n∈R } | extrusion width in slicer layer | { n>0 \| n∈R } | size of layers in slicer bottom_layer | { n>0 \| n∈Z } | number of layers on the bottom of the print -gridx | { n>0 \| n∈R } | number of bases along the x-axis -gridy | { n>0 \| n∈R } | number of bases along the y-axis -gridz | { n>0 \| n∈R } | bin height. See bin height information and
"gridz_define" below. +gridx | { n>0 \| n∈R } | number of bases along the x-axis +gridy | { n>0 \| n∈R } | number of bases along the y-axis +gridz | { n>0 \| n∈R } | bin height. See bin height information and
"gridz_define" below. length | { n>0 \| n∈R } | length of one unit of the base.
default: 42 (The Answer to the Ultimate Question of
Life, the Universe, and Everything.) n_divx | { n>0 \| n∈Z } | number of compartments along X enable_holes | boolean | toggle holes inside the base @@ -52,24 +52,24 @@ enable_zsnap | boolean | automatically snap the bin size to the nearest
7mm enable_lip | boolean | if you are not stacking the bin, you can disable the
top lip to save space. default: true enable_scoop_chamfer | boolean | toggles the chamfer on bottom edge
for easy removal of items enable_funnel | boolean | toggles funnel on back of tab.
acts as a finger grip and pour spout for small parts. -enable_inset | boolean | toggles an inset on the front of the bin.
adds strength when using scoop. -enable_pinch | boolean | toggles an outside pinch at the top lip of the bin.
adds strength. +enable_inset | boolean | toggles an inset on the front of the bin.
adds strength when using scoop. +enable_pinch | boolean | toggles an outside pinch at the top lip of the bin.
adds strength. gridz_define | { n>0 \| n∈R } | determine what the variable "gridz" applies to based on
your use case. default: 0.
• (0) gridz is the height in # of 7mm increments (Zack)
• (1) gridz is the internal height in mm
• (2) gridz is the overall external height of the bin in mm style_tab | { 0, 1, 2, 3, 4, 5 } | how the tabs for labels are generated.
• (0) Full tabs across the entire compartment
• (1) automatic tabs
- left aligned tabs on the left edge
- right aligned tabs on right edge
- center tabs otherwise
• (2) left aligned tabs
• (3) center aligned tabs
• (4) right aligned tabs
• (5) no tabs style_base | { 0, 1, 2, 3, 4} | specifies the locations for the "X" cutouts for bases.
• (0) all
• (1) corners
• (2) edges
• (3) automatic
• (4) none -a_tab | { n>0 \| n∈R } | angle of the tab +a_tab | { n>0 \| n∈R } | angle of the tab -## Modules +## Modules ### gridfinityVase -Generates the compartment section of the bin. No parameters as it uses the global parameters for construction. +Generates the compartment section of the bin. No parameters as it uses the global parameters for construction. **`gridfinityVase()`** ### gridfinityVaseBase -Generates the base section of the bin. No parameters as it uses the global parameters for construction. It only generates a single base, as all of them are the same. Use your slicer with the "outpuit individual objects" option to print a full sheet of these, or as many as you need to fit your bins. +Generates the base section of the bin. No parameters as it uses the global parameters for construction. It only generates a single base, as all of them are the same. Use your slicer with the "outpuit individual objects" option to print a full sheet of these, or as many as you need to fit your bins. -**`gridfinityVaseBase()`** \ No newline at end of file +**`gridfinityVaseBase()`** diff --git a/gridfinity-rebuilt-baseplate.scad b/gridfinity-rebuilt-baseplate.scad index 4955b45..099d235 100644 --- a/gridfinity-rebuilt-baseplate.scad +++ b/gridfinity-rebuilt-baseplate.scad @@ -17,9 +17,9 @@ $fs = 0.25; /* [General Settings] */ // number of bases along x-axis -gridx = 5; -// number of bases along y-axis -gridy = 5; +gridx = 5; +// number of bases along y-axis +gridy = 5; /* [Screw Together Settings - Defaults work for M3 and 4-40] */ // screw diameter @@ -50,7 +50,7 @@ fity = 0; // [-1:0.1:1] style_plate = 0; // [0: thin, 1:weighted, 2:skeletonized, 3: screw together, 4: screw together minimal] // enable magnet hole -enable_magnet = true; +enable_magnet = true; // hole styles style_hole = 2; // [0:none, 1:contersink, 2:counterbore] @@ -59,19 +59,19 @@ style_hole = 2; // [0:none, 1:contersink, 2:counterbore] // ===== IMPLEMENTATION ===== // screw_together = (style_plate == 3 || style_plate == 4); -color("tomato") +color("tomato") gridfinityBaseplate(gridx, gridy, l_grid, distancex, distancey, style_plate, enable_magnet, style_hole, fitx, fity); // ===== CONSTRUCTION ===== // module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, sm, sh, fitx, fity) { - + assert(gridx > 0 || dix > 0, "Must have positive x grid amount!"); assert(gridy > 0 || diy > 0, "Must have positive y grid amount!"); - gx = gridx == 0 ? floor(dix/length) : gridx; - gy = gridy == 0 ? floor(diy/length) : gridy; + 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); @@ -79,27 +79,27 @@ module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, sm, sh, fitx, fit offsetx = dix < dx ? 0 : (gx*length-0.5-dix)/2*fitx*-1; offsety = diy < dy ? 0 : (gy*length-0.5-diy)/2*fity*-1; - + difference() { translate([offsetx,offsety,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([offsetx,offsety,h_base-0.6]) rounded_rectangle(dx*2, dy*2, h_base*2, r_base); - + pattern_linear(gx, gy, length) { render(convexity = 6) { if (sp == 1) translate([0,0,-off]) cutter_weight(); - else if (sp == 2 || sp == 3) + else if (sp == 2 || sp == 3) linear_extrude(10*(h_base+off), center = true) profile_skeleton(); - else if (sp == 4) + else if (sp == 4) translate([0,0,-5*(h_base+off)]) rounded_square(length-2*r_c2-2*r_c1, 10*(h_base+off), r_fo3); @@ -113,12 +113,12 @@ module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, sm, sh, fitx, fit } } } - if (sp == 3 || sp ==4) cutter_screw_together(gx, gy, off); + if (sp == 3 || sp ==4) cutter_screw_together(gx, gy, off); } } -function calculate_off(sp, sm, sh) = +function calculate_off(sp, sm, sh) = screw_together ? 6.75 :sp==0 @@ -156,10 +156,10 @@ module hole_pattern(){ } module cutter_countersink(){ - cylinder(r = r_hole1+d_clear, h = 100*h_base, center = true); + cylinder(r = r_hole1+d_clear, h = 100*h_base, center = true); translate([0,0,d_cs]) mirror([0,0,1]) - hull() { + 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); @@ -171,14 +171,14 @@ module cutter_counterbore(){ 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]) + 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 = l_grid-2*r_c2-2*r_c1; - minkowski() { + l = l_grid-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) @@ -186,7 +186,7 @@ module profile_skeleton() { minkowski() { square([l,l]); circle(r_hole2+r_skel+2); - } + } } circle(r_skel); } @@ -197,7 +197,7 @@ module cutter_screw_together(gx, gy, off) { screw(gx, gy); rotate([0,0,90]) screw(gy, gx); - + module screw(a, b) { copy_mirror([1,0,0]) translate([a*l_grid/2, 0, -off/2]) diff --git a/gridfinity-rebuilt-bins.scad b/gridfinity-rebuilt-bins.scad index fc18129..b5976de 100644 --- a/gridfinity-rebuilt-bins.scad +++ b/gridfinity-rebuilt-bins.scad @@ -29,10 +29,10 @@ $fs = 0.25; /* [General Settings] */ // number of bases along x-axis -gridx = 5; -// number of bases along y-axis -gridy = 5; -// bin height. See bin height information and "gridz_define" below. +gridx = 5; +// number of bases along y-axis +gridy = 5; +// bin height. See bin height information and "gridz_define" below. gridz = 6; /* [Compartments] */ @@ -45,7 +45,7 @@ divy = 1; // 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] // overrides internal block height of bin (for solid containers). Leave zero for default height. Units: mm -height_internal = 0; +height_internal = 0; // snap gridz height to nearest 7mm increment enable_zsnap = false; @@ -54,7 +54,7 @@ enable_zsnap = false; style_tab = 1; //[0:Full,1:Auto,2:Left,3:Center,4:Right,5:None] // how should the top lip act style_lip = 0; //[0: Regular lip, 1:remove lip subtractively, 2: remove lip and retain height] -// scoop weight percentage. 0 disables scoop, 1 is regular scoop. Any real number will scale the scoop. +// scoop weight percentage. 0 disables scoop, 1 is regular scoop. Any real number will scale the scoop. scoop = 1; //[0:0.1:1] // only cut magnet/screw holes at the corners of the bin to save uneccesary print time only_corners = false; @@ -64,7 +64,7 @@ style_hole = 3; // [0:no holes, 1:magnet holes only, 2: magnet and screw holes - // 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; +div_base_y = 0; @@ -91,24 +91,24 @@ gridfinityInit(3, 3, height(6), 0, 42) { 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. +// 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=0); cut(0, 0.5, 1.5, 0.5, 5, 0); cut(0, 1, 1.5, 0.5, 5, 0); - + cut(0,1.5,0.5,1.5,5,0); cut(0.5,1.5,0.5,1.5,5,0); cut(1,1.5,0.5,1.5,5,0); - + 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. +// 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,0); @@ -125,8 +125,8 @@ gridfinityBase(3, 3, 42, 0, 0, 1); 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) + 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); @@ -150,9 +150,9 @@ gridfinityBase(gx, gy, 42, 0, 0, 1); gx = 4.5; gy = 4; gridfinityInit(gx, gy, height(6), 0, 42) { - for (i = [0:gx-1]) + 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); -*/ \ No newline at end of file +*/ diff --git a/gridfinity-rebuilt-lite.scad b/gridfinity-rebuilt-lite.scad index e127e5a..3608441 100644 --- a/gridfinity-rebuilt-lite.scad +++ b/gridfinity-rebuilt-lite.scad @@ -16,10 +16,10 @@ $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. +gridx = 3; +// number of bases along y-axis +gridy = 3; +// bin height. See bin height information and "gridz_define" below. gridz = 6; /* [Compartments] */ @@ -47,7 +47,7 @@ only_corners = false; // 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; +div_base_y = 0; // thickness of bottom layer bottom_layer = 1; @@ -63,7 +63,7 @@ gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap, l_gri // ===== 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, div_base_x, div_base_y, style_hole, only_corners) { difference() { union() { gridfinityInit(gridx, gridy, height(gridz, gridz_define, style_lip, enable_zsnap), 0, length) @@ -94,4 +94,4 @@ module gridfinityLite(gridx, gridy, gridz, gridz_define, style_lip, enable_zsnap } } -} \ No newline at end of file +} diff --git a/gridfinity-rebuilt-utility.scad b/gridfinity-rebuilt-utility.scad index 4d861dc..c330461 100644 --- a/gridfinity-rebuilt-utility.scad +++ b/gridfinity-rebuilt-utility.scad @@ -11,13 +11,13 @@ function height (z,d=0,l=0,s=true) = (s?((abs(hf(z,d,l))%7==0)?hf(z,d,l):hf(z,d, // 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 +// 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() // scoop_weight: scoop toggle for all compartments. see cut() module cutEqual(n_divx=1, n_divy=1, style_tab=1, scoop_weight=1) { - for (i = [1:n_divx]) + 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, scoop_weight); } @@ -26,32 +26,32 @@ module cutEqual(n_divx=1, n_divy=1, style_tab=1, scoop_weight=1) { module gridfinityInit(gx, gy, h, h0 = 0, l = l_grid) { $gxx = gx; $gyy = gy; - $dh = h; - $dh0 = h0; + $dh = h; + $dh0 = h0; color("tomato") { difference() { - color("firebrick") + color("firebrick") block_bottom(h0==0?$dh-0.1:h0, gx, gy, l); children(); } - color("royalblue") + color("royalblue") block_wall(gx, gy, l) { if (style_lip == 0) 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. +// 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. +// 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=1) { translate([0,0,-$dh-h_base]) @@ -65,7 +65,7 @@ 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 ===== // @@ -87,26 +87,26 @@ module gridfinityBase(gx, gy, l, dx, dy, style_hole, off=0, final_cut=true, only 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) + 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); - + if(only_corners) { difference(){ - pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l) + pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l) block_base(gx, gy, l, dbnx, dbny, 0, off); pattern_linear(2, 2, (gx-1)*l_grid+d_hole, (gy-1)*l_grid+d_hole) block_base_hole(style_hole, off); } } else { - pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l) + pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l) block_base(gx, gy, l, dbnx, dbny, style_hole, off); } } @@ -116,17 +116,17 @@ module block_base(gx, gy, l, dbnx, dbny, style_hole, off) { render(convexity = 2) difference() { block_base_solid(dbnx, dbny, l, off); - + if (style_hole > 0) - pattern_circular(abs(l-d_hole_from_side/2)<0.001?1:4) + 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(style_hole, off); } } -module block_base_solid(dbnx, dbny, l, o) { - xx = dbnx*l-0.05; - yy = dbny*l-0.05; +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]) @@ -153,7 +153,7 @@ module block_base_hole(style_hole, o=0) { if (style_hole==3) copy_mirror([0,1,0]) - translate([-1.5*r2,r1+0.1,h_hole-o]) + translate([-1.5*r2,r1+0.1,h_hole-o]) cube([r2*3,r2*3, 10]); } if (style_hole > 1) @@ -176,9 +176,9 @@ module profile_wall_sub() { difference() { profile_wall_sub_sub(); color("red") - offset(delta = d_clear) + offset(delta = d_clear) translate([r_base-d_clear,$dh,0]) - mirror([1,0,0]) + mirror([1,0,0]) profile_base(); } } @@ -189,9 +189,9 @@ module profile_wall() { difference() { profile_wall_sub(); difference() { - translate([0, $dh+h_base-d_clear*sqrt(2), 0]) + translate([0, $dh+h_base-d_clear*sqrt(2), 0]) circle(r_base/2); - offset(r = r_f1) + offset(r = r_f1) offset(delta = -r_f1) profile_wall_sub(); } @@ -203,13 +203,13 @@ module profile_wall() { // lipless profile module profile_wall2() { - translate([r_base,0,0]) - mirror([1,0,0]) + translate([r_base,0,0]) + mirror([1,0,0]) square([d_wall,$dh]); } module block_wall(gx, gy, l) { - translate([0,0,h_base]) + 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(); } @@ -221,7 +221,7 @@ module block_bottom( h = 2.2, gx, gy, l ) { module cut_move_unsafe(x, y, w, h) { xx = ($gxx*l_grid+d_magic); - yy = ($gyy*l_grid+d_magic); + yy = ($gyy*l_grid+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]) @@ -229,44 +229,44 @@ module cut_move_unsafe(x, y, w, h) { } 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_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 && style_lip == 0; - ycutlast = abs(y+h-$gyy)<0.001 && style_lip == 0; + ycutlast = abs(y+h-$gyy)<0.001 && style_lip == 0; xcutfirst = x == 0 && style_lip == 0; xcutlast = abs(x+w-$gxx)<0.001 && style_lip == 0; zsmall = ($dh+h_base)/7 < 3; - - ylen = h*($gyy*l_grid+d_magic)/$gyy-d_div; - xlen = w*($gxx*l_grid+d_magic)/$gxx-d_div; - + + ylen = h*($gyy*l_grid+d_magic)/$gyy-d_div; + xlen = w*($gxx*l_grid+d_magic)/$gxx-d_div; + height = $dh; - extent = (abs(s) > 0 && ycutfirst ? d_wall2-d_wall-d_clear : 0); - tab = (zsmall || t == 5) ? (ycutlast?v_len_lip:0) : v_len_tab; + extent = (abs(s) > 0 && 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]) + 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]) + 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]); @@ -281,14 +281,14 @@ module block_cutter(x,y,w,h,t,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]) @@ -296,36 +296,36 @@ module block_cutter(x,y,w,h,t,s) { 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]) + 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 (!(abs(s) > 0)&& 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]) @@ -361,32 +361,32 @@ module fillet_cutter(t = 0, c = "goldenrod") { } module profile_cutter(h, l, s) { - scoop = max(s*$dh/2-r_f2,0); + scoop = max(s*$dh/2-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]) + translate([l-2*r_f2,h-r_f2/2]) + mirror([1,1]) square(0.1); - - translate([0,h-r_f2/2]) - mirror([0,1]) + + translate([0,h-r_f2/2]) + mirror([0,1]) square(0.1); } difference() { - translate([l-scoop-2*r_f2, scoop]) + 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]) + translate([l-scoop-2*r_f2,-1]) square([-(l-scoop-2*r_f2),2*h]); - - translate([0,h]) + + translate([0,h]) square([2*l,scoop]); } } @@ -397,7 +397,7 @@ module profile_cutter_tab(h, tab, ang) { color("blue") offset(delta = r_f2) polygon([[0,h],[tab,h],[0,h-tab*tan(ang)]]); - + } // ==== Utilities ===== @@ -406,8 +406,8 @@ function clp(x,a,b) = min(max(x,a),b); module rounded_rectangle(length, width, height, rad) { linear_extrude(height) - offset(rad) - offset(-rad) + offset(rad) + offset(-rad) square([length,width], center = true); } @@ -417,38 +417,38 @@ module rounded_square(length, height, rad) { module copy_mirror(vec=[0,1,0]) { children(); - if (vec != [0,0,0]) - mirror(vec) + if (vec != [0,0,0]) + mirror(vec) children(); -} +} module pattern_linear(x = 1, y = 1, sx = 0, sy = 0) { - yy = sy <= 0 ? sx : sy; + 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]) + translate([(i-1)*sx,(j-1)*yy,0]) children(); } module pattern_circular(n=2) { - for (i = [1:n]) - rotate(i*360/n) + 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]) + copy_mirror([1,0,0]) translate([w/2,h/2,0]) - rotate_extrude(angle = 90, convexity = 4) + 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]) @@ -456,4 +456,3 @@ module sweep_rounded(w=10, h=10) { children(); } } - diff --git a/gridfinity-spiral-vase.scad b/gridfinity-spiral-vase.scad index 33bdaeb..7e80e82 100644 --- a/gridfinity-spiral-vase.scad +++ b/gridfinity-spiral-vase.scad @@ -19,37 +19,37 @@ type = 0; // [0:bin, 1:base] /* [Printer Settings] */ // extrusion width (walls will be twice this size) -nozzle = 0.6; +nozzle = 0.6; // slicer layer size layer = 0.35; -// number of base layers on build plate +// number of base layers on build plate bottom_layer = 3; /* [General Settings] */ -// number of bases along x-axis +// number of bases along x-axis gridx = 1; -// number of bases along y-axis +// number of bases along y-axis gridy = 1; -// bin height. See bin height information and "gridz_define" below. +// bin height. See bin height information and "gridz_define" below. gridz = 6; // number of compartments along x-axis n_divx = 2; /* [Toggles] */ // toggle holes on the base for magnet -enable_holes = true; +enable_holes = true; // round up the bin height to match the closest 7mm unit -enable_zsnap = false; +enable_zsnap = false; // toggle the lip on the top of the bin that allows stacking -enable_lip = true; +enable_lip = true; // chamfer inside bin for easy part removal enable_scoop_chamfer = true; // funnel-like features on the back of tabs for fingers to grab -enable_funnel = true; +enable_funnel = true; // front inset (added for strength when there is a scoop) -enable_inset = true; +enable_inset = true; // "pinches" the top lip of the bin, for added strength -enable_pinch = true; +enable_pinch = true; /* [Styles] */ // determine what the variable "gridz" applies to based on your use case @@ -59,53 +59,53 @@ style_tab = 0; // [0:continuous, 1:broken, 2:auto, 3:right, 4:center, 5:left, 6: // where to put X cutouts for attaching bases // selecting none will also disable crosses on bases style_base = 0; // [0:all, 1:corners, 2:edges, 3:auto, 4:none] - + // tab angle -a_tab = 40; +a_tab = 40; // ===== IMPLEMENTATION ===== // color("tomato") if (type != 0) gridfinityBaseVase(); // Generate a single base -else gridfinityVase(); // Generate the bin +else gridfinityVase(); // Generate the bin // ===== CONSTRUCTION ===== // 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); -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; f2c = sqrt(2)*(sqrt(2)-1); // fillet to chamfer ratio me = ((gridx*l_grid-0.5)/n_divx)-nozzle*4-r_fo1-12.7-4; m = min(d_tabw/1.8 + max(0,me), d_tabw/1.25); d_ramp = f2c*(l_grid*((d_height-2)/7+1)/12-r_f2)+d_wall2; -d_edge = ((gridx*l_grid-0.5)/n_divx-d_tabw-r_fo1)/2; -n_st = gridz <= 3 ? 6 : d_edge < 2 && style_tab != 0 && style_tab != 6 ? 1 : style_tab == 1 && n_divx <= 1? 0 : style_tab; +d_edge = ((gridx*l_grid-0.5)/n_divx-d_tabw-r_fo1)/2; +n_st = gridz <= 3 ? 6 : d_edge < 2 && style_tab != 0 && style_tab != 6 ? 1 : style_tab == 1 && n_divx <= 1? 0 : style_tab; -n_x = (n_st==0?1:n_divx); +n_x = (n_st==0?1:n_divx); spacing = (gridx*l_grid-0.5)/(n_divx); 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; -xAll = function (a,b) true; +xAll = function (a,b) true; xCorner = function(a,b) (a==1||a==gridx)&&(b==1||b==gridy); xEdge = function(a,b) (a==1)||(a==gridx)||(b==1)||(b==gridy); -xAuto = function(a,b) xCorner(a,b) || (a%2==1 && b%2 == 1); +xAuto = function(a,b) xCorner(a,b) || (a%2==1 && b%2 == 1); xNone = function(a,b) false; xFunc = [xAll, xCorner, xEdge, xAuto, xNone]; module gridfinityVase() { - $dh = d_height; + $dh = d_height; difference() { union() { difference() { block_vase_base(); - + if (n_st != 6) transform_style() transform_vtab_base((n_st<2?gridx*l_grid/n_x-0.5-r_fo1:d_tabw)-nozzle*4) @@ -127,12 +127,12 @@ module gridfinityVase() { if (n_divx > 1) pattern_linear(n_divx-1,1,(gridx*l_grid-0.5)/(n_divx)) block_divider(); - - if (n_divx < 1) + + if (n_divx < 1) pattern_linear(n_st == 0 ? n_divx>1 ? n_divx-1 : gridx-1 : 1, 1, (gridx*l_grid-r_fo1)/((n_divx>1 ? n_divx : gridx))) block_tabsupport(); } - + if (enable_funnel && gridz > 3) pattern_linear((n_st==0?n_divx>1?n_divx:gridx:1), 1, (gridx*l_grid-r_fo1)/(n_st==0?n_divx>1?n_divx:gridx:1)) transform_funnel() @@ -146,7 +146,7 @@ module gridfinityVase() { block_inset(); if (enable_pinch) block_pinch(); - + if (bottom_layer <= 0) translate([0,0,-50+layer+0.01]) cube([gridx*l_grid*10,gridy*l_grid*10,100], center=true); @@ -174,13 +174,13 @@ module gridfinityBaseVase() { cube([0.001,l_grid*gridx,d_height+d_bottom*2]); } - + pattern_circular(4) intersection() { rotate([0,0,45]) translate([-nozzle,3,-h_base+d_bottom+0.01]) cube([nozzle*2,l_grid*gridx,d_height+d_bottom*2]); - + block_base_blank(nozzle*4-0.1); } if (enable_holes) @@ -190,11 +190,11 @@ module gridfinityBaseVase() { if (enable_holes) pattern_circular(4) block_magnet_blank(0, false); - + translate([0,0,h_base/2]) cube([l_grid*2, l_grid*2, h_base], center = true); } - + if (style_base != 4) linear_extrude(d_bottom) profile_x(0.1); @@ -241,10 +241,10 @@ module block_pinch() { mirror([1,0,0]) square([10,d_height+h_base]); } - + translate([0,-50,0]) square([100,100], center = true); - + translate([d_wall2-nozzle*2-d_clear*2,0,0]) square(r_c2*2); } @@ -254,9 +254,9 @@ module block_tabsupport() { intersection() { translate([0,0,0.1]) block_vase(d_height*4); - + cube([nozzle*2, gridy*l_grid, d_height*3], center=true); - + transform_vtab_base(gridx*l_grid*2) block_tab_base(-nozzle*sqrt(2)); } @@ -269,24 +269,24 @@ module block_divider() { block_vase(); cube([nozzle*2, gridy*l_grid, d_height*2], center=true); } - + if (n_st == 0) block_tab(0.1); else block_divider_edgecut(); - + // cut divider clearance on negative Y side translate([-gridx*l_grid/2,-(gridy*l_grid/2-0.25),0]) cube([gridx*l_grid,nozzle*2+0.1,d_height*2]); - + // cut divider clearance on positive Y side mirror([0,1,0]) if (enable_scoop_chamfer) translate([-gridx*l_grid/2,-(gridy*l_grid/2-0.25),0]) cube([gridx*l_grid,d_wall2+0.1,d_height*2]); else block_divider_edgecut(); - + // cut divider to have clearance with scoop if (enable_scoop_chamfer) - transform_scoop() + transform_scoop() offset(delta = 0.1) polygon([ [0,0], @@ -295,11 +295,11 @@ module block_divider() { [-nozzle/sqrt(2),0] ]); } - + // divider slices difference() { for (i = [0:(d_height-d_bottom)/(layer)]) { - + if (2*i*layer < d_height-layer/2-d_bottom-0.1) mirror([0,1,0]) translate([0,(gridy*l_grid/2-0.25-nozzle)/2,layer/2+d_bottom+2*i*layer]) @@ -308,9 +308,9 @@ module block_divider() { if ((2*i+1)*layer < d_height-layer/2-d_bottom-0.1) 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); - + } - + // divider slices cut to tabs if (n_st == 0) transform_style() @@ -356,15 +356,15 @@ module block_vase_base() { // base translate([0,0,-h_base]) { translate([0,0,-0.1]) - color("firebrick") + color("firebrick") block_bottom(d_bottom, gridx, gridy, l_grid); - color("royalblue") + color("royalblue") block_wall(gridx, gridy, l_grid) { if (enable_lip) profile_wall(); else profile_wall2(); - } + } } - + // magic slice rotate([0,0,90]) mirror([0,1,0]) @@ -373,20 +373,20 @@ module block_vase_base() { } // scoop piece - if (enable_scoop_chamfer) - transform_scoop() + if (enable_scoop_chamfer) + transform_scoop() polygon([ [0,0], [d_ramp,d_ramp], [d_ramp,d_ramp+0.6/sqrt(2)], [-0.6/sqrt(2),0] ]); - + // outside tab cutter if (n_st != 6) translate([-(n_x-1)*spacing/2,0,0]) for (i = [1:n_x]) - translate([(i-1)*spacing,0,0]) + translate([(i-1)*spacing,0,0]) translate([shiftauto(i,n_x)*d_edge + shift*d_edge,0,0]) intersection() { block_vase(); @@ -429,7 +429,7 @@ module block_inset() { } } -module block_inset_sub(x, y, ang) { +module block_inset_sub(x, y, ang) { translate([0,(gridy*l_grid-0.5)/2+r_fo1/2,0]) mirror([0,1,0]) linear_extrude(y,center=true) @@ -452,7 +452,7 @@ module block_flushscoop() { polygon([[0,0],[gridx*l_grid/2-r_fo1/2,0],[gridx*l_grid/2-r_fo1/2,1],[gridx*l_grid/2-r_fo1/2-r_c1*5,d_wall2-nozzle*2+1],[0,d_wall2-nozzle*2+1]]); } - transform_scoop() + transform_scoop() polygon([[0,0],[d_ramp,0],[d_ramp,d_ramp]]); } @@ -472,10 +472,10 @@ module block_tabscoop(a=m, b=0, c=0, d=-1) { difference() { translate([0,0,-d_tabh*sin(a_tab)*2+d_height+2.1]) profile_tabscoop(a); - + translate([-gridx*l_grid/2,-m,-m]) cube([gridx*l_grid,m-d_tabh*cos(a_tab)+0.005+c,d_height*20]); - + if (d >= 0) translate([0,0,-d_tabh*sin(a_tab)+d_height+m/2+d+2.1]) cube([gridx*l_grid,gridy*l_grid,m],center=true); diff --git a/standard.scad b/standard.scad index 1987016..3b51dfb 100644 --- a/standard.scad +++ b/standard.scad @@ -1,59 +1,59 @@ // height of the base -h_base = 5; +h_base = 5; // outside rounded radius of bin -r_base = 4; +r_base = 4; // lower base chamfer "radius" -r_c1 = 0.8; +r_c1 = 0.8; // upper base chamfer "radius" -r_c2 = 2.4; +r_c2 = 2.4; // bottom thiccness of bin -h_bot = 2.2; +h_bot = 2.2; // outside radii 1 -r_fo1 = 8.5; +r_fo1 = 8.5; // outside radii 2 r_fo2 = 3.2; // outside radii 3 -r_fo3 = 1.6; +r_fo3 = 1.6; // length of a grid unit l_grid = 42; // screw hole radius -r_hole1 = 1.5; +r_hole1 = 1.5; // magnet hole radius -r_hole2 = 3.25; +r_hole2 = 3.25; // center-to-center distance between holes -d_hole = 26; +d_hole = 26; // distance of hole from side of bin d_hole_from_side=8; // magnet hole depth -h_hole = 2.4; +h_hole = 2.4; // slit depth (printer layer height) -h_slit = 0.2; +h_slit = 0.2; // top edge fillet radius -r_f1 = 0.6; +r_f1 = 0.6; // internal fillet radius -r_f2 = 2.8; +r_f2 = 2.8; // width of divider between compartments -d_div = 1.2; +d_div = 1.2; // minimum wall thickness -d_wall = 0.95; -// tolerance fit factor -d_clear = 0.25; +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_tabh = 15.85; +// maximum width of tab +d_tabw = 42; +// angle of tab +a_tab = 36; // lip height h_lip = 3.548; d_wall2 = r_base-r_c1-d_clear*sqrt(2); -d_magic = -2*d_clear-2*d_wall+d_div; +d_magic = -2*d_clear-2*d_wall+d_div; // Baseplate constants @@ -70,12 +70,12 @@ bp_rcut_length = 4.25; // Baseplate bottom cutout rounded thingy depth bp_rcut_depth = 2; // countersink diameter for baseplate -d_cs = 2.5; +d_cs = 2.5; // radius of cutout for skeletonized baseplate -r_skel = 2; +r_skel = 2; // baseplate counterbore radius r_cb = 2.75; // baseplate counterbore depth h_cb = 3; // minimum baseplate thickness (when skeletonized) -h_skel = 1; \ No newline at end of file +h_skel = 1;