Skip to content

Conversation

@tairabun
Copy link

@tairabun tairabun commented Feb 11, 2026

Summary

Sketch.hull() raises ZeroDivisionError when called on faces containing overlapping circles.

Reproducer:

from cadquery import Sketch, Location, Vector

Sketch() \
  .face(Sketch().circle(35).moved(Location(Vector(-19, 0, 0)))) \
  .face(Sketch().circle(35).moved(Location(Vector(19, 0, 0)))) \
  .hull()
# ZeroDivisionError: float division by zero

Traceback:

cadquery/hull.py:262, in arc_arc
    dx /= l
ZeroDivisionError: float division by zero

Root cause

When two circles overlap, boolean face fusion in Sketch.face() splits them into multiple arc segments. Arcs originating from the same circle share the same center point. When the gift-wrapping hull algorithm calls arc_arc() on two such concentric arcs, it computes l = distance_between_centers = 0 and then divides by l.

The hull algorithm was designed for one entity per circle. Multiple arcs per circle (from boolean fusion) violates this assumption.

Fix

Deduplicate arcs by center in convert_and_validate(), keeping one full-circle arc per unique center (with the largest radius). This ensures the hull algorithm sees exactly one entity per original circle, matching its design assumptions.

The fix is entirely in convert_and_validate() — no changes to the hull algorithm itself.

Test plan

  • Added test_hull_overlapping_circles — hull via .push().circle().reset().hull()
  • Added test_hull_overlapping_circles_equal_radii_via_face — hull via .face() composition
  • Verified all 691 existing tests pass (full test suite)
  • Verified the resulting hull face has positive area and can be used with .cutBlind() for 3D operations

When Sketch.hull() is called on faces containing overlapping circles,
boolean face fusion splits the circles into multiple arc segments that
share the same center. The gift-wrapping hull algorithm was not designed
for multiple arcs per circle — it causes a ZeroDivisionError in
arc_arc() (dividing by the zero distance between concentric centers).

The fix deduplicates arcs by center in convert_and_validate(), keeping
one full-circle arc per unique center (with the largest radius). This
ensures the hull algorithm sees exactly one entity per original circle,
matching its design assumptions.

Reproducer:
    Sketch()
      .face(Sketch().circle(35).moved(Location(Vector(-19, 0, 0))))
      .face(Sketch().circle(35).moved(Location(Vector(19, 0, 0))))
      .hull()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tairabun tairabun force-pushed the fix/hull-concentric-arcs-zero-division branch from 3e984ef to d2b5d1c Compare February 11, 2026 23:08
@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.15%. Comparing base (6cd5eeb) to head (d2b5d1c).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1989      +/-   ##
==========================================
+ Coverage   96.07%   96.15%   +0.07%     
==========================================
  Files          29       29              
  Lines        7956     7957       +1     
  Branches     1190     1191       +1     
==========================================
+ Hits         7644     7651       +7     
+ Misses        179      175       -4     
+ Partials      133      131       -2     

☔ View full report in Codecov by Sentry.
📢 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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant