mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 01:41:03 +00:00
fix: constrain auto-arrange to iXex primary zone when parallel mode is active
Adds std::optional<BoundingBoxf> m_ixex_primary_zone_box to PartPlate, populated by calc_ixex_zones() alongside the existing secondary/collision zone geometry. The new ixex_primary_zone() getter calls ensure_ixex_zones() so callers always get fresh data. ArrangeJob::process() replaces the full-bed bedpts with the primary zone corners when the getter returns a value, so auto-arrange no longer drops objects into the bed center. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a3cac6c139
commit
b9f7148080
@@ -540,6 +540,19 @@ 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.
|
||||
if (PartPlate* curr_plate = partplate_list.get_curr_plate()) {
|
||||
if (auto pz = curr_plate->ixex_primary_zone()) {
|
||||
BoundingBox scaled_pz = scaled(*pz);
|
||||
bedpts = {
|
||||
{ scaled_pz.min.x(), scaled_pz.min.y() },
|
||||
{ scaled_pz.max.x(), scaled_pz.min.y() },
|
||||
{ scaled_pz.max.x(), scaled_pz.max.y() },
|
||||
{ scaled_pz.min.x(), scaled_pz.max.y() },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
bool enable_wrapping = global_config.option<ConfigOptionBool>("enable_wrapping_detection")->value;
|
||||
partplate_list.preprocess_exclude_areas(params.excluded_regions, enable_wrapping, 1, scale_(1));
|
||||
|
||||
|
||||
@@ -465,6 +465,7 @@ void PartPlate::calc_ixex_zones()
|
||||
m_ixex_collision_zones.clear();
|
||||
m_ixex_collision_overlay.clear();
|
||||
m_ixex_margin_overlay.clear();
|
||||
m_ixex_primary_zone_box = std::nullopt;
|
||||
|
||||
if (!wxGetApp().preset_bundle)
|
||||
return;
|
||||
@@ -689,6 +690,7 @@ void PartPlate::calc_ixex_zones()
|
||||
double pz_x1 = has_col_sep ? x_min + (pri_col + 1) * zone_w : x_max;
|
||||
double pz_y0 = has_row_sep ? y_min + pri_row * zone_h : y_min;
|
||||
double pz_y1 = has_row_sep ? y_min + (pri_row + 1) * zone_h : y_max;
|
||||
m_ixex_primary_zone_box = BoundingBoxf(Vec2d(pz_x0, pz_y0), Vec2d(pz_x1, pz_y1));
|
||||
|
||||
// Helper: build a BoundingBoxf3 strip, clip to bed, add to members
|
||||
auto add_strip = [&](double sx0, double sx1, double sy0, double sy1) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
@@ -137,10 +138,11 @@ private:
|
||||
GLModel m_gridlines_bolder;
|
||||
std::vector<GLModel> m_ixex_copy_zones; // blue tint (Wong #56B4E9)
|
||||
std::vector<GLModel> m_ixex_mirror_zones; // orange tint (Wong #E69F00)
|
||||
std::vector<BoundingBoxf3> m_ixex_secondary_zone_boxes; // secondary (copy/mirror) zone rects — objects blocked here
|
||||
std::vector<BoundingBoxf3> m_ixex_secondary_zone_boxes; // secondary (copy/mirror) zone rects — objects blocked here
|
||||
std::vector<BoundingBoxf3> m_ixex_collision_zones; // carriage danger strips inside primary zone (mm)
|
||||
std::vector<GLModel> m_ixex_collision_overlay; // red-orange rendered fill for danger strips
|
||||
std::vector<GLModel> m_ixex_margin_overlay; // amber advisory bands just inside collision strips
|
||||
std::optional<BoundingBoxf> m_ixex_primary_zone_box; // primary zone extents in mm; empty when iXex is off/primary-only
|
||||
std::string m_ixex_zones_mode_cache{ "\x01" }; // cached mode+topology key; sentinel = unbuilt
|
||||
GLModel m_height_limit_common;
|
||||
GLModel m_height_limit_bottom;
|
||||
@@ -444,6 +446,9 @@ public:
|
||||
}
|
||||
// Returns true if any instance on this plate overlaps an iXex secondary or collision zone.
|
||||
bool has_ixex_placement_violations();
|
||||
// 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; }
|
||||
void update_slice_ready_status(bool ready_slice)
|
||||
{
|
||||
m_ready_for_slice = ready_slice;
|
||||
|
||||
Reference in New Issue
Block a user