Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ No tests exist. No linter is configured.

The full cohort graduated to v1.0 on 2026-05-07 alongside OCCT 8.0.0 GA. SemVer-stable from these floors — only bump on documented breaking changes. Pre-1.0 dep history (which API landed in which 0.x tag) lives in git log; consult it when you actually need to support an older floor, otherwise treat the v1.0 surface as the contract.

- **OCCTSwift** — `https://github.com/gsdali/OCCTSwift.git` (>= 1.15.0; xcframework built against **OCCT 8.0.0p1**). The B-Rep kernel: ~400+ methods for parametric CAD, the full ISO drawings stack (Sheet/TitleBlock/ProjectionSymbol/Section2D/Hatch/AutoCentermarks/CuttingPlaneLine/CosmeticThread/SurfaceFinish/GDT/DetailView/DrawingScale), `FeatureReconstructor` for `reconstruct`, the `SheetMetal` namespace for `compose-sheet-metal`, and the XCAF surfaces (`AssemblyNode.labelId`, `Document.node(at:)`) for `inspect-assembly` / `set-metadata`. **Floored at v1.15.0**: v1.15.0 renamed the Swift wrapper class `TopologyGraph` → `BRepGraph` (OCCTSwift#335) to match the C++ package it wraps; this repo has migrated off the deprecated `TopologyGraph` typealias onto `BRepGraph` directly (OCCTSwiftScripts#78), so the floor must guarantee the `BRepGraph` symbol exists. Earlier, v1.7.0 realigned the BRepGraph wrapper to OCCT's redesigned graph model (definitions vs references/usages, persistent UIDs, controlled layers) and v1.7.1 made the derived graph reads real again — `adjacentFaces`/`faces(of:)`/`edges(of:)`/`sharedEdges`, `faceSameDomain`, `faceIsNaturalRestriction` — plus durable `UID`/`RefUID`/`ItemUID` identity. Our graph verbs (graph-validate/compact/dedup/ml, query-topology) build and run **unchanged** against it. Behaviour changes are **confined to the BRepGraph domain**: `edgeMaxContinuity`/`setEdgeRegularity` are now no-ops (use `Shape.maxContinuity` for continuity); `degenerated`/`closed`/`sameParameter`/`sameRange` setters no-op while their getters return the live derived value. The cookbook ergonomics relied on since v1.3.1 — `Shape.circularPatternCut` (#169), orientation-normalised `Shape.sweep` + `orientedForward`/`signedVolume` (#170), `concaveEdges`/`convexEdges`/`edges(where:)` selectors (#171) — are unchanged. The rest of the cohort still resolves at its existing floors (Viewport 1.0.4 / Tools 1.1.1 / AIS 1.0.2 / Mesh 1.0.0 / IO 1.0.0), all of which compile against 1.15.0.
- **OCCTSwift** — `https://github.com/gsdali/OCCTSwift.git` (>= 1.15.0; xcframework built against **OCCT 8.0.0p1**). The B-Rep kernel: ~400+ methods for parametric CAD, the full ISO drawings stack (Sheet/TitleBlock/ProjectionSymbol/Section2D/Hatch/AutoCentermarks/CuttingPlaneLine/CosmeticThread/SurfaceFinish/GDT/DetailView/DrawingScale), `FeatureReconstructor` for `reconstruct`, the `SheetMetal` namespace for `compose-sheet-metal`, and the XCAF surfaces (`AssemblyNode.labelId`, `Document.node(at:)`) for `inspect-assembly` / `set-metadata`. **Floored at v1.15.0**: v1.15.0 renamed the Swift wrapper class `TopologyGraph` → `BRepGraph` (OCCTSwift#335) to match the C++ package it wraps; this repo has migrated off the deprecated `TopologyGraph` typealias onto `BRepGraph` directly (OCCTSwiftScripts#78), so the floor must guarantee the `BRepGraph` symbol exists. Earlier, v1.7.0 realigned the BRepGraph wrapper to OCCT's redesigned graph model (definitions vs references/usages, persistent UIDs, controlled layers) and v1.7.1 made the derived graph reads real again — `adjacentFaces`/`faces(of:)`/`edges(of:)`/`sharedEdges`, `faceSameDomain`, `faceIsNaturalRestriction` — plus durable `UID`/`RefUID`/`ItemUID` identity. Our graph verbs (graph-validate/compact/dedup/ml, query-topology) build and run **unchanged** against it. Behaviour changes are **confined to the BRepGraph domain**: `edgeMaxContinuity`/`setEdgeRegularity` are now no-ops (use `Shape.maxContinuity` for continuity); `degenerated`/`closed`/`sameParameter`/`sameRange` setters no-op while their getters return the live derived value. The cookbook ergonomics relied on since v1.3.1 — `Shape.circularPatternCut` (#169), orientation-normalised `Shape.sweep` + `orientedForward`/`signedVolume` (#170), `concaveEdges`/`convexEdges`/`edges(where:)` selectors (#171) — are unchanged. The rest of the cohort still resolves at its existing floors (Viewport 1.0.4 / Tools 1.1.1 / AIS 1.0.2 / Mesh 1.0.0 / IO 1.7.5), all of which compile against 1.15.0.
- **OCCTSwiftViewport** — `https://github.com/gsdali/OCCTSwiftViewport.git` (>= 1.0.0). Provides `OffscreenRenderer`, `CameraState`, `DisplayMode`, `ViewportBody` for `render-preview`. Graduated to v1.0.0 on 2026-05-08, one day after the rest of the cohort; floor unblocked by Tools v1.0.2 (closes #45).
- **OCCTSwiftTools** — `https://github.com/gsdali/OCCTSwiftTools.git` (>= 1.0.0; resolves to v1.0.2+ for the widened Viewport constraint). Bridge layer between the B-Rep kernel and the Metal viewport. We use `CADFileLoader.shapeToBodyAndMetadata` in `render-preview` for Shape → `ViewportBody` conversion (both input bodies and highlight sub-shapes). Lives in its own repo since Viewport v0.55.0 split.
- **OCCTSwiftAIS** — `https://github.com/gsdali/OCCTSwiftAIS.git` (>= 1.0.0). Headless-friendly subset only: `Trihedron` / `WorkPlane` / `Axis` / `PointCloud` scene objects (each emits `[ViewportBody]` via `makeBodies()`) for `render-preview`'s `--show-axes` / `--show-workplane` overlays, plus the SubShape selection vocabulary for `--highlight face[N]/edge[M]/vertex[K]`. Selection / Manipulator / SwiftUI surfaces aren't relevant to a CLI. `Dimension` overlays render via a SwiftUI Canvas inside `MetalViewportView` and so can't reach `OffscreenRenderer` — `--annotate-dimensions` is deferred (filed as OCCTSwiftViewport#26). Note: `OCCTSwiftAIS` re-exports a `DisplayMode` enum (3 cases) that collides with `OCCTSwiftViewport.DisplayMode` (6 cases); fully-qualify in `RenderPreview.swift` as `OCCTSwiftViewport.DisplayMode`.
- **OCCTSwiftMesh** — `https://github.com/gsdali/OCCTSwiftMesh.git` (>= 1.0.0). LGPL-2.1 wrapper that vendors `meshoptimizer` (BSD-2-Clause / MIT-equivalent) inside `OCCTMeshOptimizer` for QEM decimation. Powers `simplify-mesh` via `Mesh.simplified(_:)`. Smoothing / repair / remeshing are future work.
- **OCCTSwiftIO** — `https://github.com/gsdali/OCCTSwiftIO.git` (>= 1.0.0). Provides `BRepGraph.exportForML` / `exportJSON` via extension after OCCTSwift v0.171.0 hoisted them out of the kernel. **Pulled into the `GraphML` standalone target and the `graph-ml` verb only** — the rest of the package keeps its existing `ScriptManifest` type from `Sources/ScriptHarness/Manifest.swift` (which carries a `graphs` field that OCCTSwiftIO's `ScriptManifest` is missing). If a future verb wants progress-aware STEP loading via `ShapeLoader.load(from:format:progress:)`, broaden the dep then.
- **OCCTSwiftIO** — `https://github.com/gsdali/OCCTSwiftIO.git` (>= 1.7.5). Provides `BRepGraph.exportForML` / `exportJSON` via extension after OCCTSwift v0.171.0 hoisted them out of the kernel. **Pulled into the `GraphML` standalone target and the `graph-ml` verb only** — the rest of the package keeps its existing `ScriptManifest` type from `Sources/ScriptHarness/Manifest.swift` (which carries a `graphs` field that OCCTSwiftIO's `ScriptManifest` is missing). If a future verb wants progress-aware STEP loading via `ShapeLoader.load(from:format:progress:)`, broaden the dep then. **Floor raised from `>= 1.0.0, < 1.1.0` to `>= 1.7.5`** (OCCTSwiftScripts#80): the old cap (from #69, guarding against OCCTSwiftIO 1.1.0+'s heavy mesh-IO stack — SwiftPMX/SwiftX/ThreeMF/SwiftGLTF via a `MeshIO` target, plus SwiftJWW/SwiftDXF) became unsatisfiable once OCCTSwiftTools >=1.6.1 started requiring OCCTSwiftIO >=1.7.0 directly — any consumer depending on both packages at once (e.g. OCCTMCP) hit an unresolvable graph. Checked OCCTSwiftIO 1.7.5's manifest for a narrower product to preserve the cap's intent: it ships `OCCTSwiftIO` and `MeshIO` as separate library products, but the `OCCTSwiftIO` target has an unconditional target dependency on `MeshIO`, so the heavy stack is unavoidable via either product — there's no BREP/STEP-only surface to depend on instead. Floored at 1.7.5 rather than the bare 1.7.0 Tools needs because 1.7.5 is OCCTSwiftIO's own `TopologyGraph` -> `BRepGraph` rename (mirroring OCCTSwift 1.15.0's rename above), and 1.7.1-1.7.4 are pure OCCTSwift-floor repins for crash/hang fixes already required transitively via our own OCCTSwift >=1.15.0 floor.
- **macOS 15+**, **Swift 6.0+**.
90 changes: 81 additions & 9 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 26 additions & 16 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,6 @@ func occtDep(_ name: String, from version: String) -> Package.Dependency {
return .package(url: "https://github.com/SecondMouseAU/\(name).git", from: Version(version)!)
}

// As occtDep, but pins to the package's minor line instead of an open major range. Used to cap a
// transitive dependency whose newer minors pull deps we don't want in the graph — OCCTSwiftIO 1.1.0+
// pulls in the heavy mesh-IO stack (SwiftX/SwiftDXF/SwiftJWW/SwiftPMX/ThreeMF/SwiftGLTF/…), which the
// narrow GraphML/graphml usage here doesn't need and which breaks resolution for lean consumers that
// have no root package to override from (ecosystem issue: OCCTSwiftScripts#69).
func occtDepUpToNextMinor(_ name: String, from version: String) -> Package.Dependency {
let manifestDir = URL(fileURLWithPath: #filePath).deletingLastPathComponent().path
if isRealLocalSibling(manifestDir, name) {
return .package(path: "../\(name)")
}
return .package(url: "https://github.com/SecondMouseAU/\(name).git", .upToNextMinor(from: Version(version)!))
}

let package = Package(
name: "OCCTSwiftScripts",
platforms: [
Expand Down Expand Up @@ -128,9 +115,32 @@ let package = Package(
// v0.171.0 hoisted them out of the kernel. Pulled into GraphML and
// graphml verbs only — the rest of the package keeps its existing
// ScriptManifest type (with the `graphs` field) from ScriptHarness.
// Capped to the 1.0.x minor line (occtDepUpToNextMinor): 1.1.0+ pulls in the
// heavy mesh-IO stack this narrow usage doesn't need (#69).
occtDepUpToNextMinor("OCCTSwiftIO", from: "1.0.0"),
//
// Was capped to the 1.0.x minor line (occtDepUpToNextMinor(from: "1.0.0"),
// #69) because OCCTSwiftIO 1.1.0+ folds in a MeshIO target (SwiftPMX /
// SwiftX / ThreeMF / SwiftGLTF, plus SwiftJWW / SwiftDXF for 2D vector
// formats) that lean consumers didn't want in the graph. Raised to an
// open floor (OCCTSwiftScripts#80): OCCTSwiftTools >=1.6.1 now requires
// OCCTSwiftIO >=1.7.0 directly, so any consumer depending on both
// OCCTSwiftScripts and OCCTSwiftTools at once (e.g. OCCTMCP) hit an
// unsatisfiable version conflict against our <1.1.0 cap. Checked
// OCCTSwiftIO 1.7.5's Package.swift for a narrower product that could
// keep the cap's spirit: it now ships two library products,
// `OCCTSwiftIO` and `MeshIO`, but the `OCCTSwiftIO` target itself
// still lists `MeshIO` as a plain (unconditional) target dependency —
// not a product a consumer can decline. So depending on just the
// `OCCTSwiftIO` product still resolves and checks out the full
// SwiftPMX/SwiftX/ThreeMF/SwiftGLTF stack; there's no BREP/STEP-only
// product to opt into instead. Floored at 1.7.5 rather than the bare
// 1.7.0 Tools needs: 1.7.5 is OCCTSwiftIO's own TopologyGraph ->
// BRepGraph rename (mirroring OCCTSwift's 1.15.0 rename above and
// OCCTSwiftTools 1.6.1 / OCCTSwiftAIS 1.3.1's), and 1.7.1-1.7.4 are
// pure OCCTSwift-floor repins for the same OCCT kernel crash/hang
// fixes (#298/#310/#317/#318/#323) already required transitively via
// our own OCCTSwift >=1.15.0 floor above — no reason to admit an
// OCCTSwiftIO minor that predates fixes we already require elsewhere
// in the graph.
occtDep("OCCTSwiftIO", from: "1.7.5"),
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,4 @@ The `occtkit` executable is a separate target — install via the `Makefile` abo
- [OCCTSwiftTools](https://github.com/SecondMouseAU/OCCTSwiftTools) `>= 1.0.0` (bridge layer used by `render-preview` for Shape→ViewportBody conversion)
- [OCCTSwiftAIS](https://github.com/SecondMouseAU/OCCTSwiftAIS) `>= 1.0.0` (headless overlays for `render-preview`'s `--show-axes` / `--show-workplane` / `--highlight`)
- [OCCTSwiftMesh](https://github.com/SecondMouseAU/OCCTSwiftMesh) `>= 1.0.0` (powers `simplify-mesh`)
- [OCCTSwiftIO](https://github.com/SecondMouseAU/OCCTSwiftIO) `>= 1.0.0` (powers `graph-ml`'s ML feature export)
- [OCCTSwiftIO](https://github.com/SecondMouseAU/OCCTSwiftIO) `>= 1.7.5` (powers `graph-ml`'s ML feature export; floor raised from `>= 1.0.0, < 1.1.0` to stay compatible with OCCTSwiftTools' own `>= 1.7.0` requirement, see OCCTSwiftScripts#80 — no narrower product avoids OCCTSwiftIO's mesh-IO stack, see `Package.swift`)
Loading