Skip to content

[Feature Request] Add a way to get the max possible fillet #1067

@qwelyt

Description

@qwelyt

Often times you run into the problem of trying to fillet a thing (sketch, workplane, etc) but you set a too high fillet. You then have the "fun" journey of trying to figure out how much of a fillet you can actually do on your thing. Sometimes it's easy to figure out, other times it is just a pain and a lot of guess work.

Request: Add a built in function that finds the largest possible fillet given a provided acceptable range, or throw error if non can be found (like now).

We had this discussion over at the discord server. (tagging @gumyr and @dcowden as requested, and here is the start of the discussion https://discord.com/channels/964330484911972403/964330484911972406/968844115917824030 ) A function was devised by the good gumyr ( https://discord.com/channels/964330484911972403/964330484911972406/968869046332321822 )

import cadquery as cq
from OCP.StdFail import StdFail_NotDone

test_object1 = (
    cq.Workplane("XY")
    .rect(10, 8)
    .extrude(2)
    .faces(">Z")
    .workplane()
    .rect(8, 6)
    .extrude(1)
)
test_object2 = cq.Workplane("XY").rect(10, 8).extrude(2)
test_object3 = (
    cq.Workplane("XY").polygon(6, 10).workplane(offset=10).polygon(6, 6).loft()
)


def max_fillet(
    object: cq.Workplane,
    window_min: float = 0.0,
    window_max: float = None,
    tolerance=0.1,
) -> float:
    """Recurisely find the largest fillet value that doesn't fail"""
    if window_max is None:
        window_max = object.largestDimension()
    window_mid = (window_min + window_max) / 2
    print(f"{window_min=},{window_mid=},{window_max=}")

    # Do these numbers work - if not try with the smaller window
    try:
        object.edges().fillet(window_mid)
    except StdFail_NotDone:
        return max_fillet(object, window_min, window_mid, tolerance)
    else:
        if not object.edges().fillet(window_mid).val().isValid():
            return max_fillet(object, window_min, window_mid, tolerance)

    # These numbers work, are they close enough - if not try larger window
    if window_mid - window_min <= tolerance:
        return window_mid
    else:
        return max_fillet(object, window_mid, window_max, tolerance)


max_fillet_1 = max_fillet(test_object1)
max_test1 = test_object1.edges().fillet(max_fillet_1)
max_fillet_2 = max_fillet(test_object2)
max_test2 = test_object2.edges().fillet(max_fillet_2)
max_fillet_3 = max_fillet(test_object3)
max_test3 = test_object3.edges().fillet(max_fillet_3)

With perhaps an improvement ( https://discord.com/channels/964330484911972403/964330484911972406/968871675439493200 )

    try:
        trial = object.edges().fillet(window_mid)
    except StdFail_NotDone:
        return max_fillet(object, window_min, window_mid, tolerance)
    else:
        if not trial.val().isValid():
            return max_fillet(object, window_min, window_mid, tolerance)

So, please implement the given solution as a built in function. I'm sure it will save a lot of people a lot of time and pain.

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