You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of the bridge duplication audit in #381 (Pass 1b, itself a sub-issue of #377 — parallel to Pass 1a / #380). Per #377's ordering rule, triage or fix this before starting #395 (the OCCTBridge.h breakout, which depends on #381). Branch: refactor/381-pass1b — a dedicated branch for Pass 1b, separate from Pass 1a's refactor/377-segmented-audit while that branch is still under code review. PRs from this issue target refactor/381-pass1b, not main.
Duplication site
Cross-reference index (both entries stale/wrong):
Sources/OCCTBridge/include/OCCTBridge.h:426 — // ShapeFix_Face → OCCTShapeFixFace — this symbol does not exist anywhere in the codebase (confirmed via grep across Sources/ and Tests/).
Sources/OCCTBridge/include/OCCTBridge.h:427 — // ShapeFix_FaceConnect → OCCTShapeFixConnect* — this symbol also does not exist; the real function is OCCTShapeFixFaceConnect (missing the Face infix, and not a wildcard family — it's a single function).
Real ShapeFix_Face call sites (4 total, none named OCCTShapeFixFace):
Sources/OCCTBridge/src/OCCTBridge_Healing.mm:299-325 — OCCTShapeRef OCCTFaceFix(OCCTFaceRef face, double tolerance), declared OCCTBridge.h:1928. Constructs Handle(ShapeFix_Face) fixer = new ShapeFix_Face(face->face) at line 303. Does NOT call SetContext().
Sources/OCCTBridge/src/OCCTBridge_Healing.mm:4326-4342 — OCCTFaceFixerRef OCCTFaceFixerCreate(OCCTShapeRef face, double precision), declared OCCTBridge.h:16781 (struct OCCTFaceFixerRef typedef at 16778). Constructs ref->fixer = new ShapeFix_Face(...) at line 4334, then calls ref->fixer->SetContext(new ShapeBuild_ReShape) at line 4338 with an explicit #317 comment. One of the three sites the SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 fix (CLAUDE.md) patched.
Two things have actually drifted, both stemming from the same stale-index root cause:
The index entries are simply wrong — OCCTShapeFixFace and OCCTShapeFixConnect* are phantom symbols that were presumably renamed at some point (to the OCCTFaceFix/OCCTFaceFixer* family and to OCCTShapeFixFaceConnect respectively) without the index being updated. Anyone using the index as a map from OCCT class to bridge symbol gets zero hits searching for either name.
Separately, ShapeFix_FaceConnect's single real call site (OCCTShapeFixFaceConnect, backing Shape.connectedFaces(tolerance:)) has zero test coverage anywhere in Tests/ — grepping connectedFaces across the whole repo turns up only its own declaration in Shape.swift. The stale OCCTShapeFixConnect* index entry (with a wildcard, implying a family of functions) would not have led anyone to this single, untested, real function either.
Swift call sites
OCCTFaceFix → Sources/OCCTSwift/Shape.swift:3317, inside extension Face { public func fixed(tolerance: Double = 1e-6) -> Shape? } (declared ~Shape.swift:3316).
OCCTFaceFixerCreate/OCCTFaceFixerPerform/OCCTFaceFixerFixOrientation/OCCTFaceFixerFixAddNaturalBound/OCCTFaceFixerFixMissingSeam/OCCTFaceFixerFixSmallAreaWire/OCCTFaceFixerFace/OCCTFaceFixerSetMode/OCCTFaceFixerFixIntersectingWires/OCCTFaceFixerFixPeriodicDegenerated/OCCTFaceFixerFixWiresTwoCoincEdges/OCCTFaceFixerFixLoopWire/OCCTFaceFixerResult/OCCTFaceFixerStatus/OCCTFaceFixerSetMaxTolerance/OCCTFaceFixerSetMinTolerance/OCCTFaceFixerRelease → all called from public final class FaceFixer in Sources/OCCTSwift/Document.swift:12029-~12126 (despite the name, the class lives in Document.swift, not Face.swift/Shape.swift).
OCCTShapeFixFaceConnect → Sources/OCCTSwift/Shape.swift:7507, inside public func connectedFaces(tolerance: Double = 1e-4) -> Shape?. No other Swift call site.
Shape.face(from:boundary:) (OCCTShapeCreateFaceFromSurfaceWire): the SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 regression test lives here — Tests/OCCTSurfaceTests/Issue317PeriodicConicalSingleWireTests.swift, test closedEdgeOnConeSurvivesHealing(), plus general coverage in Tests/OCCTSurfaceTests/Issue233FaceFromSurfaceWireTests.swift, OCCTSurfaceTests.swift, Tests/OCCTModelingTests/OCCTModelingTests.swift, Issue234DegenerateHoleTests.swift, Issue397CircularHoleTests.swift, Tests/OCCTTopologyTests/Issue211OuterShellTests.swift, Issue439OuterShellMultiSolidTests.swift, and others.
Shape.face(from:outer:innerWires:) (OCCTShapeCreateFaceFromSurfaceWireWithHoles): tested in Tests/OCCTSurfaceTests/Issue266FaceWithHolesTests.swift (lines 27, 42, 63, 83) and Tests/OCCTSurfaceTests/Issue266FaceAnalysisFollowupTests.swift (lines 56, 72), plus Tests/OCCTShapeHealingTests/OCCTShapeHealingTests.swift:2527. No specific periodic-conical-boundary regression test found for this call site either, though it already carries the SetContext fix.
Shape.connectedFaces(tolerance:) (OCCTShapeFixFaceConnect): no test coverage found anywhere in Tests/ — grepping connectedFaces repo-wide returns only the function's own declaration in Shape.swift.
Underlying OCCT functions
OCCTFaceFix (OCCTBridge_Healing.mm:299-325): ShapeFix_Face — constructs with new ShapeFix_Face(face->face), sets SetPrecision, FixWireMode, FixOrientationMode, FixAddNaturalBoundMode, FixMissingSeamMode, FixSmallAreaWireMode, then calls Perform() and Face().
OCCTFaceFixerCreate + the OCCTFaceFixer* family (OCCTBridge_Healing.mm:4330-~4463): ShapeFix_Face, wrapped per-instance to expose individual fixes: SetContext, SetPrecision, Perform, FixOrientation, FixAddNaturalBound, FixMissingSeam, FixSmallAreaWire(true), Face(), plus mode/tolerance accessors (FixIntersectingWires, FixPeriodicDegenerated, FixWiresTwoCoincEdges, FixLoopWire, Status, SetMaxTolerance, SetMinTolerance).
OCCTShapeCreateFaceFromSurfaceWire (OCCTBridge_Modeling.mm:2239-2263): BRepBuilderAPI_MakeFace(surf, wire->wire, Standard_True) to build the initial face, then ShapeFix_Face (SetContext, Perform, Face()) to project pcurves, then BRepLib::BuildCurves3d and BRepCheck_Analyzer to validate.
OCCTShapeCreateFaceFromSurfaceWireWithHoles (OCCTBridge_Modeling.mm:2264-2298): same pattern — BRepBuilderAPI_MakeFace (with .Add(hole) per inner wire, holes reversed on the first attempt), then ShapeFix_Face (SetContext, Perform, Face()), BRepLib::BuildCurves3d, BRepCheck_Analyzer.
OCCTShapeFixFaceConnect (OCCTBridge_Healing.mm:2149-~2178+): ShapeFix_FaceConnect — construction on a shell extracted from the input shape (TopoDS::Shell cast, or the first TopAbs_SHELL found via TopExp_Explorer), then connects face pairs (a distinct OCCT class from ShapeFix_Face, despite the near-identical name).
Original audit finding: Cross-reference index: ShapeFix_Face → OCCTShapeFixFace (line 426) — that symbol doesn't exist; ShapeFix_Face is actually wrapped by the handle-based OCCTFaceFixer* family (OCCTBridge_Healing.mm:4324-4396, header:16781 on) plus several inline uses (e.g. OCCTBridge_Modeling.mm:2251) that the index entry doesn't mention at all.
Part of the bridge duplication audit in #381 (Pass 1b, itself a sub-issue of #377 — parallel to Pass 1a / #380). Per #377's ordering rule, triage or fix this before starting #395 (the OCCTBridge.h breakout, which depends on #381). Branch:
refactor/381-pass1b— a dedicated branch for Pass 1b, separate from Pass 1a'srefactor/377-segmented-auditwhile that branch is still under code review. PRs from this issue targetrefactor/381-pass1b, notmain.Duplication site
Cross-reference index (both entries stale/wrong):
Sources/OCCTBridge/include/OCCTBridge.h:426—// ShapeFix_Face → OCCTShapeFixFace— this symbol does not exist anywhere in the codebase (confirmed via grep acrossSources/andTests/).Sources/OCCTBridge/include/OCCTBridge.h:427—// ShapeFix_FaceConnect → OCCTShapeFixConnect*— this symbol also does not exist; the real function isOCCTShapeFixFaceConnect(missing theFaceinfix, and not a wildcard family — it's a single function).Real
ShapeFix_Facecall sites (4 total, none namedOCCTShapeFixFace):Sources/OCCTBridge/src/OCCTBridge_Healing.mm:299-325—OCCTShapeRef OCCTFaceFix(OCCTFaceRef face, double tolerance), declaredOCCTBridge.h:1928. ConstructsHandle(ShapeFix_Face) fixer = new ShapeFix_Face(face->face)at line 303. Does NOT callSetContext().Sources/OCCTBridge/src/OCCTBridge_Healing.mm:4326-4342—OCCTFaceFixerRef OCCTFaceFixerCreate(OCCTShapeRef face, double precision), declaredOCCTBridge.h:16781(structOCCTFaceFixerReftypedef at16778). Constructsref->fixer = new ShapeFix_Face(...)at line 4334, then callsref->fixer->SetContext(new ShapeBuild_ReShape)at line 4338 with an explicit#317comment. One of the three sites the SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 fix (CLAUDE.md) patched.Sources/OCCTBridge/src/OCCTBridge_Modeling.mm:2239-2263—OCCTShapeRef OCCTShapeCreateFaceFromSurfaceWire(OCCTSurfaceRef surface, OCCTWireRef wire), declaredOCCTBridge.h:4536. ConstructsShapeFix_Face fixer(face)at line 2251, callsfixer.SetContext(new ShapeBuild_ReShape)at line 2252, with an explicit#317comment. Second of the three SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317-patched sites.Sources/OCCTBridge/src/OCCTBridge_Modeling.mm:2264-2298—OCCTShapeRef OCCTShapeCreateFaceFromSurfaceWireWithHoles(...), declaredOCCTBridge.h:4543. ConstructsShapeFix_Face fixer(face)at line 2291, callsfixer.SetContext(new ShapeBuild_ReShape)at line 2292, with an explicit#317comment. Third of the three SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317-patched sites.Real
ShapeFix_FaceConnectcall site (1 total, not namedOCCTShapeFixConnect*):Sources/OCCTBridge/src/OCCTBridge_Healing.mm:2149-2178—OCCTShapeRef OCCTShapeFixFaceConnect(OCCTShapeRef shape, double tolerance), declaredOCCTBridge.h:6201.Divergence
Two things have actually drifted, both stemming from the same stale-index root cause:
The index entries are simply wrong —
OCCTShapeFixFaceandOCCTShapeFixConnect*are phantom symbols that were presumably renamed at some point (to theOCCTFaceFix/OCCTFaceFixer*family and toOCCTShapeFixFaceConnectrespectively) without the index being updated. Anyone using the index as a map from OCCT class to bridge symbol gets zero hits searching for either name.A concrete, currently-live consequence, exactly as CLAUDE.md's own SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 entry warns about: CLAUDE.md documents that
ShapeFix_Face::FixPeriodicDegenerated()SIGSEGVs (uncatchable, since it's an OS signal) via an unguardedContext()->Replace(...)unless the fixer is given a context up front viaSetContext(new ShapeBuild_ReShape), and that the fix was applied to "all threeShapeFix_Facecall sites." There are actually four directShapeFix_Faceconstructions in the bridge. Three (OCCTFaceFixerCreate,OCCTShapeCreateFaceFromSurfaceWire,OCCTShapeCreateFaceFromSurfaceWireWithHoles) got theSetContextguard. The fourth,OCCTFaceFix(OCCTBridge_Healing.mm:303, backingFace.fixed(tolerance:)), was never touched and still constructsShapeFix_Facewith no context — it remains exposed to the identical SIGSEGV mechanism SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 fixed everywhere else, on any face whose sole boundary wire is a closed periodic curve belting a conical/cylindrical surface's full period (the exact shapeShape.face(from:boundary:)is regression-tested against inIssue317PeriodicConicalSingleWireTests, but.fixed(tolerance:)is not). The only regression test for the SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 mechanism (Tests/OCCTSurfaceTests/Issue317PeriodicConicalSingleWireTests.swift) exercises only call site Feature Request: Coordinate System Support for CAM #3 above (face(from:boundary:)), notFace.fixed(tolerance:)— so this gap would not be caught by the existing test suite. This is precisely the failure mode the auditor flagged: someone re-auditing allShapeFix_Facecall sites for SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317-class defects via the index-listedOCCTShapeFixFacesymbol finds nothing, and manual grep is needed to find all four real sites — which is how this fourth, unpatched, untested site was found.Separately,
ShapeFix_FaceConnect's single real call site (OCCTShapeFixFaceConnect, backingShape.connectedFaces(tolerance:)) has zero test coverage anywhere inTests/— greppingconnectedFacesacross the whole repo turns up only its own declaration inShape.swift. The staleOCCTShapeFixConnect*index entry (with a wildcard, implying a family of functions) would not have led anyone to this single, untested, real function either.Swift call sites
OCCTFaceFix→Sources/OCCTSwift/Shape.swift:3317, insideextension Face { public func fixed(tolerance: Double = 1e-6) -> Shape? }(declared ~Shape.swift:3316).OCCTFaceFixerCreate/OCCTFaceFixerPerform/OCCTFaceFixerFixOrientation/OCCTFaceFixerFixAddNaturalBound/OCCTFaceFixerFixMissingSeam/OCCTFaceFixerFixSmallAreaWire/OCCTFaceFixerFace/OCCTFaceFixerSetMode/OCCTFaceFixerFixIntersectingWires/OCCTFaceFixerFixPeriodicDegenerated/OCCTFaceFixerFixWiresTwoCoincEdges/OCCTFaceFixerFixLoopWire/OCCTFaceFixerResult/OCCTFaceFixerStatus/OCCTFaceFixerSetMaxTolerance/OCCTFaceFixerSetMinTolerance/OCCTFaceFixerRelease→ all called frompublic final class FaceFixerinSources/OCCTSwift/Document.swift:12029-~12126(despite the name, the class lives inDocument.swift, notFace.swift/Shape.swift).OCCTShapeCreateFaceFromSurfaceWire→Sources/OCCTSwift/Shape.swift:4822, insidepublic static func face(from surface: Surface, boundary: Wire) -> Shape?.OCCTShapeCreateFaceFromSurfaceWireWithHoles→Sources/OCCTSwift/Shape.swift:4867, insidepublic static func face(from surface: Surface, outer: Wire, innerWires: [Wire]) -> Shape?.OCCTShapeFixFaceConnect→Sources/OCCTSwift/Shape.swift:7507, insidepublic func connectedFaces(tolerance: Double = 1e-4) -> Shape?. No other Swift call site.Associated tests
Face.fixed(tolerance:)(OCCTFaceFix): tested inTests/OCCTShapeHealingTests/OCCTShapeHealingTests.swift:115and:126, andTests/OCCTTopologyTests/OCCTTopologyTests.swift:605,614,634— all against ordinary boxes/wires/faces, none against a periodic-conical single-wire boundary (the SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 crash shape). No test exercises the SIGSEGV-risk scenario for this call site.FaceFixerclass: tested inTests/OCCTShapeHealingTests/OCCTShapeHealingTests.swift,Tests/OCCTStressTests/StressBuilderLifecycleTests.swift,Tests/OCCTSurfaceTests/Issue266FaceAnalysisFollowupTests.swift,Tests/OCCTTopologyTests/OCCTTopologyTests.swift(this call site already hasSetContext, so no SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317-specific regression test is needed here, and none was found beyond ordinary functional coverage).Shape.face(from:boundary:)(OCCTShapeCreateFaceFromSurfaceWire): the SIGSEGV in Wire.wireFromEdges on a single closed edge (seam-graph closed-ring rim) — v1.12.6+2; standalone repro attempt negative #317 regression test lives here —Tests/OCCTSurfaceTests/Issue317PeriodicConicalSingleWireTests.swift, testclosedEdgeOnConeSurvivesHealing(), plus general coverage inTests/OCCTSurfaceTests/Issue233FaceFromSurfaceWireTests.swift,OCCTSurfaceTests.swift,Tests/OCCTModelingTests/OCCTModelingTests.swift,Issue234DegenerateHoleTests.swift,Issue397CircularHoleTests.swift,Tests/OCCTTopologyTests/Issue211OuterShellTests.swift,Issue439OuterShellMultiSolidTests.swift, and others.Shape.face(from:outer:innerWires:)(OCCTShapeCreateFaceFromSurfaceWireWithHoles): tested inTests/OCCTSurfaceTests/Issue266FaceWithHolesTests.swift(lines 27, 42, 63, 83) andTests/OCCTSurfaceTests/Issue266FaceAnalysisFollowupTests.swift(lines 56, 72), plusTests/OCCTShapeHealingTests/OCCTShapeHealingTests.swift:2527. No specific periodic-conical-boundary regression test found for this call site either, though it already carries theSetContextfix.Shape.connectedFaces(tolerance:)(OCCTShapeFixFaceConnect): no test coverage found anywhere inTests/— greppingconnectedFacesrepo-wide returns only the function's own declaration inShape.swift.Underlying OCCT functions
OCCTFaceFix(OCCTBridge_Healing.mm:299-325):ShapeFix_Face— constructs withnew ShapeFix_Face(face->face), setsSetPrecision,FixWireMode,FixOrientationMode,FixAddNaturalBoundMode,FixMissingSeamMode,FixSmallAreaWireMode, then callsPerform()andFace().OCCTFaceFixerCreate+ theOCCTFaceFixer*family (OCCTBridge_Healing.mm:4330-~4463):ShapeFix_Face, wrapped per-instance to expose individual fixes:SetContext,SetPrecision,Perform,FixOrientation,FixAddNaturalBound,FixMissingSeam,FixSmallAreaWire(true),Face(), plus mode/tolerance accessors (FixIntersectingWires,FixPeriodicDegenerated,FixWiresTwoCoincEdges,FixLoopWire,Status,SetMaxTolerance,SetMinTolerance).OCCTShapeCreateFaceFromSurfaceWire(OCCTBridge_Modeling.mm:2239-2263):BRepBuilderAPI_MakeFace(surf, wire->wire, Standard_True)to build the initial face, thenShapeFix_Face(SetContext,Perform,Face()) to project pcurves, thenBRepLib::BuildCurves3dandBRepCheck_Analyzerto validate.OCCTShapeCreateFaceFromSurfaceWireWithHoles(OCCTBridge_Modeling.mm:2264-2298): same pattern —BRepBuilderAPI_MakeFace(with.Add(hole)per inner wire, holes reversed on the first attempt), thenShapeFix_Face(SetContext,Perform,Face()),BRepLib::BuildCurves3d,BRepCheck_Analyzer.OCCTShapeFixFaceConnect(OCCTBridge_Healing.mm:2149-~2178+):ShapeFix_FaceConnect— construction on a shell extracted from the input shape (TopoDS::Shellcast, or the firstTopAbs_SHELLfound viaTopExp_Explorer), then connects face pairs (a distinct OCCT class fromShapeFix_Face, despite the near-identical name).Original audit finding: Cross-reference index:
ShapeFix_Face → OCCTShapeFixFace(line 426) — that symbol doesn't exist;ShapeFix_Faceis actually wrapped by the handle-basedOCCTFaceFixer*family (OCCTBridge_Healing.mm:4324-4396, header:16781 on) plus several inline uses (e.g. OCCTBridge_Modeling.mm:2251) that the index entry doesn't mention at all.