Skip to content

Open the generated 3MF in the default slicer from the desktop app - #148

Open
officialasishkumar wants to merge 1 commit into
vycdev:developfrom
officialasishkumar:feat/issue-69-open-in-slicer
Open

officialasishkumar wants to merge 1 commit into
vycdev:developfrom
officialasishkumar:feat/issue-69-open-in-slicer

Conversation

@officialasishkumar

Copy link
Copy Markdown

After building a model in the desktop app, getting it into a slicer meant going through Save As, finding the file in the file manager and opening it by hand. This adds the "simplest first pass" from #69: an Open in Slicer item in the 3D download menu that builds the 3MF and opens it with the system's default .3mf app in one click.

What changed

Frontend

  • useAppHandlers now has one 3MF export pipeline (geometry, compression, progress overlay) shared by Download 3MF and Open in Slicer. Only the last step differs: save the file, or hand it to the native app. The overlay shows "Opening 3MF in slicer" for that step. If the handoff fails, a new localized message says so and points to Download 3MF. Build failures still show the existing "3MF export failed" message.
  • src/lib/desktopSlicer.ts sends the archive to a new open_model_in_slicer command as raw IPC bytes (invoke(cmd, Uint8Array, { headers })), so a large model isn't turned into a JSON number array. The file name (kromacut-YYYY-MM-DD.3mf, the same as Download 3MF) goes in a header.
  • PreviewActions shows the item only when App passes a handler, and App passes one only when isTauri() is true. The browser menu is unchanged. The popover is now w-auto min-w-48, so longer labels such as the French "Ouvrir dans le logiciel de découpe" fit on one line. English menus keep their current width.

Native (src-tauri/src/slicer_handoff.rs)

  • Accepts only a plain *.3mf name (ASCII letters, digits, -, _, ., no leading dot or path parts) and data that starts with a ZIP signature. Nothing other than a 3MF can be written or opened.
  • Writes to <app cache>/slicer-handoff/. It always creates a new file (name.3mf, then name-1.3mf, and so on) instead of overwriting a copy a slicer may still have open (Windows locks open files), and syncs it before launching. On each handoff, copies older than a day are removed, best effort.
  • Opens the file with the launcher the diagnostics folder already uses (open / xdg-open / explorer), renamed from open_directory to open_with_default_app so both can share it. No new plugin, dependency or capability is needed.

Strings, docs, changelog

  • Four new strings in all 12 locales. The French and Portuguese strings use "logiciel de découpe" and "laminador", the words their guides already use.
  • The export guide's Saving And Cancelling section gets a paragraph in all 12 languages. It covers what the item does, that the slicer has to be the default .3mf app (otherwise the OS may open a 3D viewer or ask which app to use), that the cached copy can be removed after a day so the project should be saved in the slicer, and that the browser should use Download 3MF.
  • Unreleased changelog entry under Added.

Most of the useAppHandlers.ts and App.tsx diff is re-indentation. Prettier only keeps a hook callback hugged when it takes no parameters, and the destructure no longer fits on one line. With whitespace hidden, the change is about 70 lines.

Scope

This is the OS file-association version the issue suggests as a first pass. It doesn't pick a slicer, remember a default, or detect slicer install paths; that could come later on top of the same command. Since the app is launched with spawn, "no app is registered for .3mf" is handled by the OS (a picker or an error dialog) rather than reported by Kromacut. The guide says this.

Closes #69

Tests

  • Rust: four new unit tests in slicer_handoff (file-name validation including traversal, drive and Unicode cases; -1 collision naming without overwriting; rejecting non-ZIP data with nothing written; removing only stale .3mf files). cargo test passes (15/15), and cargo clippy --all-targets and cargo fmt --check are clean (Linux, in a rust:1-bookworm container with the WebKitGTK dev packages).
  • e2e: tests/e2e/open-in-slicer.spec.ts (@smoke):
    • In the browser, the download menu has no Open in Slicer item.
    • On the fake desktop runtime, the built model reaches open_model_in_slicer as a valid 3MF ([Content_Types].xml and a <mesh> in 3D/3dmodel.model) with only the X-Kromacut-File-Name: kromacut-YYYY-MM-DD.3mf header. There is no Save As call, download or alert. A native failure then shows the localized error and the menu is enabled again.
    • The desktop test fails on develop, where the item doesn't exist.
  • tests/e2e/helpers/fakeDesktop.ts now passes invoke options (headers) to handlers as an optional third argument. Existing handlers are unaffected.
  • Ran in the CI Playwright image: npm run lint, npx tsc -b, npm run check:i18n, npm test (1112 pass, 1 skipped), npm run check:e2e, npm run test:e2e (85 passed, including every desktop spec that uses the fake), npm run test:e2e:i18n (17 passed), npm run test:e2e:docs (6 passed), npm run test:docs, and npm run test:i18n.
  • I couldn't launch a packaged desktop build here, so the real Windows/macOS hand-off to a slicer hasn't been tried by hand. The launcher is the same one the diagnostics-folder button already uses.

After building a model, desktop users had to save the 3MF through the
Save As dialog, find it in the file manager and open it in their slicer
by hand. The 3D download menu in the desktop app now has an "Open in
Slicer" item that does this in one step.

Frontend:
- useAppHandlers shares one 3MF export pipeline (geometry, compression
  and progress overlay) between Download 3MF and Open in Slicer. Only
  the last step differs: saving the file, or handing it to the native
  app. A failure in that last step shows a destination-specific error;
  build failures still show the existing 3MF export error.
- src/lib/desktopSlicer.ts sends the archive to the native
  open_model_in_slicer command as raw IPC bytes, so large models are not
  inflated into JSON number arrays, with the file name in a header.
- PreviewActions shows the item only when App passes a handler, which it
  does only in the desktop runtime. The menu now grows to fit longer
  translated labels.

Native (src-tauri/src/slicer_handoff.rs):
- Accepts only a plain *.3mf file name and data that starts with a ZIP
  signature, so nothing other than a 3MF can be written or opened.
- Writes a new file in <app cache>/slicer-handoff, adding -1, -2, ...
  instead of overwriting a copy a slicer may still have open, and syncs
  it before opening. Copies older than a day are removed on the next
  handoff.
- Opens the file with the system default app through the same
  open/xdg-open/explorer launcher used for the diagnostics folder, now
  shared as open_with_default_app.

Strings and the export guide's "Saving And Cancelling" section are
updated in all 12 languages, with an Unreleased changelog entry.

Tests:
- Rust unit tests for file-name validation, collision naming, rejecting
  non-3MF data and stale-file cleanup.
- tests/e2e/open-in-slicer.spec.ts (@smoke): the browser menu has no
  Open in Slicer item. On the fake desktop runtime, the built 3MF
  reaches the native command as a valid archive with a
  kromacut-YYYY-MM-DD.3mf name and no Save As dialog or download, and a
  native failure shows the localized error and re-enables the menu.
- The fake desktop runtime now passes invoke options (headers) to
  command handlers.

Closes vycdev#69
@chatgpt-codex-connector

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ❌ Failed 2026-11-13T04:55:08.308246Z
We couldn’t complete this review. Comment @codex review to try again.
f68e4f2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant