Skip to main content

Geometric diff for mechanical CAD: structured, rendered, CI-gateable diffs of STEP files. git diff for atoms.

Project description

argus-diff

ci

Site & waitlist: argusdiff.com · Live demo: the Action commenting a geometric diff on a real PR

git diff for atoms. Geometric diff for mechanical CAD: point it at two revisions of a CAD file — STEP, STL, 3MF, OBJ, PLY — and it tells you what actually changed — bodies added/removed/modified, mass and volume deltas, bounding box growth, solid-solid interference — as structured JSON, a terminal summary, and a rendered before/after/overlay image. With CI gate flags, so a mechanical change can fail a pull request the way a broken test does.

AI agents now produce engineering artifacts faster than humans can review them. Verification is the bottleneck. ECAD has diff/review tooling; mechanical CAD — the larger population — reviews screenshots in Slack. This fixes that.

Install

# PyPI release is queued; until then install from GitHub:
pip install "argus-diff[render] @ git+https://github.com/mikelmyers/argus-diff"

Use

argus diff old.step new.step
argus diff old.step new.step --json diff.json --render diff.png --density 2.70
argus diff old.step new.step --fail-on-interference --max-mass-delta-pct 2   # CI gate

Example: a sensor-mount bracket between two revisions — plate thickened, mounting holes opened up, boss enlarged and shifted, a gusset added (modeled slightly overlapping the boss — caught), a locating pin deleted:

bracket diff render

argus-diff 0.1.0
  before: bracket_rev_a.step  (4 bodies)
  after:  bracket_rev_b.step  (4 bodies)

  + 1 added   - 1 removed   ~ 2 modified   = 1 unchanged

  volume: 35638.9 -> 48318.3 mm^3 (+35.58%)
  mass:   96.23 -> 130.46 g @ 2.7 g/cm^3 (+34.23 g)
  interferences (after): 1
    ~ body_0 -> body_0: vol +32.46%, com shift 1.000 mm
        . 4x cylinder face: radius 2.500 -> 3.000 mm, area 94.25 -> 150.80 mm^2, moved 1.000 mm
        . 2x plane face: area 468.00 -> 624.00 mm^2, moved 1.000 mm
    ~ body_1 -> body_1: vol +52.38%, com shift 6.325 mm
        . cylinder face: radius 10.000 -> 12.000 mm, area 879.65 -> 1055.58 mm^2, moved 6.325 mm
    + body_2: 540.0 mm^3
    - body_2: 100.5 mm^3
    ! interference body_1 x body_2: 108.650 mm^3 overlap

Yes — that's the four corner holes opening from ⌀5 to ⌀6 and the boss growing from ⌀20 to ⌀24, localized to the faces, by name. (Face output truncated here; run it to see all lines.)

Exit codes: 0 ok, 1 a gate failed, 2 load/usage error — drop it straight into CI.

In CI / on pull requests

argus ci diffs every STEP file changed between two git refs and emits a PR-comment-ready markdown report plus per-file renders:

argus ci --base origin/main --render-dir renders/ --markdown report.md \
         --fail-on-interference --max-mass-delta-pct 2

Or use the GitHub Action — it comments the report on the PR and uploads the renders as artifacts:

# .github/workflows/cad-review.yml
on: pull_request
permissions:
  contents: read
  pull-requests: write
jobs:
  cad:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: mikelmyers/argus-diff@main
        with:
          density: "2.70"
          fail-on-interference: "true"
          max-mass-delta-pct: "2"

Read more

What changed in this 70 MB STEP file? Now you can actually know. — argus-diff run on two real revisions from the Jubilee toolchanger's history.

How it works

  • STEP is loaded with the open-source OCCT kernel (via cadquery/OCP); assemblies are flattened to solids.
  • Each body gets a geometric fingerprint: volume, surface area, center of mass, bounding box, volume-normalized principal moments of inertia, face and edge counts.
  • Bodies are matched between revisions greedily by fingerprint distance; matched-but-different = modified, unmatched = added/removed.
  • Interference = pairwise boolean-common volume between solids in the new revision (bbox-prefiltered).
  • Renders are tessellated and drawn offscreen with pyvista — works headless under xvfb-run.

Every number in this README is reproducible: python examples/make_examples.py generates the part pair, the command above generates the output.

Scope (honest)

Alpha. Today: STEP/STL/3MF/OBJ/PLY in, body-level diff out; change localization is analytic on B-rep ("4x cylinder face: radius 2.500 -> 3.000 mm") and region-based on meshes ("changed region near (149, 124, 2) mm: max deviation 2.02 mm", rigid translation removed first and stated). --cache makes repeat runs on unchanged files near-instant (measured 480x on a 2x70 MB pair). Mesh files skip the interference check (no exact booleans on meshes yet) and report it as skipped, not as zero; open (non-watertight) meshes report volume as unavailable rather than a made-up number. Not yet: rotation-aware mesh alignment (ICP), feature-tree awareness, drawing/PMI diff, proprietary formats (SolidWorks et al.). Roadmap is driven by what users actually hit — file an issue.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

argus_diff-0.1.1.tar.gz (475.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

argus_diff-0.1.1-py3-none-any.whl (23.0 kB view details)

Uploaded Python 3

File details

Details for the file argus_diff-0.1.1.tar.gz.

File metadata

  • Download URL: argus_diff-0.1.1.tar.gz
  • Upload date:
  • Size: 475.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for argus_diff-0.1.1.tar.gz
Algorithm Hash digest
SHA256 5a0955258ad3e585466b4b1ad37947420f2fcd66a2aee47c6faa0c0a12976ec7
MD5 5f888c6fdd488ee092c663d9ff8e92d0
BLAKE2b-256 3ae7d1b5e4ff48d332e65d8c79f85bce48518dac7f26e6c27c6a687cdf038a52

See more details on using hashes here.

Provenance

The following attestation bundles were made for argus_diff-0.1.1.tar.gz:

Publisher: release.yml on mikelmyers/argus-diff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file argus_diff-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: argus_diff-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 23.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for argus_diff-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6281dbbcaec435c2b67f5cc1e4c67c93cc10300907b2d655e029ceabccfe76ad
MD5 f70e3e2e77af0d51c6b1311ae49be3ae
BLAKE2b-256 0f9690223241bea0167ec3f4584ed803c5f8afbee376dabefafb8ae3f536ce0d

See more details on using hashes here.

Provenance

The following attestation bundles were made for argus_diff-0.1.1-py3-none-any.whl:

Publisher: release.yml on mikelmyers/argus-diff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page