feat(skills): OpenSCAD-Skill hinzufuegen
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
// ============================================
|
||||
// Template: L-Bracket with Mounting Holes
|
||||
// Description: Adjustable L-bracket for wall/shelf mounting
|
||||
// ============================================
|
||||
|
||||
// --- Parameters ---
|
||||
arm_length = 50; // [mm] horizontal arm
|
||||
leg_length = 40; // [mm] vertical leg
|
||||
width = 25; // [mm] bracket width
|
||||
thickness = 4; // [mm] material thickness
|
||||
fillet_r = 8; // [mm] inner fillet radius
|
||||
|
||||
// Mounting holes
|
||||
hole_d = 5; // [mm] hole diameter
|
||||
hole_inset = 10; // [mm] hole center from edges
|
||||
countersink = true; // countersink holes
|
||||
cs_d = 9; // [mm] countersink diameter
|
||||
cs_depth = 2; // [mm] countersink depth
|
||||
|
||||
// --- Quality ---
|
||||
$fn = 64;
|
||||
|
||||
// --- Render ---
|
||||
bracket();
|
||||
|
||||
// --- Modules ---
|
||||
module bracket() {
|
||||
difference() {
|
||||
union() {
|
||||
// Horizontal arm
|
||||
cube([arm_length, width, thickness]);
|
||||
|
||||
// Vertical leg
|
||||
cube([thickness, width, leg_length]);
|
||||
|
||||
// Inner fillet for strength
|
||||
translate([thickness, 0, thickness])
|
||||
fillet(fillet_r, width);
|
||||
}
|
||||
|
||||
// Arm mounting holes
|
||||
translate([arm_length - hole_inset, width/2, -0.01])
|
||||
mounting_hole(hole_d, thickness, countersink, cs_d, cs_depth);
|
||||
|
||||
// Leg mounting holes
|
||||
translate([-0.01, width/2, leg_length - hole_inset])
|
||||
rotate([0, 90, 0])
|
||||
mounting_hole(hole_d, thickness, countersink, cs_d, cs_depth);
|
||||
}
|
||||
}
|
||||
|
||||
module fillet(r, w) {
|
||||
difference() {
|
||||
cube([r, w, r]);
|
||||
translate([r, -0.01, r])
|
||||
rotate([-90, 0, 0])
|
||||
cylinder(r=r, h=w + 0.02);
|
||||
}
|
||||
}
|
||||
|
||||
module mounting_hole(d, h, countersink=false, cs_d=0, cs_depth=0) {
|
||||
union() {
|
||||
cylinder(d=d, h=h + 0.02);
|
||||
if (countersink) {
|
||||
translate([0, 0, h - cs_depth + 0.01])
|
||||
cylinder(d1=d, d2=cs_d, h=cs_depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// ============================================
|
||||
// Template: Parametric Electronics Enclosure
|
||||
// Description: Box with lid, screw posts, ventilation
|
||||
// ============================================
|
||||
|
||||
// --- Parameters ---
|
||||
width = 80; // [mm] inner width (X)
|
||||
depth = 60; // [mm] inner depth (Y)
|
||||
height = 35; // [mm] inner height (Z)
|
||||
wall = 2.5; // [mm] wall thickness
|
||||
corner_r = 3; // [mm] corner radius
|
||||
lid_height = 8; // [mm] lid inner height
|
||||
lip = 1.5; // [mm] lid overlap lip
|
||||
tolerance = 0.3; // [mm] fit tolerance
|
||||
|
||||
// Screw posts
|
||||
screw_d = 3; // [mm] screw hole diameter
|
||||
post_d = 7; // [mm] post outer diameter
|
||||
post_inset = 5; // [mm] post inset from inner wall
|
||||
|
||||
// Ventilation
|
||||
vent_slots = 5; // number of vent slots
|
||||
vent_width = 2; // [mm] slot width
|
||||
vent_length = 20; // [mm] slot length
|
||||
|
||||
// --- Quality ---
|
||||
$fn = 64;
|
||||
eps = 0.01; // epsilon for clean booleans
|
||||
|
||||
// --- Assertions ---
|
||||
assert(wall >= 1.2, "wall too thin for FDM (min 1.2mm)");
|
||||
assert(width > 2 * wall, "inner width must be positive");
|
||||
assert(depth > 2 * wall, "inner depth must be positive");
|
||||
assert(height > wall, "inner height must be positive");
|
||||
|
||||
// --- Render ---
|
||||
// Show both parts side by side
|
||||
box_bottom();
|
||||
translate([width + wall * 2 + 10, 0, 0]) box_lid();
|
||||
|
||||
// --- Modules ---
|
||||
module box_bottom() {
|
||||
difference() {
|
||||
// Outer shell
|
||||
rounded_box([width + 2*wall, depth + 2*wall, height + wall], corner_r);
|
||||
|
||||
// Inner cavity
|
||||
translate([wall, wall, wall])
|
||||
rounded_box([width, depth, height + wall + 1], max(corner_r - wall, 0.5));
|
||||
|
||||
// Ventilation slots on one side
|
||||
translate([wall + (width - (vent_slots * (vent_width + 3))) / 2, -1, height/2])
|
||||
for (i = [0:vent_slots-1])
|
||||
translate([i * (vent_width + 3), 0, 0])
|
||||
cube([vent_width, wall + 2, vent_length]);
|
||||
}
|
||||
|
||||
// Screw posts
|
||||
for (pos = screw_post_positions())
|
||||
translate([pos.x, pos.y, wall])
|
||||
screw_post(post_d, screw_d, height - 2);
|
||||
|
||||
// Lid lip (inner ridge)
|
||||
difference() {
|
||||
translate([wall - lip, wall - lip, height + wall - lip])
|
||||
rounded_box([width + 2*lip, depth + 2*lip, lip], max(corner_r - wall + lip, 0.5));
|
||||
translate([wall, wall, height + wall - lip - 0.01])
|
||||
rounded_box([width, depth, lip + 0.02], max(corner_r - wall, 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
module box_lid() {
|
||||
difference() {
|
||||
// Outer lid
|
||||
rounded_box([width + 2*wall, depth + 2*wall, lid_height + wall], corner_r);
|
||||
|
||||
// Inner cavity
|
||||
translate([wall, wall, -0.01])
|
||||
rounded_box([width, depth, lid_height + 0.02], max(corner_r - wall, 0.5));
|
||||
}
|
||||
|
||||
// Lip insert (fits inside bottom lip)
|
||||
translate([wall + tolerance, wall + tolerance, 0])
|
||||
difference() {
|
||||
rounded_box(
|
||||
[width - 2*tolerance, depth - 2*tolerance, lip],
|
||||
max(corner_r - wall - tolerance, 0.5)
|
||||
);
|
||||
translate([lip, lip, -0.01])
|
||||
rounded_box(
|
||||
[width - 2*lip - 2*tolerance, depth - 2*lip - 2*tolerance, lip + 0.02],
|
||||
max(corner_r - wall - lip - tolerance, 0.5)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module rounded_box(size, r) {
|
||||
hull() {
|
||||
for (x = [r, size.x - r])
|
||||
for (y = [r, size.y - r])
|
||||
translate([x, y, 0])
|
||||
cylinder(r=r, h=size.z);
|
||||
}
|
||||
}
|
||||
|
||||
module screw_post(outer_d, inner_d, h) {
|
||||
difference() {
|
||||
cylinder(d=outer_d, h=h);
|
||||
translate([0, 0, -0.01])
|
||||
cylinder(d=inner_d, h=h + 0.02);
|
||||
}
|
||||
}
|
||||
|
||||
function screw_post_positions() = [
|
||||
[wall + post_inset, wall + post_inset, 0],
|
||||
[wall + width - post_inset, wall + post_inset, 0],
|
||||
[wall + post_inset, wall + depth - post_inset, 0],
|
||||
[wall + width - post_inset, wall + depth - post_inset, 0]
|
||||
];
|
||||
@@ -0,0 +1,152 @@
|
||||
// ============================================
|
||||
// printable-lib.scad — Reusable modules for 3D printing
|
||||
// Include with: use <printable-lib.scad>
|
||||
// ============================================
|
||||
|
||||
eps = 0.01; // epsilon for clean boolean operations
|
||||
|
||||
// --- Clearance helpers ---
|
||||
// Returns clearance value for different fit types
|
||||
function fit_clearance(kind="close") =
|
||||
kind == "press" ? 0.15 :
|
||||
kind == "close" ? 0.25 :
|
||||
kind == "loose" ? 0.40 :
|
||||
kind == "slide" ? 0.30 : 0.25;
|
||||
|
||||
// --- Shell / Hollow box ---
|
||||
module shell_box(outer=[60,40,20], wall=2, floor=2) {
|
||||
assert(wall >= 1.2, "wall too thin for FDM (min 1.2mm)");
|
||||
assert(floor >= 0.8, "floor too thin (min 0.8mm)");
|
||||
difference() {
|
||||
cube(outer);
|
||||
translate([wall, wall, floor])
|
||||
cube([outer.x - 2*wall, outer.y - 2*wall, outer.z - floor + eps]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Rounded box (hull-based) ---
|
||||
module rounded_box(size, r=2) {
|
||||
hull() {
|
||||
for (x = [r, size.x - r])
|
||||
for (y = [r, size.y - r])
|
||||
translate([x, y, 0])
|
||||
cylinder(r=r, h=size.z);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Screw clearance hole ---
|
||||
module screw_clearance_hole(d=3, h=10, fit="close") {
|
||||
cylinder(h=h + 2*eps, d=d + fit_clearance(fit), $fn=48);
|
||||
}
|
||||
|
||||
// --- Counterbore hole (for socket head cap screws) ---
|
||||
// Head pocket at entry side (top), shaft goes through
|
||||
module counterbore_hole(shaft_d=3, head_d=6, head_h=3, h=12) {
|
||||
union() {
|
||||
screw_clearance_hole(shaft_d, h);
|
||||
translate([0, 0, h - head_h + eps])
|
||||
cylinder(h=head_h + eps, d=head_d, $fn=48);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Countersink hole ---
|
||||
module countersink_hole(d=3, cs_d=6, cs_h=2, h=10) {
|
||||
union() {
|
||||
cylinder(d=d, h=h + 2*eps, $fn=48);
|
||||
translate([0, 0, h - cs_h + eps])
|
||||
cylinder(d1=d, d2=cs_d, h=cs_h, $fn=48);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Heat-set insert boss ---
|
||||
module heatset_boss(insert_d=4.6, insert_h=5, wall=2, h=8) {
|
||||
assert(wall >= 1.6, "boss wall too thin for heat-set insert");
|
||||
difference() {
|
||||
cylinder(h=h, d=insert_d + 2*wall, $fn=64);
|
||||
translate([0, 0, -eps])
|
||||
cylinder(h=insert_h + 2*eps, d=insert_d, $fn=64);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Screw post (solid post with hole) ---
|
||||
module screw_post(outer_d=7, inner_d=3, h=10) {
|
||||
difference() {
|
||||
cylinder(d=outer_d, h=h, $fn=48);
|
||||
translate([0, 0, -eps])
|
||||
cylinder(d=inner_d, h=h + 2*eps, $fn=48);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Structural rib / gusset ---
|
||||
module rib(len=20, height=12, thick=2) {
|
||||
linear_extrude(height=thick)
|
||||
polygon([[0, 0], [len, 0], [0, height]]);
|
||||
}
|
||||
|
||||
// --- Chamfer edge (for print-friendly overhangs) ---
|
||||
module chamfer_edge(length=10, size=1) {
|
||||
translate([0, 0, -eps])
|
||||
linear_extrude(height=length)
|
||||
polygon([[0, 0], [size, 0], [0, size]]);
|
||||
}
|
||||
|
||||
// --- Snap-fit tab ---
|
||||
// Creates a cantilever snap tab extending along Y with a hook at the end
|
||||
module snap_tab(width=8, length=6, thick=1.5, overhang=0.8) {
|
||||
union() {
|
||||
// Cantilever arm
|
||||
cube([width, length, thick]);
|
||||
// Hook at the end (rotated extrusion for clean manifold)
|
||||
translate([0, length - eps, 0])
|
||||
rotate([90, 0, 90])
|
||||
linear_extrude(height=width)
|
||||
polygon([[0, 0], [thick + eps, 0], [thick/2, overhang]]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Text emboss/deboss helper ---
|
||||
// Use with difference() to deboss or union() to emboss
|
||||
module text_label(txt="Label", size=8, depth=1, font="Liberation Sans:style=Bold",
|
||||
halign="center", valign="center") {
|
||||
linear_extrude(height=depth)
|
||||
text(txt, size=size, font=font, halign=halign, valign=valign);
|
||||
}
|
||||
|
||||
// --- Ventilation grille ---
|
||||
module vent_grille(area_w=30, area_h=15, slot_w=2, slot_gap=2, depth=2) {
|
||||
n_slots = floor(area_h / (slot_w + slot_gap));
|
||||
for (i = [0:n_slots-1])
|
||||
translate([0, i * (slot_w + slot_gap), 0])
|
||||
cube([area_w, slot_w, depth + 2*eps]);
|
||||
}
|
||||
|
||||
// --- PCB standoff array ---
|
||||
module pcb_standoffs(positions, height=5, outer_d=6, hole_d=2.5) {
|
||||
for (pos = positions)
|
||||
translate(pos)
|
||||
difference() {
|
||||
cylinder(d=outer_d, h=height, $fn=32);
|
||||
translate([0, 0, -eps])
|
||||
cylinder(d=hole_d, h=height + 2*eps, $fn=32);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Profile with rounded corners (2D) ---
|
||||
// Use with linear_extrude() — preferred over hull() of cylinders
|
||||
module rounded_rect_2d(size, r=2) {
|
||||
offset(r=r)
|
||||
square([size.x - 2*r, size.y - 2*r], center=true);
|
||||
}
|
||||
|
||||
// --- Lid lip (for box closures) ---
|
||||
module lid_lip(outer_size, wall=2, lip_h=2, lip_w=1.2, tol=0.25) {
|
||||
difference() {
|
||||
rounded_box([outer_size.x, outer_size.y, lip_h], r=2);
|
||||
translate([lip_w + tol, lip_w + tol, -eps])
|
||||
rounded_box([
|
||||
outer_size.x - 2*(lip_w + tol),
|
||||
outer_size.y - 2*(lip_w + tol),
|
||||
lip_h + 2*eps
|
||||
], r=max(2 - lip_w, 0.5));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user