Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
150 commits
Select commit Hold shift + click to select a range
ba3349f
feat: blob-backed ShapeStore + lazy ShapeProxy for imported shape geo…
Krande Jul 3, 2026
124198a
feat: lazy blob-backed STEP import (ShapeStore default-on) + native-f…
Krande Jul 3, 2026
647c681
feat: lazy ShapeProxy blob fast path + consumer compatibility
Krande Jul 3, 2026
db75a90
feat: lazy shape store for IFC import (native-parametric products)
Krande Jul 3, 2026
42d1941
fix: ShapeProxy counts as Shape in get_all_physical_objects by_type f…
Krande Jul 3, 2026
aa58d3e
feat: boolean operations flow through the NGEOM stream path
Krande Jul 3, 2026
167efca
perf: slots=True on all ada.geom dataclasses
Krande Jul 3, 2026
e8c2b8e
feat: native IFC blob path — IfcNgeomStream feeds the lazy shape store
Krande Jul 3, 2026
e439a88
fix: AdacppBackend.build accepts ConnectedFaceSet and FaceSurface roots
Krande Jul 3, 2026
a5289ad
fix: audit regressions — curve shapes through the lazy store + hydrat…
Krande Jul 4, 2026
7997610
perf: move ClosedShell promotion out of the streaming reader hot loop
Krande Jul 4, 2026
ebf798a
chore: use generic model descriptions in comments
Krande Jul 4, 2026
8f11db4
feat: audit profiling toggle also enables the adacpp C++ pipeline pro…
Krande Jul 4, 2026
4f1e960
feat: C++ pipeline profiles in the audit Metrics panel
Krande Jul 4, 2026
318afae
feat: state filter dropdown in the admin audit log
Krande Jul 4, 2026
267954d
feat: corpus tree file management, upload destination prompt, and Del…
Krande Jul 5, 2026
aca7377
fix: kebab menus and folder picker hidden behind the floating admin p…
Krande Jul 5, 2026
a01a9aa
feat: move/delete/copy progress status bar and editable corpus name/d…
Krande Jul 5, 2026
c8bab5e
feat: corpus uploads skip existing keys and offer a failed-uploads re…
Krande Jul 5, 2026
429c6ce
feat: shift+click range selection in the shared file tree view
Krande Jul 5, 2026
c6bde1b
fix: resolve all 54 corpus audit failures on the buildingSMART IFC sa…
Krande Jul 5, 2026
de23c72
fix: count auto-validation parity cells into the audit run total upfront
Krande Jul 5, 2026
b29eb92
fix: resolve the 16 residual audit failures (ifc re-export + parity l…
Krande Jul 5, 2026
268a821
fix: wireframe STEP round-trip, typed-import fall-through, and the em…
Krande Jul 5, 2026
3d13874
perf: drop the per-call np.vectorize construction in round_array
Krande Jul 5, 2026
197eca9
perf: count parity elements from the tessellation stream, not an asse…
Krande Jul 6, 2026
d0fa554
perf: vectorize FEM shell -> Plate conversion over element arrays
Krande Jul 6, 2026
dae907e
perf: batch the fused FEM-plate stream through the vectorized constru…
Krande Jul 6, 2026
87a1fcf
feat: wire the SURFACE/PANEL merge strategies into the face source
Krande Jul 6, 2026
3a16d58
fix: carry UV p-curves through the streaming IFC B-rep emitter + non-…
Krande Jul 6, 2026
c4ea22f
feat: browse + visualise corpus files from the main storage panel (ad…
Krande Jul 6, 2026
f7f6807
feat: open a cell's cached product in the viewer from the audit grid
Krande Jul 6, 2026
f30e381
feat: gallery mode — prev/next HUD cycling the current scope's files
Krande Jul 6, 2026
4de1cf2
test: guard revolved-beam arc smoothness + relax tessellation-density…
Krande Jul 6, 2026
51e13fb
fix: SAT/STEP shapes render black + gallery doesn't auto-load initial…
Krande Jul 6, 2026
3bcda4e
fix: NGEOM revolve angle units + axis frame (beam splattered around w…
Krande Jul 6, 2026
27101c4
feat: tighten NGEOM stream tessellation to 10deg corpus-wide + revolv…
Krande Jul 6, 2026
bddad0d
fix: IFC beams with rotated ObjectPlacement rendered along the wrong …
Krande Jul 6, 2026
f8af80b
fix: apply the placement transpose fix to IfcShape/product reads too
Krande Jul 6, 2026
bc4d9f0
feat(frontend): auto fit-to-view toggle + gallery arrow keys + desele…
Krande Jul 6, 2026
06386ef
feat: gallery Re-convert button — throwaway conversion into a separat…
Krande Jul 6, 2026
47e7458
test: guard extruded-beam winding via the NGEOM libtess2 production path
Krande Jul 6, 2026
2725df7
fix: IfcPolygonalFaceSet shapes rendered no geometry (solid_geom reje…
Krande Jul 6, 2026
05b4247
feat: I-profile fillet support — round the web/flange junctions from …
Krande Jul 6, 2026
8c6682b
fix: IFC beam cardinal points ignored (no-parent placement path dropp…
Krande Jul 7, 2026
b6bb629
fix: NGEOM profile fillets chorded — sample ArcLine segments (flanges…
Krande Jul 7, 2026
74d684e
fix: exclude _reconvert/ (and _overlays/) blobs from audit runs
Krande Jul 7, 2026
ee0e777
test: pin angular_deg=20 in the libtess2 parity gate
Krande Jul 7, 2026
d3b127c
refactor: make Placement rotation convention self-consistent
Krande Jul 7, 2026
a0cd9e4
fix: bake a generic Shape's placement into solid_geom (rotated shapes…
Krande Jul 7, 2026
d6a0dbd
feat: render IFC4x3 alignment reference curves natively (was zero geo…
Krande Jul 7, 2026
5341f9b
fix: keep loose curve/geometric-set bodies through the STEP round-trip
Krande Jul 7, 2026
aece0f0
fix: alignment curve shapes crashed glb/obj/stl conversion (audit reg…
Krande Jul 7, 2026
3765b2f
feat: adjustable tessellation density — fixed global angle OR adaptiv…
Krande Jul 7, 2026
b71dbe6
feat: enable adaptive tessellation density by default for STEP->GLB
Krande Jul 7, 2026
c9b6a0a
fix: parity over-counted curve-bearing STEP files with an exploded solid
Krande Jul 7, 2026
ea77c2d
feat: adaptive tessellation density by default for STEP->OBJ/STL too
Krande Jul 7, 2026
4dfd201
feat: native IfcSectionedSolidHorizontal reader (was OCC-kernel face …
Krande Jul 7, 2026
cc54439
feat: native IfcMappedItem reader (the #1 corpus kernel fallback)
Krande Jul 7, 2026
a606fde
fix: apply absolute (PlacementRelTo=None) IFC ObjectPlacement to shapes
Krande Jul 7, 2026
502c22f
feat: native IfcFaceBasedSurfaceModel reader + face-set placement baking
Krande Jul 7, 2026
86881af
feat: transparently open gzip-compressed IFC files
Krande Jul 7, 2026
ff003fa
feat(viewer): gallery walk types (geoms/tree) + mesh stats panel
Krande Jul 7, 2026
7b54642
refactor(viewer): fold gallery "tree" walk into the geoms order dropdown
Krande Jul 7, 2026
ee64a2d
fix: IfcRoundedRectangleProfileDef rounding + multi-point IfcLineInde…
Krande Jul 7, 2026
8d43163
feat(viewer): click the gallery HUD name to copy it to clipboard
Krande Jul 7, 2026
69ff644
fix: skip ACIS record header when parsing plane-surface / straight-curve
Krande Jul 7, 2026
509edf9
feat: per-cell audit rerun + sum-of-cells run runtime
Krande Jul 8, 2026
5b981fb
feat: audit runtime toggle (cells vs wall) + mobile-collapsible new-r…
Krande Jul 8, 2026
df5565f
fix: a rerun adds only its own delta to wall-clock, not the whole idl…
Krande Jul 8, 2026
6ae5ef9
fix: faceted-brep (IfcFace) inner bounds cut holes, not caps
Krande Jul 8, 2026
181f7cc
feat: audit quality flags — libtess2->OCC fallback + distorted triangles
Krande Jul 8, 2026
99b2b96
fix: faceted breps render natively via libtess2 (dispatch + inferred …
Krande Jul 8, 2026
1e4bcaa
feat: stack audit toast above mobile gallery bar + hide toggle in aud…
Krande Jul 8, 2026
e643a4e
fix: gallery walk crash when switching scopes (stale/disposed mesh refs)
Krande Jul 8, 2026
07f0219
fix: ExtrudedAreaSolid with fillet arcs no longer falls back to OCC (…
Krande Jul 8, 2026
87d3caa
feat: PolygonalFaceSet renders natively via NGEOM (no OCC fallback)
Krande Jul 8, 2026
01429f9
revert: PolygonalFaceSet native encoder (flattened non-planar faces)
Krande Jul 8, 2026
3648d50
feat: PolygonalFaceSet renders natively (3D fan-triangulation, no OCC…
Krande Jul 8, 2026
3d76ad1
feat: SweptDiskSolid renders natively (swept circular profile, no OCC…
Krande Jul 8, 2026
7f0a1e1
feat: IfcAdvancedBrep renders natively (closed shell of advanced faces)
Krande Jul 8, 2026
1855b3c
feat: IfcMappedItem non-rigid + multi-instance render natively (mesh-…
Krande Jul 8, 2026
b81aa8c
feat: CompositeCurve profiles + FaceBasedSurfaceModel render natively
Krande Jul 8, 2026
91c610b
feat: "distorted" gallery walk + crows-nest spike metric
Krande Jul 8, 2026
d25c607
feat: fold Mesh stats under Properties + add a display toggle
Krande Jul 8, 2026
0b367b0
fix: adaptive tessellation coarsening on the streaming STEP->GLB path…
Krande Jul 8, 2026
b857759
fix: multi-item IfcMappedItem face sets render natively (no OCC fallb…
Krande Jul 9, 2026
dc0e982
fix: worker without a DB pool no longer crashes every job (timeout_s …
Krande Jul 9, 2026
59db6f4
chore: advertise the real →GLB engine default (libtess2, not occ-buil…
Krande Jul 9, 2026
ab694ce
feat: non-OCC STEP writer preserves multi-instance mapped shapes anal…
Krande Jul 9, 2026
df3c43a
fix: parity STEP leg uses the non-OCC writer (matches prod; keeps map…
Krande Jul 9, 2026
c77f8e1
feat: NGEOM deserialize decodes swept/CSG solid tags 50-53
Krande Jul 9, 2026
d626255
feat: carry NGEOM stream mesh_type (LINES) through to the GLB primiti…
Krande Jul 9, 2026
ef86ea3
feat(viewer): dedicated Mesh distortion-inspection panel in the scene…
Krande Jul 9, 2026
10774e4
refactor(viewer): mesh distortion scan is a Scene-dropdown "Mesh" mod…
Krande Jul 9, 2026
e2327e5
feat(viewer): mesh triangle-visibility toggles in the Scene→Mesh dist…
Krande Jul 9, 2026
0c4f50b
refactor(viewer): collapsible Options + Distorted-geoms table in the …
Krande Jul 9, 2026
b6de49f
feat(viewer): edge/triangulation toggles rebuild overlays live — no p…
Krande Jul 9, 2026
ca52882
feat: native pure-C++ IFC reader/writer selectable in from_ifc / to_i…
Krande Jul 9, 2026
a128353
feat: native IFC reader honors cad_shape_store_compress (compression …
Krande Jul 9, 2026
58480d1
feat: native adacpp IFC->GLB is the prod default (.ifc->glb), fallbac…
Krande Jul 9, 2026
a3e156e
feat: data-driven serializer × tessellator reconvert dropdowns
Krande Jul 10, 2026
43ff764
feat: native (no-pyodide) in-browser STEP→GLB route for the wasm seri…
Krande Jul 10, 2026
223d2d4
feat: OPFS-streaming tier for the native in-browser STEP→GLB route
Krande Jul 10, 2026
0dd1dcd
feat: wire native (no-pyodide) IFC→GLB wasm route; generalize the CAD…
Krande Jul 10, 2026
1220441
feat: backend-driven axis titles for the shared path selector (Tessel…
Krande Jul 10, 2026
09a7b29
feat: serializer × writer path dropdowns for B-rep→B-rep (step→ifc, i…
Krande Jul 10, 2026
c4c2171
feat: wire native (no-pyodide) in-browser B-rep writer route (STEP↔IFC)
Krande Jul 10, 2026
9c05f13
ci: viewer image promotes all adacpp wasm modules from the base image
Krande Jul 10, 2026
f0f13cd
fix: OPFS-stream the CAD→GLB source through WASMFS, not the browser O…
Krande Jul 10, 2026
4f9e251
feat: OPFS-streaming tier for the native in-browser B-rep writer (STE…
Krande Jul 10, 2026
57adf06
feat: pass cgroup-aware worker count to native IFC->GLB
Krande Jul 10, 2026
33e9dde
fix: show gallery reconvert-path Tools in geoms-walk too (was files-w…
Krande Jul 10, 2026
367d3da
ci: honour a [nodocs] marker in the head commit to skip the slow docs…
Krande Jul 10, 2026
8ef92fa
worker: refresh the adacpp overlay doc note + retrigger a full worker…
Krande Jul 10, 2026
7bd87aa
worker: liveness heartbeat file for a pull-loop livenessProbe [nodocs]
Krande Jul 10, 2026
a79e743
chart: worker livenessProbe on the pull-loop heartbeat file [nodocs]
Krande Jul 10, 2026
c62fb1d
perf: serve viewer config off a cached worker-registry snapshot
Krande Jul 10, 2026
c776549
ci: make docs build opt-in via [docs], not opt-out via [nodocs]
Krande Jul 10, 2026
25e1b42
fix: config.js must not be deferred — breaks SPA auth bootstrap
Krande Jul 11, 2026
b8f0341
perf: prioritise file-listing over worker-listing on storage load
Krande Jul 11, 2026
d9e84e9
fix(chart): heartbeat livenessProbe opt-in — stop crashlooping capabi…
Krande Jul 11, 2026
9a22aa3
perf(auth): persist OIDC discovery doc across reloads
Krande Jul 11, 2026
72567cd
fix: keep the job KV lean — stop the NATS full-bucket-scan storm
Krande Jul 11, 2026
161848d
chore: rebuild worker to pull adacpp feat/lazy-shape-store overlay
Krande Jul 11, 2026
26e1d2f
perf: pre-warm heavy CAD imports in the worker parent + make startup …
Krande Jul 11, 2026
2f79bf5
chore: rebuild worker to pull adacpp 5fe25ba (STEP->obj/stl OOM fix)
Krande Jul 11, 2026
0f81775
feat: log per-conversion triangle count in the audit (convert_meta.tr…
Krande Jul 12, 2026
f29eb0c
perf: malloc_trim the worker parent after each job (bounds fork-inher…
Krande Jul 12, 2026
bb9042c
chore: roll worker — adacpp b83a8f9 (tls model_scale fix) + tri-loggi…
Krande Jul 12, 2026
01b780c
chore: roll worker — adacpp fb9284a (GLB spill buffered in RAM, cut n…
Krande Jul 13, 2026
60b5ade
fix: don't expose caught-exception text in storage-op HTTP responses
Krande Jul 13, 2026
c9ba1fe
chore: bump prefix-dev/setup-pixi from 0.9.6 to 0.10.0
Krande Jul 13, 2026
d0bd47d
fix(viewer): move gallery hooks above the enabled early-return (rules…
Krande Jul 13, 2026
043297c
feat(viewer): jump-to-file picker from the gallery counter
Krande Jul 13, 2026
a0cc0f7
chore: roll worker+viewer — adacpp 50e8148 (IFC placement/voids, STEP…
Krande Jul 13, 2026
2981e8b
fix(viewer): stop polling a killed conversion (clears the stuck "Re-c…
Krande Jul 13, 2026
beb7395
feat: fold dropped-face health into audit convert_meta.geom_health
Krande Jul 13, 2026
44af987
feat(viewer): "dropped faces" flag in the audit run grid
Krande Jul 13, 2026
53cb026
chore: roll worker — adacpp 3baa1fe (dropped-face health counter) + a…
Krande Jul 13, 2026
213de3d
feat: adapt camera near/far to model size so small models can be zoom…
Krande Jul 13, 2026
287e2d2
feat: adjustable decimals + click-to-copy for the Clicked-at coordinate
Krande Jul 13, 2026
c1c0020
chore: roll worker — adacpp 826e347 (linear-extrusion face tessellation)
Krande Jul 13, 2026
b656979
fix: clamp rect-anchored kebab menu into the viewport (no left spill)
Krande Jul 13, 2026
fdb3d2c
fix: Clicked-at reflects the actual clicked point; drop the underline
Krande Jul 13, 2026
3133350
fix: native-path GLB tree hierarchy (numeric parent id lookup)
Krande Jul 13, 2026
497fedf
feat: face-level picking in the viewer (opt-in face_ranges consumption)
Krande Jul 13, 2026
2bb9248
fix: face picking resolved wrong mesh-name key; auto-revert to Solid
Krande Jul 13, 2026
e8da795
feat: per-face highlighting in Faces mode
Krande Jul 13, 2026
6ecdf61
fix: face picking via GPU pick (robust at any zoom) + blue face-only …
Krande Jul 13, 2026
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
37 changes: 20 additions & 17 deletions .forgejo/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -314,26 +314,29 @@ jobs:

# Docs image is a Sphinx static site (deploy/Dockerfile.docs)
# that also bundles the paradoc-backed FEA verification report.
# Rebuild on docs/**, the report source tree, pixi env files,
# the Dockerfile, or the workflow itself. Fast = only the doc
# sources changed (re-run fea-doc + sphinx on the env base);
# env/Dockerfile/workflow changes need the full build.
# It is by far the slowest image to build, so it is OPT-IN: it
# builds only when the head commit message carries a ``[docs]``
# marker, regardless of what changed. Viewer/worker builds are
# unaffected. Works for push and workflow_dispatch (GITHUB_SHA is
# the branch tip either way; fetch-depth:0 above makes the message
# available).
docs=false
docs_full=false
if match_scope "$DOCS_CHANGED" '^docs/' || \
match_scope "$DOCS_CHANGED" '^src/ada/' || \
match_scope "$DOCS_CHANGED" '^pixi\.(toml|lock)$' || \
match_scope "$DOCS_CHANGED" '^pyproject\.toml$' || \
match_scope "$DOCS_CHANGED" '^verification/' || \
match_scope "$DOCS_CHANGED" '^deploy/Dockerfile\.docs(-fast)?$' || \
match_scope "$DOCS_CHANGED" '^\.forgejo/workflows/build\.yaml$'; then
COMMIT_MSG=$(git log -1 --format=%B "$GITHUB_SHA" 2>/dev/null || echo "")
if printf '%s' "$COMMIT_MSG" | grep -qiF '[docs]'; then
docs=true
fi
if match_scope "$DOCS_CHANGED" '^pixi\.(toml|lock)$' || \
match_scope "$DOCS_CHANGED" '^pyproject\.toml$' || \
match_scope "$DOCS_CHANGED" '^deploy/Dockerfile\.docs$' || \
match_scope "$DOCS_CHANGED" '^\.forgejo/workflows/build\.yaml$'; then
docs_full=true
# Fast build (re-run fea-doc + sphinx on the cached env base)
# unless the pixi env / Dockerfile / workflow changed — those
# need a full rebuild off a fresh env base.
if match_scope "$DOCS_CHANGED" '^pixi\.(toml|lock)$' || \
match_scope "$DOCS_CHANGED" '^pyproject\.toml$' || \
match_scope "$DOCS_CHANGED" '^deploy/Dockerfile\.docs$' || \
match_scope "$DOCS_CHANGED" '^\.forgejo/workflows/build\.yaml$'; then
docs_full=true
fi
echo "[docs] present in the head commit message — building docs (full=$docs_full)."
else
echo "docs build is opt-in — add [docs] to the head commit message to build it. Skipping."
fi

{
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# SCM syntax highlighting
pixi.lock linguist-language=YAML linguist-generated=true
files/ifc_files/beam-standard-case-gz.ifc binary
2 changes: 1 addition & 1 deletion .github/workflows/ci-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
with:
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo

- uses: prefix-dev/setup-pixi@v0.9.6 # https://github.com/prefix-dev/setup-pixi
- uses: prefix-dev/setup-pixi@v0.10.0 # https://github.com/prefix-dev/setup-pixi
with:
pixi-version: v0.68.0
environments: docs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main-profiling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
fetch-depth: 0

- name: Setup Pixi
uses: prefix-dev/setup-pixi@v0.9.6
uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: profile
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-profiling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
persist-credentials: false

- name: Setup Pixi
uses: prefix-dev/setup-pixi@v0.9.6
uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: profile
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6 # https://github.com/prefix-dev/setup-pixi
- uses: prefix-dev/setup-pixi@v0.10.0 # https://github.com/prefix-dev/setup-pixi
with:
pixi-version: v0.68.0
cache: true
Expand All @@ -41,7 +41,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6
- uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: tests
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6 # https://github.com/prefix-dev/setup-pixi
- uses: prefix-dev/setup-pixi@v0.10.0 # https://github.com/prefix-dev/setup-pixi
with:
pixi-version: v0.68.0
environments: tests
Expand All @@ -39,7 +39,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6
- uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: >-
Expand All @@ -64,7 +64,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6
- uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: >-
Expand All @@ -85,7 +85,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6
- uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: >-
Expand Down Expand Up @@ -122,7 +122,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- uses: prefix-dev/setup-pixi@v0.9.6
- uses: prefix-dev/setup-pixi@v0.10.0
with:
pixi-version: v0.68.0
environments: >-
Expand Down
9 changes: 5 additions & 4 deletions deploy/Dockerfile.viewer
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ RUN npm run build:serve
COPY --from=adacpp-wheel /out/ /build/dist/wheels/
COPY --from=adapy-wheel /out/ /build/dist/wheels/

# The no-pyodide STEP->GLB embind module (adacpp_step_glb.js + .wasm) ships in the same adacpp base
# image under /out/wasm/, so the copy above lands it at dist/wheels/wasm/. Promote it to /wasm/ — where
# the in-browser "Load STEP" converter (LocalStepLoader -> stepConverter.worker) fetches it. Guarded so
# the build still works against older base images that predate the module.
# The no-pyodide embind modules (adacpp_step_glb / adacpp_ifc_glb / adacpp_brep_writer / adacpp_glb_diff
# .js + .wasm) ship in the same adacpp base image under /out/wasm/, so the copy above lands them at
# dist/wheels/wasm/. Promote the whole dir to /wasm/ — where the in-browser converters (cadGlbConverter
# / brepWriterConverter workers) and the diff utility fetch them. Guarded + globbed so the build works
# against older base images that predate any given module.
RUN mkdir -p /build/dist/wasm && \
if [ -d /build/dist/wheels/wasm ]; then \
mv /build/dist/wheels/wasm/* /build/dist/wasm/ && rmdir /build/dist/wheels/wasm; \
Expand Down
16 changes: 13 additions & 3 deletions deploy/Dockerfile.worker
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
# (the build runner has no egress to Ubuntu mirrors). The conda env
# itself dominates final image size, so a multi-stage trim wouldn't
# meaningfully shrink things.
#
# Rebuild marker (bump to re-pull the ADACPP_BRANCH overlay fresh):
# 2026-07-13d — adacpp feat/lazy-shape-store @ 826e347: tessellate linear-extrusion (tabulated
# cylinder) faces — the surface is semi-infinite along its axis, so the swept-profile inverter no
# longer clamps v to the vector magnitude (which dropped faces) and stays on one profile fold
# (removes over-filled/beyond-limits artifacts). Still carries the dropped-face health counter,
# IFC linear placement + opening voids, the bogus-SI-prefix guard (empty tanks), GLB-spill RAM
# buffering, tls model_scale fix, tri-count logging, parent malloc_trim.

ARG PIXI_VERSION=0.68.0
# CI passes --build-arg IMAGE_TAG=sha-XXXXXXX so the worker can publish
Expand All @@ -19,9 +27,11 @@ ARG IMAGE_TAG=dev
# CI stages the branch source into ./adacpp-src (clone) or an empty dir, and passes the branch
# name so the builder stage below knows whether to build. Built with adacpp's own pinned env
# (occt ==7.9.3), which matches what the released ada-cpp links → ABI-compatible .so.
# The feat/ngeom-alignment-sweep overlay HEAD carries: alignment fixed-reference swept solid
# (SweepN), the step_parity single-parse fan-out (STEP parity), and incremental meshopt in the
# native GLB writer (halves peak RSS on large merged GLBs — fixes the STEP→GLB OOM).
# The feat/lazy-shape-store overlay HEAD carries: the z=0 face-set plane-fit (IfcFacetedBrep /
# Triangulated- + PolygonalFaceSet no longer render as a flat sheet), parallel native IFC→GLB,
# a B-spline-weighted LPT cost estimate + per-solid audit instrumentation (spearman_est_ms/tris),
# the NAUO-gate fix for the crane STEP→GLB regression, and a moderate 4 MB malloc mmap/trim that
# trims streaming-tessellation peak RSS.
ARG ADACPP_BRANCH=""

# ---- optional adacpp-branch overlay (gated by ADACPP_BRANCH) -----------------------
Expand Down
27 changes: 27 additions & 0 deletions deploy/helm/adapy-viewer/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,33 @@ spec:
{{- with $w.resources }}
resources: {{- toYaml . | nindent 12 }}
{{- end }}
# Liveness: the worker touches /tmp/worker-alive on every JetStream pull-loop iteration
# (<=5s when idle) and on conversion progress (~2s). If the pull loop stalls — the durable
# consumer wedges after a NATS restart, leaving the pod "Running" but no longer fetching
# (num_waiting=0) — the file goes stale and k8s restarts the pod, instead of it sitting
# silently broken while jobs pile up unconsumed.
#
# This heartbeat probe ONLY works on pools running the adapy worker image, which writes the
# file. Capability pools that run a foreign image (abaqus, weld-gen) never write it, so the
# probe would fail every time and SIGKILL-crashloop them. Hence it is OPT-IN: emitted only
# when the pool sets `heartbeatLiveness: true` (the adapy worker default) or supplies its own
# `livenessProbe:`. Pools that do neither get no liveness probe.
{{- if or $w.livenessProbe $w.heartbeatLiveness }}
livenessProbe:
{{- with $w.livenessProbe }}
{{- toYaml . | nindent 12 }}
{{- else }}
exec:
command:
- sh
- -c
- 'test $(( $(date +%s) - $(stat -c %Y /tmp/worker-alive 2>/dev/null || echo 0) )) -lt 120'
initialDelaySeconds: 120
periodSeconds: 30
failureThreshold: 4
timeoutSeconds: 5
{{- end }}
{{- end }}
{{- with $w.securityContext }}
securityContext: {{- toYaml . | nindent 12 }}
{{- end }}
Expand Down
5 changes: 5 additions & 0 deletions deploy/helm/adapy-viewer/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ strategy:
worker:
enabled: true
replicaCount: 1
# This pool runs the adapy worker image, which writes /tmp/worker-alive on
# every pull-loop iteration, so the heartbeat livenessProbe applies (restarts
# a wedged pull loop). Capability pools on foreign images must leave this
# unset — see the livenessProbe note in _helpers.tpl.
heartbeatLiveness: true
image:
repository: ghcr.io/krande/adapy-viewer-worker
tag: ""
Expand Down
70 changes: 70 additions & 0 deletions files/ifc_files/bath-csg-solid.ifc
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [NotAssigned]'),'2;1');
FILE_NAME(
/* name */ 'bath-csg-solid.ifc',
/* time_stamp */ '2016-02-04T08:47:55',
/* author */ ('redacted'),
/* organization */ ('redacted'),
/* preprocessor_version */ 'redacted',
/* originating_system */ 'redacted - redacted - 3.14159',
/* authorization */ 'None');

FILE_SCHEMA (('IFC4X3_ADD2'));
ENDSEC;

DATA;
/* general entities required for all IFC data sets, defining the context for the exchange */
#1= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,0.0001,#3,$);
#2= IFCCARTESIANPOINT((0.0,0.0,0.0));
#3= IFCAXIS2PLACEMENT3D(#2,$,$);
#4= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#1,$,.MODEL_VIEW.,$);
#5= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#1,$,.MODEL_VIEW.,$);
/* defines the default building (as required as the minimum spatial element) */
#50= IFCBUILDING('39t4Pu3nTC4ekXYRIHJB9W',#56,'IfcBuilding',$,$,$,$,$,$,$,$,$);
#51= IFCPERSONANDORGANIZATION(#52,#53,$);
#52= IFCPERSON('redacted','redacted',$,$,$,$,$,$);
#53= IFCORGANIZATION($,'redacted',$,$,$);
#54= IFCAPPLICATION(#55,'redacted','redacted','redacted');
#55= IFCORGANIZATION($,'redacted',$,$,$);
#56= IFCOWNERHISTORY(#51,#54,$,.ADDED.,1454575675,$,$,1454575675);
#57= IFCRELCONTAINEDINSPATIALSTRUCTURE('3Sa3dTJGn0H8TQIGiuGQd5',#56,'Building','Building Container for Elements',(#225),#50);
#58= IFCAXIS2PLACEMENT3D(#2,$,$);
#100= IFCPROJECT('0$WU4A9R19$vKWO$AdOnKA',#56,'IfcProject',$,$,$,$,(#1),#101);
#101= IFCUNITASSIGNMENT((#102,#103,#104));
#102= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#103= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#104= IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.);
#105= IFCRELAGGREGATES('091a6ewbvCMQ2Vyiqspa7a',#56,'Project Container','Project Container for Buildings',#100,(#50));
#200= IFCBLOCK(#201,2000.0,800.0,800.0);
#201= IFCAXIS2PLACEMENT3D(#2,$,$);
#202= IFCROUNDEDRECTANGLEPROFILEDEF(.AREA.,'VoidProfile',$,1800.0,600.0,200.0);
#203= IFCAXIS2PLACEMENT3D(#204,$,$);
#204= IFCCARTESIANPOINT((1000.0,400.0,100.0));
#205= IFCDIRECTION((0.0,0.0,1.0));
#206= IFCEXTRUDEDAREASOLID(#202,#203,#205,700.0);
#207= IFCBOOLEANRESULT(.DIFFERENCE.,#200,#206);
#208= IFCCSGSOLID(#207);
#209= IFCREPRESENTATIONMAP(#210,#211);
#210= IFCAXIS2PLACEMENT3D(#2,$,$);
#211= IFCSHAPEREPRESENTATION(#5,'Body','SolidModel',(#208));
#212= IFCMATERIAL('Ceramic',$,$);
#213= IFCRELASSOCIATESMATERIAL('0Pkhszwjv1qRMYyCFg9fjB',#56,'MatAssoc','Material Associates',(#214),#212);
#214= IFCSANITARYTERMINALTYPE('1HarmwaPv3OeJSXpaoPKpg',#56,'Bath',$,$,$,(#209),$,$,.BATH.);
#215= IFCRELDEFINESBYTYPE('1lO$X3e3j9lfVMhNy4MzKB',#56,$,$,(#225),#214);
#216= IFCRELDECLARES('1acQrDhur9399Xqs2jQs4t',#56,$,$,#100,(#214));
#217= IFCDIRECTION((1.0,0.0,0.0));
#218= IFCDIRECTION((0.0,1.0,0.0));
#219= IFCCARTESIANPOINT((0.0,0.0,0.0));
#220= IFCCARTESIANTRANSFORMATIONOPERATOR3D(#217,#218,#219,1.0,#221);
#221= IFCDIRECTION((0.0,0.0,1.0));
#222= IFCMAPPEDITEM(#209,#220);
#223= IFCSHAPEREPRESENTATION(#5,'Body','MappedRepresentation',(#222));
#224= IFCPRODUCTDEFINITIONSHAPE($,$,(#223));
#225= IFCSANITARYTERMINAL('3$$o7C03j0KQeLnoj018fc',#56,$,$,$,#227,#224,$,$);
#226= IFCAXIS2PLACEMENT3D(#2,$,$);
#227= IFCLOCALPLACEMENT($,#226);
ENDSEC;

END-ISO-10303-21;

50 changes: 50 additions & 0 deletions files/ifc_files/beam-extruded-solid.ifc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [NotAssigned]'),'2;1');
FILE_NAME(
/* name */ 'beam-extruded-solid.ifc',
/* time_stamp */ '2016-02-04T08:11:04',
/* author */ ('redacted'),
/* organization */ ('redacted'),
/* preprocessor_version */ 'redacted',
/* originating_system */ 'redacted - redacted - 3.14159',
/* authorization */ 'None');

FILE_SCHEMA (('IFC4X3_ADD2'));
ENDSEC;

DATA;
/* general entities required for all IFC data sets, defining the context for the exchange */
#1= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,0.0001,#3,$);
#2= IFCCARTESIANPOINT((0.0,0.0,0.0));
#3= IFCAXIS2PLACEMENT3D(#2,$,$);
#4= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#1,$,.MODEL_VIEW.,$);
#5= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#1,$,.MODEL_VIEW.,$);
/* defines the default building (as required as the minimum spatial element) */
#50= IFCBUILDING('39t4Pu3nTC4ekXYRIHJB9W',$,'IfcBuilding',$,$,$,$,$,$,$,$,$);
#51= IFCRELCONTAINEDINSPATIALSTRUCTURE('3Sa3dTJGn0H8TQIGiuGQd5',$,'Building','Building Container for Elements',(#211),#50);
#52= IFCAXIS2PLACEMENT3D(#2,$,$);
#100= IFCPROJECT('0$WU4A9R19$vKWO$AdOnKA',$,'IfcProject',$,$,$,$,(#1),#101);
#101= IFCUNITASSIGNMENT((#102,#103,#104));
#102= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#103= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#104= IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.);
#105= IFCRELAGGREGATES('091a6ewbvCMQ2Vyiqspa7a',$,'Project Container','Project Container for Buildings',#100,(#50));
#200= IFCCARTESIANPOINTLIST2D(((2.8,-79.5),(2.8,79.5),(6.31471899999999,87.985281),(14.8,91.5),(50.0,91.5),(50.0,100.0),(-50.0,100.0),(-50.0,91.5),(-14.8,91.5),(-6.31471899999997,87.985281),(-2.79999999999999,79.5),(-2.8,-79.5),(-6.31471899999999,-87.985281),(-14.8,-91.5),(-50.0,-91.5),(-50.0,-100.0),(50.0,-100.0),(50.0,-91.5),(14.8,-91.5),(6.31471899999997,-87.985281)),$);
#201= IFCINDEXEDPOLYCURVE(#200,(IFCLINEINDEX((1,2)),IFCARCINDEX((2,3,4)),IFCLINEINDEX((4,5,6,7,8,9)),IFCARCINDEX((9,10,11)),IFCLINEINDEX((11,12)),IFCARCINDEX((12,13,14)),IFCLINEINDEX((14,15,16,17,18,19)),IFCARCINDEX((19,20,1))),.F.);
#202= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'IPE200',#201);
#203= IFCCARTESIANPOINT((0.0,0.0,0.0));
#204= IFCDIRECTION((0.0,1.0,0.0));
#205= IFCDIRECTION((1.0,0.0,0.0));
#206= IFCAXIS2PLACEMENT3D(#203,#204,#205);
#207= IFCDIRECTION((0.0,0.0,1.0));
#208= IFCEXTRUDEDAREASOLID(#202,#206,#207,1000.0);
#209= IFCSHAPEREPRESENTATION(#5,'Body','SweptSolid',(#208));
#210= IFCPRODUCTDEFINITIONSHAPE($,$,(#209));
#211= IFCBEAM('0EF5_zZRv0pQPddeofU3KT',$,'ExampleBeamName','ExampleBeamDescription',$,#213,#210,'Tag',$);
#212= IFCAXIS2PLACEMENT3D(#2,$,$);
#213= IFCLOCALPLACEMENT($,#212);
ENDSEC;

END-ISO-10303-21;

Binary file added files/ifc_files/beam-standard-case-gz.ifc
Binary file not shown.
Loading
Loading