---
title: secondmouseau/occtswiftinteraction
framework: Swift Package Catalog
role: article
path: packages/secondmouseau/occtswiftinteraction
---

# secondmouseau/occtswiftinteraction

Identity, selection, and the assembled CAD viewport service for the OCCTSwift stack.

## Three targets, one package

``` OCCTSwiftTools      kernel-to-renderer bridge: Shape into ViewportBody with picking metadata,                     plus the identity tables that give a picked ordinal a durable                     topological identity. No UI framework of any kind.   └─ OCCTSwiftAIS   interactive services: selection state, modes, schemes, filters, area                     selection, manipulator widgets, dimensions. Modeled on OCCT's own AIS_*.        └─ OCCTSwiftCADKit    the assembled SwiftUI CAD viewport service: import, picking,                              clipping, camera framing. ```

```swift import OCCTSwift import OCCTSwiftTools

let box = Shape.box(width: 10, height: 5, depth: 3)! let body = ViewportBody.from(box)! ```

## Why one package instead of three

These were three repositories until [ecosystem#42](https://github.com/SecondMouseAU/ecosystem/issues/42). The boundaries between them are real; the packaging of them was not. Three version lines that only ever moved together, three release cuts that had to happen in strict order, three CI setups. A single cross-cutting change needed six sequenced pull requests across three repositories with a release between each. `OCCTSwiftTools` was 1,123 lines across 9 files, carrying more repository overhead than code.

**The merge does not collapse the modules.** Each is still a SwiftPM target, so the layering stays enforced by the compiler exactly as strictly as it was across package boundaries. Depending on this package does not pull SwiftUI into a headless build: SwiftPM compiles only the targets reachable from the products you name, and `OCCTSwiftTools` imports no UI framework.

This follows `OCCTSwiftUX`, which has vended six targets from one package since well before this.

## Migrating

Your `import` lines do not change. See [docs/MIGRATION.md](docs/MIGRATION.md).

## Documentation

- [docs/MIGRATION.md](docs/MIGRATION.md), moving from the three old packages - [docs/reference/](docs/reference/), per-type reference across all three targets - [docs/guides/](docs/guides/), getting started and cookbook - Historical changelogs: [OCCTSwiftTools](docs/CHANGELOG-OCCTSwiftTools.md),   [OCCTSwiftAIS](docs/CHANGELOG-OCCTSwiftAIS.md)

## Face identity

Face identity keys on OCCT's `TopoDS_Shape::IsSame`: same `TShape`, same `Location`, orientation may differ ([#1](https://github.com/SecondMouseAU/OCCTSwiftInteraction/issues/1)). So `faces()`, the enumeration deduplicated through `TopTools_IndexedMapOfShape`, is what `FaceIdentityTable` is built from, and a face shared between two shells is one selectable thing rather than two. A caller that needs to know which use of a shared face was picked reads orientation off the returned shape, which is how OCCT answers the same question.

## Package Metadata

Repository: secondmouseau/occtswiftinteraction

Default branch: main

README: README.md
