Skip to content

chore: bump OCCTSwift floor to 2.0.0, fix #168 and AAG face-index breaks - #172

Merged
gsdali merged 2 commits into
mainfrom
chore/repin-occtswift-2.0.0
Aug 10, 2026
Merged

gsdali merged 2 commits into
mainfrom
chore/repin-occtswift-2.0.0

Conversation

@gsdali

@gsdali gsdali commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

What & why

OCCTSwift v2.0.0 (2026-08-09) is a correctness major: 17 breaking API changes (12 compile errors, 5 silent value changes), full table in docs/SEMVER.md#v200. This bumps the direct pin and fixes what the audit found.

#168 (already open, P1): Shape.centerOfMass returns nil instead of the bounding-box centre for anything enclosing no volume (OCCTSwift#605) — every vertex-anchor site now reads Shape.vertices() via a new SelectionTools.vertexPoint(_:) helper instead (SelectionTools, RemapTools, two CorrespondenceTools sites). TopologyIdentityTests' face/edge/vertex round-trip moved to surfaceInertia/edgeMidpoint/vertexPoint since centerOfMass no longer works as a generic identity probe.

AAG face-index scoping (#642/#699): AAG.detectPockets()/detectHoles()'s floorFaceIndex/wallFaceIndices/faceIndex are now occurrence indices into orientedFaces(), not faces() — only diverges on a body with a face shared between two solids (a boolean/pattern result). Three consumers fixed:

  • GapFillerTools.selectByFeature: mintFaceSelection now indexes orientedFaces() directly — this was silently grabbing the wrong face on a shared-face compound, a confirmed real bug, not just a theoretical risk.
  • AutoDimensionTool.autoDimension: converts to distinctFaceIndex before calling edgesInFace(at:), which expects a faces()-space index.
  • AnalysisTools.recognizeFeatures/featureRecognize: extracted into a shared buildFeatureReport(shape:bodyId:kinds:) helper (was two independently-copy-pasted blocks) that converts every reported index to the stable distinctFaceIndex before returning it to the LLM caller.

New AAGFaceIndexTests pins all three against a multi-solid fixture (an off-center blind hole, split down the middle so the cut face is shared between the two halves).

#541 changed Shape.faces() itself to the deduplicated convention BRepGraph already used, so TopologyIdentityTests.multiShellSharedFaceDivergence (which relied on faces() staying occurrence-based) moved to the still-occurrence-based Shape.orientedFaces().

The remaining compile-error and silent-value-change symbols (PathParser, BisectorPoint, VinertGKResult, selfIntersectionCount, continuityOrder, ContinuityAnalysis, chamfer2D, buildCurves3d, drawMesh/evaluateGrid, nbEdges/nbFaces/nbVertices, and the mass-property surface bar centerOfMass) have zero call sites in this repo.

Update: all four sibling repos have since shipped their own 2.0.0-compatible releases (OCCTSwiftIO v1.7.7, OCCTSwiftMesh v1.7.4, OCCTSwiftTools v1.6.3, OCCTSwiftScripts v1.6.0), so this PR now also re-pins OCCTMCP's own transitive floors to match. swift build && swift test clean (213 tests, 37 suites) against both the local-sibling-checkout path and OCCTMCP_FORCE_REMOTE_DEPS=1 (the real published dependency graph) — this is ready to merge and release.

One known, non-blocking issue surfaced along the way and filed upstream: OCCTSwift#830, a likely kernel regression in Shape.pipeShell(solid: true) on a helix spine (~14% volume drift), found via OCCTSwiftScripts' own recipe smoke tests. Not consumed by this repo's own code.

Closes #168
Closes #171

Checklist

  • New or changed behavior is covered by a unit test in the same PR — AAGFaceIndexTests (new) plus the updated TopologyIdentityTests.

Notes for the reviewer

  • The AutoDimensionTool/GapFillerTools bugs this fixes are real but narrow: they only trigger on a body with a face shared between two solids (a boolean or pattern result), never on an ordinary single-solid part.
  • OCCTSwiftViewport and OCCTSwiftAIS needed no re-pin: Viewport has no OCCTSwift dependency at all, and AIS floors OCCTSwiftTools (not OCCTSwift directly) at a version Tools' new release already satisfies.

gsdali and others added 2 commits August 10, 2026 19:17
OCCTSwift v2.0.0 (2026-08-09) is a correctness major: 17 breaking API
changes (12 compile errors, 5 silent value changes). Full audit against
docs/SEMVER.md#v200:

- Fixes #168: Shape.centerOfMass returns nil (not the bounding-box
  centre) for anything enclosing no volume (OCCTSwift#605). Every
  vertex-anchor site now reads Shape.vertices() via a new
  SelectionTools.vertexPoint(_:) helper instead:
  SelectionTools.selectTopology, RemapTools.remapOne,
  CorrespondenceTools (two sites). TopologyIdentityTests' face/edge/
  vertex round-trip updated to surfaceInertia/edgeMidpoint/vertexPoint
  since centerOfMass no longer works as a generic identity probe.

- AAG.detectPockets()/detectHoles()'s floorFaceIndex/wallFaceIndices/
  faceIndex are now occurrence indices into orientedFaces(), not
  faces() (OCCTSwift#642/#699) - only diverges on a body with a face
  shared between two solids (a boolean/pattern result). Three
  consumers fixed:
  - GapFillerTools.selectByFeature: mintFaceSelection now indexes
    orientedFaces() directly (was silently grabbing the wrong face on
    a shared-face compound - a confirmed real bug, not just a risk).
  - AutoDimensionTool.autoDimension: converts to distinctFaceIndex
    before calling edgesInFace(at:), which expects a faces()-space
    index.
  - AnalysisTools.recognizeFeatures/featureRecognize: extracted into
    a shared buildFeatureReport(shape:bodyId:kinds:) helper (was two
    independently-copy-pasted blocks) that converts every reported
    index to the stable distinctFaceIndex before returning it to the
    LLM caller, matching the faces()-space convention every other
    face index in this MCP's surface uses.
  New AAGFaceIndexTests pins all three against a multi-solid fixture
  (an off-center blind hole, split down the middle so the cut face is
  shared between the two halves).

- #541 changed Shape.faces() itself to the deduplicated convention
  BRepGraph already used, so TopologyIdentityTests'
  multiShellSharedFaceDivergence fixture (which relied on faces()
  staying occurrence-based) moved to the still-occurrence-based
  Shape.orientedFaces().

- The remaining compile-error and silent-value-change symbols
  (PathParser, BisectorPoint, VinertGKResult, selfIntersectionCount,
  continuityOrder, ContinuityAnalysis, chamfer2D, buildCurves3d,
  drawMesh/evaluateGrid, nbEdges/nbFaces/nbVertices, and the whole
  mass-property surface bar centerOfMass) have zero call sites here.

swift build && swift test clean (213 tests, 37 suites) against the
real OCCTSwift 2.0.0 tag via the local-sibling-checkout path.

Per issue #171: this repo is a Tier 5 leaf (ecosystem#25) with no
dependents, so the direct pin can move now; the transitive re-pins
(Mesh/Scripts/Tools/IO/AIS) and the actual release wait on those
sibling repos shipping their own 2.0.0-compatible bumps first, since
SwiftPM's `from:` semver ranges won't resolve otherwise.

Addresses #171. Fixes #168.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
OCCTSwiftMesh 1.7.0 -> 1.7.4, OCCTSwiftScripts 1.5.1 -> 1.6.0,
OCCTSwiftTools 1.6.1 -> 1.6.3, OCCTSwiftIO 1.7.0 -> 1.7.7 - each now
requires OCCTSwift >=2.0.0 itself, so the transitive graph resolves
end to end. Verified with OCCTMCP_FORCE_REMOTE_DEPS=1 (the real
published dependency graph, not the local-sibling-checkout shortcut):
swift build && swift test clean, 213 tests / 37 suites.

OCCTSwiftViewport and OCCTSwiftAIS need no change: Viewport has no
OCCTSwift dependency at all, and AIS floors OCCTSwiftTools (not
OCCTSwift directly) at from: "1.6.1", already satisfied by 1.6.3.

Closes #171.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@gsdali
gsdali merged commit 2791442 into main Aug 10, 2026
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.

Bump OCCTSwift floor to 2.0.0 Shape.centerOfMass returns nil for vertices in the next OCCTSwift release: 4 sites collapse onto the origin

1 participant