fix(imex): block slicing when the prime tower overlaps a parallel-printing zone

IMEX placement validation only walked model instances. The prime tower is
not a ModelObject, so it could sit in a secondary zone or a carriage
collision strip and slice with no warning -- on mirror mode, a carriage
crash. Span (paired-gantry multicolor) is what made towers reachable in
parallel modes, so this is a gap in that feature, not inherited breakage.

The check now returns a cause instead of a bool so the message can name the
offender, and the tower and per-instance paths share one predicate,
imex_hull_violates_zones(), moved to libslic3r and covered by tests.
Overlap is area-based: a hull flush against a zone boundary is legal, only
a crossing violates. The tests pin that in both directions, since switching
to a touch-based test would silently block placements that work today.

The tower footprint comes from the same estimate the scene draws, so
validation matches what the user sees and drags. Three config reads there
are load-bearing in non-obvious ways and are commented at the point of use.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Clifford Garwood
2026-08-03 08:26:38 -04:00
co-authored by Claude Opus 5
parent 3315b88012
commit 3852f4be61
6 changed files with 222 additions and 41 deletions
+12
View File
@@ -7,6 +7,7 @@
#include <sstream>
#include <unordered_set>
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/PresetBundle.hpp"
namespace Slic3r {
@@ -411,4 +412,15 @@ Vec2d compute_imex_slice_offset(bool firmware_managed,
return primary_zone_box->center();
}
bool imex_hull_violates_zones(const std::vector<BoundingBoxf3>& zones, const Polygon& hull)
{
if (hull.points.empty())
return false;
for (const auto& box : zones) {
if (!intersection({box.polygon(true)}, {hull}).empty())
return true;
}
return false;
}
} // namespace Slic3r