/************************************************************************************* * * Parametric Small Parts Tray * ************************************************************************************* * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT * HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * IT IS NOT PERMITTED TO MODIFY THIS COMMENT BLOCK. * * (c)2022, Claude "Tryphon" Theroux, Montreal, Quebec, Canada * http://www.ctheroux.com/ * ************************************************************************************/ // Tray width in mm layoutWidth = 143; // Tray length in mm layoutLength = 123; // Tray height in mm trayHeight = 15; // Separator tickness in mm separatorTickness = 1.2; // Bottom tickness in mm bottomTickness = 1.5; // Set to true if rounded bottom bucket are required roundedBucketEnabled = true; // Round radius in mm roundRadius = 7; // Row layout in %. // Each value is the length of the corresponding row // relative to layoutLength. The sum of the array must be 1. rowLayout = [ 0.25, 0.25, 0.25, 0.25 ]; // Column layout in % // This array must contain the layout of each rows given as an array. // There must be as many array that there's values in rowLayout. // Each sub-arrays contains the width of the buckets in the row // relative to layoutWidth. The sum of each array must be 1. columnLayout = [ [ 1 ], [ 0.50, 0.50 ], [ 0.50, 0.50 ], [ 1 / 3, 1 / 3, 1 / 3 ] ]; /////////////////////////////////////////////////////////////// // // Computed values. Nothing should be modified below this line. // effectiveLayoutWidth = layoutWidth - separatorTickness; effectiveLayoutLength = layoutLength - separatorTickness; effectiveBucketHeight = trayHeight - bottomTickness; function arraySum(theArray, index = 0, currentSum = 0) = index < len(theArray) ? arraySum(theArray, index + 1, currentSum + theArray[index]) : currentSum; // Check the row layout assert(arraySum(rowLayout) == 1, str("Invalid row layout: " , arraySum(rowLayout))); // Check the column layout for (row = [ 0 : len(columnLayout) - 1 ]) { assert(arraySum(columnLayout[row]) == 1, str("Invalid column layout: ", arraySum(columnLayout[row]), " for row ", row + 1)); } // Check if the column layout is consistent with the row layout assert(len(columnLayout) == len(rowLayout), "Row layout inconsistent with the column layout"); module roundedBucket(pWidth, pLength, pHeight, pRadius) { rotate([0, -90, 0]) translate([pRadius, pRadius, -pWidth]) union() { translate([0, -pRadius, 0]) cube([pHeight - pRadius, pLength, pWidth]); difference() { hull() { cylinder(h = pWidth, r = pRadius, $fn = 180); translate([0, pLength - 2 * pRadius, 0]) cylinder(h = pWidth, r = pRadius, $fn = 180); } translate([0, -pRadius, 0]) cube([pHeight, pLength, pWidth]); } } } module plainBucket(pWidth, pLength, pHeight, pRadius) { cube([pWidth, pLength, pHeight]); } module bucket(pWidth, pLength, pHeight, pRadius) { if( roundedBucketEnabled ) { roundedBucket(pWidth, pLength, pHeight, pRadius); } else { plainBucket(pWidth, pLength, pHeight); } } module bucketColumns(pRowLayout, pColumnLayout, pColumn, pColumnOffset, pRow, pRowOffset) { translate([pColumnOffset + separatorTickness, pRowOffset + separatorTickness, bottomTickness]) bucket(pColumnLayout[pRow][pColumn] * effectiveLayoutWidth - separatorTickness, pRowLayout[pRow] * effectiveLayoutLength - separatorTickness, effectiveBucketHeight, roundRadius); if ( pColumn + 1 < len(pColumnLayout[pRow]) ) { bucketColumns(pRowLayout, pColumnLayout, pColumn + 1, pColumnOffset + pColumnLayout[pRow][pColumn] * effectiveLayoutWidth, pRow, pRowOffset); } } module bucketRows(pRowLayout, pColumnLayout, pRow, pRowOffset) { bucketColumns(pRowLayout, pColumnLayout, 0, 0, pRow, pRowOffset); if( pRow + 1 < len(pRowLayout) ) { bucketRows(pRowLayout, pColumnLayout, pRow + 1, pRowOffset + pRowLayout[pRow] * effectiveLayoutLength ); } } module body(width, height) { cube([layoutWidth, layoutLength, trayHeight]); } module generateTray() { difference() { body(); bucketRows(rowLayout, columnLayout, 0, 0); } } generateTray();