tab_display_name() is the drawing's real filename including its own
extension (e.g. "Drawing1.dwg") - the CamExportDialogOpen handler
appended ".stl" directly onto that, producing "Drawing1.dwg.stl" instead
of "Drawing1.stl". Strips the existing extension via file_stem() first.
Root cause of "reopen shows nothing, Zoom Extents finds nothing" for any
solid saved to DWG and reopened: SabWriter round-trips exact transform
values (0/1 in an identity matrix - the common case for a freshly drawn
solid) as compact SAB integer tokens (tag 0x04), not doubles.
body_transform()'s value-extraction loop only tried
coordinate_components() -> as_float() -> as_string(), never as_integer(),
so it silently parsed 0 of 13 values out of a perfectly valid transform
record. tessellate_sat() then hit its own (already-instrumented) "no
resolvable transform" bailout and aborted the whole document.
Reproduced directly against a real saved/reopened file (a standalone
harness against acadrust+cadkernel, bypassing the app's own broken native
desktop build - unrelated pre-existing issues, not touched here): the
transform record's tokens were confirmed to be Sab{tag:4,...}, and adding
the as_integer() fallback resolved them to the expected identity matrix.
Fix: fall back to token.as_integer() (cast to f64) alongside as_float()
in body_transform(). Added regression coverage with a synthetic
SAB-integer-encoded transform record.
The web build's logger (sys.rs's BannerLogger) installs
log::set_max_level(LevelFilter::Error) - warn! records never reach it (or
even the browser console) at all, they're filtered at the macro call site.
error! also gets a free on-page banner via show_banner(), not just a
console line - the more useful behavior for a user hitting this without
DevTools open.
Every early-out here (a bad-body abort, or zero triangles produced) used
to vanish with no trace anywhere, including upstream's own UI - the exact
reason the open '3D solids don't survive save/reopen' bug has resisted
diagnosis so far. Now logs the body index, which step failed, and (for the
zero-bodies case) how many surfaces/curves/pointers lift() couldn't
resolve, so the next real occurrence is diagnosable from the browser
console instead of another silent None. No behavior change - purely
diagnostic.
Every one of those requests 404s from a CMMS deployment - the embedded
editor's build never carries opencadstudio.com's supporters.json /
video_thumbs/*.jpg / discussions payloads (fetched from pages.dev-style
static hosting upstream, not part of trunk build's output), and the
Start page they'd populate is never shown anyway (embedded launches go
straight into a file). Gated on the existing window.CAD_EDITOR_CONFIG
check; standalone/opencadstudio.com use is unaffected.
1. post_stl_export_to_host() now opens the CAM page with
window.open(..., '_blank') instead of window.location().set_href() -
the latter navigated the CAD editor's own tab away, which tears down
its WASM/GPU/worker context. Going back afterward doesn't reliably
restore it, and a user who then hit Save on the broken restored state
would silently overwrite the real file with whatever that broken state
held. A new tab leaves the original completely untouched. (User report:
CAM froze on load, then going back and saving "blanked" the file.)
2. save_with_default_format(): a plain Save (not Save As) on an
already-loaded document used to ALWAYS serialize using the hardcoded
default format (DWG 2018), ignoring what the document actually was -
confirmed live via a real corrupted attachment (a .dxf that, after one
Save, contained binary DWG bytes under its original .dxf name and
filename, size dropped ~11.6MB -> 1.5MB). This is a pre-existing
upstream gap, not something the CMMS patches introduced - native builds
never hit it because on_save_file()'s native branch has an early-return
for "just re-save to the known path" that preserves the current
version; web has no equivalent and always fell through to this
function's unconditional default. Extended the same format-preservation
logic recovery-saves already use to also apply whenever the document
has a known current_path (i.e. it's not actually a fresh, never-saved
drawing).
Previously the CMMS's STL-export-and-navigate flow was only reachable by
typing STLOUT/EXPORTSTL into the command line, with no visible button and
no way to choose the filename. Adds a proper UI entry point:
- Ribbon: a new quick-access button next to Save As (same style/position,
GEAR icon - no dedicated CAM/CNC icon asset exists), command EXPORTCAM.
- A filename dialog (ModalKind::CamExportDialog, cam_export_filename
field) mirrors the existing Save-As dialog's shape minus the format
picker (always STL) - defaults to "<drawing name>.stl", editable before
confirming.
- STLOUT/EXPORTSTL commands are unchanged (still instant-export using the
drawing's own name, no popup) - this is a second, separate entry point,
not a replacement.
Wires Message::StlExport's existing STLOUT command to the CMMS when
embedded, instead of the native save-dialog flow (which was already
non-functional on the web build regardless - handle_path() has no real
filesystem to write to there, a pre-existing upstream gap, not something
this touches).
- Cargo.toml: add the Location web-sys feature (needed for
window.location().set_href()).
- src/sys.rs: post_stl_export_to_host() - POSTs STL bytes as a new
attachment (cad_export_stl action, not cad_save/cad_save_new - STL isn't
in CAD_EDITABLE_EXT, it needs its own allowlist), then navigates the
browser straight to the CMMS's Kiri:Moto CAM page for the attachment it
just created. Splits cfg.job_id's "type:id" owner token apart to build
cam-edit.php's entity_type=/entity_id= params.
- src/app/mod.rs + update/mod.rs: CmmsStlExportResult message/handler -
only ever surfaces a failure (a success already navigated away).
- src/app/update/mod.rs: Message::StlExport gains a wasm32+embedded branch
that skips the file-picker entirely and calls the above directly.
cad-edit.php?new=1 launches the editor with no attachment_id/load_url yet -
CmmsConfig's load_url/attachment_id/original_name become Optional (only
save_url/job_id/csrf_token are always required). load_from_cmms_web() and
boot_web()'s auto-load task both skip cleanly when load_url is absent (no
error, just the normal blank Start tab). post_bytes_to_host() now takes the
filename and picks cad_save (update, has attachment_id) vs cad_save_new
(create); on a successful create it writes the new id/loadUrl/originalName
back into window.CAD_EDITOR_CONFIG in place, so the tab's *next* save
updates that row instead of creating a duplicate each time.
Additive only - standalone/opencadstudio.com use is unaffected since every
new path is gated on window.CAD_EDITOR_CONFIG being present (set by the
CMMS's cad-edit.php host page, absent everywhere else).
- src/sys.rs: cmms_config() reads window.CAD_EDITOR_CONFIG; post_bytes_to_host()
POSTs saved bytes back via FormData instead of triggering a download.
- src/io/mod.rs: load_from_cmms_web() fetches bytes from the host-provided
loadUrl and feeds them through the existing load_web_bytes parse path.
- src/app/mod.rs: boot_web() auto-loads via load_from_cmms_web() when
embedded; CmmsSaveResult message variant carries the save outcome.
- src/app/update/mod.rs: CmmsSaveResult handler surfaces success/failure
in the command line.
- src/app/update/file.rs: web save branch calls post_bytes_to_host() instead
of download_bytes() when embedded.
- Cargo.toml: add Request/RequestInit/FormData to the web-sys feature list.
Temporary fence pieces used a sentinel handle, so the source spline was included as its own cutting boundary and kernel intersection recursed indefinitely.
Refs #830