forked from 1b-agent/opencadstudio-upstream
The codec and kernel repositories and crates are renamed opencadcodec and opencadkernel. Inside OCS they are depended on under short keys, so code reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node graph engine). File-format and protocol spellings stay as they were: the ACIS product id `acadrust`, the ACADRUST_* switches and the plugin version keys `acadrust_version` / `acadrust_source`. A button left of MCP on the command line opens a translucent node graph over the viewport, with a palette of object, input, math, logic, list, text and geometry nodes added by click or drag. An object node owns drawing entities and its rows are the Properties panel's own rows for them: the single-object page is extracted from refresh_properties as entity_property_sections, values use the control protocol's property_json, and writes go through set_property_value with a property target override, so the panel, MCP and the graph share one read/write path. A list reaching an object row makes one entity per element. Each graph action is one undo step; the canvas pans and zooms. Co-Authored-By: Claude Opus 5.5 <[email protected]>
106 lines
5.6 KiB
Markdown
106 lines
5.6 KiB
Markdown
# Native vs. Web (WebAssembly)
|
|
|
|
Open CAD Studio ships as a native desktop app and as a WebAssembly build that
|
|
runs in the browser (https://hakanseven12.github.io/OpenCADStudio/). Both are
|
|
built from the same source; the web target drops or shims the pieces that a
|
|
browser can't provide. This page lists the differences.
|
|
|
|
## At a glance
|
|
|
|
| Area | Native (desktop) | Web (wasm) |
|
|
|------|------------------|------------|
|
|
| Windowing | Multi-window (`iced::daemon`) | Single window (`iced::application`); dialogs are in-canvas modals |
|
|
| 3D solid modeling | Yes | Yes — the geometry kernel is pure Rust |
|
|
| Hatch rendering | Yes | **No** — WebGL2 has no vertex-stage storage |
|
|
| Fonts | Embedded stroke fonts + system TrueType + shaping + fallback | Embedded stroke fonts only |
|
|
| File open | Native file dialog → path | Browser picker → bytes |
|
|
| File save | Path / Save dialog → write to disk | Save dialog → direct browser download |
|
|
| Parallelism | Multi-threaded (rayon) | Single-threaded |
|
|
| GPU backend | Vulkan / DX12 / Metal (wgpu) | WebGL2 (WebGPU where available) |
|
|
| Update check / external links | `ureq`, `open` | skipped / `window.open` |
|
|
| External plugins | Native packages + Plugin Manager | **No** — native libraries cannot run in a browser |
|
|
|
|
## Details
|
|
|
|
### 3D solid modeling — web: the same as native
|
|
It used to be off. The modelling kernel was truck, whose mesh and boolean
|
|
crates reach `vtkio → xz2 → lzma-sys` — a C library that cannot cross-compile
|
|
to `wasm32` — so the web build dropped a `solid3d` feature and the Model tab,
|
|
solid tessellation and ACIS import all did nothing there.
|
|
|
|
The kernel is now opencadkernel, which is pure Rust and has no C dependency at
|
|
all, so none of that applies and the feature is gone. The web build makes
|
|
primitives, runs booleans, draws ACIS solids read from a file and writes them
|
|
back out as exact geometry, exactly as the desktop build does.
|
|
|
|
### Hatch rendering — web: not drawn
|
|
The batched hatch pipeline binds a read-only storage buffer in the vertex
|
|
stage. WebGL2 lacks `VERTEX_STORAGE`, so that pipeline is skipped on wasm and
|
|
hatches simply don't render. Everything else (lines, arcs, polylines, text,
|
|
images) draws normally.
|
|
|
|
### Fonts — web: bundled stroke fonts only
|
|
- **Native** discovers installed system fonts (fontdb), extracts TrueType
|
|
outlines (ttf-parser), shapes runs with cosmic-text (ligatures, Arabic
|
|
joining, kerning, bidi), and falls back to a system font for glyphs a stroke
|
|
font lacks.
|
|
- **Web** has no system fonts, and cosmic-text panics with "no default font
|
|
found" on an empty font set, so shaping and fallback are disabled. Only the
|
|
embedded LFF stroke fonts render; a glyph missing from them is skipped.
|
|
(A future option is to fetch a font file from the server at startup.)
|
|
|
|
### File I/O — web: bytes and downloads
|
|
- **Open**: the desktop returns a filesystem path and reads it (streaming).
|
|
The web reads the picked file's bytes via the browser and parses them in
|
|
memory (`io::load_bytes`).
|
|
- **Save**: both show the in-app Save dialog (filename + format). The desktop
|
|
writes to the chosen path; the web serializes to bytes and triggers a direct
|
|
browser download (a Blob + a programmatic `<a download>` click — no
|
|
intermediate "click to download" link). The unsaved-changes prompt's *Save*
|
|
routes through the same dialog on the web.
|
|
- There is no persistent filesystem path on the web, so a name-only path stands
|
|
in for document tracking.
|
|
|
|
### Windowing — web: single window, in-canvas modals
|
|
The desktop uses `iced::daemon` and opens secondary OS windows for every
|
|
manager and style dialog. The browser has only the canvas, so the web uses
|
|
`iced::application` and renders all dialogs (layer/layout/plot managers, the
|
|
style editors, the colour picker, Save / unsaved prompts, About, shortcuts,
|
|
plugins, …) as in-canvas modal overlays. As of the Plan-B work this path is
|
|
shared: native renders the same modals too, so the desktop is effectively
|
|
single-window now. A modal's backdrop dims and blocks clicks but does not
|
|
dismiss; the ✕ button closes it.
|
|
|
|
### Parallelism — web: single-threaded
|
|
`wasm32` has no threads without SharedArrayBuffer (which needs COOP/COEP
|
|
headers GitHub Pages can't set). `crate::par::prelude` re-exports `rayon` on
|
|
native and sequential `std` iterators on wasm, so the same call sites run in
|
|
parallel on the desktop and serially in the browser. Large drawings are slower
|
|
on the web.
|
|
|
|
### External plugins — web: unavailable
|
|
|
|
Marketplace plugins are native `.dll`, `.so`, or `.dylib` packages launched in
|
|
an isolated child process. Browsers cannot load those libraries or spawn the
|
|
plugin runner. The web Plugin button and `PLUGINS` command therefore show a
|
|
short explanation with a link to download the desktop app instead of opening
|
|
the marketplace. Installed desktop plugins remain in the per-user plugins
|
|
folder and load again on the next desktop launch.
|
|
|
|
### Platform shims (`src/sys.rs`)
|
|
- `open_url`: `open::that` on native, `window.open(_blank)` on web.
|
|
- `download_bytes`: web only (Blob + anchor download).
|
|
- `handle_path`: real path on native, a name-only `PathBuf` on web.
|
|
- `platform_info`: OS + arch on native, the browser user-agent on web (used to
|
|
pre-fill the Send Feedback issue).
|
|
- The self-update check (`ureq`) is a no-op on the web.
|
|
|
|
## Build & deploy
|
|
|
|
- Native: `cargo build --release --bin OpenCADStudio`.
|
|
- Web app: `trunk build --release --public-url /app/ --dist dist/app --html-output index.html web-app.html`.
|
|
Run `sh scripts/assemble-site.sh` afterward to add the landing page.
|
|
`.github/workflows/pages.yml` builds and deploys to GitHub Pages on every
|
|
release. No COOP/COEP headers are needed because the web build is
|
|
single-threaded.
|