From f219431935cf95c499cf3bdda1b1e7a40d83c913 Mon Sep 17 00:00:00 2001 From: harrierpigeon Date: Thu, 24 Sep 2026 07:39:43 -0500 Subject: [PATCH] GUI: the plate is open along Y for containment tests on an infinite-Y belt printer PartPlate's containment tests treat the plate as open along Y on a belt printer with belt_printer_infinite_y, so a long part is no longer flagged outside the plate in Prepare while the slicer and the G-code checks accept it. The check reads the printer preset through the app object, which does not exist headlessly, so it is guarded on the plater. --- src/slic3r/GUI/PartPlate.cpp | 16 ++++++++++++++++ src/slic3r/GUI/PartPlate.hpp | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 893260f934..12f4e423e5 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -2783,6 +2783,7 @@ bool PartPlate::check_outside(int obj_id, int instance_id, BoundingBoxf3* boundi BoundingBoxf3 instance_box = bounding_box? *bounding_box: object->instance_convex_hull_bounding_box(instance_id); Polygon hull = instance->convex_hull_2d(); BoundingBoxf3 plate_box = get_plate_box(); + this->open_belt_y(plate_box); if (instance_box.max.z() > plate_box.min.z()) plate_box.min.z() += instance_box.min.z(); // not considering outsize if sinking @@ -3467,6 +3468,19 @@ Polygon PartPlate::get_shared_printable_polygon() const return m_extruder_areas.empty() ? Polygon::new_scale(m_shape) : get_shared_poly(m_extruder_areas); } + +bool PartPlate::belt_open_y() const +{ + // Headless (CLI) plates have no plater and no wxApp behind wxGetApp(); the CLI's own belt + // handling lives in Print::validate(). + if (m_plater == nullptr || wxGetApp().preset_bundle == nullptr) + return false; + const DynamicPrintConfig &printer = wxGetApp().preset_bundle->printers.get_edited_preset().config; + const auto *belt = printer.option("belt_printer"); + const auto *infinite_y = printer.option("belt_printer_infinite_y"); + return belt != nullptr && belt->value && infinite_y != nullptr && infinite_y->value; +} + bool PartPlate::contains(const Vec3d& point) const { return m_bounding_box.contains(point); @@ -3486,6 +3500,7 @@ bool PartPlate::contains(const BoundingBoxf3& bb) const print_volume.min(1) -= Slic3r::BuildVolume::BedEpsilon; print_volume.max(0) += Slic3r::BuildVolume::BedEpsilon; print_volume.max(1) += Slic3r::BuildVolume::BedEpsilon; + this->open_belt_y(print_volume); return print_volume.contains(bb); } @@ -3498,6 +3513,7 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const print_volume.min(1) -= Slic3r::BuildVolume::BedEpsilon; print_volume.max(0) += Slic3r::BuildVolume::BedEpsilon; print_volume.max(1) += Slic3r::BuildVolume::BedEpsilon; + this->open_belt_y(print_volume); return print_volume.intersects(bb); } diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index e913ebaabf..babc88f364 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -427,6 +427,10 @@ public: bool contains(const GLVolume& v) const; bool contains(const BoundingBoxf3& bb) const; bool intersects(const BoundingBoxf3& bb) const; + // A belt printer with belt_printer_infinite_y: the plate is open along Y for the + // containment tests (the drawn plate keeps its shape). + bool belt_open_y() const; + void open_belt_y(BoundingBoxf3 &box) const { if (this->belt_open_y()) { box.min.y() = -1e5; box.max.y() = 1e5; } } void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false, bool show_grid = true);