fix: exclude iXex collision strips from auto-arrange placement

Auto-arrange now injects the carriage collision zones as hard excluded
regions (is_virt_object) when an iXex parallel mode is active, using the
same BoundingBoxf3 data already stored for rendering and violation checks.
Objects will no longer be placed in the mirror-edge danger strips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Clifford Garwood
2026-04-06 14:57:57 -04:00
co-authored by Claude Sonnet 4.6
parent b9f7148080
commit 1cacc6d02d
2 changed files with 22 additions and 1 deletions
+19 -1
View File
@@ -540,7 +540,8 @@ void ArrangeJob::process(Ctl &ctl)
Points bedpts = get_shrink_bedpts(m_plater->config(),params);
// When an iXex parallel mode is active, constrain auto-arrange to the primary zone only.
// When an iXex parallel mode is active, constrain auto-arrange to the primary zone only
// and treat carriage collision strips as hard excluded regions.
if (PartPlate* curr_plate = partplate_list.get_curr_plate()) {
if (auto pz = curr_plate->ixex_primary_zone()) {
BoundingBox scaled_pz = scaled(*pz);
@@ -550,6 +551,23 @@ void ArrangeJob::process(Ctl &ctl)
{ scaled_pz.max.x(), scaled_pz.max.y() },
{ scaled_pz.min.x(), scaled_pz.max.y() },
};
for (const BoundingBoxf3& cz : curr_plate->ixex_collision_zones()) {
Polygon poly({
{ scaled(cz.min.x()), scaled(cz.min.y()) },
{ scaled(cz.max.x()), scaled(cz.min.y()) },
{ scaled(cz.max.x()), scaled(cz.max.y()) },
{ scaled(cz.min.x()), scaled(cz.max.y()) },
});
arrangement::ArrangePolygon ap;
ap.poly.contour = poly;
ap.translation = Vec2crd(0, 0);
ap.rotation = 0.0;
ap.is_virt_object = true;
ap.bed_idx = current_plate_index;
ap.height = 1;
ap.name = "IXexCollisionZone";
params.excluded_regions.emplace_back(std::move(ap));
}
}
}
+3
View File
@@ -449,6 +449,9 @@ public:
// Returns the primary-zone bounding box in mm when an iXex parallel mode is active.
// Empty (nullopt) when iXex is off or the mode is "primary" (full-bed).
std::optional<BoundingBoxf> ixex_primary_zone() { ensure_ixex_zones(); return m_ixex_primary_zone_box; }
// Returns carriage collision strips (mm) for the current iXex mode.
// Always call ixex_primary_zone() first to ensure the cache is warm.
const std::vector<BoundingBoxf3>& ixex_collision_zones() const { return m_ixex_collision_zones; }
void update_slice_ready_status(bool ready_slice)
{
m_ready_for_slice = ready_slice;