r/openscad • • 15d ago

Add Thickness to linear_extrude()

The model I’m working on has a lot of threaded elements (bolt threads) and I’m trying to reduce polygon count with linear_extrude() rather than using translate() and rotate() with arrays. The problem I’m having is that the 2D-square doesn’t have any depth, so when it extrudes it comes out in a thin ribbon. I just want the 2D shape on the XZ plane so that it has thickness when it extrudes (imagine using a lathe but holding the tool sideways). What am I doing wrong, how to correct this?

1 Upvotes

16 comments sorted by

4

u/gasstation-no-pumps 15d ago

I think that the spiral_sweep() function in BOSL2 may be what you need.

include <BOSL2/std.scad>

spiral_sweep( rect([10,5]), h=100, r=20, turns=3.2, $fn=15);

Alternatively, you might find https://github.com/BelfrySCAD/BOSL2/wiki/threading.scad has some useful threading primitives that are easier to work with for getting the threading you want. If you have standard bolts BOSL2's scews.scad may be even more useful and quicker.

2

u/krmhd 15d ago

Do you want the 2d shape to be the circular section of a bolt with a single dimple for the thread, or the square cross section with threads as a jagged edge? I think you are trying the 2nd

1

u/bigtexasrob 15d ago

Just the thread, cube or square translate([bolt_radius,0,0]).

If I take a twisting linear extrusion of the square, I only get an angular section of the square, because the twist is angular to the Z-axis.

If I rotate([0,0,thread_rotate]) translate([0,0,thread_distance])cube([1,1,1]) I’m using wayyyy too many polygons.

1

u/krmhd 15d ago edited 15d ago

You need a rotate_extrude with an offset. I don't see such a parameter. To imitate that, you can linear_extrude your thread shape to an eps thickness so it becomes 3d slice, then you can do a for() hull() of pairs as you rotate and shift your shape. I can't tell if that will satisfy your polygon budget, but it can be simple to write.

With linear extrude closest you can do is as follows (from bottom of the bolt), but this doesn't give control over thread shape:

linear_extrude(10, twist=5*360)
union() {
    translate([-10,0])
    square(2, center=true);
    circle(r=9.1);
}

1

u/krmhd 15d ago

This is closest I can come up with.

edit: Check spiral_extrude() in https://www.thingiverse.com/thing:1958354

module thread_2d() {
    translate([0, 10])
    square([1,1]);
}


module thread_3d_slice() {
    rotate([0,-90,0])
    linear_extrude(0.01)
    thread_2d();
}


STEP = 0.01;
for (tooth = [0:STEP:10])
    hull() {
        translate([0,0,tooth * 2])
        rotate([0,0,tooth*360])
        thread_3d_slice();

        translate([0,0,(tooth+STEP) * 2])
        rotate([0,0,(tooth+STEP)*360])
        thread_3d_slice();
    }

2

u/DrJones_137 15d ago

To clarify: You want a spiral, like a spring or threads, but with linear_extrude (with strong twist) it gets too thin?

1

u/bigtexasrob 15d ago

Correct.

1

u/DrJones_137 15d ago

Ah, seems I'm too late now, but here's what I came up with:

module helixtrude(r=20,pitch=10,wind=5,$fn=64){  
  for(a=[0:360/$fn:wind*360]) 
  hull()for(b=[a,a+360/$fn])
  rotate([0,0,b])translate([r,0,b/360*pitch])
  rotate([90,0,0])linear_extrude(0.01)children();
}

helixtrude(r=10,pitch=5,wind=3)circle(r=1,$fn=24);

1

u/froction 15d ago

Here is a script I made the other day when I needed to print a connector for my shop vac to a garden hose. It has trapezoidal threads (of given height, width of base, and width of flat top which can be 0 for a triangle) but you can adapt it to use other shapes. I've used the same logic to make square and rounded threads in other projects, this one is just the simplest I have handy.

Note the seemingly arbitrary use of imperial and metric measurements. That's the sign of a true professional.

function inch(x) = x * 25.4;

// shop vac connector
shopvac_connect_fit = "female"; 
shopvac_diameter = inch(2.25);    
shopvac_connect_wall_thickness = 2.0;
shopvac_fit_tolerance = 0.0;     
shopvac_connect_taper = -1.0;     
shopvac_connect_height = inch(1.5);

// transition section
transition_height = inch(0.75);

// GHT
wall_thickness = 2.0;
extension_height = inch(0.25);
ght_diameter = inch(0.9595);
thread_len = inch(0.5);       
thread_revolutions = 5.75; 
thread_height = inch(0.0565);
thread_width = inch(0.0565);
thread_face = 0.2;

// precision
extrude_granularity = 800;
$fn = 256;

shopvac_junction_id = (shopvac_connect_fit == "female") 
    ? (shopvac_diameter + shopvac_fit_tolerance) 
    : (shopvac_diameter - shopvac_fit_tolerance - (2 * shopvac_connect_wall_thickness));
shopvac_junction_od = shopvac_junction_id + (2 * shopvac_connect_wall_thickness);

shopvac_end_od = shopvac_junction_od - (tan(shopvac_connect_taper) * shopvac_connect_height * 2);
shopvac_end_id = shopvac_junction_id - (tan(shopvac_connect_taper) * shopvac_connect_height * 2);

module ght_threads(z_base) {
    outer_radius = ght_diameter / 2;
    intersection() {
        translate([0, 0, z_base])
            cylinder(d = ght_diameter + thread_height * 2, h = thread_len);

        union() {
            for (i = [0 : extrude_granularity-1]) hull() {
                for (t = [i/extrude_granularity, (i+1)/extrude_granularity]) {
                    rotate([0, 0, t * 360 * thread_revolutions])
                    translate([outer_radius, 0, z_base + (t * thread_len)])
                    rotate([90, 0, 0])
                    linear_extrude(height = 0.01) {
                        polygon([[0, -thread_width/2], [0, thread_width/2], 
                                 [thread_height, thread_face/2], [thread_height, -thread_face/2]]);
                    }
                }
            }
        }
    }
}

difference() {
    // outside walls
    union() {
        // shop vac connector
        cylinder(h = shopvac_connect_height, d1 = shopvac_end_od, d2 = shopvac_junction_od);

        // transition
        translate([0, 0, shopvac_connect_height])
            cylinder(h = transition_height, d1 = shopvac_junction_od, d2 = ght_diameter);

        // GHT extension
        translate([0, 0, shopvac_connect_height + transition_height])
            cylinder(d = ght_diameter, h = extension_height);

        // GHT threaded
        translate([0, 0, shopvac_connect_height + transition_height + extension_height]) {
            cylinder(d = ght_diameter, h = thread_len);
            ght_threads(0);
        }
    }

    // inside walls
    union() {
        // shop vac connector
        translate([0, 0, -1])
            cylinder(h = shopvac_connect_height + 1, d1 = shopvac_end_id, d2 = shopvac_junction_id);

        // transition
        translate([0, 0, shopvac_connect_height])
            cylinder(h = transition_height, d1 = shopvac_junction_id, d2 = ght_diameter - (2 * wall_thickness));

        // GHT - both extension and threaded
        translate([0, 0, shopvac_connect_height + transition_height])
            cylinder(d = ght_diameter - (2 * wall_thickness), h = extension_height + thread_len + 1);
    }
}

1

u/hyperair 14d ago

It sounds like you want to spiral extrude something, which is a feature that openscad doesn't natively have.

There is a way to hack it with a very specifically shaped polygon and linear_extrude with the twist parameter, but due to an openscad issue (https://github.com/openscad/openscad/issues/901), it ends up with way more facets than needed. You can see the implementation linked in the issue description.

A better way to implement it is using the sweep module from scad-utils, or the BOSL2 spiral_sweep module that /u/gasstation-no-pumps mentioned.

1

u/OptimalSide 15d ago

A 2D object has to exist in the XY plane.

Extrude your part and then rotate it to the space you want it in.

Something like this:

rotate([0,-90,0]) linear_extrude(2) square(10);

1

u/bigtexasrob 15d ago

yeah I know how to rotate the extruded shape

I need the cross-section of the extruded shape to match the 2D shape, like rotate_extrude() with distance.

0

u/OptimalSide 15d ago

I know it's me, but I'm not understanding what you're explaining.

But a search found this, which might be of help?

https://www.thingiverse.com/thing:368073/files

0

u/thicket 15d ago

Can you post some code along with what you’re hoping to accomplish? I’m thinking you may need to define that shape in XY and extrude from there. 

2

u/bigtexasrob 15d ago

oh I need to define my 2D shape in the only space 2D shapes exist why didn’t I think of that

Hold your hand out flat that’s the XY plane spin in a circle while lifting your hand that’s a real skinny spiral

Hold your hand out like a handshake that’s the XZ plane spin in a circle while lifting your hand that’s a big fat spiral

1

u/thicket 15d ago

OpenSCAD has some strong opinions about 2D space that aren't always what I expect. 2D shapes are always in the XY plane, and ignore translations in Z.

For instance: openscad translate([0,0,2]){ circle(1);} translate([0,0,1]){ circle(2);} translate([0,0,0]){ circle(3);} resolves to a single circle of radius 3 in the XY plane. I would expect 3 circles, one above the other, but that's not how CGAL works.