Ventilated Paint Brush Travel Tube
by Mach3 ·
This is an artist's breathable paint brush tube & travel case.
My daughter has long artisan brushes, so the container size is 250mm height, 44mm inner diameter (change these parameters easily via Makerworld Customizer)
Interactive Preview & Customizer
3D preview with OpenSCAD rendering on parameter changes.
Total assembled interior length (mm)
Internal radius of the tube (mm)
Main tube outer wall thickness (mm)
Base & top end plate thickness (mm)
Thread pitch (mm)
Thread engagement height (mm)
Thread profile depth (mm)
Thread angle (degrees)
3D printer clearance/slop (mm)
Minimum wall thickness under thread spigot root (mm)
Minimum wall thickness over female thread socket (mm)
Height of the reinforced collar zone (mm)
Transition bevel length (mm)
Enable top end cap ventilation pattern
Style of top cap ventilation
Enable upper sidewall ventilation slots
Number of sidewall ventilation slot columns
Height of sidewall ventilation slots (mm)
Width of sidewall ventilation slots (mm)
Enable tactile fluting / knurling grip ribs
Number of grip flutes around perimeter
Depth of grip flutes (mm)
Select what to render
Prompt
create a ventilated paint brush travel tube, use bosl2 for threads, 250mm height, 44mm inner diameter
OpenSCAD Code
/**
* Brush Tube Case (Тубус для кисточек) v10
*
* Features in v10:
* - 3MF export pre-configured in print-ready orientation:
* both halves standing side-by-side with flat caps/bases on build plate (Z=0)
* - Squeak-free, silky-smooth 10.5mm thread with 2.8mm pitch (~3.75 continuous turns)
* - 0.32mm thread slop for zero-binding Silk PLA operation
* - Solid top cap center with clean radial ventilation slot rings
* - Uniform 1.2mm minimum wall thickness throughout
* - 22mm internal radius (44mm ID), 250mm total interior length
* - 100% support-free 3D printing
*/
include <BOSL2/std.scad>
include <BOSL2/threading.scad>
/* [Main Dimensions] */
// Total assembled interior length (mm)
total_length = 250; // [150:10:400]
// Internal radius of the tube (mm)
inner_radius = 22; // [15:1:50]
// Main tube outer wall thickness (mm)
wall_thickness = 1.2; // [1.0:0.1:3.0]
// Base & top end plate thickness (mm)
end_thickness = 1.6; // [1.2:0.2:3.0]
/* [Thread & Collar Parameters] */
// Thread pitch (mm)
thread_pitch = 2.8; // [2.0:0.2:4.5]
// Thread engagement height (mm)
thread_height = 10.5; // [8.0:0.5:18.0]
// Thread profile depth (mm)
thread_depth = 0.72; // [0.4:0.05:1.0]
// Thread angle (degrees)
thread_angle = 45; // [30:5:60]
// 3D printer clearance/slop (mm)
thread_slop = 0.32; // [0.15:0.02:0.5]
// Minimum wall thickness under thread spigot root (mm)
min_spigot_wall = 1.2; // [1.0:0.1:2.0]
// Minimum wall thickness over female thread socket (mm)
min_female_wall = 1.2; // [1.0:0.1:2.0]
// Height of the reinforced collar zone (mm)
joint_collar_height = 12.0; // [8.0:1.0:20.0]
// Transition bevel length (mm)
joint_collar_trans = 3.0; // [1.5:0.5:5.0]
/* [Ventilation] */
// Enable top end cap ventilation pattern
enable_top_ventilation = true;
// Style of top cap ventilation
top_vent_style = "radial_slots"; // [radial_slots:Radial Slots, circular_holes:Circular Holes, spiral_slots:Spiral Rosette]
// Enable upper sidewall ventilation slots
enable_side_ventilation = true;
// Number of sidewall ventilation slot columns
side_vent_columns = 10; // [6:1:18]
// Height of sidewall ventilation slots (mm)
side_vent_height = 20; // [10:2:35]
// Width of sidewall ventilation slots (mm)
side_vent_width = 2.4; // [1.5:0.1:4.0]
/* [Grip & Texture] */
// Enable tactile fluting / knurling grip ribs
enable_grip_fluting = true;
// Number of grip flutes around perimeter
grip_flutes_count = 28; // [16:2:48]
// Depth of grip flutes (mm)
grip_flute_depth = 0.30; // [0.15:0.05:0.6]
/* [View & Export Mode] */
// Select what to render
part_view = "print_plate"; // [print_plate:Print Plate (Both Halves Cap/Base Down), assembled:Assembled Full View, separated:Exploded / Separated, bottom_only:Bottom Half (Base on Bed), top_only:Top Half (Cap on Bed), cross_section:Cross Section Cutaway]
/* [Hidden] */
$fn = $preview ? 72 : 128;
// Derived geometry values
d_in = inner_radius * 2;
r_out = inner_radius + wall_thickness;
d_out = r_out * 2;
// Spigot and Thread dimensions
spigot_root_r = inner_radius + min_spigot_wall;
thread_major_r = spigot_root_r + thread_depth;
thread_major_d = thread_major_r * 2;
// Reinforced collar outer radius (guarantees min_female_wall thickness over internal thread socket)
r_joint = thread_major_r + thread_slop + min_female_wall;
d_joint = r_joint * 2;
bottom_half_len = total_length / 2;
top_half_len = total_length / 2;
// -------------------------------------------------------------------------
// Grip Fluting Cutter
// -------------------------------------------------------------------------
module grip_fluting_mask(h, r, flute_count, depth) {
if (enable_grip_fluting) {
for (i = [0 : flute_count - 1]) {
rotate([0, 0, i * 360 / flute_count])
translate([r, 0, 0])
cylinder(r = depth, h = h, center = true, $fn = 16);
}
}
}
// -------------------------------------------------------------------------
// Top Ventilation Patterns (Solid center)
// -------------------------------------------------------------------------
module top_ventilation_mask() {
if (enable_top_ventilation) {
if (top_vent_style == "radial_slots") {
// Inner ring slots (6 slots)
for (i = [0 : 5]) {
rotate([0, 0, i * 60])
translate([8.5, 0, 0])
rotate([0, 0, 90])
rect_tube(size=[2.2, 5.0], h=end_thickness * 4, rounding=1.1);
}
// Outer ring slots (12 slots)
for (i = [0 : 11]) {
rotate([0, 0, i * 30 + 15])
translate([15.5, 0, 0])
rotate([0, 0, 90])
rect_tube(size=[2.2, 6.0], h=end_thickness * 4, rounding=1.1);
}
} else if (top_vent_style == "circular_holes") {
// Ring 1 (6 holes)
for (i = [0 : 5]) {
rotate([0, 0, i * 60])
translate([8.5, 0, 0])
cylinder(r = 1.8, h = end_thickness * 4, center = true, $fn = 18);
}
// Ring 2 (12 holes)
for (i = [0 : 11]) {
rotate([0, 0, i * 30 + 15])
translate([15.5, 0, 0])
cylinder(r = 2.0, h = end_thickness * 4, center = true, $fn = 18);
}
} else if (top_vent_style == "spiral_slots") {
for (i = [0 : 7]) {
rotate([0, 0, i * 45])
for (r_pos = [7.5, 14.5]) {
rotate([0, 0, r_pos * 2.2])
translate([r_pos, 0, 0])
rotate([0, 0, 45])
rect_tube(size=[2.0, 5.0], h=end_thickness * 4, rounding=1.0);
}
}
}
}
}
// Helper 2D/3D rounded rectangle slot for top cap
module rect_tube(size, h, rounding) {
linear_extrude(height = h, center = true, convexity = 4)
rect(size = size, rounding = rounding);
}
// -------------------------------------------------------------------------
// Sidewall Ventilation Slots
// -------------------------------------------------------------------------
module sidewall_ventilation_mask(z_center) {
if (enable_side_ventilation) {
for (i = [0 : side_vent_columns - 1]) {
rotate([0, 0, i * 360 / side_vent_columns])
translate([0, 0, z_center])
rotate([90, 0, 0])
linear_extrude(height = r_out * 3, center = true, convexity = 4)
rect(size = [side_vent_width, side_vent_height], rounding = side_vent_width / 2);
}
}
}
// -------------------------------------------------------------------------
// Bottom Half Module (Standard upright orientation, base at Z=0)
// -------------------------------------------------------------------------
module bottom_half() {
collar_start_z = bottom_half_len - joint_collar_height;
trans_start_z = collar_start_z - joint_collar_trans;
difference() {
union() {
// Main lower tube body
cyl(
d = d_out,
h = trans_start_z,
chamfer1 = 1.0,
chamfer2 = 0,
anchor = BOTTOM
);
// Tapered transition to reinforced collar
translate([0, 0, trans_start_z])
cyl(
d1 = d_out,
d2 = d_joint,
h = joint_collar_trans,
anchor = BOTTOM
);
// Reinforced collar section
translate([0, 0, collar_start_z])
cyl(
d = d_joint,
h = joint_collar_height,
anchor = BOTTOM
);
// Continuous Male threaded spigot (full spiral with top lead-in & bevel)
translate([0, 0, bottom_half_len])
trapezoidal_threaded_rod(
d = thread_major_d,
l = thread_height,
pitch = thread_pitch,
thread_depth = thread_depth,
thread_angle = thread_angle,
blunt_start1 = false,
blunt_start2 = true,
bevel2 = true,
anchor = BOTTOM
);
}
// Internal cylindrical cavity (smooth continuous bore R=22mm)
translate([0, 0, end_thickness])
cyl(
d = d_in,
h = bottom_half_len + thread_height + 5,
anchor = BOTTOM
);
// Chamfer on inner bottom base for easy cleaning
translate([0, 0, end_thickness - 0.01])
cyl(
d1 = d_in - 2,
d2 = d_in,
h = 0.8,
anchor = BOTTOM
);
// Grip flutes on the reinforced collar
translate([0, 0, bottom_half_len - joint_collar_height / 2])
grip_fluting_mask(
h = joint_collar_height - 2,
r = r_joint,
flute_count = grip_flutes_count,
depth = grip_flute_depth
);
// Grip flutes near the bottom base
translate([0, 0, 16])
grip_fluting_mask(
h = 16,
r = r_out,
flute_count = grip_flutes_count,
depth = grip_flute_depth
);
}
}
// -------------------------------------------------------------------------
// Top Half Module (Standard upright orientation, rim at Z=0, cap at Z=top_half_len)
// -------------------------------------------------------------------------
module top_half() {
collar_end_z = joint_collar_height;
trans_end_z = collar_end_z + joint_collar_trans;
difference() {
union() {
// Reinforced collar section around female thread
cyl(
d = d_joint,
h = collar_end_z,
anchor = BOTTOM
);
// Tapered transition down to main tube body
translate([0, 0, collar_end_z])
cyl(
d1 = d_joint,
d2 = d_out,
h = joint_collar_trans,
anchor = BOTTOM
);
// Main upper tube body
translate([0, 0, trans_end_z])
cyl(
d = d_out,
h = top_half_len - trans_end_z,
chamfer2 = 1.0,
anchor = BOTTOM
);
}
// Internal cylindrical cavity
translate([0, 0, -1])
cyl(
d = d_in,
h = top_half_len - end_thickness + 1,
anchor = BOTTOM
);
// Female internal thread socket matching male thread
translate([0, 0, -0.1])
trapezoidal_threaded_rod(
d = thread_major_d,
l = thread_height + 0.4,
pitch = thread_pitch,
thread_depth = thread_depth,
thread_angle = thread_angle,
internal = true,
blunt_start1 = true,
blunt_start2 = false,
bevel1 = true,
anchor = BOTTOM,
$slop = thread_slop
);
// Top end cap ventilation holes (No central hole)
translate([0, 0, top_half_len - end_thickness / 2])
top_ventilation_mask();
// Upper sidewall ventilation slots
sidewall_ventilation_mask(z_center = top_half_len - end_thickness - side_vent_height / 2 - 4);
// Grip flutes on the reinforced collar of top half
translate([0, 0, joint_collar_height / 2])
grip_fluting_mask(
h = joint_collar_height - 2,
r = r_joint,
flute_count = grip_flutes_count,
depth = grip_flute_depth
);
}
}
// -------------------------------------------------------------------------
// Top Half Inverted Module (Cap down on build plate Z=0, threaded socket up)
// -------------------------------------------------------------------------
module top_half_cap_down() {
translate([0, 0, top_half_len])
rotate([180, 0, 0])
top_half();
}
// -------------------------------------------------------------------------
// Render Selector
// -------------------------------------------------------------------------
if (part_view == "print_plate") {
// Both parts side-by-side with bottoms/caps down on Z=0 build plate (Print-Ready)
translate([-d_joint * 0.65, 0, 0])
color("#1E88E5") bottom_half();
translate([d_joint * 0.65, 0, 0])
color("#FB8C00") top_half_cap_down();
}
else if (part_view == "assembled") {
// Both halves fully screwed together
color("#1E88E5") bottom_half();
color("#FB8C00") translate([0, 0, bottom_half_len]) top_half();
}
else if (part_view == "separated") {
// Exploded view showing threads and alignment
color("#1E88E5") bottom_half();
color("#FB8C00") translate([0, 0, bottom_half_len + thread_height + 30]) top_half();
}
else if (part_view == "bottom_only") {
// Bottom half on build plate (Z=0 base down)
color("#1E88E5") bottom_half();
}
else if (part_view == "top_only") {
// Top half oriented for printing (cap down on build plate Z=0)
color("#FB8C00") top_half_cap_down();
}
else if (part_view == "cross_section") {
// Cross-section cutaway showing wall thickness, thread engagement, and internal cavity
front_half(s=500) {
color("#1E88E5") bottom_half();
}
front_half(s=500) {
color("#FB8C00") translate([0, 0, bottom_half_len]) top_half();
}
}


