Skip to content

Cut an external thread #407

@marcus7070

Description

@marcus7070

I've been trying to cut an external thread, but I am continually running into kernel bugs. The following code (the final cut call in particular) slowly chews up all my 32GB of RAM then starts paging out and I have to kill CQ-editor.

import math
import cadquery as cq


def profile(base, pitch, h, extra=True):
    """
    Creates a trapezoidal wire for the cross section of the thread. If the
    cross section only goes out to the major diameter, then it doesn't cut a
    cylinder for some reason. Set extra=True to extend the cross section beyond
    the major diameter, to be certain it clears the outer surface of the base
    cylinder.
    """
    vertices = [
        base + cq.Vector(-5 / 8 * h, 0, -pitch / 8)
        , base + cq.Vector(0, 0, -7 / 16 * pitch)
    ]
    if extra:
        vertices.extend([
            base + cq.Vector(h, 0, -7 / 16 * pitch)
            , base + cq.Vector(h, 0, 7 / 16 * pitch)
        ])
    vertices.extend([
        base + cq.Vector(0, 0, 7 / 16 * pitch)
        , base + cq.Vector(-5 / 8 * h, 0, pitch / 8)
    ])
    vertices.append(vertices[0])
    return vertices


def thread_solid(pitch=3.5, major_diam=30, length=10, included_angle=60, offset=0):
    """
    Makes a solid representing a metric thread. Can be unioned to a tube with
    ID == major_diam to make an internal thread, or cut from a cylinder with
    OD == major_diam for an external thread. If offset != 0, then the profile
    is offset before sweeping, which can be used to add clearance.
    """
    h = pitch / (2 * math.tan(included_angle / 2 * math.pi / 180))
    base = cq.Vector(major_diam / 2, 0, 0)
    vertices = profile(base, pitch, h)
    profile_wire = cq.Wire.makePolygon(vertices)
    if offset:
        profile_wire = profile_wire.offset2D(offset)[0]  # offset2d returns a list, we need the one and only wire returned
    # make the helical path to sweep
    path = cq.Wire.makeHelix(pitch, length + 2 * pitch, major_diam / 2, center=cq.Vector(0, 0, -pitch))
    thread = cq.Solid.sweep(profile_wire, [], path, isFrenet=True)
    print(thread.isValid())
    return thread


thread = thread_solid(length=20)
screw = (
    cq
    .Workplane(origin=(0, 0, 5))  # make sure the thread cutting tool extends below the screw
    .circle(30 / 2)
    .extrude(10)  # make sure the thread cutting toold extends above the screw
    .cut(thread)
)

Screenshots always help me with these issues, so here is the screw before being cut:
screenshot2020-07-17-205653

Here is the thread that I try to cut from the screw:
screenshot2020-07-17-205902

Here are both objects, showing the overlap:
screenshot2020-07-17-210007

Has anyone got a method to either get this code working, or a method that successfully cuts external threads (using an up to date CadQuery master branch)? I know threads have been done in the past, but I'm basically copying the old CQParts method here and I can't get it to work now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions