poly-mech/cad/drawers/tools/box_folding_tool.scad
2025-07-04 12:37:24 +02:00

268 lines
10 KiB
OpenSCAD

// Customizable parameters for the box folding tool
// These values are based on the provided screenshot.
// Overall dimensions
TotalWidth = 500; // [100:1000]
TotalLength = 500; // [100:1000]
Height = 80; // [20:200]
// Material and slot properties
TotalThickness = 5; // [1:20]
BaseThickness = 3; // [0.5:19]
Slot_Width_Walls = 8; // [1:20]
// Internal grid configuration
Nb_Boxes_U = 2; // [1:10]
Nb_Boxes_V = 2; // [1:10]
// View control
Folded_View = false; // [true, false]
// Use "export" to render all parts separately for STEP conversion
view_mode = "preview"; // ["preview", "export"]
// Note: InnerBox_Width from the screenshot (100) is not used directly.
// Instead, the compartment widths are calculated based on TotalWidth, Height, and Nb_Boxes_U/V.
// This ensures the design remains consistent with the overall dimensions.
// ---------------------------------------------------------------------
// Main module to generate the box folding pattern
// ---------------------------------------------------------------------
module unfolded_pattern() {
GrooveDepth = TotalThickness - BaseThickness;
difference() {
// 1. Create the base plate
cube([TotalWidth, TotalLength, TotalThickness], center = true);
// 2. Create the cutting grooves
translate([0, 0, TotalThickness/2 - GrooveDepth/2]) {
// Grooves for the main box walls
wall_grooves();
// Grooves for internal compartments
if (Nb_Boxes_U > 1 || Nb_Boxes_V > 1) {
internal_grooves();
}
}
}
}
// ---------------------------------------------------------------------
// Helper modules
// ---------------------------------------------------------------------
// Module for creating the grooves for the outer walls
module wall_grooves() {
InnerWidth = TotalWidth - 2 * Height;
InnerLength = TotalLength - 2 * Height;
GrooveDepth = TotalThickness - BaseThickness;
// Grooves parallel to Y-axis (vertical)
translate([-InnerWidth/2, 0, 0])
cube([Slot_Width_Walls, TotalLength, GrooveDepth], center=true);
translate([InnerWidth/2, 0, 0])
cube([Slot_Width_Walls, TotalLength, GrooveDepth], center=true);
// Grooves parallel to X-axis (horizontal)
translate([0, -InnerLength/2, 0])
cube([TotalWidth, Slot_Width_Walls, GrooveDepth], center=true);
translate([0, InnerLength/2, 0])
cube([TotalWidth, Slot_Width_Walls, GrooveDepth], center=true);
}
// Module for creating the grooves for the internal compartments
module internal_grooves() {
InnerWidth = TotalWidth - 2 * Height;
InnerLength = TotalLength - 2 * Height;
GrooveDepth = TotalThickness - BaseThickness;
CompartmentWidth = (InnerWidth - (Nb_Boxes_U - 1) * Slot_Width_Walls) / Nb_Boxes_U;
CompartmentLength = (InnerLength - (Nb_Boxes_V - 1) * Slot_Width_Walls) / Nb_Boxes_V;
// Internal vertical grooves
if (Nb_Boxes_U > 1) {
for (i = [1 : Nb_Boxes_U - 1]) {
x_pos = -InnerWidth/2 + i * CompartmentWidth + (i - 1/2) * Slot_Width_Walls;
translate([x_pos, 0, 0])
cube([Slot_Width_Walls, InnerLength, GrooveDepth], center = true);
}
}
// Internal horizontal grooves
if (Nb_Boxes_V > 1) {
for (i = [1 : Nb_Boxes_V - 1]) {
y_pos = -InnerLength/2 + i * CompartmentLength + (i - 1/2) * Slot_Width_Walls;
translate([0, y_pos, 0])
cube([InnerWidth, Slot_Width_Walls, GrooveDepth], center = true);
}
}
}
// ---------------------------------------------------------------------
// Modules for Folded View
// ---------------------------------------------------------------------
// Generates the fully assembled 3D box
module folded_box() {
// Inner dimensions of the box
InnerWidth = TotalWidth - 2 * Height;
InnerLength = TotalLength - 2 * Height;
// Material thickness for all parts
wall_thickness = TotalThickness;
// 1. Base Plate
translate([0, 0, wall_thickness / 2])
cube([InnerWidth, InnerLength, wall_thickness], center = true);
// 2. Outer Walls
// South Wall (bottom) - Full Width
translate([0, -InnerLength/2, Height/2 + wall_thickness])
rotate([90, 0, 0])
cube([InnerWidth, Height, wall_thickness], center=true);
// North Wall (top) - Full Width
translate([0, InnerLength/2, Height/2 + wall_thickness])
rotate([-90, 0, 0])
cube([InnerWidth, Height, wall_thickness], center=true);
// West Wall (left) - Shortened to fit between North/South walls
translate([-InnerWidth/2, 0, Height/2 + wall_thickness])
rotate([0, 90, 0])
cube([Height, InnerLength - 2 * wall_thickness, wall_thickness], center=true);
// East Wall (right) - Shortened to fit between North/South walls
translate([InnerWidth/2, 0, Height/2 + wall_thickness])
rotate([0, -90, 0])
cube([Height, InnerLength - 2 * wall_thickness, wall_thickness], center=true);
// 3. Internal Dividers
internal_dividers_folded();
}
// Generates the interlocking internal dividers for the folded view
module internal_dividers_folded() {
InnerWidth = TotalWidth - 2 * Height;
InnerLength = TotalLength - 2 * Height;
divider_thickness = Slot_Width_Walls; // Use slot width as the divider material thickness
// Calculate compartment sizes
Compartment_U = (InnerWidth + divider_thickness) / Nb_Boxes_U;
Compartment_V = (InnerLength + divider_thickness) / Nb_Boxes_V;
// Vertical dividers (U-direction)
for (i = [1 : Nb_Boxes_U - 1]) {
x_pos = -InnerWidth/2 + i * Compartment_U - divider_thickness/2;
difference() {
// Main divider piece
translate([x_pos, 0, Height/2 + TotalThickness])
cube([divider_thickness, InnerLength, Height], center=true);
// Slots for horizontal dividers (top-down)
for (j = [1 : Nb_Boxes_V - 1]) {
y_pos = -InnerLength/2 + j * Compartment_V - divider_thickness/2;
translate([x_pos, y_pos, Height * 0.75 + TotalThickness])
cube([divider_thickness + 0.1, divider_thickness, Height/2], center=true);
}
}
}
// Horizontal dividers (V-direction)
for (j = [1 : Nb_Boxes_V - 1]) {
y_pos = -InnerLength/2 + j * Compartment_V - divider_thickness/2;
difference() {
// Main divider piece
translate([0, y_pos, Height/2 + TotalThickness])
cube([InnerWidth, divider_thickness, Height], center=true);
// Slots for vertical dividers (bottom-up)
for (i = [1 : Nb_Boxes_U - 1]) {
x_pos = -InnerWidth/2 + i * Compartment_U - divider_thickness/2;
translate([x_pos, y_pos, Height * 0.25 + TotalThickness])
cube([divider_thickness, divider_thickness + 0.1, Height/2], center=true);
}
}
}
}
// ---------------------------------------------------------------------
// Module for exporting all parts separately
// ---------------------------------------------------------------------
module export_layout() {
wall_thickness = TotalThickness;
InnerWidth = TotalWidth - 2 * Height;
InnerLength = TotalLength - 2 * Height;
// 1. Base Plate
translate([0, 0, -TotalThickness/2])
cube([InnerWidth, InnerLength, wall_thickness], center = true);
// Spacing for laying out parts
spacing = TotalWidth;
// 2. Outer Walls
translate([spacing, 0, 0])
cube([InnerWidth, Height, wall_thickness], center=true); // South
translate([spacing, Height + 10, 0])
cube([InnerWidth, Height, wall_thickness], center=true); // North
translate([spacing + InnerWidth + 10, 0, 0])
cube([InnerLength - 2 * wall_thickness, Height, wall_thickness], center=true); // West
translate([spacing + InnerWidth + 10, Height + 10, 0])
cube([InnerLength - 2 * wall_thickness, Height, wall_thickness], center=true); // East
// 3. Internal Dividers
divider_thickness = Slot_Width_Walls;
Compartment_U = (InnerWidth + divider_thickness) / Nb_Boxes_U;
Compartment_V = (InnerLength + divider_thickness) / Nb_Boxes_V;
// Place all vertical dividers in a row
for (i = [1 : Nb_Boxes_U - 1]) {
translate([2 * spacing + (i-1)*(divider_thickness+10), 0, 0])
internal_divider_vertical_export(InnerLength, Compartment_V);
}
// Place all horizontal dividers in a row
for (j = [1 : Nb_Boxes_V - 1]) {
translate([2 * spacing, (j-1)*(Height+10) + Height + 10, 0])
internal_divider_horizontal_export(InnerWidth, Compartment_U);
}
}
// Helper modules for export layout (without difference operations)
module internal_divider_vertical_export(length, compartment_v_size) {
divider_thickness = Slot_Width_Walls;
difference() {
cube([divider_thickness, length, Height], center=true);
// Notches for horizontal dividers (bottom-up)
for (i = [1 : Nb_Boxes_V - 1]) {
y_pos = -length/2 + i * compartment_v_size - divider_thickness/2;
translate([0, y_pos, -Height/4])
cube([divider_thickness + 0.1, divider_thickness, Height/2], center=true);
}
}
}
module internal_divider_horizontal_export(length, compartment_u_size) {
divider_thickness = Slot_Width_Walls;
difference() {
cube([length, divider_thickness, Height], center=true);
// Notches for vertical dividers (top-down)
for (j = [1 : Nb_Boxes_U - 1]) {
x_pos = -length/2 + j * compartment_u_size - divider_thickness/2;
translate([x_pos, 0, Height/4])
cube([divider_thickness, divider_thickness + 0.1, Height/2], center=true);
}
}
}
// ---------------------------------------------------------------------
// Render the final object
// ---------------------------------------------------------------------
if (view_mode == "export") {
export_layout();
} else {
if (Folded_View) {
folded_box();
} else {
unfolded_pattern();
}
}