Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions miscellaneous.scad
Original file line number Diff line number Diff line change
Expand Up @@ -619,4 +619,78 @@ module round3d(r, or, ir, size=1000)



// Section: 3D Printing Helpers


// Module: bridged_hole()
// Synopsis: Creates bridging geometry for unsupported holes in FDM printing.
// SynTags: Geom
// Topics: 3D Printing, FDM, Holes
// See Also: cyl(), cylinder()
// Usage:
// bridged_hole(r|d=, layer_height, [layers=], [spin=], [anchor=], [orient=]) [ATTACHMENTS];
// Description:
// Creates a set of progressively rounder polygonal layers at the bottom of a
// hole to provide bridging support for FDM 3D printing without external
// supports. The first layer is a rectangle (2 bridges), the second is
// rotated 90 degrees, and subsequent layers are regular polygons with
// increasing sides (8, 16, 32...) that gradually approximate the circle.
// .
// This module generates only the bridging geometry. Use it inside a
// {{diff()}} together with the actual hole geometry.
// Arguments:
// r = Radius of the hole to bridge.
// layer_height = Height of each bridging layer. Required.
// ---
// d = Diameter of the hole to bridge.
// layers = Number of bridging layers. Default: 3
// spin = Rotation angle for the first bridge direction. Default: 0
// anchor = Translate so anchor point is at origin. Default: `BOTTOM`
// orient = Vector to rotate top toward. Default: `UP`
// Example(3D): Basic bridged hole in a cube
// diff()
// cuboid([30,30,10], anchor=BOTTOM)
// attach(TOP, inside=true, shiftout=0.01)
// bridged_hole(r=8, layer_height=0.2, layers=4);
// Example(3D): With a cylinder hole underneath
// diff()
// cuboid([30,30,10], anchor=BOTTOM) {
// attach(TOP, inside=true, shiftout=0.01)
// bridged_hole(r=8, layer_height=0.2, layers=5);
// attach(TOP, inside=true, shiftout=0.01)
// cyl(h=10, r=8);
// }
module bridged_hole(r, layer_height, d, layers=3, spin=0, anchor=BOTTOM, orient=UP) {
r = get_radius(r=r, d=d);
assert(is_finite(r) && r>0, "\nr or d must be a positive number.");
assert(is_finite(layer_height) && layer_height>0, "\nlayer_height must be a positive number.");
assert(is_integer(layers) && layers>=1, "\nlayers must be a positive integer.");
total_h = layer_height * layers;
attachable(anchor, spin, orient, r=r, l=total_h) {
down(total_h/2)
zrot(spin)
union() {
// Layer 1: rectangle (2 bridges)
linear_extrude(height=layer_height)
rect([r*2, r*2]);
// Layer 2: rectangle rotated 90 degrees
if (layers >= 2)
up(layer_height)
linear_extrude(height=layer_height)
zrot(90) rect([r*2, r*2]);
// Layers 3+: polygons with increasing sides
for (i = [2:1:layers-1])
let(
sides = pow(2, i+1),
h_off = i * layer_height
)
up(h_off)
linear_extrude(height=layer_height)
zrot(180/sides) circle(r=r, $fn=sides);
}
children();
}
}


// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
19 changes: 19 additions & 0 deletions tests/test_miscellaneous.scadtest
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[[test]]
name = "test_bridged_hole"
script = '''
include <../std.scad>

module test_bridged_hole() {
// Basic usage with radius
bridged_hole(r=5, layer_height=0.2);
// With diameter
bridged_hole(d=10, layer_height=0.3, layers=5);
// With spin rotation
bridged_hole(r=8, layer_height=0.2, layers=4, spin=45);
// Minimum layers (just one rectangle)
bridged_hole(r=3, layer_height=0.2, layers=1);
// Two layers
bridged_hole(r=4, layer_height=0.15, layers=2);
}
test_bridged_hole();
'''
Loading