Skip to content

Fix hull failure with collinear circle centres - #2093

Open
kimstik wants to merge 2 commits into
CadQuery:masterfrom
kimstik:hull_fix
Open

Fix hull failure with collinear circle centres#2093
kimstik wants to merge 2 commits into
CadQuery:masterfrom
kimstik:hull_fix

Conversation

@kimstik

@kimstik kimstik commented Sep 8, 2026

Copy link
Copy Markdown

Sketch.hull() fails on three equal circles with collinear centres:

s = cq.Sketch()
for x in (0.0, 8.0, 16.0):
    s = s.arc((x, 0.0), 2.5, 0.0, 360.0)
s.hull()   # StdFail_NotDone: BRep_API: command not done

The tangent line between the outer two circles also touches the middle one, so it
enters the hull spanning zero degrees. finalize_hull() then builds a full circle
instead of a zero-length arc and the wire cannot close.

It only fails about two runs in three: convert_and_validate() returns
list(set(arcs)) and Arc is unhashable, so the traversal order follows id().
Hence the repeats in the test.

Same guard as in #1344, which has been open since June 2023 and bundles three
other changes. This is just that guard, plus a test - happy to close it if #1344
is revived instead.

A circle tangent to the hull without contributing to it enters as a zero-span
arc, which makeCircle turns into a full circle, so the wire cannot close. Skip
such arcs. Intermittent because convert_and_validate returns list(set(arcs))
and Arc is unhashable, so the traversal order follows id().
@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.74%. Comparing base (a6bedc0) to head (534bcec).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2093      +/-   ##
==========================================
+ Coverage   95.67%   95.74%   +0.06%     
==========================================
  Files          30       30              
  Lines        9534     9540       +6     
  Branches     1421     1422       +1     
==========================================
+ Hits         9122     9134      +12     
+ Misses        255      251       -4     
+ Partials      157      155       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@adam-urbanczyk

Copy link
Copy Markdown
Member

I suppose adding __hash__ and __eq__ to Arc would make the test reproducible. Would you be up to it?

@kimstik

kimstik commented Sep 9, 2026

Copy link
Copy Markdown
Author

I suppose adding __hash__ and __eq__ to Arc would make the test reproducible. Would you be up to it?

Absolutely, I was aiming for a minimal, clean, non-intrusive patch. __hash__ and __eq__ are of course cleaner.

@kimstik

kimstik commented Sep 9, 2026

Copy link
Copy Markdown
Author

btw, the type check in __eq__ isn't cosmetic: without it arc == None raises instead of returning False.
It works on master, where Arc has no __eq__ and object.__eq__ defers to the other operand correctly. I added the same check to Point.__eq__ for symmetry

convert_and_validate returns list(set(arcs)); without __hash__ the set was
keyed on id(), so the order varied between runs. Keying on the arc definition
makes it stable, and identical arcs now collapse instead of reaching arc_arc
with a zero distance between centres.

Both __eq__ compare the type first, otherwise == is not commutative between
the two classes, and arc == None would raise instead of returning False.
Strict rather than isinstance: a subclass adding fields would inherit a hash
built from the base fields only.

test_collinear permutes its input instead of repeating it - with a stable
order the repeats would all take the same path.

@adam-urbanczyk adam-urbanczyk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants