Skip to content

recipe 03 chamfer never applies: chamfered() returns nil and the ?? fallback hides it #103

Description

@gsdali

Found during review of #102. Pre-existing, out of scope for that PR.

The defect

recipes/03-pipe-flange/main.swift:64:

flange = flange.chamfered(distance: 1.0) ?? flange

chamfered(distance:) returns nil every time, so the ?? flange fallback fires and no edge
break is ever applied. Verified directly against the fixed solid flange:

flange: solids=1 vol=228707.95
chamfered(1.0) -> nil

The volume arithmetic in #102 independently confirms it. The committed reference volume is
228927.86, which equals 247400.42 - 18472.57 (raw revolve minus the eight bolt holes) to eight
significant figures. A real 1 mm chamfer on the OD alone would remove roughly 235 mm3, about
0.1%, and there is no room for it in that figure.

Why it matters

The recipe advertises the chamfer in three places: the file header, the README prose, and the
"OCCTSwift APIs used" list. So the recipe ships something other than what it documents, and the
?? fallback is what hides it.

This is the same failure shape as #100 itself: an operation silently degrades, the output still
looks plausible by every metric measured, and nothing asserts the thing that was actually
requested.

Suggested fix

Two parts, and the second matters more than the first:

  1. Work out why the chamfer fails. An all-edge chamfer on a revolved solid hits the seam
    edge and the circular edges at the bore and OD. Likely one of those is unchamferable at 1 mm.
    Selecting specific edges (the OD and the raised-face step) rather than all of them is the
    usual fix, and matches how recipe 01 selects with concaveEdges.
  2. Stop silently swallowing the failure. ?? flange should not be how an advertised feature
    degrades. Either fail loudly, or drop the chamfer from the recipe and its docs. A recipe is a
    reference example, so a silent no-op is worse here than in ordinary code.

If the chamfer turns out to be genuinely unsupportable on this shape, removing it from the code
and all three doc mentions is a perfectly good outcome. What should not persist is code that
claims to do it and does not.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions