Models

funnel.scad

Source: funnel.scad
/**
 * @file funnel.scad
 * @brief Generate a funnel shape using the given parameters.
 * @author Cameron K. Brooks
 * @copyright 2025
 *
 * This file contains modules for generating a funnel shape using the given parameters.
 * Uses polygon() and rotate_extrude() to create the funnel shape in an efficient manner.
 *
 */

/* [Funnel] */
// Height of the cone (mm)
funnel_height = 60; // [10:1:200]
// Inside radius at the top of the cone (mm)
funnel_top_radius = 50; // [10:1:150]
// Height of the straight throat below the cone (mm)
throat_height = 20; // [5:1:100]
// Inside radius of the throat (mm)
throat_radius = 15; // [2:0.5:60]
// Wall thickness, square to the wall (mm)
wall_thickness = 0.8; // [0.4:0.1:4]
// Height of the straight rim above the cone (mm)
top_edge_height = 5; // [0:1:30]

funnel(funnel_height = funnel_height, funnel_top_radius = funnel_top_radius, throat_height = throat_height,
       throat_radius = throat_radius, wall_thickness = wall_thickness, top_edge_height = top_edge_height);

/*
 * @brief Generate a funnel shape using the given parameters.
 *
 * @param funnel_height Height of the funnel section.
 * @param funnel_top_radius Inner radius of the funnel's top.
 * @param throat_height Vertical height of the throat section.
 * @param throat_radius Inner radius of the throat.
 * @param wall_thickness Thickness of the funnel wall, measured square to the wall.
 * @param top_edge_height Additional height at the funnel's top edge.
 * @param smoothness_segments Number of segments for a smooth rotation.
 */
module funnel(funnel_height, funnel_top_radius, throat_height, throat_radius, wall_thickness, top_edge_height,
              smoothness_segments = 128)
{
    rotate_extrude($fn = smoothness_segments)
        polygon(funnel_profile(funnel_height, funnel_top_radius, throat_height, throat_radius, wall_thickness,
                               top_edge_height));
}

/*
 * @brief The funnel's cross-section as [radius, height] points, inside wall
 * first from the bottom of the throat to the top edge, then back down the
 * outside.
 *
 * The outside of the sloped section is parallel to the inside and
 * wall_thickness away from it, so its corners sit below the inside ones by
 * wall_thickness * (slope length - funnel_height) / (top radius - throat radius).
 */
function funnel_profile(funnel_height, funnel_top_radius, throat_height, throat_radius, wall_thickness,
                        top_edge_height) =
    let(run = funnel_top_radius - throat_radius, slope = norm([ run, funnel_height ]),
        drop = wall_thickness * (slope - funnel_height) / run,
        top = throat_height + funnel_height + top_edge_height)
        assert(run > 0, "funnel_top_radius must be larger than throat_radius")
            assert(drop < throat_height, str("throat_height must be more than ", drop,
                                             " mm, or the outside of the slope runs below the throat"))
                [
                    [ throat_radius, 0 ], [ throat_radius, throat_height ],
                    [ funnel_top_radius, throat_height + funnel_height ], [ funnel_top_radius, top ],
                    [ funnel_top_radius + wall_thickness, top ],
                    [ funnel_top_radius + wall_thickness, throat_height + funnel_height - drop ],
                    [ throat_radius + wall_thickness, throat_height - drop ], [ throat_radius + wall_thickness, 0 ]
                ];

funnel.scad on GitHub

funnel_with_fins.scad

Source: funnel_with_fins.scad
/**
 * @file funnel_with_fins.scad
 * @brief Generate a funnel with fins and an air gap for vase mode printing.
 * @author Adapted by Cameron K. Brooks from the original design by DrJones
 * @copyright 2025
 *
 * This file contains modules for generating a funnel with a cone section, stem, air gap, and turbo fins using the given
 * parameters.
 *
 * Adapted from:
 * vase mode parametric funnel v2
 * by DrJones   printables.com/@DrJones   makerworld.com/@DrJones
 * License: CC-BY
 * Source: https://www.printables.com/model/895032-parametric-vase-mode-funnel-v2
 * This adaptation is under the MIT license in this repository's LICENSE.
 *
 * Printing:
 *    Use VASE MODE and set EXTUSION WIDTH (LINE WIDTH) to 0.7mm
 *
 */

/* [Cone] */
// Outer diameter of the wide end (mm)
outer_diameter = 100; // [20:150]
// Included angle of the cone (degrees)
cone_angle = 60; // [30:100]

/* [Stem] */
// Stem diameter where it meets the cone (mm)
stem_diameter = 20; // [10:60]
// Length of the stem (mm)
stem_length = 50; // [5:150]
// How much narrower the stem's end is, as a % of its diameter
stem_taper = 15; // [0:50]
// Diameter of the air gap channel, as a % of the stem diameter; 0 for none
air_gap_percentage = 40; // [0:70]

/* [Fins] */
// Type of "turbo" fins
fin_type = 1; // [0:off, 1:common fins, 2:improved]
// Number of fins
fin_count = 10; // [0:15]
// How far the fins twist (degrees)
fin_twist_angle = 45; // [0:60]
// Twist direction
fin_direction = 0; // [0:clockwise, 1:counterclockwise]
// How deep the fins reach into the cone (mm)
fin_depth = 3; // [1:8]

/* [Hidden] */
$fn = $preview ? 128 : 128 * 2;

finned_funnel(outer_diameter, cone_angle, stem_diameter, stem_length, stem_taper, air_gap_percentage, fin_type,
              fin_count, fin_twist_angle, fin_direction, fin_depth);

/**
 * @brief: Module to create a funnel with fins and an air gap.
 *
 * This module creates a funnel with a cone section, a stem section, an air gap, and fins.
 *
 * @param outer_d: Outer diameter of the funnel.
 * @param cone_ang: Cone angle of the funnel.
 * @param stem_d: Stem diameter of the funnel.
 * @param stem_len: Length of the stem.
 * @param stem_tap: Taper percentage of the stem.
 * @param air_gap_pct: Air gap diameter as a percentage of the stem diameter.
 * @param fin_typ: Type of "turbo" fins.
 * @param fin_ct: Number of fins.
 * @param fin_twist_ang: Twist angle of the fins.
 * @param fin_dir: Twist direction of the fins.
 * @param fin_dep: Depth of the fins.
 */
module finned_funnel(outer_d, cone_ang, stem_d, stem_len, stem_tap, air_gap_pct, fin_typ, fin_ct, fin_twist_ang,
                     fin_dir, fin_dep)
{

    // Derived values:
    cone_h = (outer_d - stem_d) / 2 / tan(cone_ang / 2);
    air_gap_d = stem_d * air_gap_pct / 100;

    difference()
    {
        union()
        {
            // Cone section: from the outer diameter to the stem diameter.
            cylinder(h = cone_h, d1 = outer_d, d2 = stem_d);
            // Stem section: translated upward by the cone height.
            translate([ 0, 0, cone_h ]) cylinder(h = stem_len, d1 = stem_d, d2 = stem_d * (1 - stem_tap / 100));
        }
        if (air_gap_pct > 0)
            airgap(outer_d, cone_ang, stem_d, cone_h, stem_len, stem_tap, air_gap_d);
        if (fin_typ == 1)
            fins_original(outer_d, cone_h, stem_d, fin_ct, fin_twist_ang, fin_dir, fin_dep);
        if (fin_typ == 2)
            improved_fins(outer_d, cone_h, stem_d, fin_ct, fin_twist_ang, fin_dir, fin_dep);
    }

    // Thumb tab: a small cylinder translated along X.
    translate([ outer_d / 2 - tan(cone_ang / 2), 0, 0 ]) cylinder(h = 2, d = 5 + outer_d * 0.05);
}

/**
 *  @brief: Module to create an air gap in the funnel.
 *
 * This module creates an air gap in the funnel to allow air to escape.
 *
 *  @param outer_d: Outer diameter of the funnel.
 *  @param cone_ang: Cone angle of the funnel.
 *  @param stem_d: Stem diameter of the funnel.
 *  @param cone_h: Height of the cone section.
 *  @param stem_len: Length of the stem.
 *  @param stem_tap: Taper percentage of the stem.
 *  @param air_gap_d: Diameter of the air gap.
 */
module airgap(outer_d, cone_ang, stem_d, cone_h, stem_len, stem_tap, air_gap_d)
{
    air_gap_rot_ang = cone_ang / 2 + air_gap_d * cos(cone_ang / 2) * 28.6 / (cone_h - 2);
    stem_ext_ang = atan((stem_d * stem_tap / 100) / 2 / stem_len);

    translate([ stem_d / 2, 0, cone_h ])
    {
        sphere(d = air_gap_d);
        rotate([ 0, 180 - air_gap_rot_ang, 0 ]) cylinder(h = sqrt(outer_d * outer_d / 4 + cone_h ^ 2), d = air_gap_d);
        rotate([ 0, -stem_ext_ang, 0 ]) cylinder(h = stem_len + 10, d = air_gap_d);
    }
}

/**
 * @brief: Module to create the original turbo fins.
 *
 * This module creates the original turbo fins for the funnel.
 *
 * @param outer_d: Outer diameter of the funnel.
 * @param cone_h: Height of the cone section.
 * @param stem_d: Stem diameter of the funnel.
 * @param fin_ct: Number of fins.
 * @param fin_twist_ang: Twist angle of the fins.
 * @param fin_dir: Twist direction of the fins.
 */
module fins_original(outer_d, cone_h, stem_d, fin_ct, fin_twist_ang, fin_dir, fin_dep)
{
    difference()
    {
        mirror([ 0, fin_dir, 0 ]) union() for (fin_ang = [2.5 + 360 / outer_d:360 / fin_ct:359])
            rotate([ 0, 0, fin_ang ]) linear_extrude(cone_h, twist = -tan(fin_twist_ang) * 2 * 57.3 * cone_h / outer_d)
                translate([ stem_d / 2 + 3, 0, 0 ]) square([ outer_d / 2, 0.1 ]);
        cylinder(h = cone_h - fin_dep, d1 = outer_d - 2 * fin_dep, d2 = stem_d);
    }
}

/**
 * @brief: Module to create the improved turbo fins.
 *
 * This module creates the improved turbo fins for the funnel.
 *
 * @param outer_d: Outer diameter of the funnel.
 * @param cone_h: Height of the cone section.
 * @param stem_d: Stem diameter of the funnel.
 * @param fin_ct: Number of fins.
 * @param fin_twist_ang: Twist angle of the fins.
 * @param fin_dir: Twist direction of the fins.
 */
module improved_fins(outer_d, cone_h, stem_d, fin_ct, fin_twist_ang, fin_dir, fin_dep, n = 12)
{
    sub_h = cone_h / n;
    twist_fact = -tan(fin_twist_ang) * 2 * 57.3 * sub_h;

    // Recursive helper module
    module sub(i)
    {
        if (i < n)
        {
            current_d = outer_d + (i + 0.5) * sub_h / cone_h * (stem_d - outer_d);
            section_twist = twist_fact / current_d;
            for (fin_ang = [2.5 + 360 / outer_d:360 / fin_ct:359])
                rotate([ 0, 0, fin_ang ]) linear_extrude(sub_h, twist = section_twist)
                    translate([ stem_d / 2 + 3, 0, 0 ]) square([ current_d / 2, 0.1 ]);
            translate([ 0, 0, sub_h ]) rotate([ 0, 0, -section_twist ]) sub(i + 1);
        }
    }

    mirror([ 0, fin_dir, 0 ]) difference()
    {
        sub(0);
        cylinder(h = cone_h - fin_dep, d1 = outer_d - 2 * fin_dep, d2 = stem_d);
    }
}

funnel_with_fins.scad on GitHub


This site uses Just the Docs, a documentation theme for Jekyll.