Commit graph

12 commits

Author SHA1 Message Date
01de9fdcac Fix 7 issues from deep review
- pyproject.toml: add bcf to [service] dependencies (ifcurl-9rk)
- README.md: replace bogus GET /viewer row with POST /bcf (ifcurl-ttb)
- viewer-url.js: fix GitLab host detection (includes → startsWith) (ifcurl-3n4)
- git.py: call _evict_if_needed() after fetch, not only after clone (ifcurl-t1k)
- bcf.py: add description param to build_bcf(); markup.bcf now includes
  <Description> when provided (ifcurl-7wg)
- service.py: pass request URL as description to build_bcf() (ifcurl-7wg)
- viewer.html: BCF export reads visibility= from URL and sets
  DefaultVisibility accordingly (ifcurl-sto)
- viewer.html: applyCameraParam now switches to orthographic projection
  and applies scale when scale= is present in URL (ifcurl-4l7)
- tests: 3 new tests for description field; update JS tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 11:57:06 +01:00
dae1435519 Add BCF export: /bcf endpoint, build_bcf(), viewer panel
- ifcurl/bcf.py: build_bcf() builds BCF 2.1 zips with perspective/
  orthographic camera, clipping planes, component selection, and
  isolate visibility mode
- ifcurl/service.py: /bcf POST endpoint parses ifc:// URL, resolves
  selector → GUIDs when present, delegates to build_bcf()
- viewer.html: BCF toolbar button + collapsible title/comment form;
  client-side zip generation via JSZip (esm.sh CDN) so the browser
  does not need service access
- tests/test_bcf.py: 21 tests covering build_bcf() unit behaviour and
  the /bcf endpoint including SSRF rejection and selector resolution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 09:59:22 +01:00
7b95551cb8 forgejo: add MIT SPDX license headers to JS/HTML assets
viewer.html, viewer-url.js, and footer.tmpl are intended for Forgejo
contribution and carry MIT headers matching Forgejo's per-file convention.
ThatOpen @thatopen/components (loaded from CDN) is also MIT-licensed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 08:30:56 +01:00
d98d4c35d5 viewer: extract URL logic to viewer-url.js, add JS tests
parseIfcUrl, buildIfcUrl, toRawUrl extracted from viewer.html into
viewer-url.js so they can be imported and tested independently.
viewer.html imports from the module. 32 Node test-runner tests in
tests/test_viewer_url.mjs cover all three functions across GitHub,
GitLab, Forgejo/Gitea, SSH user@ prefix, and round-trip cases.

Caught a bug: + (selector union operator) was being URL-encoded as
%2B in buildIfcUrl; fixed by adding .replace(/%2B/g, "+") alongside
the existing comma fix, in both viewer-url.js and syncCameraUrl.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 07:31:19 +01:00
13c8687027 viewer.html: interactive clipping plane tool
Replaces the raw renderer.clippingPlanes approach with OBC.Clipper:
URL-specified clip= planes are seeded as draggable SimplePlanes.
Toolbar '✂ clip' toggle + double-click on model surface to add planes;
'⊗ clips' button (shown when planes exist) to clear all. syncCameraUrl
now serialises current plane state back to the ifc:// URL on every
camera move or plane drag/create/delete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 07:24:06 +01:00
a33a4f9296 viewer.html: implement clip= clipping planes
applyClipPlanes() parses all repeatable clip= params (6 floats: point +
normal in IFC world coords), transforms each via toThree() into Three.js
space, and sets world.renderer.three.clippingPlanes. syncCameraUrl already
preserves clip= params when rebuilding the URL on camera movement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 07:10:19 +01:00
459047c42a viewer.html: implement selector= parameter
applySelector() classifies elements via OBC.Classifier.byCategory(), then
maps the selector type names to matching categories using prefix matching
(so IfcWall also covers IfcWallStandardCase), and calls hider.isolate() to
show only matching elements. Supports simple type names and + union syntax.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 07:01:41 +01:00
60596ef1a7 viewer.html: structured form UI for ifc:// URL components
Adds a second toolbar row with labelled fields for repo, ref, path,
and selector. Editing any field rebuilds and reloads the ifc:// URL.
The raw URL in row 1 remains editable and copyable. Closes ifcurl-yju.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 22:32:09 +01:00
05ff461ec5 viewer.html: generalise URL parsing, add FOV control
- toRawUrl() now handles SSH user@ prefix, GitHub (raw.githubusercontent.com),
  GitLab (/-/raw/), and Forgejo/Gitea; strips heads/tags/ prefix for hosts
  that don't use gitnamespace form
- FOV input in toolbar: shows current FOV, editing it updates the camera
  and syncs the fov= param in the ifc:// URL
- applyCameraParam now restores fov= from URL when placing camera

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 22:08:53 +01:00
7370776ed6 viewer.html: fix toolbar input focus blocked by camera controls
- Shrink viewer div to start below toolbar (CSS var --toolbar-h via
  ResizeObserver) so the canvas never overlaps the input area
- Disable camera controls on input focus, re-enable on blur
- Stop pointer event propagation from input to prevent camera-controls
  capture

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:41:40 +01:00
81f022d4af viewer.html: URL input, drag-and-drop, IFC coordinate transform, camera placement
- Replace url-display span with editable input; Enter or drag-and-drop loads
  a new ifc:// URL by navigating to the same page with updated ?url= param
- Fix syncCameraUrl: convert Three.js → IFC world coords (x,-z,y) before
  serialising camera= param so URLs are in Z-up IFC space
- Apply IFC → Three.js transform (x,z,-y) when placing camera from URL param
- Drop viewer.py: viewer is now a Forgejo static file; service.py has no
  /viewer or /proxy endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:15:30 +01:00
c2bbcc62c2 Deploy viewer as Forgejo static file; update footer.tmpl URL
viewer.html is now served directly from Forgejo at /assets/viewer.html,
fetching IFC bytes via Forgejo's raw URL (same-origin, auth inherited).
footer.tmpl updated to point to /assets/viewer.html instead of the
ifcurl service. No proxy needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 20:48:36 +01:00