Fix sequential print collision check depending on object list order - #630
Fix sequential print collision check depending on object list order#630KuzuriAo wants to merge 1 commit into
Conversation
|
/bot add-label bug-fix |
|
Hi, @KuzuriAo I am very glad to see your root cause analysis and fix attempts. |
Follow-up: when this fix still isn't enough@zackaree-shen I wanted to bring this up, since I ran into it myself right after posting this PR: this fix resolves the case where a valid print order exists but the old code never searched for it. It does not, and should not, silence a genuinely unavoidable collision. If two objects are both taller than So if you hit the error after this fix and reordering, cutting/pasting, or nudging objects around doesn't clear it no matter what you try, don't assume the fix is broken. It probably means the printer's clearance settings genuinely can't be satisfied by the current plate layout. How to actually fix a genuine oneThe check only cares about Y position, not X. Two tall objects can sit anywhere in X without conflict, they just can't occupy overlapping Y bands (specifically, within In practice this is fiddlier than it sounds if the objects are large: I tried it on a real case and the two conflicting objects each needed to span nearly the plate's full Y depth, leaving only a few mm of margin to work with after finding a split that satisfied both directions of the constraint. A much easier and more reliable fix, if the flagged object is a merged multi-part "Assembly": split it apart and reposition the pieces individually.
Why this works: the collision check uses Quick summary
|
|
Hello! @KuzuriAo Next, we will proceed with actual print tests to evaluate edge cases under different conditions. At the same time, we will discuss internally the appropriate timeline and version for incorporating this bugfix. We will not merge this PR directly, but once we officially include a fix that contains your contribution, we will definitely link your current PR in the release notes and explicitly express our gratitude to you. If there is any progress, I will contact you. You are also welcome to reach out to me anytime if you have any questions. Thank you again for your support and contribution – let's work together to make things even better! |
|
Thank you for the update. I'm happy that the PR seems to be of help. It certainly has fixed this particular issue for me, but it has also uncovered another deeper issue that I have no had the time or the resources to dig into. It is very peculiar and at first glance, almost appears as if it's the same issue that this PR fixed, but I don't think it is. Over the next few days I hope to have the time to document this issue for you. But, would you like for me to append my findings in this PR or open up a bug? Let me know your preference. |
|
Hi, @KuzuriAo |
|
@zackaree-shen This is a 3MF that I found that triggered this condition after this PR fix has been applied. I have also tested this in the official Snapmaker Orca v2.3.5, without this PR applied and the result is exactly the same. So, it feels like it's a similar issue that this PR fixed, but it's appears that it's deeper than that and there is something really strange that's going on with the This is the part where I haven't had the time or resources to investigate deeper, however I have outlined the exact steps to reproduce this behaviour below. Summy of Steps
By all accounts, this should slice cleanly and with no problem. It does not. Summary of Fix
Detailed stepsDownload the AMS 3MF profile for this model: Switch the printer profile from Bambu Lab P1S to Snapmaker U1: This is the plate in it's default configuration. However, a few things to consider:
After the objects were spread out just enough, the brown shell still shows it's too tall, even though it's exactly the same height as the tan bottom half:
So, I rearranged the plate so the two 30.50mm objects were in the same Y path, so a clean slicing order should be found:
Interestingly, now the blue tail (27.52mm) is now the object that is "too tall", even though it's in the X path with the 30.50mm tan bottom section:
It got me curious why there would even be an object that is still hitting the Z bounding error at all, and why it would be the shorter of the two. So, I decided to test adjusting the
I simply added
The Z bounding error plane disappears:
The plate slices cleanly:
Finally, I sent the print and it printed with no errors at all:
|
|
Thanks a lot! @KuzuriAo
I will check that these day
|
Following up: the Squirtle case, and measuring the U1's actual height-to-rod@zackaree-shen I finally had some time to try and close the loop on the Squirtle 3MF I posted above. Short version: it is not a regression or a gap in this PR. It's the "genuine collision" fallback doing exactly what it should, and I've now measured the U1's real nozzle-to-beam clearance to confirm the profile's What was actually going on with that plateI pulled the geometry straight out of the 3MF instead of trusting the GUI readouts. Plate 1, with the U1 profile (
The part that fooled me was thinking two objects of equal height in the same Y band should be fine. They aren't. The beam sits at (nozzle Z + 27.5) and spans the full X width of the machine, so while the second 30.5 mm object prints its first ~3 mm, the beam runs straight through the top 3 mm of the first one, wherever it is in X. Equal heights don't cancel; the first-printed one is what gets hit. The only escapes are separate Y bands or the single "printed last" slot, and here two objects need it. "Y band" is wider than it looks, too: the check treats raw footprints within My "+0.02 mm on height-to-rod fixes it" observation was a coincidence of margins, not evidence against the check. In that arrangement I had already put the two 30.5s in separate Y bands; the only remaining conflict was the tail (27.52) against one of them. Nudging the threshold to 27.52 dropped the tail out of the "taller than the rod" set and the cycle disappeared. It printed fine because the nozzle is at Z 0.2 on the first layer, which puts the beam at ~27.7, 0.18 mm above the tail. Why the error "moves around" between objects depending on arrangement: when the fallback fires, the vertical check flags the first object in list order that has a later Y-overlapping neighbour. Which member of the cycle gets named is arbitrary. That's cosmetic, but it's what sent me chasing the tail instead of the two shells (see item 2 below). Measuring the real height-to-rodSince the whole thing hinges on whether 27.5 is physically right (upstream OrcaSlicer bumped it to 60 in OrcaSlicer#12824 and reverted to 27.5 in OrcaSlicer#14097 without a measurement being posted either time), I measured it. First, what didn't work: my earlier "it printed fine with height-to-rod raised" tests were all inconclusive. On the U1 the X beam sits in front of the nozzle, so in every one of those layouts the beam passed over empty bed at the critical moment, not over the tall object. The nozzle is the lowest point on the toolhead. So, even though in this test both towers are 30.5mm high and I got the "object too tall" error, when I bumped Height to rod to 30.5, sliced and it printed fine. It printed fine because the beam sits ahead of the nozzle and passed over empty bed, not because there was clearance:
The gauge that did work (two prints, by-object, single filament):
Results:
So the beam's underside is 27.2 to 27.4 mm above the nozzle tip on my U1. The profile's 27.5 is correct. If anything it's ~0.1–0.3 optimistic, but the 0.2 mm first layer covers most of that. The 60 mm value in OrcaSlicer#12824 would have been really unsafe. What this means for the PR, and what I'd do next
Bottom line: the Squirtle case doesn't change anything about this PR. The fix does what it set out to do and that is find a valid print order when one exists, and when one doesn't, it fails the same way it always has, now for a reason I've physically verified rather than one we were guessing at. I'd consider #630 good to go as-is. The follow-ups above (naming the cycle, a one-click "move them apart", bringing auto-arrange in line with the checker, and only counting material above the rod) all build on the order-agnostic check this PR introduces, so this lays the groundwork for making print-by-object actually usable in both Snapmaker Orca and upstream OrcaSlicer. None of this is U1-specific: the check reads three numbers from any printer profile, and the U1 just happens to have the lowest one, so everything above applies to any printer that sets them. Once this PR is in, I think discussion on some of the next-steps would be in order and I would be happy to try and help out where I can. |
…-793 fix(print): sequential clearance Kahn sort + above-rod Y extent (Snapmaker#630, Snapmaker#793)

















Hi @zackaree-shen,
I believe this is a solid fix for issue #586 that we were discussing.
Fix sequential print collision check depending on object list order, not actual geometry
The bug
I ran into this with models designed for Bambu printers, mostly 3mf files pulled from MakerWorld. They'd slice and print fine in Bambu Studio on an actual Bambu printer. But opening the same file in Snapmaker Orca (or Orca) and switching the printer profile over to a Snapmaker U1 would sometimes throw "Assembly is too tall, and collisions will be caused.", error.
That's was the hint that this isn't a real geometry problem. If a file slices and prints cleanly on in Bambu Studio on a Bambu printer, there's no physical reason it shouldn't also slice cleanly on a Snapmaker U1 or any other printer. Swapping the printer profile doesn't change the objects' heights or positions relative to each other. So the error had to be coming from the slicer's own collision check, not from an actual collision.
That's what turned up in
sequential_print_clearance_valid()insrc/libslic3r/Print.cpp. It's supposed to check whether a sequential print's object heights and positions can actually be printed without the toolhead colliding with already-finished objects. Instead, it just sorts objects by their raw position in the object list (object_index) and checks clearance against that order. If the list order happens to put a tall object before a short one it shouldn't, you get the "too tall" error, even when a valid, non-colliding print order exists. Since a 3mf's object-list order is just an artifact of how the file was authored (Bambu Studio, MakerWorld, whatever produced it), and not something the printer profile changes, this made the error effectively random with respect to which printer profile you picked.The workaround right now is cutting an object out of the model and pasting it back in, which reshuffles its position in the object list and sometimes gets you a list order that happens to work. That's luck, not a fix, and it's easy to end up with a file where no amount of cut/paste helps because the check was never actually looking for a valid order in the first place. It was just checking the one it was handed.
There's also a disabled (
#if 0) block above the current logic that tried to solve this properly with a score-propagation heuristic, but it wasn't guaranteed to converge and was turned off.Where "the object list" actually is
The object list lives in
3D/3dmodel.model, in two places that stay in lockstep: a<resources>block with one<object id="N">entry per top-level printable object, and a<build>block with one<item objectid="N" transform="...">entry per instance placed on the plate. Whatever order those entries appear in the XML is the order libslic3r assigns as each object'sobject_indexwhen it loads the file. It's just file order, with no geometric meaning at all. (Each<object>can itself be a multi-part "Assembly": several sub-meshes with their own per-part extruder/color assignments merged into one printable item, which is exactly what the "Assembly is too tall" wording refers to; that's a separate, unrelated feature from the ordering bug.)I confirmed this directly on one of my failing files, saved twice from the same project: once with a Bambu printer profile selected (worked fine) and once after switching to the Snapmaker U1 profile (threw the error). Diffing the two
3dmodel.modelfiles, the geometry, transforms, and part assignments are identical. The only thing that changed is which of the two top-level "Assembly" objects (a shorter Hilt assembly and a taller Body assembly with arms and wings) is listed first:Same two objects, same everything else, just swapped in the list. Under the old code, only the object printed last gets the full
printable_heightallowance; whichever one lands earlier is capped atextruder_clearance_height_to_lid. So depending purely on which of these two saves you opened, either the taller Body assembly got the "last" slot (fine) or the shorter Hilt did (Body then gets capped and throws "too tall"). Nothing about switching the printer profile changes this ordering. It's an incidental side effect of when and how the file gets re-saved (cut/paste, re-export, whatever). Bambu Studio's own sequential-print handling clearly doesn't treat that raw list order as the print order, or the same 3MF file would have thrown the same false collision on the Bambu printer it was designed for, and it didn't.The Fix
Replace the list-order sort with an actual search for a valid print order. The constraint is: every instance except the one printed last is capped at
extruder_clearance_height_to_lid, or the stricterextruder_clearance_height_to_rodif some later-printed instance overlaps it in Y. So at most one instance can need the "last slot," and among the rest, any two instances that overlap in Y and are both taller than the rod-clearance height need the taller one scheduled first.That's a topological sort over a "must print before" constraint graph. The fix builds that graph and runs Kahn's algorithm, breaking ties by the original object index so the result is the smallest reordering of what you already had, not something arbitrary. If a valid order exists, it's used. If it genuinely doesn't (a real, unavoidable collision), it falls back to the original object-list order so the vertical-clearance check below still fires the same descriptive error it always has. The goal here is to stop false positives, not to hide real ones.
Testing
Test files:
The following was a 3mf that sliced cleanly and printed with no problems in Bambu Studio on a Bambu X1C:
Z-bambu.3mf.zip
You can see it will slice cleanly in Bambu Studio:
However, this is the same file opened in Sn(orca) and had the printer profile changed to Snapmaker U1:
Z-U1 2.3mf.zip
Here is by macOS (Apple Silicon) build with the patch applied and no error, slices cleanly:
Here is by Ubuntu 25.10 (questing) build with the patch applied and no error, slices cleanly:
Tested Builds
Built and tested locally against both OrcaSlicer and Snapmaker Orca on:
Results:
This is a pure logic change in one function. No platform-specific code, so it should behave identically everywhere.
Other bugs
While I don't really see any issues opened on Snapmaker/Orcaslicer (other than mine that I think this applies to), I did find a bunch on the main OrcaSlicer github repository that seem like are referring to this bug:
On OrcaSlicer/OrcaSlicer:
#6876: the same false "too tall" warning, reported in 2024 and closed as completed. It clearly came back (or was never fixed at the root), which lines up with what's in this repo now: a disabled #if 0 heuristic block that looks like an earlier, half-working attempt at this exact problem, later turned off in favor of the naive list-order sort that reintroduced the bug.
#14435: a feature request making essentially the same diagnosis, that using height-to-rod/height-to-lid as blind cutoffs "without checking actual geometry is too crude." Its proposed fix is more ambitious than this one (axis-based bounding-box sectors instead of a height plane), but the root-cause framing matches.
#12386: a cruder version of the same idea, force the tallest object last and skip the check for it. This fix effectively derives that outcome as a special case when it's actually needed, instead of asserting it unconditionally, and without giving up the check for genuine unavoidable collisions. Links its own related cluster: #6601 and #6828.
#12505: the mirror-image bug, where the slicer doesn't warn when it should and a real collision gets through during abort or end-of-print parking. Not something this PR touches (that's end-of-print G-code behavior, closer to the Snapmaker #453 family above), but it's a good reminder that getting the ordering logic right matters in both directions.