Skip to content

Split multi-object 3MF builds into real kit parts - #32

Open
bbolinger wants to merge 3 commits into
mainfrom
feature/3mf-kit-split
Open

Split multi-object 3MF builds into real kit parts#32
bbolinger wants to merge 3 commits into
mainfrom
feature/3mf-kit-split

Conversation

@bbolinger

Copy link
Copy Markdown
Owner

A multi-object .3mf (the MakerWorld/Printables project shape) used to fuse into one un-arrangeable blob: every resource object concatenated, all transforms ignored, treated as a kit of one. This splits each build item into its own world-space STL so parts route through selection, orientation, arrangement, and previews exactly like a zip of STLs.

What resolves now

  • Per-item and per-component transforms (row-vector convention per the core spec)
  • Component trees, with cycle and depth guards
  • Production-extension p:path references into sibling model files inside the archive (the layout MakerWorld/Bambu project files use)
  • Authored object names become the part names in the form; two copies of one object on the authored plate stay two parts

What stays exactly as before

  • Single build item, missing build section, or any parse surprise degrades to the old fused single-mesh path instead of failing the kit
  • Zips with loose STL entries keep priority; the split only serves archives with no direct STLs
  • Over-limit builds reject cleanly through the existing ingest error path

Also widens the u1_kit tool contract to name every accepted input (.stl, .3mf, or a .zip of either) so 3MF uploads are part of the schema rather than model improvisation, and teaches the legacy dispatcher check to route multi-object 3MFs to the kit workflow.

Testing: 16 new tests (transform convention pin, component composition, p:path, quantity, sanitization, all fallbacks, limits, routing); full suite 1115 passed / 14 skipped; on-box end-to-end with real Orca: synthetic two-object 3MF split into named parts, arranged on one plate, sliced to 511KB gcode carrying both part names with correct printer/material metadata.

A .3mf holding several objects used to fuse into one un-arrangeable blob
(every resource object concatenated, transforms ignored, treated as a kit
of one). Build items are now extracted as individual world-space STLs:
per-item and per-component transforms resolved (row-vector convention),
component trees walked with cycle/depth guards, and production-extension
p:path references into sibling model files followed, so MakerWorld-style
projects split correctly. Parts take the names authored in the file and
flow through selection, orient, arrange, and previews like a zip of STLs.

Anything that is not a genuine multi-object build keeps the old fused
path: single build item, no build section, or a parse surprise all
degrade to prior behavior instead of failing the kit. Over-limit builds
reject cleanly through KitIngestError rather than silently fusing.

Also widens the u1_kit tool contract to name every accepted input (.stl,
.3mf, or a .zip of either) so 3MF uploads are covered by the schema
instead of relying on the driving model to try it anyway, and routes
multi-object 3MFs to the kit workflow in the legacy dispatcher check.
The plugin registers u1_kit with its own short description, and it still
said zip-of-STLs only; the same accepted-inputs list now appears in both
model-facing surfaces.
Review pass on the split turned up three things worth closing:

- A mirroring transform (negative determinant, which 3MF permits) flipped
  triangle winding and produced an inside-out STL; the winding is now
  restored whenever the accumulated transform mirrors. Pinned by a
  signed-volume test.
- Model-XML entries were read wholly into RAM with no size cap, unlike
  the STL entries which have had one since v2.1. Every model-entry read
  (split, count, and the old fused path) now rejects declared-oversized
  entries before the bytes are read.
- A resolution failure on a later build item used to leave the earlier
  items' STLs behind next to the fused fallback's output; resolution now
  completes for every item before anything is written.
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