prepare_print_project
Converts a 3MF project or STL into a new tuned 3MF with adjusted slicing settings and layout, ready for you to open in Bambu Studio, slice and print yourself without altering the original.
Instructions
Turn a part (a 3MF project or an STL) into a NEW project 3MF with tuned slicing parameters, ready for the user to open in Bambu Studio, slice and print THEMSELVES. It never prints and never contacts a printer; the original file is never modified (its SHA-256 is checked before and after) and the output never overwrites a file. It reads the part, lays the knowledge-base overlay on top of the project's own settings (never only the original's), then loops: slice with the Bambu Studio CLI, read the G-code, adjust, slice again (z-hop travels that can knock the part over, brim only when needed, warping, support, walls...) until the engine has nothing more to change, a ladder runs out of steps, it repeats itself, the budget ends, or you cancel. Every round is kept and the best measured one is delivered. First it slices the retargeted, untuned project once as the 'before' baseline. Returns a report (JSON plus a short Portuguese 'resumo' to show the user): verdict ready | ready_with_caveats | not_ready with the reasons; the diff (retarget, tuning, combined versus the original) where every change carries its confidence tag, guide source, rule ids, the round it came in and whether it is VERIFIED (measured on the G-code, slice result, mesh or 3MF, with the fact and its before/after) or PREDICTED ONLY; before/after metrics; the history per round; weak suggestions NOT applied; actions skipped because the part was not described (with the facts to declare); exhausted ladders with the guide's text; blind facts; and untouched risks (hardware checks the engine cannot change). Report the verdict honestly: 'ready' means the engine found nothing left to fix and everything it applied was measured; it is never 'every possibility was tested'. Say what was tried and what was measured, and what is only a guess (most knowledge-base rules are weak: relato, hipotese, nao verificado), and that no printer validated anything. Layout (automatic by default, layout: auto): after the printer retarget it checks that every object stands inside its plate on the TARGET printer's plate grid (outside the plate, straddling an edge, between plates, too close or overlapping, out of the nozzle's reach, too tall, a locked plate) and, when something is wrong or the project uses more plates than it needs, re-lays it out by a fixed policy: one colour (filament set) per plate and never mixed, split across plates, only 0 or 90 degree turns about Z (the authors' tilt is kept), a gap of max(8 mm, 2 x brim + 2 mm) between objects and 5 mm to the edge. The number of plates is decided by MEASURING: each candidate (the fewest plates, then +1 and +2 for the largest colour, and the project as authored moved onto the new grid, which is a measuring stick that wins only when more than 3% faster than every proposal) is sliced with the Studio CLI in one call and the lowest total predicted time over all plates wins (layouts within 3% are tied: smaller longest plate first). The report's layout section lists the issues with evidence, the policy, a table of every candidate (plates, objects per plate, total and longest time, weight, crossing travels per plate), the chosen layout plate by plate and what the slicer estimate cannot see (a failure ruins a whole plate, adhesion, real cooling). layout: check_only reports the issues and the plan and changes nothing; layout: off skips the stage. A locked plate or an object that fits no plate is not fixed and makes the verdict not_ready. The layout has its own slicing budget (layout_max_slices default 6, layout_max_minutes default 12), separate from max_slices. After a layout change the tuning loop measures the plate with the longest predicted time, unless plate_index is passed (then it means the NEW numbering). part_context: declare ONLY what the user told you about the part, in their own words, because no file says it. Set a key when the user said it (true when they said the part is so; false only when they said it is not) and LEAVE IT OUT otherwise: an undeclared key stays unknown, the actions that need it are skipped and listed in the report (skipped.declare_to_enable), never guessed. Do not infer anything from the file name, from how the model looks or from its size: the guide gives no threshold for large, tall-and-narrow or tiny parts, so ask the user (the report's part.questions_for_the_user has the numbers) and call again with the answer. Keys: kind (keychain, pix_plate, face_down_plate or other); load_class (none = decorative; functional = holds, fits or moves something; high_load = takes load or impact, such as a hook or bracket); mold_kind (rigid = plaster, cement or wax poured into it; silicone = a box that silicone is poured into; none ONLY if the user said it is not a mold); booleans is_large_part, is_tall_narrow, is_tiny_part, has_fit_pins_and_holes, has_tight_fit_male_part, is_cut_part, is_cut_pin. Budget: max_slices (default 12) counts every CLI slice, the baseline, an STL's one-off retarget slice and final all-plate verification included; max_minutes (default 20) is checked before each slice, using the last slice's duration. A stop by budget is a caveat, never 'ready'. dry_run builds the plan from the project's own data without slicing anything (needs a 3MF; nothing is delivered). apply 'recommended' writes preset, oficial, bug conhecido, teste de revisor and relato values; hipotese and nao verificado stay suggestions, except ladder steps that a measured trigger checks (reported as weak). 'strong_only' writes only preset, oficial and bug conhecido values, but ladder steps that a measured trigger checks are still applied (reported as weak). Slicing takes minutes per round on a big plate (and per layout candidate): the call reports progress, layout stage included. The output defaults to ~/.fatia-mcp/outputs (or FATIA_OUTPUT_DIR); set output_dir to keep it elsewhere.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Local .3mf project (also a .gcode.3mf) or .stl. Never modified. | |
| apply | No | Which confidences are written. Default recommended. | |
| layout | No | auto (default): fix the layout, deciding the number of plates by measurement. check_only: report the issues and the plan, change nothing. off: skip the layout stage. | |
| dry_run | No | Plan only: no slicing, nothing delivered (the layout is analysed and planned, its candidates unmeasured). Default false. | |
| max_slices | No | Most CLI slices in all (retarget, baseline, tuned rounds and final verification). Default 12. | |
| output_dir | No | Folder for the new project. Default: ~/.fatia-mcp/outputs (or FATIA_OUTPUT_DIR). | |
| bambu_model | No | Printer the user will slice for (x2d, a1, h2d, ...). Default BAMBU_MODEL; the reference printer is the X2D. A project made for another printer is retargeted first. | |
| max_minutes | No | Wall-clock budget in minutes. Default 20. | |
| output_name | No | File name of the new project (not a path). Default <source>_tuned.3mf; a name that exists gets a numeric suffix. | |
| plate_index | No | 0-based plate of a multi-plate 3MF to slice and judge. Default 0, or the plate with the longest predicted time after a layout change. When passed, it means the NEW numbering if the layout rewrote the plates. | |
| part_context | No | What the user said about the part; leave a key out when they did not say it. Never infer from the file. | |
| layout_gap_mm | No | Edge-to-edge gap between objects on a plate. Default max(8, 2 x brim width + 2 when the project has a brim). | |
| open_in_studio | No | Open the new, unsliced project in Bambu Studio for review. Default true; a failure to open is a warning. | |
| layout_margin_mm | No | Distance kept from the edge of the usable area. Default 5. | |
| layout_max_slices | No | CLI slices the layout candidates may use (one per candidate, all its plates). Separate from max_slices. Default 6. | |
| layout_max_minutes | No | Wall-clock minutes the layout candidates may take. Separate from max_minutes. Default 12. |