diff --git a/readme.md b/readme.md index fb90dbe..2b8c6e8 100644 --- a/readme.md +++ b/readme.md @@ -24,18 +24,18 @@ See [usage](docs/usage.md) for requirements, installation instructions and a usa Belts LED_meters Rod Carriers Fillet Polyholes Blowers LEDs SCS_bearing_blocks Corner_block Gears Rounded_rectangle Bulldogs Leadnuts SK_brackets Door_hinge Hanging_hole Sphere - Buttons Light_strips SMDs Door_latch Layout Teardrops - Cable_strips Linear_bearings SSRs Fan_guard Maths - Cameras Mains_sockets Screws Fixing_block Offset - Circlips Microswitches Sealing_strip Flat_hinge Quadrant - Components Microview Sheets Foot Round - DIP Modules Spades Handle Rounded_cylinder - D_connectors Nuts Spools PCB_mount Rounded_polygon - Displays O_ring Springs PSU_shroud Sector - Extrusion_brackets Opengrab Stepper_motors Printed_box Sweep - Extrusions PCB Swiss_clips Ribbon_clamp Thread - Fans PCBs Toggles SSR_shroud Tube - Fuseholder PSUs Transformers Screw_knob + Buttons Light_strips SMDs Door_latch Horiholes Teardrops + Cable_strips Linear_bearings SSRs Fan_guard Layout + Cameras Mains_sockets Screws Fixing_block Maths + Circlips Microswitches Sealing_strip Flat_hinge Offset + Components Microview Sheets Foot Quadrant + DIP Modules Spades Handle Round + D_connectors Nuts Spools PCB_mount Rounded_cylinder + Displays O_ring Springs PSU_shroud Rounded_polygon + Extrusion_brackets Opengrab Stepper_motors Printed_box Sector + Extrusions PCB Swiss_clips Ribbon_clamp Sweep + Fans PCBs Toggles SSR_shroud Thread + Fuseholder PSUs Transformers Screw_knob Tube Geared_steppers Panel_meters Tubings Socket_box Green_terminals Pillars Variacs Strap_handle Hot_ends Pin_headers Veroboard @@ -5287,6 +5287,32 @@ Method to print holes in mid air. See Top + +--- + +## Horiholes +Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops). + + +[utils/horiholes.scad](utils/horiholes.scad) Implementation. + +[tests/horiholes.scad](tests/horiholes.scad) Code for this example. + +### Functions +| Function | Description | +|:--- |:--- | +| ```teardrop_plus_x(r, y, h)``` | Calculate the ordinate of a compensated teardrop given y. | +| ```teardrop_x(r, y)``` | Calculate the ordinate of a teardrop given y. Sweeping y from -r to + r yields the positive X half of the shape. | + +### Modules +| Module | Description | +|:--- |:--- | +| ```horihole(r, z, h = 0, center = true)``` | For making horizontal holes that don't need support material and are correct dimensions | + +![horiholes](tests/png/horiholes.png) + + Top --- @@ -5859,6 +5885,9 @@ This ensures `hull` and `minkowski` results have the correct dimensions when sph For making horizontal holes that don't need support material. Small holes can get away without it, but they print better with truncated teardrops. +Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips +do not intrude into the circle. + [utils/core/teardrops.scad](utils/core/teardrops.scad) Implementation. @@ -5867,12 +5896,12 @@ Small holes can get away without it, but they print better with truncated teardr ### Modules | Module | Description | |:--- |:--- | -| ```semi_teardrop(h, r, d = undef, center = true, chamfer = 0)``` | A semi teardrop in the positive Y domain | -| ```teardrop(h, r, center = true, truncate = true, chamfer = 0)``` | For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging | +| ```semi_teardrop(h, r, d = undef, center = true, chamfer = 0, plus = false)``` | A semi teardrop in the positive Y domain | +| ```teardrop(h, r, center = true, truncate = true, chamfer = 0, plus = false)``` | For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging | | ```teardrop_chamfer(h, center, chamfer)``` | Helper module for adding chamfer to a teardrop | -| ```teardrop_plus(h, r, center = true, truncate = true, chamfer = 0)``` | Slightly bigger teardrop to allow for the 3D printing staircase effect | -| ```tearslot(h, r, w, center = true, chamfer = 0)``` | A horizontal slot that doesn't need support material | -| ```vertical_tearslot(h, r, l, center = true, chamfer = 0)``` | A vertical slot that doesn't need support material | +| ```teardrop_plus(h, r, center = true, truncate = true, chamfer = 0)``` | Slightly elongated teardrop to allow for the 3D printing staircase effect | +| ```tearslot(h, r, w, center = true, chamfer = 0, plus = false)``` | A horizontal slot that doesn't need support material | +| ```vertical_tearslot(h, r, l, center = true, chamfer = 0, plus = false)``` | A vertical slot that doesn't need support material | ![teardrops](tests/png/teardrops.png) diff --git a/tests/horiholes.scad b/tests/horiholes.scad new file mode 100644 index 0000000..a53bac5 --- /dev/null +++ b/tests/horiholes.scad @@ -0,0 +1,86 @@ +// +// NopSCADlib Copyright Chris Palmer 2020 +// nop.head@gmail.com +// hydraraptor.blogspot.com +// +// This file is part of NopSCADlib. +// +// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +// GNU General Public License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with NopSCADlib. +// If not, see . +// +$layer_height = 0.25; +include <../utils/core/core.scad> +use <../utils/horiholes.scad> + +show_disc = true; +thickness = 3; +length = 50; +height = 20; +overlap_x = 15; +overlap_y = 5; + +module hole_positions() { + for($i = [0 : 4], $z = 5 + $i * layer_height / 5, $r = 3) + translate([5 + $i * 10, $z]) + children(); + + for($i = [0 : 4], $z = 15 + $i * layer_height / 5, $r = 0.5 + $i / 2) + translate([5 + $i * 10, $z]) + children(); +} + +module horiholes_stl(t = thickness) { + rotate([90, 0, 0]) + difference() { + linear_extrude(t, center = true) { + difference() { + square([length, height]); + + hole_positions() + horihole($r, $z); + } + } + } + if(t == thickness) + translate([length / 2, 0]) + rounded_rectangle([length + 2 * overlap_x, thickness + 2 * overlap_y, 2], 5); +} + +module horiholes() { + stl_colour(pp1_colour) + rotate([-90, 0, 0]) + horiholes_stl(eps); + + if(show_disc) + hole_positions() + color(silver) + cylinder(r = $r, h = eps, center = true, $fn = 360); + + hole_positions() + color("red") + linear_extrude(2 * eps, center = true) + //offset(0.01, $fn = 360) + intersection() { + difference() { + square(8, center = true); + + horihole($r, $z); + } + + circle($r, $fn = 360); + } +} + +if($preview) + rotate(is_undef($bom) ? 0 : [70, 0, 315]) + horiholes(); +else + horiholes_stl(); diff --git a/tests/png/flat_hinge.png b/tests/png/flat_hinge.png index b228a2d..e91bf77 100644 Binary files a/tests/png/flat_hinge.png and b/tests/png/flat_hinge.png differ diff --git a/tests/png/horiholes.png b/tests/png/horiholes.png new file mode 100644 index 0000000..573240c Binary files /dev/null and b/tests/png/horiholes.png differ diff --git a/tests/png/teardrops.png b/tests/png/teardrops.png index 6c28aa4..b04ef9d 100644 Binary files a/tests/png/teardrops.png and b/tests/png/teardrops.png differ diff --git a/utils/core/teardrops.scad b/utils/core/teardrops.scad index 79f27e5..24e84a5 100644 --- a/utils/core/teardrops.scad +++ b/utils/core/teardrops.scad @@ -20,18 +20,24 @@ // //! For making horizontal holes that don't need support material. //! Small holes can get away without it, but they print better with truncated teardrops. +//! +//! Using teardrop_plus() or setting the plus option on other modules will elongate the teardrop vertically by the layer height, so when sliced the staircase tips +//! do not intrude into the circle. // -module teardrop(h, r, center = true, truncate = true, chamfer = 0) { //! For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging - module teardrop_2d(r, truncate) { - hull() { - circle4n(r); - if(truncate) - translate([0, r / 2]) - square([2 * r * (sqrt(2) - 1), r], center = true); - else - polygon([[0, 0], [eps, 0], [0, r * sqrt(2)]]); - } - } +module teardrop(h, r, center = true, truncate = true, chamfer = 0, plus = false) { //! For making horizontal holes that don't need support material, set ```truncate = false``` to make traditional RepRap teardrops that don't even need bridging + module teardrop_2d(r, truncate) + hull() + for(y = plus ? [-1 : 1] : 0) + translate([0, y * (layer_height / 2 - eps)]) { + + circle4n(r); + + if(truncate) + translate([0, r / 2]) + square([2 * r * (sqrt(2) - 1), r], center = true); + else + polygon([[0, 0], [eps, 0], [0, r * sqrt(2)]]); + } render(convexity = 5) extrude_if(h, center) @@ -40,23 +46,23 @@ module teardrop(h, r, center = true, truncate = true, chamfer = 0) { //! For mak teardrop_chamfer(h, center, chamfer) { linear_extrude(eps, center = true) teardrop_2d(r + chamfer / 2, truncate); + translate_z(-chamfer / 2) linear_extrude(eps, center = true) teardrop_2d(r, truncate); } } -module semi_teardrop(h, r, d = undef, center = true, chamfer = 0) { //! A semi teardrop in the positive Y domain - module semi_teardrop_2d(r, d) { +module semi_teardrop(h, r, d = undef, center = true, chamfer = 0, plus = false) { //! A semi teardrop in the positive Y domain + module semi_teardrop_2d(r, d) intersection() { R = is_undef(d) ? r : d / 2; - teardrop(r = R, h = 0); + teardrop(r = R, h = 0, plus = plus); sq = R + 1; translate([-sq, 0]) square([2 * sq, sq]); } - } render(convexity = 5) extrude_if(h, center) @@ -65,22 +71,21 @@ module semi_teardrop(h, r, d = undef, center = true, chamfer = 0) { //! A semi t teardrop_chamfer(h, center, chamfer) { linear_extrude(eps, center = true) semi_teardrop_2d(r + chamfer / 2, d); + translate_z(-chamfer / 2) linear_extrude(eps, center = true) semi_teardrop_2d(r, d); } } -module teardrop_plus(h, r, center = true, truncate = true, chamfer = 0) //! Slightly bigger teardrop to allow for the 3D printing staircase effect - teardrop(h, r + layer_height / 4, center, truncate, chamfer); +module teardrop_plus(h, r, center = true, truncate = true, chamfer = 0) //! Slightly elongated teardrop to allow for the 3D printing staircase effect + teardrop(h, r, center, truncate, chamfer, plus = true); -module tearslot(h, r, w, center = true, chamfer = 0) { //! A horizontal slot that doesn't need support material - module tearslot_2d(r, w) { - hull() { - translate([-w / 2, 0]) teardrop(r = r, h = 0); - translate([w / 2, 0]) teardrop(r = r, h = 0); - } - } +module tearslot(h, r, w, center = true, chamfer = 0, plus = false) { //! A horizontal slot that doesn't need support material + module tearslot_2d(r, w) + hull() + for(x = [-1, 1]) + translate([x * w / 2, 0]) teardrop(r = r, h = 0, plus = plus); extrude_if(h, center) tearslot_2d(r, w); @@ -88,19 +93,19 @@ module tearslot(h, r, w, center = true, chamfer = 0) { //! A horizontal slot tha teardrop_chamfer(h, center, chamfer) { linear_extrude(eps, center = true) tearslot_2d(r + chamfer / 2, w); + translate_z(-chamfer / 2) linear_extrude(eps, center = true) tearslot_2d(r, w); } } -module vertical_tearslot(h, r, l, center = true, chamfer = 0) { //! A vertical slot that doesn't need support material - module vertical_tearslot_2d(r, l) { - hull() { - translate([0, l / 2]) teardrop(0, r, true); - translate([0, -l / 2]) circle4n(r); - } - } +module vertical_tearslot(h, r, l, center = true, chamfer = 0, plus = false) { //! A vertical slot that doesn't need support material + module vertical_tearslot_2d(r, l) + hull() + for(y = [-1, 1]) + translate([0, y * l / 2]) + teardrop(0, r, true, plus = plus); extrude_if(h, center) vertical_tearslot_2d(r, l); @@ -108,6 +113,7 @@ module vertical_tearslot(h, r, l, center = true, chamfer = 0) { //! A vertical s teardrop_chamfer(h, center, chamfer) { linear_extrude(eps, center = true) vertical_tearslot_2d(r + chamfer / 2, l); + translate_z(-chamfer / 2) linear_extrude(eps, center = true) vertical_tearslot_2d(r, l); @@ -123,4 +129,3 @@ module teardrop_chamfer(h, center, chamfer) { //! Helper module for adding chamf hull() children(); } - diff --git a/utils/horiholes.scad b/utils/horiholes.scad new file mode 100644 index 0000000..4328e80 --- /dev/null +++ b/utils/horiholes.scad @@ -0,0 +1,49 @@ +// +// NopSCADlib Copyright Chris Palmer 2020 +// nop.head@gmail.com +// hydraraptor.blogspot.com +// +// This file is part of NopSCADlib. +// +// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the +// GNU General Public License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with NopSCADlib. +// If not, see . +// + +// +//! Utilities for depicting the staircase slicing of horizontal holes made with [`teardrop_plus()`](#teardrops). +// +include <../utils/core/core.scad> + +function teardrop_x(r, y) = //! Calculate the ordinate of a teardrop given y. Sweeping y from -r to + r yields the positive X half of the shape. + let(x2 = sqr(r) - sqr(y)) + y > r / sqrt(2) ? y >= r ? 0 + : r * sqrt(2) - y + : x2 > 0 ? sqrt(x2) + : 0; + +function teardrop_plus_x(r, y, h) = //! Calculate the ordinate of a compensated teardrop given y. + y < -h ? teardrop_x(r, y + h) + : y > h ? teardrop_x(r, y - h) + : r; + +module horihole(r, z, h = 0, center = true) { //! For making horizontal holes that don't need support material and are correct dimensions + bot_layer = floor((z - r) / layer_height); + top_layer = ceil((z + r) / layer_height); + render(convexity = 5) + extrude_if(h, center) + for(i = [bot_layer : top_layer]) { + Z = i * layer_height; + x = teardrop_plus_x(r, Z - z + layer_height / 2, layer_height / 2); + if(x > 0) + translate([-x, Z - z]) + square([2 * x, layer_height]); + } +}