Skip to content

STEP from batched boolean is not watertight: 1267/2641 edges used once, import yields empty solid (rana can) #880

Description

@ecto

Problem

After #877, vcad export --strict-brep of the rana-60-cnc can.loon (ecto/rana branch 60-cnc, cad/parts-60-cnc/can.loon) produces a 379-face analytic STEP whose shell is not closed:

  • STEP declares CLOSED_SHELL / MANIFOLD_SOLID_BREP, 379 ADVANCED_FACE, 30 cylinders + 39 planes — looks right at the entity-count level
  • but of 2 641 EDGE_CURVEs, 1 267 are referenced by exactly one ORIENTED_EDGE (a closed 2-manifold references every edge exactly twice; histogram {1: 1267, 2: 1374})
  • vcad import of the file reports "Imported 1 solid(s)" but writes a 334-byte STL (empty) — the round-trip silently fails
  • Shapr3D (Parasolid) opens it as loose sheets: the floor disc floats, the walls are open rings, bosses are unstitched (screenshot from the user attached in ecto/rana if needed)

Also suspicious for a 30-cyl/39-plane solid: 2 199 LINE edges, 15 795 VERTEX_POINTs — the cylindrical faces look split into many strips with unshared edges, i.e. the batched difference emitted per-face edge copies instead of a shared edge table.

Ask

  • the writer must emit shared edges (one EDGE_CURVE per topological edge, two ORIENTED_EDGEs), or the kernel must merge coincident edges after the batched boolean before writing
  • --strict-brep should fail on a shell whose edge-use histogram isn't all-2s — right now it certifies a non-manifold as B-rep
  • vcad import must error (not write an empty STL) when it can't build a solid
  • regression test: export → import round-trip volume within 0.1 % on the pocketed-disc fixture and on the can, and an assertion that every edge is used exactly twice

Repro: vcad export --strict-brep can.loon can.step && python3 -c "import re,collections;s=open('can.step').read();ec=set(re.findall(r'^#(\d+)\s*=\s*EDGE_CURVE',s,re.M));r=collections.Counter(re.findall(r'ORIENTED_EDGE\s*\(\s*\'[^\']*\'\s*,\s*\*\s*,\s*\*\s*,\s*#(\d+)',s));print(collections.Counter(r[e] for e in ec))"

Follow-up to #872 / #877.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions