Reusable stainless steel and silicone drinking straws ($\varnothing 6.0\text{ mm}$) have become universal, but identifying individual glasses at social gatherings or family tables remains an annoyance. Decorative straw charms provide an ideal 3D-printing application: small, fast to print ($< 25\text{ minutes}$), and easily customizable.

However, modeling charms with clean organic curves, proper slide-fit tolerances, and comfortable, filleted edges that won’t scratch cups or snag lips is tedious in traditional CAD tools.

Here is how we designed a fully procedural straw charm generator in Blender 5.x using algebraic parametric curves and Python automation.


1. The Mathematical Heart Contour

Rather than manually tracing bezier curves with inconsistent curvatures, the heart silhouette is generated using the classical algebraic formulation:

$$\begin{aligned} x(t) &= w \cdot \sin^3(t) \\ y(t) &= h \cdot \left( 13\cos(t) - 5\cos(2t) - 2\cos(3t) - \cos(4t) \right) / 16 \end{aligned}$$

Sampling $t \in [0, 2\pi)$ across $N = 64$ points creates an aesthetically balanced heart silhouette with a sharp cleft at the top and a defined lower apex:

def generate_heart_points(num_points=64, scale_w=11.5, scale_h=11.5):
    """Generates continuous 2D planar perimeter coordinates for heart."""
    pts = []
    for i in range(num_points):
        t = (2.0 * math.pi * i) / num_points
        x = scale_w * (math.sin(t) ** 3)
        y = scale_h * (13.0 * math.cos(t) - 5.0 * math.cos(2.0 * t) 
                       - 2.0 * math.cos(3.0 * t) - math.cos(4.0 * t)) / 16.0
        pts.append(Vector((x, y, 0.0)))
    return pts

2. Two Distinct Mounting Architectures

We evaluated two structural configurations for mounting onto a standard $\varnothing 6.0\text{ mm}$ metal straw:

    Option 1: Central Bead               Option 3: Rear Offset Sleeve
         .---.---.                            .---.---.
        /    |    \                          /         \
       |     O     |                        |   SOLID   |  (===) <-- Sleeve
        \    |    /                          \         /
         '---'---'                            '---'---'
     (Through-Hole Ø6.4mm)                 (Pristine Solid Front)

Option 1: The Central Bead

  • Concept: A vertical cylindrical through-bore ($\varnothing 6.4\text{ mm}$) runs directly down the vertical center-of-mass of the heart.
  • Pros: Perfectly balanced center of gravity; compact and minimal material usage ($~4.2\text{ g}$).
  • Tradeoff: Punctures the central cleft of the heart, reducing the visual impact of the decorative front.

Option 3: Solid Charm with Rear Sleeve

  • Concept: The decorative heart remains 100% solid and unpunctured. An offset cylindrical sleeve ($\varnothing 6.4\text{ mm}$ ID, $\varnothing 8.8\text{ mm}$ OD) is fused to the rear face.
  • Pros: Complete artistic freedom on the front surface (clean embosses, names, or smooth facets).
  • Tradeoff: Slight forward weight offset, requiring a snug slide-fit tolerance to avoid rotation on the straw.

3. Fit Tolerances for Standard Metal Straws

Standard commercial metal straws measure between $5.95\text{ mm}$ and $6.05\text{ mm}$ in diameter. FDM perimeters printed with a $0.4\text{ mm}$ nozzle exhibit inner diameter shrinkage due to hoop stress and polymer cooling.

Dimension Value Engineering Rationale
Straw Outer Diameter $\varnothing 6.0\text{ mm}$ Nominal commercial stainless steel straw
Charm Bore Diameter $\varnothing 6.4\text{ mm}$ $+0.4\text{ mm}$ radial clearance allows smooth sliding while preventing free fall
Sleeve Wall Thickness $1.2\text{ mm}$ Exactly 3 perimeters ($0.4\text{ mm}$ line width) for rigid mechanical hoop strength
Perimeter Edge Bevel $1.2\text{ mm} \times 45^\circ$ Eliminates sharp 90° edges for comfortable tactile feel

4. Procedural BMesh Construction & Filleting

To guarantee 100% watertight manifold geometry, the script constructs the prism using BMesh:

  1. Create bottom face from the mathematical contour points.
  2. Extrude vertically by prism thickness ($D = 10.0\text{ mm}$).
  3. Inset the top and bottom faces by $1.2\text{ mm}$ and pull the outer perimeter edges inwards to form a smooth rolling chamfer.
  4. Execute bmesh.ops.difference with an exact cylindrical cutter representing the straw bore:
def make_through_hole(bm, diameter=6.4, length=20.0):
    """Executes a high-precision boolean bore through the charm."""
    cutter_mesh = bpy.data.meshes.new("Cutter")
    bm_cutter = bmesh.new()
    bmesh.ops.create_cone(
        bm_cutter,
        cap_ends=True,
        cap_tris=False,
        segments=32,
        radius1=diameter / 2.0,
        radius2=diameter / 2.0,
        depth=length
    )
    # Exact CSG Boolean Difference
    bmesh.ops.boolean(bm, geom1=bm.faces[:], geom2=bm_cutter.faces[:], operation='DIFFERENCE')
    bm_cutter.free()

5. Automated Slicing & Verification

The script automatically verifies manifold integrity before saving:

  • Counts non-manifold edges: asserts len(non_manifold) == 0.
  • Exports straw_heart_charm_option1_bead.stl and straw_heart_charm_option3_offset.stl.
  • Generates a photorealistic preview using Blender’s EEVEE Next engine.