Split multi-object 3MF builds into real kit parts - #32
Open
bbolinger wants to merge 3 commits into
Open
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
What stays exactly as before
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.